Smir Smir - 1 month ago 11
C# Question

Getting subentity vertex points of solid in AutoCAD

I am trying to find the vertex points of a swept polyline.
So i have a solid that was created by sweeping a circle along a 3D polyline.
It looks like that:image of sweeped solid

Googeling the whole of friday last week i think i have to play around with the subentity part. I found out how to change the color of the subentity edges for instance, but couldnt for christs sake not find out how to access the geometric

This is what i tried out so far, but as i noted right at the bottom i am kinda lost there:

[CommandMethod("SubEntExample")]
public void SubEntExample()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;

PromptEntityOptions peo = new PromptEntityOptions("\nSelect a 3D solid: ");
peo.SetRejectMessage("\nInvalid selection...");
peo.AddAllowedClass(typeof(Solid3d), true);

PromptEntityResult per = ed.GetEntity(peo);

if (per.Status != PromptStatus.OK)
return;

using (Transaction Tx = db.TransactionManager.StartTransaction())
{
Solid3d solid = Tx.GetObject(per.ObjectId, OpenMode.ForWrite) as Solid3d;

ObjectId[] ids = new ObjectId[] { per.ObjectId };

FullSubentityPath path = new FullSubentityPath(ids, new SubentityId(SubentityType.Null, IntPtr.Zero));

List<SubentityId> subEntIds = new List<SubentityId>();

using (Autodesk.AutoCAD.BoundaryRepresentation.Brep brep =
new Autodesk.AutoCAD.BoundaryRepresentation.Brep(path))
{
foreach (Autodesk.AutoCAD.BoundaryRepresentation.Edge edge in brep.Edges)
{
subEntIds.Add(edge.SubentityPath.SubentId);
}
}

foreach (SubentityId subentId in subEntIds)
{

*** here i am lost ***

}
Tx.Commit();
}
}


Thanks for any help already in advantage

Answer

my first solution involved getting all the grips and deciding which are relevant, but thank to a bit of help from the internet ( :) ) i came up with a way better solution

    /// <summary>
    /// Checks if there are boundaryreps that are marked as elliptical or circular arcs
    /// returns true if we found at least 2 of those points
    /// also stores the points in a referenced Point3dCollection
    /// </summary>
    /// <param name="solid"></param>
    /// <param name="pts"></param>
    /// <returns></returns>
    private bool GetSweepPathPoints(Solid3d solid, ref Point3dCollection pts)
    {
        // create boundary rep for the solid
        using (Brep brep = new Brep(solid))
        {
            // get edges of the boundary rep
            BrepEdgeCollection edges = brep.Edges;
            foreach (Edge edge in edges)
            {
                // get the nativ curve geometry of the edges and then 
                // check if it is a circle
                // for more info look at:
                // http://adndevblog.typepad.com/autocad/2012/08/retrieving-native-curve-geometry-using-brep-api.html
                Curve3d curv = ((ExternalCurve3d)edge.Curve).NativeCurve;
                if (curv is CircularArc3d)
                {
                    // transform curved arch into circle and add it to the colecction 
                    // (if not in it alreadz)
                    CircularArc3d circle = curv as CircularArc3d;
                    if (!pts.Contains(circle.Center)) pts.Add(circle.Center);
                }
            }
        }
        return (pts.Count > 1) ? true : false;
    }

I call the whole thing the following way then

            Point3dCollection pts = new Point3dCollection();
            // only do the whole thing if we face a swept solid
            if (GetSweepPathPoints(sld, ref pts))
            {
                for (int i = 0; i < pts.Count; i++)
                {
                    ed.WriteMessage("\nPt[{0}] = {1}", i, pts[i]);
                }
            }