View Full Version : OBTAINING BOUNDARY BOX POINTS OF AN OBJECT IN UCS
marko_ribar
2008-03-09, 02:34 PM
Can anyone tell me how to obtain boundary box points of an object in UCS, not WCS in AutoLISP or Visual LISP...
To obtain it from WCS is by transfering object information into ActivX object :
(vl-load-com)
(setq sn (car (entsel)))
(setq entActivX (vlax-ename->vla-object sn))
and getting WCS boundary by:
(vla-getboundingbox entActivX 'bmin 'bmax)
(setq bmin (vlax-safearray->list bmin))
(setq bmax (vlax-safearray->list bmax))
My question is considered changed UCS so Bounding Box changes also...
Above mentioned points bmin and bmax can be transformed in UCS by (trans bmin 0 1) or (trans bmax 0 1), but the result isn't what I needed... By entering LIST or MASSPROP command while changed UCS result is different... How to see how LIST or MASSPROP command works?
Thanks for any new thread post...
'gile'
2008-03-09, 06:10 PM
Hi,
Here's a routine which returns a list of the UCS coordinates of the minpoint and maxpoint of the bounding box of the object about current UCS.
;; Doug C. Broad, Jr.
;; can be used with vla-transformby to
;; transform objects from the UCS to the WCS
(defun UCS2WCSMatrix ()
(vlax-tmatrix
(append
(mapcar
'(lambda (vector origin)
(append (trans vector 1 0 t) (list origin))
)
(list '(1 0 0) '(0 1 0) '(0 0 1))
(trans '(0 0 0) 0 1)
)
(list '(0 0 0 1))
)
)
)
;; transform objects from the WCS to the UCS
(defun WCS2UCSMatrix ()
(vlax-tmatrix
(append
(mapcar
'(lambda (vector origin)
(append (trans vector 0 1 t) (list origin))
)
(list '(1 0 0) '(0 1 0) '(0 0 1))
(trans '(0 0 0) 1 0)
)
(list '(0 0 0 1))
)
)
)
;; UCS-BBOX (gile)
;; Returns the UCS coordinates of the object bounding box about UCS
;;
;; Argument
;; obj : a graphical object (ename or vla-object)
;;
;; Return
;; a list of left lower point and right upper point UCS coordinates
(defun ucs-bbox (obj / space bb minpoint maxpoint line lst)
(vl-load-com)
(and (= (type obj) 'ENAME)
(setq obj (vlax-ename->vla-object obj))
)
(vla-TransformBy obj (UCS2WCSMatrix))
(setq bb (vla-getboundingbox obj 'minpoint 'maxpoint))
(vla-TransformBy obj (WCS2UCSMatrix))
(list
(vlax-safearray->list minpoint)
(vlax-safearray->list maxpoint)
)
)
Working the same way, the attached file creates an object (box or 3d polyline) figuring the UCS bbox.
marko_ribar
2008-03-10, 04:09 PM
Thanks a lot, that helped me in finishing my sol2blk.lsp...
Still it doesn't work for all positions in space but it works for verticaly placed solids with same volume and for those that are rotated in 2D or arrayed...
As a present I'll post *.lsp for those that want to use it...
Thanks again...
Marko Ribar, arch.
LSP: sol2blk.lsp
(defun c:sol2blk (/ entActivX entActivXss)
(arxload "geomcal.arx")
(command "ucs" "W")
(command "undo" "m")
(setq echocmd (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq oscmd (getvar "osmode"))
(setvar "osmode" 0)
(setq lacmd (getvar "clayer"))
(print)
(prompt "\nTransforming identical solids <same layer and volume> into block which is implemented at the same place with exact orientation if solids are positioned vertically from XY plane; original solids are being erased ")
(print)
(setq sn (car (entsel "\nSelect base solid")))
(setq s (ssadd))
(ssadd sn s)
(vl-load-com)
;; Doug C. Broad, Jr.
;; can be used with vla-transformby to
;; transform objects from the UCS to the WCS
(defun UCS2WCSMatrix ()
(vlax-tmatrix
(append
(mapcar
'(lambda (vector origin)
(append (trans vector 1 0 t) (list origin))
)
(list '(1 0 0) '(0 1 0) '(0 0 1))
(trans '(0 0 0) 0 1)
)
(list '(0 0 0 1))
)
)
)
;; transform objects from the WCS to the UCS
(defun WCS2UCSMatrix ()
(vlax-tmatrix
(append
(mapcar
'(lambda (vector origin)
(append (trans vector 0 1 t) (list origin))
)
(list '(1 0 0) '(0 1 0) '(0 0 1))
(trans '(0 0 0) 1 0)
)
(list '(0 0 0 1))
)
)
)
(setq entActivX (vlax-ename->vla-object sn))
(setq lays (vla-get-Layer entActivX))
(setq dir (vlax-safearray->list (vlax-variant-value (vla-get-PrincipalDirections entActivX))))
(setq v1 (list (nth 0 dir) (nth 1 dir) (nth 2 dir)))
(setq v2 (list (nth 3 dir) (nth 4 dir) (nth 5 dir)))
(setq v3 (list (nth 6 dir) (nth 7 dir) (nth 8 dir)))
(setq cents (vlax-safearray->list (vlax-variant-value (vla-get-Centroid entActivX))) )
(setq vols (vla-get-Volume entActivX))
(setq bname (getstring "\nEnter the name of block : "))
(initget 1 "Yes No")
(setq izblay (getkword "\nDo you want me to put solid into \"0\" Layer and make block in its Layer or to keep reference Layer <Yes/No> : "))
(if (equal izblay "Yes")
(command "change" s "" "p" "la" "0" "")
)
(setq o '(0 0 0))
(command "ucs" "3p" cents (cal "cents+v1") (cal "cents+v2") "")
(vla-TransformBy entActivX (UCS2WCSMatrix))
(vla-getboundingbox entActivX 'minpoint 'maxpoint)
(vla-TransformBy entActivX (WCS2UCSMatrix))
(setq bmin (vlax-safearray->list minpoint))
(setq bmax (vlax-safearray->list maxpoint))
(command "-block" bname o s "")
(setvar "clayer" lays)
(command "-insert" bname o "" "" "")
(prompt "\nOriginal solid transformed into block : ")(princ bname)
(setq sss (ssadd))
(ssadd (entlast) sss)
(setq sslaysol (ssget "X" (list (cons 0 "3DSOLID") (cons 8 lays))))
(setq sslaysoln (sslength sslaysol))
(setq k -1)
(command "ucs" "W")
(repeat sslaysoln
(setq k (+ k 1))
(setq n (+ k 1))
(prompt "\nImplementing : ")(princ n)(prompt " solid with block : ")(princ bname)
(setq ssent (ssname sslaysol k))
(setq entActivXss (vlax-ename->vla-object ssent))
(setq volss (vla-get-Volume entActivXss))
(setq centss (vlax-safearray->list (vlax-variant-value (vla-get-Centroid entActivXss))) )
(setq dirss (vlax-safearray->list (vlax-variant-value (vla-get-PrincipalDirections entActivXss))))
(setq v1ss (list (nth 0 dirss) (nth 1 dirss) (nth 2 dirss)))
(setq v2ss (list (nth 3 dirss) (nth 4 dirss) (nth 5 dirss)))
(setq v3ss (list (nth 6 dirss) (nth 7 dirss) (nth 8 dirss)))
(if (= (fix (- vols volss)) 0)
(progn
(command "ucs" "3p" o (cal "o+v1ss") (cal "o+v2ss") "")
(setq cu (trans centss 0 1))
(command "ucs" "m" cu)
(vla-TransformBy entActivXss (UCS2WCSMatrix))
(vla-getboundingbox entActivXss 'minpoints 'maxpoints)
(vla-TransformBy entActivXss (WCS2UCSMatrix))
(setq bmins (vlax-safearray->list minpoints))
(setq bmaxs (vlax-safearray->list maxpoints))
(if (and (< (abs (- (car bmin) (car bmins))) 0.01) (< (abs (- (cadr bmin) (cadr bmins))) 0.01) (< (abs (- (caddr bmin) (caddr bmins))) 0.01) (< (abs (- (car bmax) (car bmaxs))) 0.01) (< (abs (- (cadr bmax) (cadr bmaxs))) 0.01) (< (abs (- (caddr bmax) (caddr bmaxs))) 0.01) ) ()
(progn
(command "ucs" "z" -90)
(vla-TransformBy entActivXss (UCS2WCSMatrix))
(vla-getboundingbox entActivXss 'minpoints 'maxpoints)
(vla-TransformBy entActivXss (WCS2UCSMatrix))
(setq bmins (vlax-safearray->list minpoints))
(setq bmaxs (vlax-safearray->list maxpoints))
))
(if (and (< (abs (- (car bmin) (car bmins))) 0.01) (< (abs (- (cadr bmin) (cadr bmins))) 0.01) (< (abs (- (caddr bmin) (caddr bmins))) 0.01) (< (abs (- (car bmax) (car bmaxs))) 0.01) (< (abs (- (cadr bmax) (cadr bmaxs))) 0.01) (< (abs (- (caddr bmax) (caddr bmaxs))) 0.01) ) ()
(progn
(command "ucs" "z" -90)
(vla-TransformBy entActivXss (UCS2WCSMatrix))
(vla-getboundingbox entActivXss 'minpoints 'maxpoints)
(vla-TransformBy entActivXss (WCS2UCSMatrix))
(setq bmins (vlax-safearray->list minpoints))
(setq bmaxs (vlax-safearray->list maxpoints))
))
(if (and (< (abs (- (car bmin) (car bmins))) 0.01) (< (abs (- (cadr bmin) (cadr bmins))) 0.01) (< (abs (- (caddr bmin) (caddr bmins))) 0.01) (< (abs (- (car bmax) (car bmaxs))) 0.01) (< (abs (- (cadr bmax) (cadr bmaxs))) 0.01) (< (abs (- (caddr bmax) (caddr bmaxs))) 0.01) ) ()
(progn
(command "ucs" "z" -90)
))
))
(command "erase" ssent "")
(command "-insert" bname o "" "" "")
(command "ucs" "W")
(ssadd (entlast) sss)
)
(setq n (+ n 1))
(prompt "\nAll together transformed : ")(princ n)(prompt " solids counting with original")
(prompt "\nSelection set with transformed solids into blocks are kept in variable sss <!sss> - it is now gripped")
(setvar "osmode" oscmd)
(setvar "clayer" lacmd)
(setvar "cmdecho" echocmd)
(command "undo" "end")
(princ "\nType \"undo\" \"back\"")
(textscr)
(sssetfirst sss sss)
(princ)
)
Moderator Note:
Please use [ CODE ] tags... (http://forums.augi.com/misc.php?do=bbcode#code)
'gile'
2008-03-10, 04:43 PM
Still it doesn't work for all positions in space
What do you mean by this ?
marko_ribar
2008-04-01, 01:04 PM
Sorry, for it has come to little mistake while putting brackets...
This was recently reviewed while working on model with many solid objects in same layer as base for picking and converting into block... Routine failed to go to next repetition of loop as brackets for ending if - progn statement were before command for inserting block - witch was intended to be inside loop...
Now this revision is correct... (Translate into English lines that are in Serbian language - not many of them)
Bye, Marko Ribar, architect
marko_ribar
2008-04-03, 04:30 PM
I ment this code works for all positions; its just about *.lsp I am working on...
I left final version of sol2blk.lsp, and now it works for all positions as I applied code you gave me for all possible rotations of UCS by 90 degrees along x,y,z, and all combinations of them, as printipal directions vary from case to case...
This routine can be applied at any time while working in 3D and recognition of exactly same SOLID objects by volume and layer is OK. Further more implementation is correct for any poslible position in space no matter objects are arrayed or 3droteted or rotated or just copied...
Only thing you have to have in mind is that for SOLID objects that don't have main Moment of inertion (simple cube, cylinder, ...), implementation is done no matter what position they are to represent in 3D model, so if possible advice is to make simple object unioned with small sphere or dummy (helper object) and position them according to model situation (if you have fence in arc - all sticks are to be oriented arrayed - with helper object as orientation). After sol2blk.lsp all solids are replaced with block as much as there are exactly same solids as picked base one, and oriented correctly... You should use refedit and do slidedit to separate unioned solid and delete helper object...
Now refedit allows you to change the way the sticks look like, to add other elements - for hands and so on...
When you refclose with save changes all sticks have changes applied...
Now you should quick select object by criteria block with picked name you entered while sol2blk.lsp, and you should explode all blocks with that name, then you purge block with that name and transformation is done...
vBulletin® v3.6.7, Copyright ©2000-2009, Jelsoft Enterprises Ltd.