Correct forwarding of arguments throught several functions

Correct forwarding of arguments throught several functions

denys_gorkovchuk
Contributor Contributor
573 Views
5 Replies
Message 1 of 6

Correct forwarding of arguments throught several functions

denys_gorkovchuk
Contributor
Contributor

Hi comunity!

I have several functions which work together. Simplified code is here:

 

(defun loop (sset functiontext / entity) ;receive selection set and text of function as input and do that function on every object of selection set

   (if sset

      (progn

         ;(loop code for loop through every object of selection set

            (eval (read functiontext )) ;evaluate function within loop

         ;)end of loop

      );progn

   );if

); defun

 

(defun mainfunction (entity point1 point2 param / ) ; main function, which will be evaluated within the loop
(command "_POINTCLOUDCROP" entity point1 point2 param)
);defun

 

(defun C:test (/ ss point1 point2 param func) ;command, which should join everything together and receive input from user

   (setq ss (ssget)) ;select objects

   (setq point1 (getpoint "\nSpecify first corner point")) ;specify arguments
   (setq point2 (getcorner point1 "\nSpecify second corner point :"))

   (setq param "_Inside")

   (setq func (strcat "(mainfunction entity (list " (vl-princ-to-string point1) ") " (vl-princ-to-string point2) " \"" (vl-princ-to-string param ) "\")" )) ;build a text of function to execute


   (if ss

      (loop ss func) ;start loop

   );if

 

);defun

 

I assume there is somewhere error in building the text of function to execute. Similar simple functions with 1 argument works fine, but here i need to transfer several arguments: lists (points) and string. And I got errors "bad function", "unknown command".

I believe there is some very simple solution with correct syntax, but can't find that in manuals.

Can you help me?

0 Likes
Accepted solutions (1)
574 Views
5 Replies
Replies (5)
Message 2 of 6

paullimapa
Mentor
Mentor

in c:test with this line of code where is entity defined?

  (setq func (strcat "(mainfunction entity (list " (vl-princ-to-string point1) ") " (vl-princ-to-string point2) " \"" (vl-princ-to-string param ) "\")" )) ;build a text of function to execute


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 3 of 6

denys_gorkovchuk
Contributor
Contributor

entity is not defined in C:test. Here it is just a string value.

Entity is defined in mainfunction, so when function text is evaluated in mainfunction it recognize this string as argument, so everything works.

When function is very simple, only with entity, - it works perfectly. But when I need more arguments, then I get errors. I assume the problem is in transferring the lists.

0 Likes
Message 4 of 6

denys_gorkovchuk
Contributor
Contributor
Accepted solution

ok, now I have found my own error. I have forwarded lists and string. And in both cases i used vl-princ-to-string to convert list to string for strcat. but param was already a string, so there was no need to use vl-princ-to-string. I have removed it and everything works now.

0 Likes
Message 5 of 6

paullimapa
Mentor
Mentor

when I run test after selecting objects and the corners of the window, AutoCAD always returns 

error: bad function: ####  where ## is a real number that varies

I still don't know what you're passing as the entity

This line of code equates a call to mainfunction sub routine with entity as one of the arguments:

(setq func (strcat "(mainfunction entity (list " (vl-princ-to-string point1) ") " (vl-princ-to-string point2) " \"" (vl-princ-to-string param ) "\")" )) ;build a text of function to execute

Then when you pass func as an argument to your loop function all you are doing is evaluated the expression as code:

(eval (read functiontext ))

This then jumps to your mainfunction sub routine with still entity as the first argument which is never defined.


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 6 of 6

Moshe-A
Mentor
Mentor

@denys_gorkovchuk  hi,

 

to gather symbols into one variable, put them is a list as quoted items. see line 44. at the point you want to call the  function, use (eval) see line 21.

 

a good coding at the beginning of command is to collect all data inputs and validate them so if user miss some, the command will exit without any errors. this saves you from validating the same variables along the road.

 

note the 'eph variable which is an Ename Place Holder to be substitute by entity.  lines 34, 16

 

enjoy

Moshe

 

 

 

; main function, which will be evaluated within the loop
(defun mainfunction (entity point1 point2 param)
 (command "_POINTCLOUDCROP" entity point1 point2 param)
);defun


; receive selection set and text of function as input and do that function on every object of selection set
(defun loop (sset functiontext / i entity)
 ; sset is check in c:test 
 ; (if sset
 ;  (progn
  ; (eval (read functiontext )) ;evaluate function within loop

   ; (loop code for loop through every object of selection set
   (setq i -1)
   (repeat (sslength sset)
    (setq i (1+ i)) 
    (setq entity (ssname sset i))
    (setq functiontext (append (reverse (cdr (member 'eph (reverse func)))) (list 'entity) (cdr (member 'eph func)))) ; replace 'eph with entity
     
    (eval functiontext) 
   ); repeat - end of loop
;  );progn
; );if
  
); defun


; command, which should join everything together and receive input from user
(defun c:test (/ ss point1 point2 entity param eph func)
 (if (and
       (setq ss (ssget)) ;select objects
       (setq point1 (getpoint "\nSpecify first corner point")) ; specify arguments
       (setq point2 (getcorner point1 "\nSpecify second corner point :"))
     )
  (progn 
   (setq entity (ssname ss 0))
   (setq param "_Inside")
 ; (setq func (strcat "(mainfunction entity (list " (vl-princ-to-string point1) ") " (vl-princ-to-string point2) " \"" (vl-princ-to-string param ) "\")" ))

   (setq eph "enamePlaceHolder")
   
   ; build a text of function to execute
   (setq func (list 'mainfunction 'eph 'point1 'point2 'param)) 
  
 ;| (if ss
    (loop ss func)
   ) |;

   (loop ss func) ;start loop
  ); progn
 ); if
   
);defun

 

 

 

0 Likes