Multiple Div Command

Multiple Div Command

apariZRF6P
Explorer Explorer
740 Views
10 Replies
Message 1 of 11

Multiple Div Command

apariZRF6P
Explorer
Explorer

Hello,

 

I've never used LISP before. Know a bit of programmation. Recently got the courage to try some AutoLisp thanks to ChatGPT. Sadly there are some limitation to it (most of his suggestion gets me into errors). 

 

Basically I've tried to create a multiple-lines-div tool, because the div command is great but only for one line at the time, and I usually need to perform it on about 200 lines at the time. I've came up with this code below. The function was working well on VLIDE for a couple of days. Than I restarted AutoCAD and used Appload to showcase the function to a collegue, and as predictable, it was not working anymore.

Better explained, the function actually runs, I select the lines, I select the amount of divisions I want to do, the function runs, I can actually track the points being correctly calculated on VLIDE watch. But the function always ends with 3 points (startpoint, midpoint, endpoint) no matter what I entered and I get a error message of this kind:
- Unknown command "MULT-DIV". Press F1 for help.

- Command: <Selection set: 17>

 

Feel free to share with me a solution that someone already did 20 years ago. It seems to me that this function should be integrated to ACAD. Anyway, here is the code:

(defun c:mult-div ()
  (setq ss (ssget '((0 . "LINE")))) ; Select all lines
  (if (zerop (sslength ss))
    (princ "\nNo lines selected.") ; No lines found
    (progn
      (setq numlines (sslength ss)) ; Get the number of selected lines
      
      (setq div-count (getint "\nEnter the number of divisions: ")) ; Prompt user for division count

      (repeat numlines
        (setq line (vlax-ename->vla-object (ssname ss 0))) ; Get the first line from the selection set
        (setq startpt (vlax-curve-getstartpoint line)) ; Get the start point of the line
        (setq endpt (vlax-curve-getendpoint line)) ; Get the end point of the line

        ; Calculate the x-distance and y-distance for dividing the line into divisions
        (setq x-dist (/ (- (car endpt) (car startpt)) div-count))
        (setq y-dist (/ (- (cadr endpt) (cadr startpt)) div-count))

        ; Create points at the intermediate positions based on the division count
		(setq count 0)
		(repeat (1- div-count)
		  (setq pt (list (+ (car startpt) (* x-dist (1+ count))) (+ (cadr startpt) (* y-dist (1+ count)))))
		  (command "_.point" pt "")
		  (setq count (1+ count)) ; Increament the inner iteration count
        )

        (setq ss (ssdel (ssname ss 0) ss)) ; Remove the processed line from the selection set
      )
    )
  )
)
0 Likes
Accepted solutions (1)
741 Views
10 Replies
Replies (10)
Message 2 of 11

Kent1Cooper
Consultant
Consultant
Accepted solution

@apariZRF6P wrote:

... the function always ends with 3 points (startpoint, midpoint, endpoint) no matter what I entered ....


For that part, my guess is that you have running Object Snap including END and MID modes, and that if you ask for more than four divisions, either the end or midpoint locations or both will have more than one Point at them.  Try turning off running Osnap and running it again.  You can build that into the code if you don't want to be required to turn it off yourself first.

Kent Cooper, AIA
Message 3 of 11

ronjonp
Mentor
Mentor

@apariZRF6P 

Give this a try:

 

(defun c:foo (/ d i n s)
  ;; RJP » 2023-05-23
  (if (and (setq s (ssget '((0 . "LINE"))))
	   (> (setq i (getint "\nEnter the number of divisions: ")) 1)
      )
    (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
      (setq d (/ (distance (vlax-curve-getstartpoint e) (vlax-curve-getendpoint e)) i))
      (setq n 0)
      (repeat (1- i)
	(entmake (list '(0 . "POINT")
		       ;; Layer
		       '(8 . "POINT")
		       ;; Color
		       '(62 . 8)
		       (cons 10 (vlax-curve-getpointatdist e (setq n (+ n d))))
		 )
	)
      )
    )
  )
  (princ)
)

 

Message 4 of 11

Kent1Cooper
Consultant
Consultant

@apariZRF6P wrote:

... I get a error message of this kind:

- Unknown command "MULT-DIV". Press F1 for help.

....

....
		  (command "_.point" pt "")
....

That is probably because the Point command ends with giving it the location, the extraneous "" at the end recalls the latest command, but that "works" only for native AutoCAD command names, so the MULT-DIV command is not recognized.  Try removing the "".

Kent Cooper, AIA
Message 5 of 11

apariZRF6P
Explorer
Explorer

Oh! You are right!

This (Snap Object) was indeed the problem for my specific error codes. Thank you.

 

Regarding the "unknown command" your comment also fixed this other problem I had. Could you point out a reference where I could find all the arguments for a specific command? Because I could not find it. In this case I just copied what ChatGPT was suggesting and it was not the right thing to do apparently...!

 

 

0 Likes
Message 6 of 11

apariZRF6P
Explorer
Explorer
This solution works great and it's much more compact. I'll study it for better understanding. Thank you.
0 Likes
Message 7 of 11

Kent1Cooper
Consultant
Consultant

@apariZRF6P wrote:

.... Could you point out a reference where I could find all the arguments for a specific command? Because I could not find it. In this case I just copied what ChatGPT was suggesting and it was not the right thing to do apparently...!


Help is your friend.  To figure out what to put into a (command) function, run the command manually but starting it with an AutoLisp (command) function, e.g. (command "_.point"), because there are a few commands that operate a little differently inside (command) functions than they do at the Command: line.  Keep track of the prompt sequence and the answers you supply.

 

[ChatGPT simply doesn't know the language well enough yet, and gets lots of things wrong.  Maybe it will improve in time.]

Kent Cooper, AIA
0 Likes
Message 8 of 11

ronjonp
Mentor
Mentor

@apariZRF6P wrote:
This solution works great and it's much more compact. I'll study it for better understanding. Thank you.

@apariZRF6P Glad to help. If you have questions let me know. 👍

0 Likes
Message 9 of 11

Sea-Haven
Mentor
Mentor

Another using divide.

 

(defun c:wow ( / )
(setvar 'pdmode 34)
(if (and (setq s (ssget '((0 . "LINE"))))
	(> (setq i (getint "\nEnter the number of divisions: ")) 1)
    )
(repeat (setq x (sslength s))
(command "divide" (ssname s (setq x (1- x))) i)
)
)
; add point at start and end here if required.
(princ)
)
(c:wow)

 

 Preset a layer etc for the points. 

0 Likes
Message 10 of 11

komondormrex
Mentor
Mentor

hey,

yet another take

(defun c:multiple_divide (/ init division_length start_point line_angle)
	(if (null division_number) (setq division_number 2)) 
	(if (setq init (initget 7) 
		  division_number (getint (strcat "\nEnter division number per line <" (itoa division_number) ">: ")) 
		  line_sset (ssget '((0 . "line")))
	    )
			(foreach line (vl-remove-if 'listp (mapcar 'cadr (ssnamex line_sset)))
				(setq division_length (/ (getpropertyvalue line "Length") division_number)
					  start_point (cdr (assoc 10 (entget line)))
					  line_angle (getpropertyvalue line "Angle")
				)
				(repeat (1- division_number)
					(entmake
						(list
							'(0 . "point")
							 (cons 10 (setq start_point (polar start_point line_angle division_length)))
						)
					)
				)
			)
	)
	(princ)
)
0 Likes
Message 11 of 11

ronjonp
Mentor
Mentor

@apariZRF6P Here's another version that works on other objects too:

(defun c:foo (/ d i n s)
  ;; RJP » 2023-05-24
  (if (and (setq s (ssget '((0 . "ARC,CIRCLE,LINE,*POLYLINE,SPLINE,ELLIPSE"))))
	   (> (setq i (getint "\nEnter the number of divisions: ")) 1)
      )
    (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
      (setq d (/ (vlax-curve-getdistatparam e (vlax-curve-getendparam e)) i))
      (setq n 0)
      (repeat (if (vlax-curve-isclosed e)
		i
		(1- i)
	      )
	(entmake (list '(0 . "POINT")
		       '(8 . "POINT")
		       '(62 . 8)
		       (cons 10 (vlax-curve-getpointatdist e (setq n (+ n d))))
		 )
	)
      )
    )
  )
  (princ)
)