Lisp for total line length for lines which in every separately box

Lisp for total line length for lines which in every separately box

mss_selcukuni
Contributor Contributor
7,877 Views
53 Replies
Message 1 of 54

Lisp for total line length for lines which in every separately box

mss_selcukuni
Contributor
Contributor

Hi Everyone,

I want to make this with lisp in Autocad... 

 

I want to export totale line lenght to excel table..

but i want to see lenght of lines with their box name with lenght..

Pls see example in attachment,

 

Can you help me pls this issueAutocad Lisp.jpg

0 Likes
7,878 Views
53 Replies
Replies (53)
Message 2 of 54

AVCPlugins
Advisor
Advisor

If your boxes are blocks, then you just need to use ready-made data extraction programs. For example, the DataTable plugin can extract and sum the length of any objects and can group data into blocks.


Plugins for AutoCAD
A>V>C>
AppStore | Facebook | Twitter | YouTube | Blog
0 Likes
Message 3 of 54

devitg
Advisor
Advisor

@mss_selcukuni 

 

For better understanding, and maybe get further help, please upload such sample.dwg
As far as I know, ACAD only can edit DWG.
Or send it to devitg@gmail.com

0 Likes
Message 4 of 54

calderg1000
Mentor
Mentor

Regards @mss_selcukuni 

Try this code, which exports the data to CSV.
Previously the polylines must be in the layers with their respective name. After entering the name of the output file, it will be created in the directory where the current CAD file is located.

calderg1000_0-1648382880974.png

 

(defun c:list_Box (/ ss i en nlay lx spol j lp lcomp lcompl)
(vl-load-com)
  (setq nn (getstring "\nGet Filename:"))
  (princ"\nSelect polyline in consecutive order:")
  (setq ss (ssget '((0 . "lwpolyline")))
        f  (open (strcat (getvar 'dwgprefix) nn "." "csv") "w")
  )
  (write-line "Box Name: Length" f)
  (repeat (setq i (sslength ss))
    (setq en   (ssname ss (setq i (1- i)))
          nlay (cdr (assoc 8 (entget en)))
          lx   (ver-pol en)
          spol (ssget "wp" lx '((0 . "Lwpolyline")))
    )
    (repeat (setq j (sslength spol))
      (setq lp
                   (vla-get-length (vlax-ename->vla-object (ssname spol (setq j (1- j))))
                   )
            lcomp  (strcat nlay ": " (rtos lp 2 2))
            lcompl (cons lcomp lcompl)
      )
    )
  )
  (repeat (setq k (length lcompl))
    (write-line (nth (setq k (1- k)) (reverse lcompl)) f)
  )
  (close f)
)
(defun ver-pol (s / x)
  (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget s)))
)

 

 


Carlos Calderon G
EESignature
>Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

0 Likes
Message 5 of 54

mss_selcukuni
Contributor
Contributor

Hi calderg1000,

thank you so much..

I installed successfully.. But when i use lisp its error..

 

It ask me "Filename:"

Then after it ask me select polyline 

"Error: Wrong Type - nil"

 

Why it errors? How can I fix it? can you help me pls

0 Likes
Message 6 of 54

calderg1000
Mentor
Mentor

Regards

I do not explain what the problem could be, I tried it with your file and it worked. I attached the video of its operation.

https://knowledge.autodesk.com/community/screencast/931b5820-c9a6-49f9-9be1-5b78b0da19ef


Carlos Calderon G
EESignature
>Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

0 Likes
Message 7 of 54

hak_vz
Advisor
Advisor

@mss_selcukuni 

Try this.

From your sample I deduced that each box is a polyline in a layer with name Box x .....

Code collects polylines in layers Box 1, Box 2.....Box n

Takes coordinates of each box so box can be complex polygon with straight segments

Inside each box polyline it takes all elements inside closing clipping polygone and removes box polyline from selection set.

For each box total length is calculated for all lines or lwpolylines and stored to list like

Care is taken to remove from selection all overlapping box polylines from other layers or lines that cross the box.

 

(("Box 2" . 277.23)("Box 4" . 277.23) ("Box 1" . 359.309)  ("Box 3" . 277.23) ("Box 5" . 277.23))

 

List is then sorted and result is written to outer CSV file and that file is opened in Excel

 

(defun c:boxtotlen ( / *error* _openfile take pointlist2d i j k ss ps fs f file1 eo mo boxname boxlen ret)
	(defun *error* (msg)
		(if (not (member msg '("Function cancelled" "quit / exit abort")))
			(princ)
		)
		(if (and file1) (close file1))
		(princ)
	)
	(defun _openfile (file / sh)
	  ;thanks to @ronjohnp	
	  (setq sh (vlax-get-or-create-object "Shell.Application"))
	  (vlax-invoke-method sh 'open (findfile file))
	  (vlax-release-object sh)
	)
	(defun take (amount lst / ret)(repeat amount (setq ret (cons (car lst) (take (1- amount) (cdr lst))))))
	(defun pointlist2d (lst / ret) (while lst (setq	ret (cons (take 2 lst) ret) lst (cddr lst))) (reverse ret))
	(setq
		i -1
		ss (ssget "X" '((0 . "LWPOLYLINE")(8 . "box*")))
		f (getfiled "Output CSV file:" (getvar "dwgprefix") "csv" 3)
		
	)
	(cond
		((and ss f)
			(while (< (setq i  (1+ i)) (sslength ss))
				(setq 
					e (ssname ss i)
					eo (vlax-ename->vla-object e)
					boxname (vlax-get eo 'Layer)
					boxlen 0
					coords (pointlist2d (vlax-get eo 'Coordinates))
					coords (append coords (list (car coords)))
					ps (ssget "_CP" coords)
					fs (ssget "_F" coords)
					j -1	
				)
				(cond 
					((and ps)
						(setq k -1)
						(while (< (setq k (1+ k)) (sslength fs))
							(setq ps (ssdel (ssname fs k) ps))
						)
						(while (< (setq j  (1+ j)) (sslength ps))
							(setq mo (vlax-ename->vla-object (ssname ps j)))
							(if (member (vlax-get mo 'ObjectName) '("AcDbLine" "AcDbPolyline" "AcDb2DPolyline"))
								(setq boxlen (+ boxlen (vla-get-length mo)))
							)
						)
						(setq ret (cons (cons boxname boxlen) ret))
					)
				)
			)
			(setq 
				file1 (open f "w")
				ret (vl-sort ret '(lambda (x y) (< (car x)(car y))))
			)
			(foreach element ret
				(write-line (strcat (car element) ";" (rtos (cdr element) 2 2)) file1)
			)
			(close file1)
			(_openfile f)
		)
	)
	(princ "\nDone!")
	(princ)
)

 

 

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 8 of 54

mss_selcukuni
Contributor
Contributor

Hi Calderg1000,

today i try code it's running.. Wondeful... Thank you so so much...

can i ask from you someting else?

 

can we add some spesific point?

for example;

  • we can calculate this code with line, area (closed items)?
  • and maybe can we separate Box Name and lenght/area to colums when paste in excel?
0 Likes
Message 9 of 54

mss_selcukuni
Contributor
Contributor

Hi Dear Hk_vz,

Your code is working wonderful... Thank you su much...

My calculeted data was separated to colums.. it was so good...

 

  • But one of ideas in my head, can i want to select box or boxes to calculate.. when i used your code, lisp is calculating all of drawing.. I want to draw 1 or more special box in drawing and calculate data's in these boxes..
  • and if we add calculating of areas, lenght of line (not only polyline), circle lenght an area, rectengular or another closed shapes lenght and areas.. if we can do this.. it will be dreamy for me...

 

I hope you help...

Message 10 of 54

hak_vz
Advisor
Advisor

I'm currently at work. What you ask is easy to do and I I'll change the code latter today.

Instead of full automation lets make a change so that bounding polyline doesn't have to lay in layer "Box x" but in whatever layer ( let say "Room 1" "Toilet 21"....).

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 11 of 54

mss_selcukuni
Contributor
Contributor

Thank you so much hak_vz;

have a good working...

 

I am civil engineer too. I want to calculate quantity diffrent areas such as ceramic, wall, handrail in boundered area and boundered areas decribe construction dilatation or rooms goups..

 

You're right.. I dont want to run with automation. I want to calculate areas which I desire

And if this code make 2 things below .., This will be my hero;

1) I would like to select area or drawing my calculate boundry around the line, poliyline, rectangle or another shape..

2) I would like to calculate line, polyline, rectangle or another shape..

2) I desire to put in excel sheet with layer name and length or areas and box/boundry name...

 

For example pls see attach.

 

we can use "Box" description in boundry name...

so lisp doesn't think that every closed boxes/layers is a boundry...

0 Likes
Message 12 of 54

hak_vz
Advisor
Advisor

@mss_selcukuni 

 

Try this for a start

 

(defun c:boxinfo ( / *error* _openfile take pointlist2d i j k ss ps fs f file1 eo mo areaname boxlayer boxlen boxarea ret)
	(defun *error* (msg)
		(if (not (member msg '("Function cancelled" "quit / exit abort")))
			(princ)
		)
		(if (and file1) (close file1))
		(princ)
	)
	(defun _openfile (file / sh)
	  ;thanks to @ronjohnp	
	  (setq sh (vlax-get-or-create-object "Shell.Application"))
	  (vlax-invoke-method sh 'open (findfile file))
	  (vlax-release-object sh)
	)
	(defun pick_boundary (msg)
		(setq e (car(entsel msg)))
		(if (and (not e) (= (getvar 'Errno) 7)) (pick_boundary msg) e)
	)
	
	(defun take (amount lst / ret)(repeat amount (setq ret (cons (car lst) (take (1- amount) (cdr lst))))))
	(defun pointlist2d (lst / ret) (while lst (setq	ret (cons (take 2 lst) ret) lst (cddr lst))) (reverse ret))
	(setq 
		i -1
		f (getfiled "Output CSV file:" (getvar "dwgprefix") "csv" 3)
	)
	(cond
		((and f)
			(while (setq e (pick_boundary "\nSelect selection boundary >"))
				(setq 
					eo (vlax-ename->vla-object e)
				    areaname (getstring "\nArea name >")
					boxlayer(vlax-get eo 'Layer)
					boxlen 0
					boxarea 0
					coords (pointlist2d (vlax-get eo 'Coordinates))
					coords (append coords (list (car coords)))
					ps (ssget "_CP" coords)
					fs (ssget "_F" coords)
					j -1	
				)
				(cond 
					((and ps)
						(setq k -1)
						(cond 
							((and fs)
								(while (< (setq k (1+ k)) (sslength fs))
									(setq ps (ssdel (ssname fs k) ps))
								)
							)
						)
						(while (< (setq j  (1+ j)) (sslength ps))
							(setq mo (vlax-ename->vla-object (ssname ps j)))
							(if (member (vlax-get mo 'ObjectName) '("AcDbLine" "AcDbPolyline" "AcDb2DPolyline" "AcDbCircle" "AcDbEllipse"))
								(setq 
									boxlen (+ boxlen (vlax-curve-getdistatparam mo (vlax-curve-getendparam mo)))
									boxarea (+ boxarea (vlax-curve-getarea mo))
									
								)
							)
						)
						(setq items (itoa (1+ j)) ret (cons (list areaname boxlayer items boxlen boxarea) ret))
					)
				)
			)
			(setq file1 (open f "w") ret (reverse ret))
			(write-line "Area name;Layer name;Items;Length;Area" file1)
			(foreach element ret
				(write-line (strcat (car element) ";" (cadr element) ";" (caddr element) ";" (rtos (nth 3 element) 2 2) ";" (rtos (nth 4 element) 2 2)) file1)
			)
			(close file1)
			(_openfile f)
		)
	)
	(princ "\nDone!")
	(princ)
)

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 13 of 54

calderg1000
Mentor
Mentor

Saludos @mss_selcukuni 

Here is something simple not very elegant but it should work for your everyday jobs

See demo video: https://knowledge.autodesk.com/community/screencast/afffb40c-ea08-44a6-93b8-831b1ed97acf

;;;----------------Polyline property list in CSV file----------------------
(vl-load-com)
(defun c:list_Box2
       (/ nn ss fln An i en nlay lx spol j enp ln Ar lcomp lcompl k)
  (princ "\nSelect polyline and Text in consecutive order:")
  (setq nn  (getstring "\nEnter output file name:")
        fln (open (strcat (getvar 'dwgprefix) nn "." "csv") "w")
  )
  (write-line (strcat "Area Name" ";" "Layer Name" ";" "Length" ";" "Area") fln)
  (While (setq ss (entsel "\nSelect Perimeter polyline containing objects to measure:"))
    (setq
      An (cdr (assoc 1 (entget (car (entsel "\nSelect text with Name of the Selected Area:")))))
    )
    (setq en   (car ss)
          nlay (cdr (assoc 8 (entget en)))
          lx   (ver-pol en)
          spol (ssget "_wp" lx '((0 . "*line")))
    )
    (repeat (setq j (sslength spol))
      (setq enp    (vlax-ename->vla-object (ssname spol (setq j (1- j))))
            ln     (vlax-get enp 'length)
            Ar     (vlax-get enp 'Area)
            lcomp  (strcat An ";" nlay ";" (rtos ln 2 2) ";" (rtos Ar 2 2))
            lcompl (cons lcomp lcompl)
      )
    )                                             
  )                                               
  (repeat (setq k (length lcompl))
    (write-line (nth (setq k (1- k)) lcompl) fln)
  )
  (close fln)
)
(defun ver-pol (s / x)
  (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget s)))
)

 


Carlos Calderon G
EESignature
>Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

0 Likes
Message 14 of 54

Sea-Haven
Mentor
Mentor

Hak_vz why not write direct to excel ? Once you get your head around the complexity of it, its actually pretty easy. There is various help tools out there like Getxecel.lsp, my attempt based on Getexel and a good library of routines by denon@alxfunctions.com,  Rlx EXCEL example.lsp to mention a few.

0 Likes
Message 15 of 54

hak_vz
Advisor
Advisor

@Sea-Haven When I write complex programs I use outer libraries and code. For majority code I write upon user requests on this forum I try to write simple code to show that writing lisp code is not a nuclear science. I think that one of purposes of this forum is to show users how to write code. That is why i mostly post my code in reply and not as an attachment.

There are some members of this forum that at first were only asking for solution, but now write their own code.  And I'm happy for it.

Let's hope that @mss_selcukuni will go this way.   

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 16 of 54

mss_selcukuni
Contributor
Contributor

Dear @hak_vz ;

Thank you so so much..

Firstly, you are right.. I would like to write simple codes which are my needed.. And i will analyze @hak_vz 's code.. This workshop being good for me. Thank you againg @hak_vz 

 

1. Point:

I try your code... And pls see my notes below and help me.. I am sure you are kind to help us..

 

I mean layers name are not layer name of boxes'..  I mean layer name of shapes in boxes.

I want to give each layer the name of material.. and then when i run the lisp, autocad give me all of layers name in boxes and length of each layer...

then we can filtre by layer (material name), can take subtotal..

 

did can i describe my desire?

 

Figure 1:

mss_selcukuni_1-1648722680500.png

 

Figure 2:

mss_selcukuni_3-1648725232728.png

 

Sample Sheet in my head;

pls track with figure 2;

 

mss_selcukuni_4-1648725938778.png

 

Another point:

lisp is taking area of every shape which are not right line (such as box_solust: 2. box_sagust: 1, 2. box_alt: 2, 3)

Pls see figure 2 up.

Lisp calculating areas of shape 2 and shape 3 in alt_box.. The Lisp seing these shape like triangle..

So maybe lisp can look for closed shape to calculate area... Another side code calculate only length..

Pls see my sample table up...

 

0 Likes
Message 17 of 54

hak_vz
Advisor
Advisor

@mss_selcukuni 

 

It is a bit complicated to separate objects by layers as you wish but I'll try during the weekend.

Lisp will calculate length and areas but you as a user have to separate content and see what is meaningful data.

For example if in a box you have rectangles that represent ceramics then info about area and number of items is correct, but length data is useless. On the other hand if you have polylines or lines that represent pipes, then length data is OK, but area data is nonsense.

 

Create a polyline with more than 2 segments, open properties an select it. You will see that you receive area data as well. If you only have segments between 2 points that are not connected then area data is correct and total length too.

 

To create a program that will do all what you want, attach sample drawing from your practice, and not just a simplified drawing.   

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 18 of 54

mss_selcukuni
Contributor
Contributor

Hi Dear @hak_vz;

I would like to seperate and calculate object's quantity by layer name.. If you can do it.. I will be happy..

 

ok i understood you well.. yes you are right about proporties..

 

I put my sample drawing study in attachment. looks like below.

 

mss_selcukuni_0-1648742694010.png

 

I want to make list which at attachment..

 

can you pls?

 

 

0 Likes
Message 19 of 54

mss_selcukuni
Contributor
Contributor

Hi @hak_vz,

Did you can check our study?

0 Likes
Message 20 of 54

hak_vz
Advisor
Advisor

@mss_selcukuni 

Unfortunately I don't have time to work on your code or any code at all. My long term health condition has become worse in a last year, and I'm getting prepared for an complicated operation and working on it. My presence at this forum will be scarce in next few months.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes