<?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>

Leave a Reply