Volume calculation

Volume calculation

k005
Advisor Advisor
1,894 Views
26 Replies
Message 1 of 27

Volume calculation

k005
Advisor
Advisor

 

 

Uzunluk : 25x45x989
Uzunluk : 30x45x1160
Uzunluk : 30x45x315

Uzunluk : 325

Uzunluk : 450

...

...

 

Hello friends

 

 

From the data in this section;

a- How can I divide by 100 and multiply the ones with x in them and add the results?

b- How can I add the ones that do not have an x in them? and divide 100

 

 

desired result

a... Total Volume: 3.103 m³

b... Total Length : 7.75 m

 

 

 

 

0 Likes
Accepted solutions (1)
1,895 Views
26 Replies
Replies (26)
Message 2 of 27

ronjonp
Mentor
Mentor

Assuming you're selecting text...

(defun c:foo (/ l s str v x)
  ;; RJP » 2021-08-12
  (cond	((setq s (ssget '((0 . "text"))))
	 (setq l 0 v 0)
	 (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
	   (if (vl-string-search "x" (setq str (cdr (assoc 1 (entget e)))))
	     (setq v (+	v
			(apply '*
			       (mapcar '(lambda (x) (/ x 100.))
				       (read (strcat "(" (vl-string-translate "x" " " str) ")"))
			       )
			)
		     )
	     )
	     (setq l (+ l (atof str)))
	   )
	 )
	)
  )
  (princ (strcat "\nVolume: " (vl-princ-to-string v)))
  (princ (strcat "\nLength: " (vl-princ-to-string l)))
  (princ)
)
Message 3 of 27

Kent1Cooper
Consultant
Consultant

EDIT:  Great minds think alike, even down to the letter used in the argument in the (lambda) function.  I was beat to the punch, but here anyway....

 

One way to do the the numerical parts of extracting information in meters from centimeter inputs, in the first 'a' and 'b':

 

(setq str "25x45x989")

[extracted from first item], then:

(apply '* (mapcar '(lambda (x) (/ x 100.0)) (read (strcat "(" (vl-string-translate "x" " " str) ")"))))
returns the volume of that item:

1.11263

 

If str is set to just "325", extracted in the same way from the fourth item, the same code returns 3.25.

 

Later I may try putting the rest of it together....

 

But I wonder:  If you are selecting Text objects, are they only the numbers [with or without x's], or do they include the  Uzunluk :  part that would need to be stripped off?

Kent Cooper, AIA
Message 4 of 27

k005
Advisor
Advisor

@ronjonp 

 

Results and plugin:

* it processes when I separate the text. But for now, there is no such distinction.

 

* Add : Let it select the texts in the "KirisuzunlukYazi" layer only..

Thanks.

0 Likes
Message 5 of 27

k005
Advisor
Advisor

@Kent1Cooper 

 

 

There is no part to remove... just exactly as I wrote it.

 

 

I'm also wondering;

Did you write this part for me or is it general?

 

EDIT: Great minds think alike, even down to the letter used in the argument in the (lambda) function. I was beat to the punch, but here anyway....

0 Likes
Message 6 of 27

ronjonp
Mentor
Mentor

@k005 wrote:

@ronjonp 

 

Results and plugin:

* it processes when I separate the text. But for now, there is no such distinction.

 

* Add : Let it select the texts in the "KirisuzunlukYazi" layer only..

Thanks.


For the layer filter change this: 

(setq s (ssget '((0 . "text"))))

to this:

(setq s (ssget '((0 . "text") (8 . "KirisuzunlukYazi"))))

Message 7 of 27

k005
Advisor
Advisor

@ronjonp 

 

Ok I added the layer part. . All right, making a choice.

 

but :

 

I am getting the following error: ;

 

error: bad argument type: numberp: UZUNLUK

0 Likes
Message 8 of 27

ronjonp
Mentor
Mentor
Accepted solution

@k005 wrote:

@ronjonp 

 

Ok I added the layer part. . All right, making a choice.

 

but :

 

I am getting the following error: ;

 

error: bad argument type: numberp: UZUNLUK


Try this mod:

 

 

(defun c:foo (/ l s str v x)
  ;; RJP » 2021-08-12
  (cond	((setq s (ssget '((0 . "text") (1 . "*#*") (8 . "KirisuzunlukYazi"))))
	 (setq l 0 v 0)
	 (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
	   (setq str (cdr (assoc 1 (entget e))))
	   (while (null (wcmatch (substr str 1 1) "#")) (setq str (substr str 2)))
	   (if (vl-string-search "x" str)
	     (setq v (+	v
			(apply '*
			       (mapcar '(lambda (x) (/ x 100.))
				       (read (strcat "(" (vl-string-translate "x" " " str) ")"))
			       )
			)
		     )
	     )
	     (setq l (+ l (atof str)))
	   )
	 )
	)
  )
  (princ (strcat "\nVolume: " (vl-princ-to-string v)))
  (princ (strcat "\nLength: " (vl-princ-to-string l)))
  (princ)
)

 

 

 

Message 9 of 27

k005
Advisor
Advisor

@ronjonp 

 

; error: bad argument type: stringp <Selection set: 3e>

0 Likes
Message 10 of 27

ronjonp
Mentor
Mentor

Try the code above again .. had a typo.

0 Likes
Message 11 of 27

Kent1Cooper
Consultant
Consultant

@k005 wrote:

 

There is no part to remove... just exactly as I wrote it.

 

I'm also wondering;

Did you write this part for me or is it general?

 

EDIT: Great minds think alike, even down to the letter used in the argument in the (lambda) function. I was beat to the punch, but here anyway....


Exactly as you wrote it is not entirely clear.  Does each line at the beginning of Message 1 represent the content of a separate Text object, and the User would select those Text objects?  If so, it would be necessary to remove the  Uzunluk :  part from the contents of each string, to leave only the relevant numerical parts.  If selected Text objects would actually be just the numerical parts, without the  Uzunluk :  part, then no, there would be nothing to remove.  But since you didn't specify the nature of the "data," other possibilities exist:  they could be in a spreadsheet file, or a table, or Attributes in Blocks, or....

 

The "great minds" statement is about the fact that both @ronjonp and I, independently, came up with exactly the same way of calculating the volume in cubic meters from a text string of lengths in centimeters with x's between them.  There are certainly other ways to structure that calculation, so it was interesting to me that ours were identical.

Kent Cooper, AIA
Message 12 of 27

k005
Advisor
Advisor

there is one more mistake. cannot choose.

0 Likes
Message 13 of 27

ronjonp
Mentor
Mentor

Post your sample drawing.

 

* And try the code above again. 

Message 14 of 27

k005
Advisor
Advisor

 

attaching the file.

 

 

0 Likes
Message 15 of 27

k005
Advisor
Advisor

@ronjonp 

 

 

Ok. Thank you very much, 🤗

0 Likes
Message 16 of 27

Kent1Cooper
Consultant
Consultant

So they are separate Text objects, including the prefix.  If that prefix is always exactly the same, then (substr TextContent 11) will get just the numerical part at the end.  If it might vary, it could be stripped off in other ways.

Kent Cooper, AIA
0 Likes
Message 17 of 27

ronjonp
Mentor
Mentor

@k005 wrote:

@ronjonp 

 

 

Ok. Thank you very much, 🤗


Glad to help .. here's a mod that filters by text string so we can chop off the prefix then do the calcs.

(defun c:foo (/ l s str v x)
  ;; RJP » 2021-08-12
  (cond	((setq s (ssget '((0 . "text") (1 . "Uzunluk : *"))))
	 (setq l 0 v 0)
	 (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
	   (setq str (substr (cdr (assoc 1 (entget e))) 11))
	   (if (vl-string-search "x" str)
	     (setq v (+	v
			(apply '*
			       (mapcar '(lambda (x) (/ x 100.))
				       (read (strcat "(" (vl-string-translate "x" " " str) ")"))
			       )
			)
		     )
	     )
	     (setq l (+ l (atof str)))
	   )
	 )
	)
  )
  (princ (strcat "\nVolume: " (vl-princ-to-string v)))
  (princ (strcat "\nLength: " (vl-princ-to-string l)))
  (princ)
)
Message 18 of 27

k005
Advisor
Advisor

@ronjonp 

 

 

It was even more beautiful. Thank you. I can easily change this. 🤗  OK.

0 Likes
Message 19 of 27

hak_vz
Advisor
Advisor

@k005  I'm a bit late to the show, but anyway.

 

 

(defun c:moo (/ ss i l a v ss e string_to_list *error*)
	(defun *error* ( msg )
		(if (not (member msg '("Function cancelled" "quit / exit abort")))
			(princ)
		)
	)
	(defun string_to_list ( str del / pos )
		(if (setq pos (vl-string-search del str))
			(cons (substr str 1 pos) (string_to_list (substr str (+ pos 1 (strlen del))) del))
			(list str)
		)
	)
	(princ "\nSelect length/area/volume text:")
	(setq ss (ssget '((0 . "TEXT")(8 . "KirisuzunlukYazi"))))
	(setq i -1 l 0.0 a 0.0 v 0.0)
	(while (< (setq i (1+ i)) (sslength ss))
		(setq e (cdr (assoc 1 (entget(ssname ss i)))))
		(cond 
			((and(vl-string-position (ascii "x") e))(setq e (string_to_list (substr  e (+ (strlen "Uzunluk :")2)) "x")))
			(T (setq e (list(substr  e (+ (strlen "Uzunluk :")2)))))
		)
		(cond 
			((= (length e) 1) (setq l (+ l (apply '* (mapcar '* (mapcar 'atof e))))))
			((= (length e) 2) (setq a (+ a (apply '* (mapcar '* (mapcar 'atof e))))))
			((= (length e) 3) (setq v (+ v (apply '* (mapcar '* (mapcar 'atof e))))))
		)
	)
	(cond ((> l 0) (princ (strcat "\nTotal length = " (rtos (* 1e-2 l) 2 4) " m"))))
	(cond ((> a 0) (princ (strcat "\nTotal area = " (rtos (* 1e-4 a) 2 4) " m2"))))
	(cond ((> v 0) (princ (strcat "\nTotal volume = " (rtos (* 1e-6 v) 2 4) " m3"))))
	(princ)
)

 

 Calculates total length, area and volume.

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 20 of 27

k005
Advisor
Advisor

@hak_vz 

 

 

Yes. This is very nice work.

Thank you very much. I save it in my archive. 🤗

0 Likes