Divide lisp does not change _PDMODE

Divide lisp does not change _PDMODE

keshishian1
Participant Participant
250 Views
5 Replies
Message 1 of 6

Divide lisp does not change _PDMODE

keshishian1
Participant
Participant

Hello,

The lisp below works but it does not change the point style to cross and then back to point. I am forcing a few REGENs to no avail. Any suggestions and simplifications will be very much appreciated. If possible, it will be nice to put the points on the Defpoints layer.

Thank You.

 

(defun c:DV ()
(command "._PDMODE" 2)
(command "._REGEN") ; Refresh before divide
(princ "\nPoint style set to Cross.")

(setq sel (entsel "\nSelect object to divide: "))
(if sel
(progn
(setq obj (car sel))
(setq segments (getint "\nEnter number of segments: "))
(if segments
(progn
(command "._DIVIDE" obj (itoa segments))
(command "._REGEN") ; Refresh to show new points
(command "._PDMODE" 0)
(command "._REGEN") ; Refresh again to apply new style
(princ "\nPoint style changed to Dot.")
)
(princ "\nInvalid number of segments.")
)
)
(princ "\nNo object selected.")
)

(princ "")
)

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

paullimapa
Mentor
Mentor

works for me.  and don't put the points on DEFPOINTS layer because POINT objects will always remain the same behavior as if pdmode is set to 0 


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

Moshe-A
Mentor
Mentor
Accepted solution

@keshishian1  hi,

 

First, point style is controlled by PDSIZE sysvar, you also have to set it in order to see point style. so you set PDMODE at start, do some work (DIVIDE), reset it back at exit. that would be normal coding but not for points style 😀. PDMODE + PDSIZE are fully dynamic much like dimensions style. when you set them, AutoCAD applies the change on all existing points so

restoring PDMODE back will leave you with nothing (see noting).

 

lets look at the next line...

(command "._DIVIDE" obj (itoa segments))

(command) function can accept number of data type of arguments . string is one of them (what you did is ok) but where is possible it also can have numbers (int or real) even list for points so in this case there is no need to convert the int to string.

 

So your code basically good but i would like to show you another solid method.

in cases you need multiple tesing in a row, use (cond) function to test on negative path, that is, if user fail to select object for divide issue error message. if user fail to provide the number for divide issue error message.

 

and one last thing 😀

good practice is to wrap the command with 

(command "._undo" "_begin")

.......

.......

.......

(command "._undo" "_end")

this enables you to undo the command with one U (as any other AutoCAD standard commands)

 

see my example code.

 

enjoy

Moshe 

 

(defun c:DV (/ sel segments obj)
 (setvar "cmdecho" 0) 		; disable command echo
 (command "._undo" "_begin")	; start undo mark
  
 (setvar "pdmode"  2) 		; point style
 (setvar "pdsize" -2) 		; point size
 (princ "\nPoint style set to Cross.")

 (cond
  ((not (setq sel (entsel "\nSelect object for divide: ")))
   (prompt "\nNo object selected.")
  ); case
  ((not (setq segments (getint "\nDivide to number of segments: ")))
   (prompt "\nRequire number segments.")
  ); case
  (t
    (setq obj (car sel))
    (command "._divide" obj segments)
  ); case
 ); cond

 (command "._undo" "_end") ; end undo mark 
 (setvar "cmdecho" 1)      ; restore command echo
 (princ)
); c:DV

0 Likes
Message 4 of 6

komondormrex
Mentor
Mentor

@keshishian1 

check the following

(defun c:DV ()
  (setvar 'pdmode 2)
  (princ "\nPoint style set to Cross.")
  (setq sel (entsel "\nSelect object to divide: "))
  (if (and
	sel
	(setq obj (car sel))
	(setq segments (getint "\nEnter number of segments: "))
	(null (command "._DIVIDE" obj (itoa segments)))
	(princ "\nHit any key to finish")
	(vl-catch-all-apply 'grread '()) 
      )
      (progn
      	(setvar 'pdmode 0)
	(while (setq obj (entnext obj))
	  (entmod (append (entget obj) '((8 . "Defpoints"))))
	)
      )
      (princ "\nInvalid number of segments or no object selected") 
  )
  (princ)
)
0 Likes
Message 5 of 6

Kent1Cooper
Consultant
Consultant

WARNING:  I can't test it, because I get a suspicious-content warning when I try to copy and paste into Notepad.  Something is embedded that should not be there.

But if that's just some kind of oversight, and not malicious:  The routine simply changes PDMODE back immediately, so of course you don't get a chance to see the Points in their cross shape.

If you provide some pause to allow that, you could still have a problem if you simply have a too-tiny PDSIZE setting.

I would suggest simplifying it with a (command-s) function that will encompass the entire Divide command, including the number-of-segments prompt and re-prompt if you should give it something incorrect like a letter.

(defun C:DV ()
  (setvar 'pdmode 2)
  (prompt "\nPoint style set to Cross.")
  (command-s "_.divide")
  (setvar 'pdmode 0)
  (prompt "\nPoint style changed to Dot.")
  (prin1)
)

But that still has the immediate-reset problem, which I will leave you to incorporate from others' suggestions.

By the way, don't put the Points on the DEFPOINTS Layer.  It has special properties other than only not plotting, and should be left to AutoCAD to use for its purposes only.  The use of it for non-plotting stuff is an archaic hold-over from the old days when it was the only Layer that would not plot.  But it's been many years [decades?] now since you've been able to set any Layer to not plot.  So make a non-plotting Layer for your division points, with a meaningful name.

Kent Cooper, AIA
0 Likes
Message 6 of 6

keshishian1
Participant
Participant

Thank you all for your responses.

0 Likes