Jump to content

Move blocks individually in Y plan


RubberDinero

Recommended Posts

I'm trying to create a lisp to cross select multiple blocks and change their Y plane value with a mouse click each one by one starting with the upper-most block selected and then moving the second upper-most, etc until all are stacked with the desired spacing (each spacing can vary so specifying a set stack space wouldn't work). 

This is where I'm at, tried for hours creating my own code and also mashing different codes together, but I couldn't even get 1 to move ever.

 

(defun c:test (/ blks blk ) 
	(if (and (setq blks (ssget ":L" '((0 . "INSERT")))));create block list from selected blocks

	(repeat (setq x (sslength blks));returns the number of blocks selected as an integer
	(foreach blk (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex blks))));Not my forte, probably where I'm messing up the rest
		(setq p (getpoint "\Pick Y alignment point: "));get a point, only need y value
		;here is where no matter what I add, I can't get anything to move. probably my list formation above is wrong
	)
	)
	)

 

I tried adding and modifying a code, I believe I got from LeeMac.

you select a bunch of blocks and it aligns them based on X, Y or Z, but all at once. Useful and it's one of my most used Lisp Routine to this day. But it wouldn't work for this new case as I need to stack(or change the spacing of the current stack) based on only the Y plane.

(defun c:XYZ (/ a i k p s)
  (or (setq k (getenv "AlignBlocks")) (setq k "X"))
  (if (and (not (initget "X Y Z"))
	   (setq k (cond ((getkword (strcat "\nAlignment [X/Y/Z] <" k ">: ")))
			 (k)
		   )
	   )
	   (setq p (getpoint "\Pick an alignment point: "))
	   (setq s (ssget '((0 . "insert"))))
      )
    (progn
      (setenv "AlignBlocks" k)
      (setq i (vl-position k '("X" "Y" "Z")))
      (setq a (nth i p))
      (foreach b (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))
	(vlax-invoke b 'move (setq p (vlax-get b 'insertionpoint)) (subst a (nth i p) p))
      )
    )
  )
  (princ)
)
(vl-load-com)

 

 

Thanks ahead of time!

Link to comment
Share on other sites

I HAVE MADE PROGRESS!!!

 

(defun c:test (/ a i k p s)
    (setq s (ssget '((0 . "insert"))))
    (repeat (setq x (sslength s))
    (foreach b (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))
  (or (setq k (getenv "AlignBlocks")) (setq k "X"))
  (if (and (not (initget "X Y Z"))
	   (setq k (cond ("Y")
			 (k)
		   )
	   )
	   (setq p (getpoint "\Pick an alignment point: "))
      )
    (progn
      (setenv "AlignBlocks" k)
      (setq i (vl-position k '("X" "Y" "Z")))
      (setq a (nth i p))
      
	(vlax-invoke b 'move (setq p (vlax-get b 'insertionpoint)) (subst a (nth i p) p))
      
    )
  )))
  (princ)
)
(vl-load-com)

 

 

It keeps looping through after it reaches the end. Need to find a way to end the command after the last entity.

 

EDIT: like I feared, it picks the bottom most blocks first, so I'm having to manually select each block in inverse "Y" order, but it's a start!!!

Edited by RubberDinero
Link to comment
Share on other sites

31 minutes ago, RubberDinero said:

EDIT: like I feared, it picks the bottom most blocks first, so I'm having to manually select each block in inverse "Y" order, but it's a start!!!

Reverse the order of the selection set. :)

 

 

Link to comment
Share on other sites

@TemporaryCADGot it!!!

 

(foreach b (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex s (setq x (- x 1))))))

 

 

THANKS!!!

 

EDIT: that simple (setq x (- x 1)) even fixed the looping! I'm starting to believe!

Edited by RubberDinero
  • Like 1
Link to comment
Share on other sites

To reverse a list use the REVERSE function.

(reverse (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))))

 

Link to comment
Share on other sites

@ronjonpOkay Cool! I will keep that in mind for future reference. I'm always trying to continue learning, but I don't get a chance to write lisps all that often.

 

The code here is actually a small part of a larger program I have  created to automate some tedious tasks. I can easily say I saved myself about 10-20 minutes and hundreds of clicks and keystrokes for smaller jobs. Maybe thousands on larger jobs.

 

There are more improvements that could automate the picking point portion, but for the moment I am content with the current state.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...