Hi guys,
Can you help me with a routine that does the followings:
1) Prompts me to choose the entity or entities to copy
2) Once selected, it will copy the entities 500', 1000', 1500', 2000', 2500', 3000' at 90 degree angle or at the direction of the Y coordinate.
Also, this could be in the same routine, but it functions slightly differently. I'd like to be able to make a copy of whichever entities and once selected, have it create 4 copies at 100', 200', 300' and 300' to the right of the item (generally only one block or reference). I also need the copies rotated at predefined degrees: 2nd copy to be rotated at 180 degree, 3rd copy to be rotated 90 degrees and 4th copy to be rotated -90 degrees.
Thanks in advance.
Solved! Go to Solution.
Solved by stevor. Go to Solution.
@kameron1967 wrote:
....
Can you help me with a routine that does the followings:
1) Prompts me to choose the entity or entities to copy
2) Once selected, it will copy the entities 500', 1000', 1500', 2000', 2500', 3000' at 90 degree angle or at the direction of the Y coordinate.
....
That sounds exactly like what a rectangular Array with 1 column, 7 rows, and a row spacing of 500' would do. Is what you want to do somehow different from an Array?
Yes, something like that. Except the 2nd routine is slightly different - with the rotation specified, Kent. Thanks.
I wanted to just type in YY and have whatever entities that I picked to be copied at the specified distances. Same as the XX, but the copies are then rotated. These will generally be either a block or an xref.
Update: I don't mind using the array command. But if you or anyone can help with the 2nd routine, that woud be great. Thanks! 🙂
@kameron1967 wrote:
....
Also, this could be in the same routine, but it functions slightly differently. I'd like to be able to make a copy of whichever entities and once selected, have it create 4 copies at 100', 200', 300' and 300' to the right of the item (generally only one block or reference). I also need the copies rotated at predefined degrees: 2nd copy to be rotated at 180 degree, 3rd copy to be rotated 90 degrees and 4th copy to be rotated -90 degrees.
....
[I think my first Reply was before your Edit was posted with the second routine.] I would assume the last distance should be 400'. If it's only one Block or Xref, can the Rotation base points be their insertion points, assuming those are at or close to the middle of each one? If it's sometimes more than one thing [or one thing that has no insertion point], what should be the base point for Rotation of each copy? The middle of the collective bounding box? The insertion point of some Block or Xref that's part of the selection if there is one? What if there's more than one thing in the selection with an insertion point? Etc.
@kameron1967 wrote:
I wanted to just type in YY and have whatever entities that I picked to be copied at the specified distances. ....
Update: I don't mind using the array command. ....
If you do the same thing repeatedly with the same relationship, a routine can certainly be built that would handle the Arraying part for you with only object selection on the part of the User. I may give it a try in combination with the "XX" idea after getting answers to the questions about that.
Another try of rich text, to maintain some formatting.
And an attachment, attempt.
; no offset
(Defun BBox_2p ( en )
(vla-getboundingbox (vlax-ename->vla-object en) 'minpt 'maxpt)
(list (vlax-safearray->list minpt)
(vlax-safearray->list maxpt) ) )
(DeFun mid_p (a b / c d) (setq @u"mid=p") (mapcar '(Lambda (c d)
(* 0.5 (+ c d))) a b) )
(defun dxf_ (n L) (cdr (assoc n L)) )
; Copy and rotate, boundingbox mid
(Defun C:CR4 ()
(if (and (setq es (entsel "\n Sel Ent: "))
(setq en (car es) sp (cadr es))
(or (= "INSERT" (dxf_ 0 (entget en)))
(and (princ"\n NOT Insert, is: ")
(princ (dxf_ 0 (entget en))) nil)) )
(progn
(setq odl2 (list 100 200 300 400 )) ; last? 300 or400
(setq ral2 (list 0 180 90 -90 )) ;
(setq bbl (BBox_2p en) mp (mid_P (car bbl) (cadr bbl)))
(mapcar '(lambda (od ra )
(command "copy" en "" mp (polar mp 0 od) )
(command "rotate" (entlast) "" (polar mp 0 od) ra)
)
odl2 ral2 )
)
)
(princ " done" ) (princ) )
You might as well learn the codework,
it is too easy to not.
For part 1, a couple changes:
; Copy in Y by 6 element distance list
(Defun C:C6Y (/ es en sp ) (setvar 'osmode 0) ; Object Snap off
(if (and (setq es (entsel "\n Sel Ent at Start PT: "))
(setq en (car es) sp (cadr es))
(or (= "INSERT" (dxf_ 0 (entget en)))
(and (princ"\n NOT Insert, is: ")
(princ (dxf_ 0 (entget en))) nil)) )
(progn
; (setq ben (Blk_Name en)) (PP_"ben")
(setq odl1 (list 500 1000 1500 2000 2500 3000)) ; 6 elem
;(setq odl2 (list 100 200 300 400 )) ; last? 300 or400
;(setq ral2 (list 0 180 90 -90 )) ;
;(setq bbl (BBox_2p en) mp (mid_P (car bbl) (cadr bbl)))
(mapcar '(lambda ( od )
(command "copy" en "" sp (polar sp (/ pi 2) od ) )
) odl1 )
)
)
(princ " done-6 " ) (princ) )
Thanks, Stevor. I wish I understand the code as well as you guys do. I looked at the two (similar) codes and noticed some differences. But I'm not able to decipher where you specified the 90 degree angle. Much appreciated it, though. It worked like a charm!
As I understand it,
the Command interperter uses degrees,
while the Autolisp interperter uses radians.
(/ pi 2) is evaluated as half of the Pi value;
which is half of 180 degrees.
The 'pi is a constant for 3.14....
unless otherwise defined by users,
which is unwise.
Here's one that does both the vertical and horizontal/rotated copies, and works with single or multiple selected objects. It also does some of the things differently, not that they're better ways, but just the way it would occur to me to do them. It could use the addition of error handling, etc.
(defun C:CRR (/ ss edata base ent ell eur LL UR); = Column of copies and Row of Rotated copies
(setq cmde (getvar 'cmdecho) osm (getvar 'osmode))
(setvar 'cmdecho 0)
(setvar 'osmode 0)
(if (setq ss (ssget "_:L")); selection [filter out objects on locked Layers]
(progn ; 'then
(if
(and
(= (sslength ss) 1); only one object
(wcmatch (cdr (assoc 0 (setq edata (entget (ssname ss 0))))) "INSERT,*TEXT,CIRCLE,ELLIPSE")
; something with insertion point or other easier-to-extract center
; [remove ELLIPSE if reference for partial Ellipses should be from
; bounding box, not center; add ARC if it should be geometric center, not from bb]
); amd
(setq base (cdr (assoc 10 edata))); 'then' -- use object's reference point
(progn; 'else' -- build collective bounding box
(repeat (setq n (sslength ss))
(setq ent (ssname ss (setq n (1- n))))
(vla-getboundingbox (vlax-ename->vla-object ent) 'mi 'ma)
(setq
ell (vlax-safearray->list mi); = Entity's Lower Left
eur (vlax-safearray->list ma); = Entity's Upper Right
LL (if LL (mapcar 'min LL ell) ell)
UR (if UR (mapcar 'max UR eur) eur)
); setq
); repeat
(setq base (mapcar '/ (mapcar '+ LL UR) '(2 2 2))); midpoint of bb
); progn
); if [one object or multiple]
(command "_.array" ss "" "_rectangular" 7 1 "500'"); column of copies
(foreach rot '(0 180 270 180); angles are relative to previous copy, not to original
(command
"_.copy" "_previous" "" "0,0" "0,0" ; copy in place, then:
"_.move" "_previous" "" "100',0" "" ; move P so it will still be P for next one
"_.rotate" "_previous" "" (setq base (polar base 0 1200)) rot
); command
); foreach
); progn
); if [selection]
(setvar 'cmdecho cmde)
(setvar 'osmode osm)
); defun
Kent - I finally had a chance to test your routine. For some reason, I'm getting this prompt. Can you please check into it? Thanks.
Command: CRR
Select objects: 1 found
Select objects:
Requires number or two 2D corner points.
; error: Function cancelled
Enter the distance between rows or specify unit cell (---):
@kameron1967 wrote:
... I'm getting this prompt. Can you please check into it? Thanks.
Command: CRR
....
Requires number or two 2D corner points.
; error: Function cancelledEnter the distance between rows or specify unit cell (---):
That's obviously within the Array command. It may be a version difference in the prompt sequence. [I'm not sure, but I probably worked that out at my Acad2004 location, where I also am now, so I can't try it in Acad2015 until later.] You could try doing an Array command manually, and check for the exact sequence of prompts and answers, and coordinate what's in the (command "_.array" ... ) line with what it takes in your version.
I was able to get it to work by converting 500' into 6000. Same with 100' into 1200. Thank you for your time, Kent! Cheers!