Determine height and radius of 3DSolid cylinder

CommonGroundIndustries
Participant
Participant

Determine height and radius of 3DSolid cylinder

CommonGroundIndustries
Participant
Participant

I am writing a routine that is supposed to get the heights and radii of all cylinders in a drawing. The cylinders are not necessarily aligned with WCS.

 

I am able to successfully find and identify which 3D Solids are cylinders, but am having a really hard time determining the height and radii of these entities. I am using ARX and the COM interface to get to the place where I identify the entity as a cylinder. From there I have tried either using properties of the Solid3D class, or the Acad3DSolid class. Example properties include: centroid, moments of inertia, principal moments, bounding box etc. Volume is also a property. I believe there is some math that can be done with these properties to determine height and radius, but most of my attempts only work if the cylinder is aligned with WCS. The requirements dictate the cylinder can be at any orientation. The Autodesk.AutoCAD.Geometry.Cylinder object does have a height and radius property, but I cannot find away to cast either the Solid3D or Acad3DSolid objects into the geometry. Any help would be appreciated, either with the correct math to determine on the object properties or some way to utilize another class. Looking at the properties of a cylinder in AutoCAD itself, the 3DSolid cylinder solidType clearly have height and radius properties (see screen shot).

 

Private Shared Sub getCylinderLengths()

 

     Dim Solid3DobjectIDs As New List(Of ObjectId)

     Solid3DobjectIDs = getAll3dSolidObjIDs() 'returns a list of objectID that are of type 3DSolid

     Dim db As Database = HostApplicationServices.WorkingDatabase

 

     If Solid3DobjectIDs.Count > 0 Then

          For Each objid In Solid3DobjectIDs

              Using t As Transaction = db.TransactionManager.StartTransaction()

                       Dim thisSolid As Solid3d = TryCast(t.GetObject(objid, OpenMode.ForRead), Solid3d)

                       Dim AcadSol As Autodesk.AutoCAD.Interop.Common.Acad3DSolid = thisSolid.AcadObject

                       If AcadSol.SolidType = "Cylinder" Then
                                'find radius and height here.

                       End If


              t.Commit()

           End Using
     Next

   End If

End Sub

0 Likes
Reply
Accepted solutions (1)
556 Views
4 Replies
Replies (4)

hosneyalaa
Advisor
Advisor

Hi

Try

IMG_٢٠٢٣٠٣٢٠_٢٢١٦٢٨.jpg

0 Likes

kdub_nz
Advisor
Advisor

I don't think the Solid3DMassProperties will give you what you want.

 

You'll probably need to make use of the BREP API

// Assembly acdbmgdbrep, Version 24.2.0.0
Location for me:D:\ObjectARX_2023\inc\acdbmgdbrep.dll

 

The API assumes a 'healthy' knowledge of 3D solids creation .

 

https://help.autodesk.com/view/OARX/2023/ENU/?guid=OARX-ManagedRefGuide-Autodesk_AutoCAD_BoundaryRep...

 

Regards


// Called Kerry in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect.
Sometimes the question is more important than the answer.

class keyThumper<T> : Lazy<T>;      another  Swamper

0 Likes

_gile
Mentor
Mentor
Accepted solution

Hi,

As @kdub_nz said, using the Boundary Representation is a good way.

Here's an example:

        private static bool IsCylinder(Solid3d solid, out double radius, out double height)
        {
            radius = height = 0.0;
            using (var brep = new Brep(solid))
            {
                var cylinder = brep.Faces
                    .Select(face => ((ExternalBoundedSurface)face.Surface).BaseSurface)
                    .FirstOrDefault(surface => surface is Cylinder);
                if (cylinder == null)
                    return false;
                radius = ((Cylinder)cylinder).Radius;
                height = ((Cylinder)cylinder).Height.Length;
                return true;
            }
        }

 

And a testing command:

        [CommandMethod("TEST")]
        public void Test()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var peo = new PromptEntityOptions("\nSelect cylinder: ");
            peo.SetRejectMessage("\nSelected object is not a Solid 3d.");
            peo.AddAllowedClass(typeof(Solid3d), true);
            var per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var solid = (Solid3d)tr.GetObject(per.ObjectId, OpenMode.ForRead);
                if (IsCylinder(solid, out double radius, out double height))
                {
                    ed.WriteMessage($"\nRadius = {radius}\tHeight = {height}");
                }
                else
                {
                    ed.WriteMessage("\nSelected solid 3d is not a cylinder.");
                }
                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

CommonGroundIndustries
Participant
Participant

@_gileThank you so much! Your solution is working and it doesn't seem to care about the alignment of the solid. For posterity, here is my implementation in VB.NET. If you're ever in Montana I'll buy you a beer. Had been really stuck on this. 

 

        Private Shared Function isCylinder(ByVal solid As Solid3d, ByRef radius As Double, ByRef height As Double)

            radius = height = 0

            Using brep = New BoundaryRepresentation.Brep(solid)
                Dim cylinder = brep.Faces.[Select](Function(face) (CType(face.Surface, ExternalBoundedSurface)).BaseSurface).FirstOrDefault(Function(surface) TypeOf surface Is Cylinder)
                If cylinder Is Nothing Then Return False
                radius = (CType(cylinder, Cylinder)).Radius
                height = (CType(cylinder, Cylinder)).Height.Length
                Return True
            End Using

        End Function

 

It's been interesting getting under the hood and seeing how CAD deals with solids. 3D geometry is not for the faint of heart!

0 Likes