| name | acad-regions-solids |
| description | Regions, 3D solids — boolean ops, extrusion, sweep, loft, mass properties, Brep |
AutoCAD Regions and 3D Solids
Use this skill when creating or manipulating regions (2D enclosed areas), 3D solids, surfaces, and bodies. Covers boolean operations, solid primitives, extrusion/revolution/sweep/loft, mass properties, sectioning, and sub-entity access via the Brep API.
Region Creation from Closed Curves
Regions are 2D enclosed areas created from closed curve boundaries. Region.CreateFromCurves accepts a DBObjectCollection of curves that form one or more closed loops (curves must meet end-to-end within tolerance).
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
Polyline pline = new Polyline();
pline.AddVertexAt(0, new Point2d(0, 0), 0, 0, 0);
pline.AddVertexAt(1, new Point2d(100, 0), 0, 0, 0);
pline.AddVertexAt(2, new Point2d(100, 50), 0, 0, 0);
pline.AddVertexAt(3, new Point2d(0, 50), 0, 0, 0);
pline.Closed = true;
btr.AppendEntity(pline);
tr.AddNewlyCreatedDBObject(pline, true);
DBObjectCollection curves = new DBObjectCollection();
curves.Add(pline);
DBObjectCollection regions = Region.CreateFromCurves(curves);
foreach (DBObject obj in regions)
{
Region region = (Region)obj;
btr.AppendEntity(region);
tr.AddNewlyCreatedDBObject(region, true);
}
tr.Commit();
}
Multiple open curves that together close a loop also work:
DBObjectCollection curves = new DBObjectCollection();
curves.Add(line1);
curves.Add(arc1);
curves.Add(line2);
DBObjectCollection regions = Region.CreateFromCurves(curves);
Region Boolean Operations
Region regionA = ;
Region regionB = ;
regionA.BooleanOperation(BooleanOperationType.BoolUnite, regionB);
regionA.BooleanOperation(BooleanOperationType.BoolSubtract, regionB);
regionA.BooleanOperation(BooleanOperationType.BoolIntersect, regionB);
Solid3d Primitives
All primitives are created centered at the world origin. Use TransformBy to position them.
Solid3d box = new Solid3d();
box.CreateBox(100, 50, 25);
Solid3d sphere = new Solid3d();
sphere.CreateSphere(25);
Solid3d cyl = new Solid3d();
cyl.CreateFrustum(50, 15, 15, 15);
Solid3d cone = new Solid3d();
cone.CreateFrustum(50, 20, 20, 0);
Solid3d torus = new Solid3d();
torus.CreateTorus(40, 10);
Solid3d wedge = new Solid3d();
wedge.CreateWedge(100, 50, 25);
Solid3d pyramid = new Solid3d();
pyramid.CreatePyramid(50, 4, 20);
Positioning Primitives
Solid3d box = new Solid3d();
box.CreateBox(100, 50, 25);
Matrix3d move = Matrix3d.Displacement(new Vector3d(200, 300, 0));
Matrix3d rot = Matrix3d.Rotation(Math.PI / 4, Vector3d.ZAxis, new Point3d(200, 300, 0));
box.TransformBy(rot * move);
Solid3d from Extrusion
Region region = ;
Solid3d solid = new Solid3d();
solid.Extrude(region, 30.0, 0.0);
Extrude Along a Path
Region profile = ;
ObjectId pathId = ;
Solid3d solid = new Solid3d();
solid.ExtrudeAlongPath(profile, pathId, 0.0);
Solid3d from Revolution
Region profile = ;
Point3d axisPoint = new Point3d(0, 0, 0);
Vector3d axisDir = Vector3d.YAxis;
Solid3d solid = new Solid3d();
solid.Revolve(profile, axisPoint, axisDir, 2 * Math.PI);
Solid3d from Sweep
Entity profileEntity = ;
Entity pathEntity = ;
SweepOptions sweepOpts = new SweepOptions();
Solid3d solid = new Solid3d();
solid.CreateSweptSolid(profileEntity, pathEntity, sweepOpts);
Solid3d from Loft
Entity[] crossSections = new Entity[] { profile1, profile2, profile3 };
LoftOptions loftOpts = new LoftOptions();
Solid3d solid = new Solid3d();
solid.CreateLoftedSolid(crossSections, null, null, loftOpts);
solid.CreateLoftedSolid(crossSections, new Entity[] { guide1 }, null, loftOpts);
Solid3d Boolean Operations
Solid3d solidA = ;
Solid3d solidB = ;
solidA.BooleanOperation(BooleanOperationType.BoolUnite, solidB);
solidA.BooleanOperation(BooleanOperationType.BoolSubtract, solidB);
solidA.BooleanOperation(BooleanOperationType.BoolIntersect, solidB);
Practical Example: Box with Cylindrical Hole
Solid3d box = new Solid3d();
box.CreateBox(100, 100, 50);
btr.AppendEntity(box);
tr.AddNewlyCreatedDBObject(box, true);
Solid3d hole = new Solid3d();
hole.CreateFrustum(60, 15, 15, 15);
btr.AppendEntity(hole);
tr.AddNewlyCreatedDBObject(hole, true);
box.BooleanOperation(BooleanOperationType.BoolSubtract, hole);
Solid3d Mass Properties
Solid3d solid = (Solid3d)tr.GetObject(solidId, OpenMode.ForRead);
double volume = solid.MassProperties.Volume;
Point3d centroid = solid.MassProperties.Centroid;
double[] momentsOfInertia = solid.MassProperties.MomentsOfInertia.ToArray();
double[] productsOfInertia = solid.MassProperties.ProductsOfInertia.ToArray();
double[] radiiOfGyration = solid.MassProperties.RadiiOfGyration.ToArray();
double[] principalMoments = solid.MassProperties.PrincipalMoments.ToArray();
Vector3d[] principalDirs = solid.MassProperties.PrincipalDirections;
Solid3d Sectioning and Slicing
Sectioning (creates a Region cross-section)
Solid3d solid = (Solid3d)tr.GetObject(solidId, OpenMode.ForWrite);
Plane sectionPlane = new Plane(new Point3d(0, 0, 25), Vector3d.ZAxis);
Entity sectionEntity = solid.GetSection(sectionPlane);
if (sectionEntity != null)
{
btr.AppendEntity(sectionEntity);
tr.AddNewlyCreatedDBObject(sectionEntity, true);
}
Slicing (cuts the solid in two)
Plane slicePlane = new Plane(new Point3d(50, 0, 0), Vector3d.XAxis);
Solid3d otherHalf = solid.Slice(slicePlane, true);
if (otherHalf != null)
{
btr.AppendEntity(otherHalf);
tr.AddNewlyCreatedDBObject(otherHalf, true);
}
solid.Slice(slicePlane, false);
SubEntity Access via Brep API
The Brep (Boundary Representation) API provides access to faces, edges, and vertices. Hierarchy: Complex -> Shell -> Face -> BoundaryLoop -> Edge -> Vertex.
using Autodesk.AutoCAD.BoundaryRepresentation;
Solid3d solid = (Solid3d)tr.GetObject(solidId, OpenMode.ForRead);
using (Brep brep = new Brep(solid))
{
foreach (Face face in brep.Faces)
{
ExternalBoundedSurface surf = face.Surface;
double faceArea = face.GetArea();
foreach (BoundaryLoop loop in face.Loops)
{
foreach (Edge edge in loop.Edges)
{
ExternalCurve3d curve = edge.Curve;
Point3d startPt = curve.StartPoint;
Point3d endPt = curve.EndPoint;
}
}
}
foreach (Edge edge in brep.Edges)
{
Point3d pt1 = edge.Vertex1.Point;
Point3d pt2 = edge.Vertex2.Point;
}
foreach (Vertex vertex in brep.Vertices)
Point3d pt = vertex.Point;
int faceCount = brep.Faces.Count();
int edgeCount = brep.Edges.Count();
foreach (Shell shell in brep.Shells)
ShellType type = shell.ShellType;
}
Body and Surface Entities
Surface entities are open surfaces (area but no volume). They cannot participate in solid boolean operations.
ExtrudedSurface extSurf = new ExtrudedSurface();
extSurf.CreateExtrudedSurface(profileEntity, new Vector3d(0, 0, 50), new SweepOptions());
RevolvedSurface revSurf = new RevolvedSurface();
revSurf.CreateRevolvedSurface(profileEntity, axisPoint, axisDir, angle, 0.0, new RevolveOptions());
LoftedSurface loftSurf = new LoftedSurface();
loftSurf.CreateLoftedSurface(crossSections, null, null, new LoftOptions());
SweptSurface sweptSurf = new SweptSurface();
sweptSurf.CreateSweptSurface(profileEntity, pathEntity, new SweepOptions());
PlaneSurface planeSurf = new PlaneSurface();
planeSurf.CreateFromRegion(region);
Body is a lower-level entity rarely used directly. Import from SAT data with Body.CreateFromSatFile("model.sat").
3D Coordinate Systems and Transforms for Solids
Solid3d solid = new Solid3d();
solid.CreateBox(100, 50, 25);
Point3d targetOrigin = new Point3d(500, 200, 100);
Vector3d targetX = new Vector3d(1, 1, 0).GetNormal();
Vector3d targetZ = Vector3d.ZAxis;
Vector3d targetY = targetZ.CrossProduct(targetX).GetNormal();
Matrix3d xform = Matrix3d.AlignCoordinateSystem(
Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
targetOrigin, targetX, targetY, targetZ);
solid.TransformBy(xform);
Matrix3d ucsMatrix = ed.CurrentUserCoordinateSystem;
solid.TransformBy(ucsMatrix);
Solid3d copy = (Solid3d)solid.Clone();
btr.AppendEntity(copy);
tr.AddNewlyCreatedDBObject(copy, true);
copy.TransformBy(Matrix3d.Scaling(2.0, Point3d.Origin));
Gotchas
Region.CreateFromCurves requires curves forming closed loops. Open curves or gaps return an empty collection with no error.
Region.CreateFromCurves accepts a DBObjectCollection, not an ObjectIdCollection. Pass entity objects, not their IDs.
- After a boolean on regions, the second operand becomes a null region (zero area). After a boolean on solids, the second operand is erased from the database.
- Solid primitives are always centered at the world origin. You must
TransformBy to position them.
CreateFrustum with equal radii creates a cylinder. With topRadius = 0 it creates a cone.
Extrude taper angle is in radians. A taper that causes self-intersection throws an exception.
ExtrudeAlongPath requires the path curve to be in the database (pass its ObjectId).
Revolve requires the profile to be entirely on one side of the revolution axis.
CreateSweptSolid and CreateLoftedSolid require all entities to already exist in the database.
Brep must be disposed (using block). Failing to dispose leaks unmanaged ACIS resources.
Brep collections use LINQ-style enumeration. Call .Count() (method), not .Count (property).
Solid3d.MassProperties computes on access. Cache the result for repeated queries.
Solid3d.Slice with getNegativeSide = true returns the other half -- you must add it to the database yourself.
GetSection returns null if the plane does not intersect the solid. Always null-check.
- Surface entities are open surfaces, not solids. They have area but no volume and cannot participate in solid boolean operations.
Related Skills
acad-geometry -- points, vectors, matrices, planes, and coordinate system transforms used to position solids
acad-polylines -- closed polylines as region boundaries and extrusion profiles
acad-hatches -- solid fills and boundary loops share region-based workflows
acad-editor-input -- prompting for entity selection and point picks when building solids interactively