AutoCAD Hatches and Gradient Fills
Use this skill when creating or modifying hatch patterns, solid fills, or gradient fills in drawings.
Creating a Hatch Pattern
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
Hatch hatch = new Hatch();
hatch.SetDatabaseDefaults();
hatch.Normal = Vector3d.ZAxis;
hatch.Elevation = 0.0;
// Step 1: Add to database FIRST (required before SetHatchPattern and AppendLoop)
btr.AppendEntity(hatch);
tr.AddNewlyCreatedDBObject(hatch, true);
// Step 2: Set pattern AFTER AppendEntity, BEFORE AppendLoop
hatch.SetHatchPattern(HatchPatternType.PreDefined, "ANSI31");
hatch.PatternScale = 1.0;
hatch.PatternAngle = 0.0;
// Step 3: Set Associative BEFORE AppendLoop
hatch.Associative = true;
// Step 4: Add boundary loop
ObjectIdCollection boundaryIds = new ObjectIdCollection();
boundaryIds.Add(polylineId); // closed polyline as boundary
hatch.AppendLoop(HatchLoopTypes.External, boundaryIds);
// Evaluate to generate hatch lines
hatch.EvaluateHatch(true);
tr.Commit();
}
Boundary Loop Types
From Entity IDs (most common)
ObjectIdCollection outerBoundary = new ObjectIdCollection();
outerBoundary.Add(outerPolylineId);
hatch.AppendLoop(HatchLoopTypes.External, outerBoundary);
// Add island (inner boundary)
ObjectIdCollection innerBoundary = new ObjectIdCollection();
innerBoundary.Add(innerCircleId);
hatch.AppendLoop(HatchLoopTypes.Default, innerBoundary);
From Polyline Vertices (with bulge)
Point2dCollection vertices = new Point2dCollection();
vertices.Add(new Point2d(0, 0));
vertices.Add(new Point2d(100, 0));
vertices.Add(new Point2d(100, 100));
vertices.Add(new Point2d(0, 100));
DoubleCollection bulges = new DoubleCollection();
bulges.Add(0); bulges.Add(0); bulges.Add(0); bulges.Add(0);
hatch.AppendLoop(HatchLoopTypes.External | HatchLoopTypes.Polyline,
vertices, bulges);
From 2D Curve Edges
Curve2dCollection edges = new Curve2dCollection();
IntegerCollection edgeTypes = new IntegerCollection();
edges.Add(new LineSegment2d(new Point2d(0, 0), new Point2d(100, 0)));
edgeTypes.Add((int)HatchEdgeType.Line); // 1
edges.Add(new CircularArc2d(
new Point2d(100, 0), new Point2d(100, 50), new Point2d(100, 100)));
edgeTypes.Add((int)HatchEdgeType.CircularArc); // 2
edges.Add(new LineSegment2d(new Point2d(100, 100), new Point2d(0, 0)));
edgeTypes.Add((int)HatchEdgeType.Line);
hatch.AppendLoop(HatchLoopTypes.External, edges, edgeTypes);
Using HatchLoop Object
HatchLoop loop = new HatchLoop(HatchLoopTypes.External);
// loop is read-only after construction; use for inspection:
// loop.Curves, loop.Polyline, loop.LoopType, loop.IsPolyline
hatch.AppendLoop(loop);
Loop Management
int loopCount = hatch.NumberOfLoops;
HatchLoopTypes loopType = hatch.LoopTypeAt(0);
HatchLoop loop = hatch.GetLoopAt(0);
// Insert loop at specific position
hatch.InsertLoopAt(1, HatchLoopTypes.Default, boundaryIds);
hatch.InsertLoopAt(1, hatchLoop);
// Remove loop
hatch.RemoveLoopAt(0);
// Get associated objects for a loop
ObjectIdCollection assocIds = hatch.GetAssociatedObjectIdsAt(0);
ObjectIdCollection allAssocIds = hatch.GetAssociatedObjectIds();
hatch.RemoveAssociatedObjectIds();
Solid Fill
Hatch hatch = new Hatch();
hatch.SetDatabaseDefaults();
hatch.Normal = Vector3d.ZAxis;
hatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
// IsSolidFill will be true
Gradient Fills
Hatch gradient = new Hatch();
gradient.SetDatabaseDefaults();
gradient.Normal = Vector3d.ZAxis;
gradient.HatchObjectType = HatchObjectType.GradientObject;
// Set gradient type
gradient.SetGradient(GradientPatternType.PreDefinedGradient, "LINEAR");
// Other names: "CYLINDER", "INVCYLINDER", "SPHERICAL", "INVSPHERICAL",
// "HEMISPHERICAL", "INVHEMISPHERICAL", "CURVED", "INVCURVED"
gradient.GradientAngle = Math.PI / 4; // 45 degrees
// Two-color gradient
gradient.GradientOneColorMode = false;
GradientColor[] colors = new GradientColor[2];
colors[0] = new GradientColor(Color.FromRgb(255, 0, 0), 0.0f); // start
colors[1] = new GradientColor(Color.FromRgb(0, 0, 255), 1.0f); // end
gradient.SetGradientColors(colors);
// One-color gradient (single color with tint)
gradient.GradientOneColorMode = true;
gradient.ShadeTintValue = 0.5f; // 0 = dark, 1 = light
gradient.GradientShift = 0.0f;
// Add boundary and evaluate
btr.AppendEntity(gradient);
tr.AddNewlyCreatedDBObject(gradient, true);
gradient.AppendLoop(HatchLoopTypes.External, boundaryIds);
gradient.EvaluateHatch(true);
Gradient methods:
SetGradient(GradientPatternType type, string name)- set gradient patternGetGradientColors()->GradientColor[]- get color stopsSetGradientColors(GradientColor[] colors)- set color stopsEvaluateGradientColorAt(float value)->Color- sample color at position (0-1)
Enums
HatchLoopTypes (flags): Default=0x0, External=0x1, Polyline=0x2, Derived=0x4, Textbox=0x8, Outermost=0x10, NotClosed=0x20, SelfIntersecting=0x40, TextIsland=0x80, Duplicate=0x100
HatchEdgeType: Line=1, CircularArc=2, EllipticalArc=3, Spline=4
HatchStyle: Normal=0 (fills between nested boundaries), Outer=1 (outermost boundary only), Ignore=2 (ignores internal boundaries)
HatchPatternType: UserDefined=0, PreDefined=1, CustomDefined=2
HatchObjectType: HatchObject=0, GradientObject=1
GradientPatternType: PreDefinedGradient=0, UserDefinedGradient=1
Gotchas
- Set the pattern type/name BEFORE adding loops and BEFORE calling
EvaluateHatch AppendLoopmust be called AFTERAppendEntityandAddNewlyCreatedDBObject- the hatch must be in the database firstEvaluateHatch(true)underestimates line count (faster);EvaluateHatch(false)is accurate but slower- For user-defined patterns, use
PatternSpaceinstead ofPatternScale; setPatternDouble = truefor crosshatch Associativemust be set totrueBEFORE adding boundary loops for associativity to work- Boundary loops must be closed - open boundaries cause
EvaluateHatchto fail silently - The outer boundary should use
HatchLoopTypes.External; inner islands should useHatchLoopTypes.Default HatchStyle.Normalalternates fill between nested boundaries;Outerfills only the outermost;Ignorefills everything- For gradients, set
HatchObjectType = HatchObjectType.GradientObjectbefore callingSetGradient PatternNameandPatternTypeare read-only - useSetHatchPattern()to change them- After changing
PatternScale,PatternAngle, orPatternSpace, you must re-callSetHatchPattern(type, name)before callingEvaluateHatch()— otherwise the change has no visual effect - BulgeVertex
Bulgevalue: 0 = straight segment, positive = counterclockwise arc, negative = clockwise arc;tan(includedAngle/4)
Related Skills
acad-polylines— polylines as hatch boundaries; vertex+bulge loop constructionacad-layers— layer assignment for hatch entities