In a similar fashion to the Polyline to Region process mentioned earlier, here an alternate method of retrieving centroids. Sure it’s cheating and ridiculously heavy handed, but isn’t that truly the American way. Just kidding.
Granted, it is probably even slower still than the Poly/Region method – it does, however, allow for the inclusion of “Curved” Polys, Splines, and Regions.
[CommandMethod("EntCen")]
static public void centroid()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions opts = new PromptEntityOptions("\nSelect a planar entity: ");
opts.AllowNone = true;
opts.AllowObjectOnLockedLayer = true;
opts.SetRejectMessage("\nEntity not valid.");
opts.AddAllowedClass(typeof(Polyline), false);
opts.AddAllowedClass(typeof(Polyline2d), false);
opts.AddAllowedClass(typeof(Region), false);
opts.AddAllowedClass(typeof(Spline), false);
PromptEntityResult per = ed.GetEntity(opts);
if (per.Status == PromptStatus.OK)
{
ObjectId ObjID = per.ObjectId;
try
{
using (Transaction trans = db.TransactionManager.StartTransaction())
{
Entity ent = (Entity)trans.GetObject(ObjID, OpenMode.ForRead, false);
CentroidViaSol c = new CentroidViaSol(ent);
if (c.Success)
{
Point3d cen = c.DerivedCentroid;
DBPoint pt = new DBPoint(cen);
BlockTable bTable = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord cSpace = (BlockTableRecord)trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
cSpace.AppendEntity(pt);
trans.AddNewlyCreatedDBObject(pt, true);
trans.Commit();
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage("Error: " + ex.Message);
}
}
}
// New Class //////////////
class CentroidViaSol
{
//Fields
public Boolean Success;
private Region m_region;
private Solid3d m_derivedSolid;
private Vector3d m_normal;
private Point3d m_centroid;
private DBObjectCollection m_entCol;
//Constructor ///////////
public CentroidViaSol(Entity PlanarEnt)
{
m_entCol = new DBObjectCollection();
string entType = PlanarEnt.GetType().ToString();
switch (entType)
{
case "Autodesk.AutoCAD.DatabaseServices.Polyline":
Polyline poly = PlanarEnt as Polyline;
if (poly.Closed)
{
m_entCol.Add(poly);
CreateRegion();
}
break;
case "Autodesk.AutoCAD.DatabaseServices.Polyline2d":
Polyline2d poly2d = PlanarEnt as Polyline2d;
if (poly2d.Closed)
{
m_entCol.Add(poly2d);
CreateRegion();
}
break;
case "Autodesk.AutoCAD.DatabaseServices.Spline":
Spline entSpline = PlanarEnt as Spline;
if (entSpline.IsPlanar && entSpline.Closed)
{
m_entCol.Add(entSpline);
CreateRegion();
}
break;
case "Autodesk.AutoCAD.DatabaseServices.Region":
m_region = (Region)PlanarEnt;
Success = true;
break;
}
if (!m_region.IsNull)
{
m_normal = m_region.Normal;
m_derivedSolid = new Solid3d();
m_derivedSolid.Extrude(m_region, 2.0, 0.0);
m_centroid = m_derivedSolid.MassProperties.Centroid;
m_centroid = m_centroid - m_normal;
}
}
//Properties //////////
public Point3d DerivedCentroid
{
get { return m_centroid; }
}
//Internal ////////////
private void CreateRegion()
{
try
{
m_region = (Region)(Region.CreateFromCurves(m_entCol)[0]);
Success = true;
}
catch
{
Success = false;
}
}
}