Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Extract radius and height from cylinders &boxes

16 REPLIES 16
SOLVED
Reply
Message 1 of 17
Anonymous
1991 Views, 16 Replies

Extract radius and height from cylinders &boxes

Hello,

      I design a small plant in Autocad 2012. For the pipes we used cylinders and boxes(for square pipe), now we need to make the bill of materials, but I don't know how to extract the data from each cylinder(radius and height) or box.

      It is possible to do this?

      I place a small sample from the plant. Totally I am having around 6000 elements.

16 REPLIES 16
Message 2 of 17
Anonymous
in reply to: Anonymous

      Nobody wants to help me?Smiley Sad

Message 3 of 17
hmsilva
in reply to: Anonymous


@Anonymous wrote:

      Nobody wants to help me?Smiley Sad


 

Not quite septimiu1985, we all are in this discussion group, to get help, give help and learn.

If nobody has helped yet, I think it is due to the difficulty in access to 3DSOLID data, because it is encrypted, and it is not easy to accessed via LISP.

A few years ago, I did some things similar to what you need, I need to dig through my old files trying to find these routines, but at this moment I am on vacation, and dont have those files with me...

If no one else jump in to assist, when I find those files, I'll come back to give some help...

 

Henrique

EESignature

Message 4 of 17
Anonymous
in reply to: Anonymous

      Thank for your answer, for me this think is not urgent so I can wait ( I am glad that someone will help me)!

Enjoy your vacation!

Message 5 of 17
Kent1Cooper
in reply to: Anonymous

If they're always running in orthogonal directions as it looks like they do in your sample, you could get their length and cross-sectional dimension [whether the side length of a square section or the diameter of a round one] from the differences in XYZ coordinates of the corners of their bounding boxes.  But A) that might not be reliable if any are shorter in length than in width/diameter, and B) I haven't found any way to determine whether a given one is a cylinder or a rectangular prism, from entity data or VLA properties, and C) all bets are off if any of them run in non-orthogonal directions.

Kent Cooper, AIA
Message 6 of 17
hmsilva
in reply to: Anonymous

septimiu1985,
here is a demo, only for the cylinders (boxes, requires a different type of approach, in my old files...), will create a .csv file.

 

(defun c:test (/ fname itm num obj ht rad str fl)
  (if (and (setq fname (getfiled "Output File" "" "csv" 1))
	   (setq ss (ssget '((0 . "3DSOLID"))))
      )
    (progn
      (setq itm	0
	    num	(sslength ss)
      )
      (while (< itm num)
	(setq obj (vlax-ename->vla-object
		    (ssname ss
			    itm
		    )
		  )
	)
	(If (= (vl-catch-all-apply 'vla-get-SolidType (list obj))
	       "Cylinder"
	    )
	  (setq
	    ht	(read (rtos (* 2
			       (distance (vlax-get obj 'Position)
					 (vlax-get obj 'centroid)
			       )
			    )
			    2
			    2
		      )
		)
	    rad	(read (rtos (sqrt (/ (vla-get-Volume obj) (* pi ht))) 2 2))
	    lst	(cons
		  (list	rad
			ht
		  )
		  lst
		)
	  )
	)
	(setq itm (1+ itm))
      );; while
      (setq lst	(vl-sort lst
			 '(lambda (a b)
			    (if	(equal (car a) (car b))
			      (< (cadr a) (cadr b))
			      (< (car a) (car b))
			    )
			  )
		)
      )
      (setq fl (open fname "w"))
      (foreach n lst
	(setq str (strcat (rtos (car n) 2 2) "\t" (rtos (cadr n) 2 2)))
	(setq str (vl-string-translate "." "," str))
	(write-line str fl)
      );; foreach
      (close fl)
      (setq ss	nil
	    lst	nil
      )
    );; progn
  );; if
  (princ)
);; test

Hope that helps
Henrique

EESignature

Message 7 of 17
phanaem
in reply to: Kent1Cooper


@Kent1Cooper wrote:

..... and C) all bets are off if any of them run in non-orthogonal directions.



You can find radius an length of a cylinder at any orientation  like this:

(if
  (setq e (ssget ":E:S" '((0 . "3DSOLID"))))
  (progn
    (setq e (vlax-ename->vla-object (ssname e 0))
        i ((lambda (x) (if
                         (equal (car x) (cadr x) (* 0.001 (car x)))
                         (caddr x)
                         (if
                           (equal (car x) (caddr x) (* 0.001 (car x)))
                           (cadr x)
                           (car x)
                           )
                         )
             )
            (vlax-get e 'PrincipalMoments)
            )
        v (vlax-get e 'Volume)
        r (sqrt (/ (* 2.0 i) v))
        l (/ v (* pi r r))
        )
    (princ "\nL=") (princ l) (princ "\tr=") (princ r)
    )
  )

 It works for extruded circles too.

Message 8 of 17
stevor
in reply to: Anonymous

The 3DSolids can usually be exploded to determine dimensions of edges; although it takes several steps. Similarly, the SOLIDEDIT command might be useful.
S
Message 9 of 17
Anonymous
in reply to: hmsilva

Hello,

          Unfortunately is not working, I had made a .lsp file, I am loading the application, I start the application, it ask me where shell I place the file (I choose the adress), next I am selecting the elements, and finally I recive this error:

Command: TEST
Select objects: Specify opposite corner: 303 found
Select objects:
; error: no function definition: VLAX-ENAME->VLA-OBJECT    "

 

Message 10 of 17
Anonymous
in reply to: phanaem

Hello phanaem,

 

           Also this application is not working, I made a .lsp file, I am loading the file , it's telling me to select the object and I recive the following error (without selecting any object / I am not able to select objects)

Command: _appload Colectare.lsp successfully loaded.
Command:
Select objects:
; error: no function definition: VLAX-ENAME->VLA-OBJECT    "

Message 11 of 17
phanaem
in reply to: Anonymous

You need to load Visual Lisp library, once per acad sesion.

Type (vl-load-com) at command prompt and hit enter.

 

Try this new one. It works for cylinders and boxes, but is for testing only.

(defun C:TEST (/ e m i v r l a b c d)
  (vl-load-com)
  (if
    (setq e (ssget ":E:S" '((0 . "3DSOLID"))))
     (progn
       (setq e (vlax-ename->vla-object (ssname e 0))
             m (vlax-get e 'PrincipalMoments)
             i (if
                 (equal (car m) (cadr m) (* 0.001 (car m)))
                  (caddr m)
                  (if
                    (equal (car m) (caddr m) (* 0.001 (car m)))
                     (cadr m)
                     (car m)
                     )
                  )
             v (vlax-get e 'Volume)
             r (sqrt (/ (* 2.0 i) v))
             l (/ v (* pi r r))
             a (sqrt (/ (* 6.0 (+ (car m) (cadr m) (- (caddr m)))) v))
             b (sqrt (/ (* 6.0 (+ (cadr m) (caddr m) (- (car m)))) v))
             c (sqrt (/ (* 6.0 (+ (caddr m) (car m) (- (cadr m)))) v))
             d (vl-sort (list a b c) '<)
             )
       (if
         (equal (* a b c) v 1e-5)
         (progn
           (princ "\nLungime = ")(princ (caddr d))(princ "\tSectiune = ")(princ (car d))(princ " x ")(princ (cadr d))
           )
         (progn
          (princ "\nLungime = ")(princ l)(princ "\traza = ")(princ r)
        )
       )
     )
   )
 (princ)
)

 

 

Message 12 of 17
hmsilva
in reply to: Anonymous

septimiu1985,
my fault, I have "vl-load-com" function in my acaddoc.lsp, so all the extended AutoLISP functions are loaded at startup.
you'll have to add

 

(defun c:test (/ fname itm num obj ht rad str fl)
(vl-load-com);; to load the extended AutoLISP functions
  (if (and (setq fname (getfiled "Output File" "" "csv" 1))

...

 

Henrique

EESignature

Message 13 of 17
hmsilva
in reply to: Anonymous

septimiu1985,
for accuracy reasons, this routine only works with PRIMITIVE SOLIDS, with EXTRUSIONS, is difficult to know if the original object was a CIRCLE, a ELLIPSE, or a POLYLINE, or even know if the object top is beveled.
This code works with BOX and CILINDER objects, and writes the result to a .csv file, is not a fast code, because it have to dig down through various sub-entities to get entity I need, but will do the trick...

 

(defun c:test (/ BLST CLST DATA DEP DIA FL FNAME ITM LEN NUM SS STR WID)
  (vl-load-com)
  (if (and (setq fname (getfiled "Output File" "" "csv" 1))
	   (setq ss (ssget '((0 . "3DSOLID"))))
      )
    (progn
      (setq itm	0
	    num	(sslength ss)
      );; setq
      (while (< itm num)
	(setq data
	       (entget
		 (cdr
		   (assoc
		     360
		     (member
		       '(100 . "AcDbEvalGraph")
		       (entget
			 (cdr (assoc
				360
				(member
				  '(100 . "AcDbShHistory")
				  (entget (cdr (assoc 350
						      (member '(100 . "AcDb3dSolid")
							      (entget (ssname ss
									      itm
								      )
							      )
						      )
					       )
					  )
				  )
				)
			      )
			 )
		       )
		     )
		   )
		 )
	       )
	);; setq
	(if (eq	(cdr (nth 1 (member '(100 . "AcDbShPrimitive") data)))
		"AcDbShBox"
	    )
	  (setq	wid  (cdr (assoc 40 (member '(100 . "AcDbShPrimitive") data)))
		dep  (cdr (assoc 41 (member '(100 . "AcDbShPrimitive") data)))
		len  (cdr (assoc 42 (member '(100 . "AcDbShPrimitive") data)))
		blst (cons (list wid dep len) blst)
	  );; setq
	);; if
	(if (eq	(cdr (nth 1 (member '(100 . "AcDbShPrimitive") data)))
		"AcDbShCylinder"
	    )
	  (setq	dia  (*	2
			(cdr (assoc 41 (member '(100 . "AcDbShPrimitive") data)))
		     )
		len  (cdr (assoc 40 (member '(100 . "AcDbShPrimitive") data)))
		clst (cons (list dia len) clst)
	  );; setq
	);; if
	(setq itm (1+ itm))

      );; while
      (if (or clst
	      blst
	  )
	(progn
	  (setq fl (open fname "w"))
	  (if blst
	    (progn
	      (setq blst (vl-sort blst
				  '(lambda (a b)
				     (if (= (cadr a) (cadr b))
				       (< (car a) (car b))
				       (< (cadr a) (cadr b))
				     )
				   )
			 )
	      );; setq
	      (write-line "Width\tDepth\tLength" fl)
	      (foreach n blst
		(setq str (strcat (rtos (car n) 2 2)
				  "\t"
				  (rtos (cadr n) 2 2)
				  "\t"
				  (rtos (caddr n) 2 2)
			  )
		)
		(setq str (vl-string-translate "." "," str))
		(write-line str fl)
	      );; foreach
	    );; progn
	  );; if
	  (if clst
	    (progn
	      (setq clst (vl-sort clst
				  '(lambda (a b)
				     (if (= (car a) (car b))
				       (< (cadr a) (cadr b))
				       (< (car a) (car b))
				     )
				   )
			 )
	      )
	      (write-line "Diameter\tLength" fl)
	      (foreach n clst
		(setq
		  str (strcat (rtos (car n) 2 2) "\t" (rtos (cadr n) 2 2))
		)
		(setq str (vl-string-translate "." "," str))
		(write-line str fl)
	      );; foreach
	    );; progn
	  );; if
	  (close fl)
	);; progn
      );; if or
    );; progn
  );; If
  (princ)
);; test

 

Hope that helps
Henrique

EESignature

Message 14 of 17
Anonymous
in reply to: hmsilva

Hello,

 

         This one is perfect, thank you very much Henrique!

          Just one more thing, I have test it and is working perfect, but it is possible somehow to calculate also the sum from every cylinders which have the same diameter, and the sum for boxes which have the same width&depth, because I saw that the elements are placed in order according to the diameter size, or by the width and length for the boxes.

         For exemple if I am having the following:

Width Depth Length
50 50 2250
50 50 700
50 50 2150
50 50 900
10 100 900
10 100 900

Diameter Length
85 6748,7
85 7098,7
154 8410,56
154 9275

           To have only:

Width Depth Length
50 50 6000

10 100 1800

Diameter Length

85 13847,4

154 17685.56

              Thank you very much one more time! 

         

 

Message 15 of 17
Anonymous
in reply to: phanaem

Hello phanaem,

 

             It's working, but it doesn't help me so much, because I need to extract this data from the elements for the Bill of Materials, I am having more than 100 elements in each file, and the biggest one has arround 6 000 elements.

             Thank you for your help! 

Message 16 of 17
hmsilva
in reply to: Anonymous


@Anonymous wrote:

Hello,

 

         This one is perfect, thank you very much Henrique!

          Just one more thing, I have test it and is working perfect, but it is possible somehow to calculate also the sum from every cylinders which have the same diameter, and the sum for boxes which have the same width&depth, because I saw that the elements are placed in order according to the diameter size, or by the width and length for the boxes.

...

         

 


You're welcome, septimiu1985,

can be made, but like I said before, I'm on vacation, and I'm too lazy, so, you have to do something...  Smiley Wink

One way:

1-Open the .csv file with the notepad (or other text editor)

2-Ctrl+T (to select all), Ctrl+C (to copy all)

3-Open Excel (or other spreadsheet)

4-select a cell and Ctrl+V

Now it is easy to obtain the total length of all elements with the same characteristics...

 

Henrique

EESignature

Message 17 of 17
Anonymous
in reply to: hmsilva

Ok, enjoy your vacation, today I am paying the beers!

Spoiler
Smiley Wink

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost