Extract footprint from volumes, mesh or solids

Extract footprint from volumes, mesh or solids

Haider_of_Sweden
Collaborator Collaborator
5,088 Views
27 Replies
Message 1 of 28

Extract footprint from volumes, mesh or solids

Haider_of_Sweden
Collaborator
Collaborator

Take a look at this screenshot

exampleexample

 

Can LISP extract the footprint, for example the top-face and bottom-face of these volumes, which could be meshes or solids?

I have a solution how it can be done in 3dsMax, but I am investigating this to be done directly in AutoCAD environment.

0 Likes
Accepted solutions (1)
5,089 Views
27 Replies
Replies (27)
Message 2 of 28

Anonymous
Not applicable

@Haider_of_Sweden  Something like ?

 

;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/autolisp-volume-of-a-solid/td-p/88...
;;Edited by Júnior Nogueira

(defun C:TEST ( / ent hnd vol cen ) (setq ent (entsel "\nSelect Object: ")) (if (null ent) (progn (setq hnd (car ent) axo (vlax-ename->vla-object hnd) vol (vla-get-volume axo)) (princ (strcat "\nVolume: " (rtos vol))) (if (vlax-property-available-p axo "Centroid") (progn (setq cen (vlax-get axo "Centroid")) (princ (strcat "\nX: " (rtos (car cen)))) (princ (strcat "\nY: " (rtos (cadr cen)))) (princ (strcat "\nZ: " (rtos (caddr cen)))) ) ) ) ) (princ) )

 

0 Likes
Message 3 of 28

marko_ribar
Advisor
Advisor

Use (vla-getboundingbox) method to get lower left bottom point and upper right top point... Then you can EXPLODE BOXES and iterate through regions again using (vla-getboundingbox) method... If (equal (caddr ll) (caddr ur) 1e-8) of one of regions then region is top or bottom footprint - now you only need to check if (equal (caddr ll) (caddr llbottom) 1e-8) then REGION is bottom footprint, and if (equal (caddr ll) (caddr urtop) 1e-8) then it's top footprint... Now you can copybase REGIONS with point 0,0,0 and undo everything to before EXPLODE-ing... Exit routine and just pasteclip from clipboard to 0,0,0... Footprints will be extracted and BOXES will be present too... Now you only need to decide what to do with footprints REGIONS...

HTH., M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 4 of 28

Haider_of_Sweden
Collaborator
Collaborator

@Anonymous wrote:

@Haider_of_Sweden  Something like ?

 

;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/autolisp-volume-of-a-solid/td-p/88...
;;Edited by Júnior Nogueira

(defun C:TEST ( / ent hnd vol cen ) (setq ent (entsel "\nSelect Object: ")) (if (null ent) (progn (setq hnd (car ent) axo (vlax-ename->vla-object hnd) vol (vla-get-volume axo)) (princ (strcat "\nVolume: " (rtos vol))) (if (vlax-property-available-p axo "Centroid") (progn (setq cen (vlax-get axo "Centroid")) (princ (strcat "\nX: " (rtos (car cen)))) (princ (strcat "\nY: " (rtos (cadr cen)))) (princ (strcat "\nZ: " (rtos (caddr cen)))) ) ) ) ) (princ) )

 


Nothing happened after I selected an object, after it asked me to Select Object. Also, dragging  a box over multiple objects is a preferable selection method.

 


@marko_ribar wrote:

Use (vla-getboundingbox) method to get lower left bottom point and upper right top point... Then you can EXPLODE BOXES and iterate through regions again using (vla-getboundingbox) method... If (equal (caddr ll) (caddr ur) 1e-8) of one of regions then region is top or bottom footprint - now you only need to check if (equal (caddr ll) (caddr llbottom) 1e-8) then REGION is bottom footprint, and if (equal (caddr ll) (caddr urtop) 1e-8) then it's top footprint... Now you can copybase REGIONS with point 0,0,0 and undo everything to before EXPLODE-ing... Exit routine and just pasteclip from clipboard to 0,0,0... Footprints will be extracted and BOXES will be present too... Now you only need to decide what to do with footprints REGIONS...

HTH., M.R.


Could you please help me by rewriting this to script?

0 Likes
Message 5 of 28

Kent1Cooper
Consultant
Consultant

If they're always and only simple shapes with vertical side planes as in your image, you can draw another rectangle or Circle or any closed shape that completely surrounds them, and use BOUNDARY, picking a point inside that surrounding shape but outside any of the objects.  Eliminate the surrounding shape and the resulting Polyline or Region that coincides with it, and the remaining resulting Polylines or Regions will be the footprints of the objects [though only one  per object, not top and  bottom planes].

 

If the objects have "simple" complications, like taper  but with top and bottom planes parallel to the drawing plane [such as from a simple EXTRUDE with a taper angle], Boundary makes results that duplicate the shapes of both  the top and bottom surfaces, though both at Elevation = 0.  I haven't experimented with what happens when they have further complications such as sloped  top surfaces, more complex notches cut out, holes through them, etc. -- I leave that to you if you have those kinds of configurations to deal with.

Kent Cooper, AIA
0 Likes
Message 6 of 28

Haider_of_Sweden
Collaborator
Collaborator

@Kent1Cooper - I've got a huge amount of volumes, so it gotta be automated.

Also,I missed to mention a crucial part. The extracted footprints need to have the same elevation as the surfaces they were extracted from. 


0 Likes
Message 7 of 28

Kent1Cooper
Consultant
Consultant

@Haider_of_Sweden wrote:

.... The extracted footprints need to have the same elevation as the surfaces they were extracted from. 



 

And what exactly do you mean by "extracted"?  If you just want to have  them in the drawing as separate drawn objects from the source objects, can you simply EXPLODE each source object [or a copy of it]?  You'll get Regions for all the faces from a Solid, or 3DFaces from a Mesh, and they'll be at the right elevations, orientations, etc.  If you mean you want only certain ones  among those, as Message 1 implies, then some coordinate evaluation as already suggested by @marko_ribar  would help identify the right ones, depending on the complexity of the shapes.  If, on the other hand, "extract" involves something else, such as putting information about them into an external file, that's another level....

Kent Cooper, AIA
0 Likes
Message 8 of 28

CodeDing
Mentor
Mentor

@Haider_of_Sweden ,

 

To give my bare-bones interpretation, I believe this could be accomplished with the following workflow:

- Use XEDGES to create linework outlining object
- Create selection set of new lines created from XEDGES
- FLATTEN new selection set (ss)
- Create REGION around ss
- Save entity (ent) created by region
- Delete items in ss (since we don't need them anymore)
- Bring ent to correct elevation
*Do stuff with region*

...I just don't have any of this coded Lol. Thoughts anybody?

 

Best,

~DD

0 Likes
Message 9 of 28

Haider_of_Sweden
Collaborator
Collaborator

Please take a look at the screenshot, a scene could look like this:

Sample SceneSample Scene

 

 

I also provided some sample DWGs:
Buildings Footprint 3D solids.DWG - buildings in 3D. They all have the same height. In a real model, the buildings would most likely have different heights.
Buildings Footprint 3D mesh.DWG - as stated before, my question was also about mesh-objects, whether a LISP could handle mesh surfaces and not only solids.
Buildings Footprint 2D top level - this one was made in 3dsMax. The footprints are generated based on the top-faces of the volumes. THIS is the result I am looking for, but in AutoCAD. Why? Because I want options. I don't want to be dependent on 3dsMax.

 

 

Both the BOUNDARY and XEDGES commands were cool and useful (no matter how good I think I am in AutoCAD, there are still commands I didn't know of 😄 ). So thanks for those tips, but still, they are not relevant in this case.
@Kent1Cooper - with "extract" I mean have.


The project could be much larger than the sample file, therefore exploding and manually doing this will simply not work. This is why I hope this thread will result in a scripted/automated solution.

Message 10 of 28

CodeDing
Mentor
Mentor

@Haider_of_Sweden ,

 

This will probably not be your final solution, but it is a start.

Here is the workflow:

- get all 3D SOLIDS

- loop through each solid entity

- explode entity into regions

- explode regions into lines

- find lowest elevation of lines (to use as base elevation)

- select only lines at lowest elevation

- extract vertices at lowest lines

- erase lines

- create polyline (I can't figure the best way to close the polyline, it works though)

- (optional) bring back 3DSOLID entity

 

PLEASE NOTE:

- This ONLY works on 3DSOLIDs

- This ONLY works from a "top-down" perspective

- This ASSUMES there are NO other Lines and NO other Regions in your model space

 

Hope this helps. It's the furthest I can get at the moment.

(defun c:TEST ( / osm cmd cnt tmp e3D ss3D ssR ssL ssLF elev eL sZ eZ eList pList)
;helper function(s)
  (defun ElevLWPoly (lst cls elev)
    (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline")
                            (cons 90 (length lst)) (cons 70 cls) (cons 38 elev))
                      (mapcar (function (lambda (p) (cons 10 p))) lst)))
  );defun
;begin work
(if (setq ss3D (ssget '((0 . "3DSOLID") (410 . "Model"))))
  (progn
    (setq osm (getvar 'OSMODE) cmd (getvar 'CMDECHO))
    (setvar 'OSMODE (logior 16384 osm)) (setvar 'CMDECHO 0)
    (repeat (setq cnt (sslength ss3D))
      (setq e3D (ssname ss3D (setq cnt (1- cnt))))
      (command "_.EXPLODE" e3D)
      (setq ssR (ssget "_P" '((0 . "REGION") (410 . "Model"))))
      (setvar 'QAFLAGS 1) (command "_.EXPLODE" ssR "") (setvar 'QAFLAGS 0)
      (setq ssL (ssget "_P" '((0 . "LINE") (410 . "Model"))))
      (setq elev nil)
      ;find our bottom elevation
      (repeat (setq cnt2 (sslength ssL))
	(setq eL (ssname ssL (setq cnt2 (1- cnt2))))
	(setq sZ (getpropertyvalue eL "StartPoint/Z")
	      eZ (getpropertyvalue eL "EndPoint/Z"))
	(if elev
	  (setq elev (min elev sZ eZ))
	  (setq elev (min sZ eZ))
	);if
      );repeat
      ;create new sel set with only bottom elevation lines
      (setq ssLF (ssget "_P" (list '(0 . "LINE") '(410 . "Model")
				   '(-4 . "*,*,=") (cons 10 (list 0.0 0.0 elev))
				   '(-4 . "*,*,=") (cons 11 (list 0.0 0.0 elev)))))
      ;get coordinates from final lines
      (setq eList nil)
      (setq pList (mapcar '(lambda (x) (cdr (assoc 10 x)))
			  (mapcar 'entget (repeat (setq cnt2 (sslength ssLF))
						  (setq tmp (ssname ssLF (setq cnt2 (1- cnt2))))
						  (if eList (setq eList (cons tmp eList)) (setq eList (list tmp)))))))
      (command "_.ERASE" ssL "");delete unnecessary lines
      (ElevLWPoly pList 0 elev);create PLINE
      ;(entdel e3D);Bring back 3D Solid, if desired
      (setq ssR nil ssL nil ssLF nil eList nil pList nil)
    );repeat
    (setvar 'OSMODE osm) (setvar 'CMDECHO cmd)
  );progn
;else
  (prompt "\n...No 3D Solids found in Model space.")
);if
(princ)
);defun

Best,

~DD

Message 11 of 28

Haider_of_Sweden
Collaborator
Collaborator

@CodeDing wrote:

This will probably not be your final solution, but it is a start.

- find lowest elevation of lines (to use as base elevation)


I think its a great start! Wonderful job. And I so love the lisp working itself through the objects 🙂

Is it possible to find the heighest elevation of lines?

 


@CodeDing wrote:

- explode entity into regions

- explode regions into lines


1) When I exploded the polyline, I noticed that there were two lines where I thought there should be one. Why is that?

2) I will use this tool in Civil3D to explort SHP files. I just checked and the MAPEXPORT tool supports Polygon which appears to be the same thing as regions. What alteration do we need to do have it stop at regions, ie not doing the whole polyline conversion?

 


@CodeDing wrote:

- create polyline (I can't figure the best way to close the polyline, it works though)

- (optional) bring back 3DSOLID entity

 

PLEASE NOTE:

- This ASSUMES there are NO other Lines and NO other Regions in your model space


1) thanks for informing about non-closed polylines. I will select them all and close them that way. If anyone who reads this has a solution, please share your knowledge to the community. 🙂

2) I am curious, how could it bring back the 3D Solids? Wheren't they deleted the first place?

3) Just for the record. Out of curiosity, I tested with lines in the model space. Works without any problems with lines, ie, nothing halts or crashes.

 

 

Last but not least. I noticed a strange behaviour. Initially, I wanted to stress-test the script to see if it would mess things up if two volumes share the same edge/border.

To do so, I created two boxes and placed them next to each other. In other words, they were made in AutoCAD and not like the other volumes in the sample file. The box are also 3D Solids, but had their handles left.

So what happened was that the face/footprint was triangulated. Why did this happen?

0 Likes
Message 12 of 28

CodeDing
Mentor
Mentor

@Haider_of_Sweden ,

 

I am very sorry, but I will be very busy through the rest of today and the weekend. I will have to reply in detail next week. If somebody else decides to help you or explain further, that would be great! Enjoy your weekend!

 

Best,

~DD

0 Likes
Message 13 of 28

Haider_of_Sweden
Collaborator
Collaborator

Ah, thank you for replying! I never expected to get a reply this fast anyway. Wish you a great weekend as well!

 

In the meanwhile, I'd like to add something else to what you said before, regarding closed polylines.

I know that LISP can run regular AutoCAD commands. Also, I am assuming (not sure though) that the lisp can remember the entity it was doing something with before going further to the next one - if so, then this is what we can do with an entity:

- Explode region

- PEDIT > Multiple > Select all the lines created above > Join > 0 > Close > ENTER

 

If this can be run in LISP, then there we got the solution. Also, we prevent the double lines in the polyline...

 

EDIT: Using P when asked for a selection selects the last selected item, which in this case was the Region. Not sure if works from within Lisp...

0 Likes
Message 14 of 28

doaiena
Collaborator
Collaborator

I think you should look at the "solprof" command. There is a high possibility that you could achieve your desired result, without the need for autolisp automation. Have in mind, that this will work for 3dSolids only.

 

1. soprof all solids

2. explode the resulting block

3. join all lines into polylines

 

That operation took me a few seconds to do by hand on your drawing.

Message 15 of 28

devitg
Advisor
Advisor

Please clear if each block or building have a regular  or equal Z value for its bottom. and if all are prismatic, say the same area at top and bottom.   And for better understand,  upload a REAL DWG where you need to apply the LISP 

 

0 Likes
Message 16 of 28

Haider_of_Sweden
Collaborator
Collaborator

@doaiena wrote:

I think you should look at the "solprof" command. There is a high possibility that you could achieve your desired result, without the need for autolisp automation. Have in mind, that this will work for 3dSolids only.

 

1. soprof all solids

2. explode the resulting block

3. join all lines into polylines

 

That operation took me a few seconds to do by hand on your drawing.


please keep in mind that the polylines need to be in their correct elevation in 3D. SOLPROF is a 2D tool for layouts.

 


@devitg wrote:

Please clear if each block or building have a regular  or equal Z value for its bottom. and if all are prismatic, say the same area at top and bottom.   And for better understand,  upload a REAL DWG where you need to apply the LISP 

 


Each building have different elevation/z-value for bottom and top.

The provided DWG is real 🙂 - however, I provided yet another scene, that has buildings from a real place. File unit is meter, coordinate system is SWEREF 99 18 00. It is located in central Stocholm, Sweden.

As you notice, the buldings have different roof height, different bottom elevation and so on.

 

This LISP need to be able to create polylines that represent the exact same face locations as the original solids.

 

I also provided a MESH-version of the same site. If anyone knows a solution that works on mesh too, then please share the solution with us. I had to go through Rhino to convert the mesh to solids. I don't mind using multiple software, but if there are solutions that work in one single software, I would like to know it.

 

 

0 Likes
Message 17 of 28

doaiena
Collaborator
Collaborator

@Haider_of_Sweden wrote:


please keep in mind that the polylines need to be in their correct elevation in 3D. SOLPROF is a 2D tool for layouts.


Are you sure?

If this is the expected result, i might be on to something.

0 Likes
Message 18 of 28

Kent1Cooper
Consultant
Consultant

@Haider_of_Sweden wrote:

.... This LISP need to be able to create polylines that represent the exact same face locations as the original solids .....

 

I was thinking one could Explode a Solid into Regions, Explode the Regions into Lines, Join the Lines into Polylines, assuming they would be rectangles, and then compare the coordinates of their corners to decide whether they lie in a horizontal or a vertical plane.  If a rectangle has two corners at one Z coordinate value and the other two at another, it's one that came from the side of a Solid, and could be eliminated.

 

But I find that the boxy Solids Explode into Regions that all seem to be triangles, and the Solids' faces are made of multiple triangles, not rectangles:
Solid-to-Regions.JPG

I guess there could still be some analysis of which of them should be eliminated and which kept, but I'm not sure it would be possible to come up with [for example] the rectangle that represents the top of that box.

Kent Cooper, AIA
0 Likes
Message 19 of 28

devitg
Advisor
Advisor

I use other way , to get the section at the down point[dl] from Boundingbox , But some building have  the DL  a bit downward than the building . I do not not why, but it is. 

So  If there is no section at such down point I iterate by 0.01 up to get the section, so the section will be at most 0.01 m from the original footprint. 

Hope it will no matter. 

See attached dwg and LISP

I have to say that I do LISP , as  Fred  Flintstone.  NO NOTHING , error , vars , and so on 

 

 

 

 

  

 

See dwg attached 

0 Likes
Message 20 of 28

devitg
Advisor
Advisor

Please download the LSP . I forgot a defun and the LAY-COLL 

0 Likes