Count solids with sizes

Count solids with sizes

Rikkes
Advocate Advocate
2,208 Views
9 Replies
Message 1 of 10

Count solids with sizes

Rikkes
Advocate
Advocate

Is there a way to count the solids in a selection, listed with their individual sizes. 
For example: 
180 x 38 x 2000: 10
160 x 38 x 2000: 5
etc...
I found the (graet) boxcount lisp but that only counts the total lenght of solids based on their section.

I am looking for the same routine but not the total lenght. I would like the individual lenghts...

0 Likes
2,209 Views
9 Replies
Replies (9)
Message 2 of 10

Sea-Haven
Mentor
Mentor

Without a dwg you may be able to use Massprop as it provides the box size, you can write to file then read the file back in to get the values, the other may be using VL bounding box.

 

You can create a list and sort it then count up the same sizes. Note though 180x200x50 is same 200x180x50 if object is rotated.

0 Likes
Message 3 of 10

CodeDing
Advisor
Advisor

@Rikkes ,

 

This could get you on the right track. Please see my NOTE about ignoring orientation..

This boolean value accounts for the issue that @Sea-Haven mentions in their comment..

Set it to "nil" if Length MUST equal Length, Width MUST equal Width, and Height MUST equal Height..

Or set to "t" if shapes must only be geometrically the same regardless of orientation

 

(defun c:GB ( / ignoreOrientation ss boxList cnt e len finals tmp a b)
;Get Boxes
;if orientation does NOT matter (i.e. these two are equal-> (6x4x2) (2x4x6)) set to t, else nil
(setq ignoreOrientation nil)
(if (setq boxList '() ss (ssget '((0 . "3DSOLID"))))
  (progn
    ;check solids for boxes
    (repeat (setq cnt (sslength ss))
      (setq e (ssname ss (setq cnt (1- cnt))))
      ;if boxes, save info
      (if (eq "Box" (getpropertyvalue e "SolidType"))
	(setq boxList (cons (list (getpropertyvalue e "Length")
				  (getpropertyvalue e "Width")
				  (getpropertyvalue e "Height")) boxList));length/width/height
      );if
    );repeat
    ;if we have boxes, count equal values, then present data to user in command history
    (if (> (setq len (length boxList)) 0)
      (progn
	(setq finals "" tmp '())
	(while boxList
	  (setq a (car boxList) boxList (cdr boxList) cnt 1)
	  (foreach b boxList
	    (if (if ignoreOrientation (equal (vl-sort a '<) (vl-sort b '<)) (equal a b))
	      (setq cnt (1+ cnt))
	      (setq tmp (cons b tmp))
	    );if
	  );foreach
	  (if ignoreOrientation
	    (setq finals (strcat finals (rtos (car a) 2 0) "x"
				        (rtos (cadr a) 2 0) "x"
				        (rtos (caddr a) 2 0) " | "
				        "Count: " (itoa cnt)))
	    (setq finals (strcat finals "\nLength: " (rtos (car a) 2 0) " | "
				        "Width: " (rtos (cadr a) 2 0) " | "
				        "Height: " (rtos (caddr a) 2 0) " | "
				        "Count: " (itoa cnt)))
	  );if
	  (if boxList (setq boxList tmp tmp '()) (setq boxList nil))
	);while
	(prompt finals)
      );progn
    ;else
      (prompt "\n...No box solids found.")
    );if
  );progn
;else
  (prompt "\n...No 3d Solids selected.")
);if
(setq ss nil)
(prompt "\nGB Complete...")
(princ)
);defun

 

Best,

~DD

Message 4 of 10

cadffm
Consultant
Consultant
English: (if (eq "Box" (getpropertyvalue e "SolidType"))

 

 


For other language packs/Versions - change this line an add your local name. Sample English,German,Francais,Espanol,,

(if (wcmatch (getpropertyvalue e "SolidType") "Box,Quader,Boite,Prismarect")

 

Sebastian

Message 5 of 10

drakejest
Participant
Participant

Hello,

 

I tried using your code but i am getting ". . . No box solids found". This is my first time using lisp commands so it maybe just me doing something wrong. Here is what i did

 

I have attached the dwg file on the one im testing with and the exact lsp file i am using. The object is made with several duplicate parts and i am sure they are the same since they were made using the copy command. These objects were made from a line > joined > extruded.

 

When executing: gb > selected the whole object; The response is ". . . No box solids found"

 

Do you think you can help me with this sir ? It is greatly appreciated

0 Likes
Message 6 of 10

Kent1Cooper
Consultant
Consultant

@drakejest wrote:

.... i am getting ". . . No box solids found".

.... These objects were made from a line > joined > extruded.

....


The "Box" type of Solid results only from the BOX command.  Use that, and look at its Properties for the "Solid type" entry in the Geometry category.  That will have Length/Width/Height properties farther down.

 

Something made by Extruding lists its "Solid type" as "Extrusion," and does not  have those properties, even if it's box-shaped.  But if it's box-shaped, and orthogonally oriented, its bounding box could be used to calculate the length/width/height.

Kent Cooper, AIA
Message 7 of 10

drakejest
Participant
Participant

Thank you very much that worked ! Would there be a way to convert an extruded object to a box given that the extruded object is just a simple box?

0 Likes
Message 8 of 10

drakejest
Participant
Participant

I having trouble making the code to ignore orientation, upon modifying the code as you instructed :

 

(setq ignoreOrientation nil)

 

to

 

(setq ignoreOrientation t)

 

the console was giving me these result

 

dase.JPG

 

which does not makes sense to me as i dont have those dimension on the boxes.

0 Likes
Message 9 of 10

CodeDing
Advisor
Advisor

@drakejest ,

 

It appears there was a missed string in the original code..

This piece:

	    (setq finals (strcat finals (rtos (car a) 2 0) "x"
				        (rtos (cadr a) 2 0) "x"
				        (rtos (caddr a) 2 0) " | "
				        "Count: " (itoa cnt)))

Should be modified to include the newline character:

	    (setq finals (strcat finals "\n" (rtos (car a) 2 0) "x"
				        (rtos (cadr a) 2 0) "x"
				        (rtos (caddr a) 2 0) " | "
				        "Count: " (itoa cnt)))

 

...try that and see if it helps.

Best,

~DD

0 Likes
Message 10 of 10

Kent1Cooper
Consultant
Consultant

@drakejest wrote:

....Would there be a way to convert an extruded object to a box given that the extruded object is just a simple box?


Try this [minimally tested]:

 

(defun C:BOXIFY (/ ss n oldbox minpt maxpt LL UR delta)
  (prompt "\nTo convert orthogonal box-shaped 3D Solid(s) to actual \"BOX\" objects,")
  (if (setq ss (ssget "_:L" '((0 . "3DSOLID"))))
    (repeat (setq n (sslength ss)); then
      (setq oldbox (ssname ss (setq n (1- n))))
      (vla-getboundingbox (vlax-ename->vla-object oldbox) 'minpt 'maxpt)
      (setq
        LL (vlax-safearray->list minpt)
        UR (vlax-safearray->list maxpt)
        delta (mapcar '- UR LL)
      ); setq
      (command
        "_.box" "_none" LL "_length" (car delta) (cadr delta) (caddr delta)
        "_.chprop" "_last" "" "_layer" (cdr (assoc 8 (entget oldbox))) ""
        "_.erase" oldbox ""
      ); command
    ); repeat
  ); if
  (princ)
); defun

 

It's up to you to select only orthogonally-oriented box-shaped Solids -- it doesn't verify that's what you picked.  I think it would be hugely complicated, if even possible, to do that by any kind of calculation, given the inscrutability of 3DSolid entity data.  The one way that may work would be to build the new Box, SUBTRACT the original from the new one, and if nothing is left, the original was the right kind of shape and orientation.  Then it would Undo the Subtraction, and delete the original.  Otherwise it would Undo the Subtraction and  the building of the new Box, and leave the original.

Kent Cooper, AIA
0 Likes