p7q Posted 22 hours ago Posted 22 hours ago 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. Quote
mhupp Posted 21 hours ago Posted 21 hours ago (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 21 hours ago by mhupp 1 Quote
Danielm103 Posted 9 hours ago Posted 9 hours ago 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 1 Quote
Danielm103 Posted 9 hours ago Posted 9 hours ago 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 1 Quote
p7q Posted 7 hours ago Author Posted 7 hours ago 14 hours ago, mhupp said: 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 Thank you. My concern is not damaging the original solid, but losing topology after exploding the copy. I need to identify each face, its boundary edges, edge lengths, and which faces share the same edge. Would exploding a copy preserve enough information to determine these relationships reliably? 1 Quote
p7q Posted 6 hours ago Author Posted 6 hours ago @Danielm103 Thank you for the explanations and code examples. I will compare the suggested methods, decide which one is the most suitable, and start testing it. You mentioned that one of the code examples was generated with AI. Which AI tools do you use for writing or improving AutoLISP, Python, .NET, or ObjectARX code? Do you have any recommendations based on your experience? 1 Quote
Danielm103 Posted 2 hours ago Posted 2 hours ago One that’s free : ), Gemini, also GLM is pretty good a lisp. With AI, don’t try to one shot it, work though the ACIS/SAT patterns and ask questions 2 Quote
p7q Posted 1 hour ago Author Posted 1 hour ago 1 hour ago, Danielm103 said: One that’s free : ), Gemini, also GLM is pretty good a lisp. With AI, don’t try to one shot it, work though the ACIS/SAT patterns and ask questions Paid tools are fine as well. I currently use a custom GPT called AutoCAD Automator. I usually design the overall algorithm myself. I use AI mainly to write supporting functions, research specific AutoCAD or ACIS/SAT topics in depth, compare alternative approaches, and help improve individual parts of the code. If you know a tool that would be more effective for this kind of workflow, I would be interested in trying it or switching to it. 1 Quote
Danielm103 Posted 47 minutes ago Posted 47 minutes ago AI + AutoCAD, Python is the way, connect to agents in AutoCAD’s process space, I connect to LM studio 1 Quote
Recommended Posts
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.