Jump to content

Recommended Posts

Posted

Hello,

I want to collect detailed information about all faces of a `3DSOLID` without exploding or modifying the original solid.

For each face, I would like to obtain information such as:

* Face area
* Face type, such as planar, cylindrical or curved
* Boundary edges of the face
* Length of each edge
* Start and end points of each edge
* Which edges are shared by two adjacent faces
* Which faces are connected to each other through a common edge
* The angle between adjacent faces
* Face normal direction, where available

Ideally, I would like to store the result in a structured form similar to:

Is it possible to retrieve this topology directly using AutoLISP or Visual LISP without using `EXPLODE`?

Would this require the AutoCAD .NET BRep API or ObjectARX, or is there an existing AutoLISP approach?

Any examples, references or recommended methods would be helpful.

Thank you.

Posted (edited)
50 minutes ago, p7q said:

without exploding or modifying the original solid.

Often times I would make a copy of a polyline explode it and work over its sub-parts deleting them as i go. no reason you shouldn't do the same here keep the original un touched, make a copy either to a new location or layer and explode and process each part. you shouldn't avoid explode just use it on the copy. 

 

-edit

https://www.cadtutor.net/forum/topic/34725-autocad2012-3d-solidsurface-into-3d-face/#findComment-281787

Edited by mhupp
Posted

It’s possible with lisp, but really hard. When you entget a solid, you see the garbage at the end that looks like “{kn rn {rn {km rnqhlokhlhhjjnimjmoll {kl nqhlokhlhhjjnimjmoll”, you can actually decode that and get vertices, edges and faces.

 

Python, .NET, or ObjectARX you can use AcDbAssocPersSubentIdPE, It’s like a BRep shortcut. Or use Brep

 

from pyrx import Ap, Db, Ed, Ge, Br

print("added command pygetsubents")

def pygetsubents(ent: Db.Entity):
    pe = Db.AssocPersSubentIdPE(ent.queryX(Db.AssocPersSubentIdPE.desc()))
    print("vertex")
    for vtx in pe.getAllSubentities(ent, Db.SubentType.kVertexSubentType):
        # Get the geometric position of each vertex
        pos = pe.getVertexSubentityGeometry(ent, vtx)
        print(pos)

    print("edge")
    for edge in pe.getAllSubentities(ent, Db.SubentType.kEdgeSubentType):
        curve = pe.getEdgeSubentityGeometry(ent, edge)
        print(curve.getStartPoint(), curve.getEndPoint())

    print("surface")
    for face in pe.getAllSubentities(ent, Db.SubentType.kFaceSubentType):
        brface = Br.Face()
        brface.setSubentPath(Db.FullSubentPath(ent.objectId(), face))
        print("Area", brface.getArea())

@Ap.Command()
def doit():
    es, id, pnt = Ed.Editor.entSel("\nPick it: \n")
    ent = Db.Entity(id)
    pygetsubents(ent)
    

 

 

Command: DOIT
Pick it:
vertex
(117.71953884538620,11.77489209746249,100.00000000000000)
(117.71953884538620,16.43799615292209,100.00000000000000)
(17.71953884538620,16.43799615292209,100.00000000000000)
(17.71953884538620,11.77489209746249,100.00000000000000)
(117.71953884538620,16.43799615292209,0.00000000000000)
(117.71953884538620,11.77489209746249,0.00000000000000)
(17.71953884538620,11.77489209746249,0.00000000000000)
(17.71953884538620,16.43799615292209,0.00000000000000)
edge
(17.71953884538620,16.43799615292209,100.00000000000000) (117.71953884538620,16.43799615292209,100.00000000000000)
(117.71953884538620,16.43799615292209,0.00000000000000) (17.71953884538620,16.43799615292209,0.00000000000000)
(17.71953884538620,11.77489209746249,100.00000000000000) (17.71953884538620,16.43799615292209,100.00000000000000)
(17.71953884538620,16.43799615292209,100.00000000000000) (17.71953884538620,16.43799615292209,0.00000000000000)
(17.71953884538620,16.43799615292209,0.00000000000000) (17.71953884538620,11.77489209746249,0.00000000000000)
(117.71953884538620,11.77489209746249,100.00000000000000) (17.71953884538620,11.77489209746249,100.00000000000000)
(17.71953884538620,11.77489209746249,100.00000000000000) (17.71953884538620,11.77489209746249,0.00000000000000)
(17.71953884538620,11.77489209746249,0.00000000000000) (117.71953884538620,11.77489209746249,0.00000000000000)
(117.71953884538620,16.43799615292209,100.00000000000000) (117.71953884538620,16.43799615292209,0.00000000000000)
(117.71953884538620,16.43799615292209,100.00000000000000) (117.71953884538620,11.77489209746249,100.00000000000000)
(117.71953884538620,11.77489209746249,100.00000000000000) (117.71953884538620,11.77489209746249,0.00000000000000)
(117.71953884538620,11.77489209746249,0.00000000000000) (117.71953884538620,16.43799615292209,0.00000000000000)
surface
Area 466.31040554595984
Area 466.31040554595984
Area 10000.0
Area 466.31040554595984
Area 10000.0
Area 466.31040554595984

 

Posted

something like this (AI generated)

 

;;; =========================================================================
;;; AutoLISP ACIS/SAT Geometric Decoder Script - Print to Screen
;;; Decodes scrambled DXF groups 1 and 3 data and prints it to the command line
;;; =========================================================================

(defun c:DecodeSatPrint ( / ent enx dxfPair strBytes itm lin cha decodedStr)
  (vl-load-com)
  
  ;; 1. User prompts to select a valid 3D Solid or Region
  (setq ent (car (entsel "\nSelect 3D Solid or Region to decode: ")))
  
  (if ent
    (progn
      (setq enx (entget ent))
      
      ;; Verify if the entity type actually holds ACIS data
      (if (member (cdr (assoc 0 enx)) '("3DSOLID" "REGION" "SURFACE" "BODY"))
        (progn
          (princ "\n--- START OF DECODED ACIS SAT DATA ---\n")
          
          ;; 2. Parse and Loop through DXF group codes 1 and 3 
          (while (setq dxfPair (car enx))
            (if (member (car dxfPair) '(1 3))
              (progn
                ;; Convert string to ASCII character byte-list and reverse it
                (setq strBytes (reverse (vl-string->list (cdr dxfPair)))
                      itm nil
                      lin nil)
                
                ;; Rebuild scrambled bytes using standard bitwise operators
                (while strBytes
                  (setq cha (car strBytes)
                        strBytes (cdr strBytes))
                  (cond 
                    ((= cha 95)) ;; Skip formatting delimiters
                    ((= cha 86)  (setq itm (cons 73 itm)))
                    ((= cha 32)  (setq lin (cons (if itm (vl-list->string itm) "") lin) itm nil))
                    ((boole 6 cha 95) (setq itm (cons (boole 6 cha 95) itm)))
                  )
                )
                
                ;; Print structural line streams directly to the command line
                (setq decodedStr (vl-list->string itm))
                (if (/= decodedStr "")
                  (princ (strcat decodedStr "\n"))
                )
              )
            )
            (setq enx (cdr enx))
          )
          
          (princ "--- END OF DECODED ACIS SAT DATA ---\n")
          (princ "\nTip: Press F2 to open the AutoCAD Text Window to copy the full log.")
        )
        (princ "\nError: Selected entity does not contain ACIS geometry data.")
      )
    )
  )
  (princ)
)

(princ "\nACIS SAT Decoder (Print version) Loaded. Type 'DecodeSatPrint' to execute.")
(princ)

 

asmheader
body
lump
transform
shell
face
face
loop
plane-surface
face
loop
plane-surface
coedge
face
loop
plane-surface
coedge
coedge
coedge
coedge
edge

 

I'd bet you could make AI make a mini brep for lisp

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...