Finding Axis end points of a cylindrical 3d solid

<?xml encoding=”UTF-8″>By Balaji Ramamoorthy

In a recent query from a developer, the axis end points of a cylindrical solid were needed to be retrieved. For this, it is required to get the circular edges that make the cylinder and find its center points. I remembered Gilles Chanteau’s elegant code snippet in a discussion forum post that made use of Linq query with BRep API and went in search of it and found this. It turned out that the code could be made to retrieve the axis end points of a cylindrical solid with minimal change.

So here is the modified code snippet and thanks to Gilles.

 [CommandMethod(<span>"FindCylinderAxis"</span><span> )]</span>
 <span>public</span><span>  <span>void</span><span>  FindCylinderAxis()</span></span>
 <span>{</span>
     Document doc 
     = Application.DocumentManager.MdiActiveDocument;
     Editor ed = doc.Editor;
 
     PromptEntityOptions peo 
     = <span>new</span><span>  PromptEntityOptions(<span>"Pick a cylinder : "</span><span> );</span></span>
     peo.SetRejectMessage
     (<span>"\nA 3d solid of cylindrical shape must be selected."</span><span> );</span>
     peo.AddAllowedClass(
     <span>typeof</span><span> (Autodesk.AutoCAD.DatabaseServices.Solid3d), <span>true</span><span> );</span></span>
     PromptEntityResult per = ed.GetEntity(peo);
     <span>if</span><span>  (per.Status != PromptStatus.OK)</span>
         <span>return</span><span> ;</span>
 
     <span>using</span><span>  (Transaction tr </span>
     = doc.Database.TransactionManager.StartTransaction())
     <span>{</span>
         Solid3d sld = tr.GetObject(
         per.ObjectId, OpenMode.ForRead, <span>false</span><span> ) <span>as</span><span>  Solid3d;</span></span>
         Point3d axisPt1 = Point3d.Origin;
         Point3d axisPt2 = Point3d.Origin;
         <span>if</span><span>  (GetCylinderAxis(sld, <span>ref</span><span>  axisPt1, <span>ref</span><span>  axisPt2))</span></span></span>
         <span>{</span>
             ed.WriteMessage(String.Format(<span>"<span>{</span>0<span>}</span>Axis points : <span>{</span>1<span>}</span> <span>{</span>2<span>}</span>"</span><span> , </span>
             Environment.NewLine, 
             axisPt1.ToString(), axisPt2.ToString()));
         <span>}</span>
         <span>else</span><span> </span>
             ed.WriteMessage(String.Format(<span>"<span>{</span>0<span>}</span>Not a cylinder."</span><span> , </span>
             Environment.NewLine));
 
         tr.Commit();
     <span>}</span>
 <span>}</span>
 
 <span>private</span><span>  <span>bool</span><span>  GetCylinderAxis(</span></span>
     Solid3d solid, <span>ref</span><span>  Point3d axisPt1, <span>ref</span><span>  Point3d axisPt2)</span></span>
 <span>{</span>
     <span>bool</span><span>  isCylinder = <span>false</span><span> ;</span></span>
     axisPt1 = Point3d.Origin;
     axisPt2 = Point3d.Origin;
     <span>using</span><span>  (Brep brep = <span>new</span><span>  Brep(solid))</span></span>
     <span>{</span>
         <span>if</span><span>  (brep.Complexes.Count() != 1)</span>
             <span>return</span><span>  <span>false</span><span> ;</span></span>
         <span>if</span><span>  (brep.Faces.Count() != 3)</span>
             <span>return</span><span>  <span>false</span><span> ;</span></span>
         BrepEdgeCollection edges = brep.Edges;
         <span>if</span><span>  (edges.Count() != 2)</span>
             <span>return</span><span>  <span>false</span><span> ;</span></span>
         CircularArc3d[] circles = brep.Edges
             .Select(edge => 
             ((ExternalCurve3d)edge.Curve).NativeCurve 
             <span>as</span><span>  CircularArc3d)</span>
             .Where(circle => circle != <span>null</span><span> )</span>
             .ToArray();
         <span>if</span><span>  (circles.Length != 2)</span>
             isCylinder = <span>false</span><span> ;</span>
         <span>else</span><span> </span>
         <span>{</span>
             isCylinder = 
             (circles[0].Radius == circles[1].Radius &&
             circles[0].Normal.IsParallelTo(circles[1].Normal));
             axisPt1 = circles[0].Center;
             axisPt2 = circles[1].Center;
         <span>}</span>
     <span>}</span>
     <span>return</span><span>  isCylinder;</span>
 <span>}</span>
 


Comments

2 responses to “Finding Axis end points of a cylindrical 3d solid”

  1. i am very new to objectarx, I am trying to implement boolean subtract operation using objectarx for subtracting a cylinder from a cuboid. Could you provide some reference code as how can I do this?

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading