mdbdesign Posted December 4, 2007 Posted December 4, 2007 Hi! Recently find nice codes written by VVA and posted by ASMI: http://www.cadtutor.net/forum/showthread.php?t=14493&highlight=draw+boundary+box+around+selected+object Question is: I need similar routine that will draw rectangular box around selected object with option to offset it at user specify distance from most outer edges of selected objects as shown on dwg with phantom yellow line, can you help me? enclose object with rectngle.dwg Quote
VovKa Posted December 4, 2007 Posted December 4, 2007 it will draw a rectangle (with offset) around selected objects. it DOES NOT work correctly with splines (vl-load-com) (defun vk_GetEntBoundingBox (Ent / LL UR) (vla-GetBoundingBox (vlax-ename->vla-object Ent) 'LL 'UR) (list (vlax-safearray->list LL) (vlax-safearray->list UR)) ) (defun vk_GetSSBoundingBox (SS /) (if SS ((lambda (Coords) (apply (function (lambda (mn mx) (mapcar (function (lambda (n x) (list n x))) mn mx)) ) (mapcar (function (lambda (c) (list (apply 'min c) (apply 'max c)))) (list (mapcar 'car Coords) (mapcar 'cadr Coords)) ) ) ) (apply 'append (mapcar (function vk_GetEntBoundingBox) (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS))) ) ) ) ) ) (defun test (/ SS Offset Bounds) (setq Offset 5.0) (if (setq SS (ssget)) (progn (setq Bounds (mapcar (function (lambda (Coords Off) (mapcar (function (lambda (c) (- c Off))) Coords) ) ) (vk_GetSSBoundingBox SS) (list Offset (- Offset)) ) ) (entmake (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 4) (cons 70 1) (cons 10 (car Bounds)) (list 10 (caar Bounds) (cadadr Bounds)) (cons 10 (cadr Bounds)) (list 10 (caadr Bounds) (cadar Bounds)) ) ) ) ) (princ) ) Quote
mdbdesign Posted December 5, 2007 Author Posted December 5, 2007 Tested tried, work very good. I know I will never use it for spline. Thank you VovKa Quote
vladthedog Posted February 5, 2009 Posted February 5, 2009 I was searching the forums for a lisp that does what this sounds like it does. However I've never dealt with this sort of list. what is the command for this? Quote
taner Posted February 10, 2009 Posted February 10, 2009 Maybe this one is easier to understand. (defun vk_GetSSBoundingBox (SS / ptlst llur) (if SS (progn (setq ptlst (apply 'append (mapcar (function vk_GetEntBoundingBox) (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS) ) ) ) ) ) (setq llur (list (apply 'mapcar (cons 'min ptlst) ) (apply 'mapcar (cons 'max ptlst) ) ) ) ) ) ) Quote
Hunter Posted February 10, 2009 Posted February 10, 2009 Hi all: I'm new to lisp, would u please tell me how to run this code? type "vk_GetEntBoundingBox" seems don't work~ thanks~ Quote
Lee Mac Posted February 10, 2009 Posted February 10, 2009 For help on running LISPs in general, refer to the FAQ section on this site. As for this LISP - I assume you are referring to the LISP posted by VVA - all functions in the LISP are left local and so cannot be run through the command line. When I say "local" I mean, they use: (defun ... () instead of (defun [b]c[/b]: ... () To run the posted LISP, just make the "test" function into a "defun c:..." function and it can be run through the command line as normal. Hope this helps Lee Quote
vladthedog Posted February 25, 2009 Posted February 25, 2009 Ok, I've been playing around with this lisp, and have actually found quite a few uses for my process which cuts minutes off processing time. However, It seemingly randomly doesn't work. But when it doesn't work it's consistent to the objects i'm trying to surround. attached is a dwg with a top (I work in countertops) WITH the outcome of running this lisp. As you can see it draws a square but it's huge. When I say it's consistent, I can copy/paste that top onto a completely new (and empty) template, and run the lisp and it will produce the exact same outcome. Any help/pointers would be greatly appreciated. Thanks. boxsurroundtest.dwg Quote
VovKa Posted February 26, 2009 Posted February 26, 2009 vladthedog, it seems that vla-GetBoundingBox does not like your "arced" wall-polyline. try using "._pedit _decurve" on it. Quote
vladthedog Posted February 26, 2009 Posted February 26, 2009 Looks like you are right. Played around with it a bit, and that's exactly it. Unfortunately, and this is where I become difficult; I do apologize.... I can't decurve my polyedited lines (in this example it would be ok, but there are times it wouldn't) and I need the lines to be polyedited............. Quote
VovKa Posted February 26, 2009 Posted February 26, 2009 you can also use ._convertpoly _light command to convert your heavyweight polylines into light ones. this will solve your problem. you may also want to set system variable plinetype to 2. Quote
sadhu Posted February 11, 2010 Posted February 11, 2010 it will draw a rectangle (with offset) around selected objects.it DOES NOT work correctly with splines (vl-load-com) (defun vk_GetEntBoundingBox (Ent / LL UR) (vla-GetBoundingBox (vlax-ename->vla-object Ent) 'LL 'UR) (list (vlax-safearray->list LL) (vlax-safearray->list UR)) ) (defun vk_GetSSBoundingBox (SS /) (if SS ((lambda (Coords) (apply (function (lambda (mn mx) (mapcar (function (lambda (n x) (list n x))) mn mx)) ) (mapcar (function (lambda (c) (list (apply 'min c) (apply 'max c)))) (list (mapcar 'car Coords) (mapcar 'cadr Coords)) ) ) ) (apply 'append (mapcar (function vk_GetEntBoundingBox) (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS))) ) ) ) ) ) (defun test (/ SS Offset Bounds) (setq Offset 5.0) (if (setq SS (ssget)) (progn (setq Bounds (mapcar (function (lambda (Coords Off) (mapcar (function (lambda (c) (- c Off))) Coords) ) ) (vk_GetSSBoundingBox SS) (list Offset (- Offset)) ) ) (entmake (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 4) (cons 70 1) (cons 10 (car Bounds)) (list 10 (caar Bounds) (cadadr Bounds)) (cons 10 (cadr Bounds)) (list 10 (caadr Bounds) (cadar Bounds)) ) ) ) ) (princ) ) Can you help me modify / integrate the above code. I need to add a number to the box (rectangle) so that all the boxes on the drawing are progressively numbered . The number should be placed bottom-center or bottom-right. the numbers should not repeat. thankx Quote
JohnM Posted February 11, 2010 Posted February 11, 2010 give this a try it works with splines, arcs, polylines, blocks (vl-load-com) (defun c:mkbbx ( / a axss lpx lpy upx upy rtpts maxp minp points ss ofdst pt1 pt3) (setq ss (ssget)) (if ss (progn (setq axss (vla-get-activeselectionset(vla-get-activedocument(vlax-get-acad-object))) ) (vlax-for a axss (if(not (vl-catch-all-error-p (vl-catch-all-apply (function (lambda () (vla-getboundingbox a 'minp 'maxp)))))) (setq points (append (list (vlax-safearray->list minp) (vlax-safearray->list maxp)) points) ) ) ) (setq lpx (car(car(vl-sort points (function (lambda (a b) (> (car a) (car b)) ))))) );_setq (setq lpy (cadr(car(vl-sort points (function (lambda (a b) (< (cadr a) (cadr b)) ))))) );_setq (setq upx (car(car(vl-sort points (function (lambda (a b) (< (car a) (car b)) ))))) );_setq (setq upy (cadr(car(vl-sort points (function (lambda (a b) (> (cadr a) (cadr b)) ))))) );_setq (setq rtpts (list(list upx upy)(list lpx lpy))) (setq ofdst (getreal "\nEnter Offset")) (if ofdst (progn (setq pt1 (nth 0 rtpts)) (setq pt3 (nth 1 rtpts)) (setq pt1 (polar (polar pt1 (angtof "90" 0) ofdst) (angtof "180" 0) ofdst)) (setq pt3 (polar (polar pt3 (angtof "0" 0) ofdst) (angtof "270" 0) ofdst)) (command "rectangle" pt1 pt3) );_progn );_if );_progn );_if );_defun Quote
sadhu Posted February 11, 2010 Posted February 11, 2010 Thankx John. Mkbbx works fine for me . I use it for blocks. I still need to have them numbered univocally. A hint on how I should proceed or look for will be helpful. Quote
JohnM Posted February 11, 2010 Posted February 11, 2010 You need to make a few decisions on the text first and the code will be easer to do You can approach it 2 different ways Make your rectangles then come back and make one text to the scale and layer you want then copy the text and use express tools automatic text number command. This is a manual method If you want the code to do it you would need to create a specific layer for the text so you can use SSGET to determine the number to be used. What happens if you delete a rectangle in the middle of a number sequence? Will the number text be scaled? Quote
sadhu Posted February 11, 2010 Posted February 11, 2010 Do you think its possible to add an attribute - ( auto incremental ) to the rectangle ? Quote
JohnM Posted February 11, 2010 Posted February 11, 2010 Almost anything is possible if you try I would use a block with a attribute just for easy access if you want to change it. I think a quick way is to: Create a wblock or a block that you save to your template with one attribute In your code find the insert point for your block on the rectangle Insert the block Use ssget with a filter for the block name so you can determine the attribute number Use sslength for the number Write the number to the attribute. Now it’s your turn to write the code If you get stuck just post for help Quote
Lee Mac Posted February 11, 2010 Posted February 11, 2010 Another way to box it: (defun c:BoxObj (/ ss obj ss doc Mi Ma pts) (vl-load-com) ;; Lee Mac ~ 11.02.10 (if (setq ss (ssget)) (progn (vlax-for obj (setq ss (vla-get-ActiveSelectionSet (setq doc (vla-get-ActiveDocument (vlax-get-acad-object))))) (vla-getBoundingbox obj 'Mi 'Ma) (setq pts (cons (vlax-safearray->list Mi) (cons (vlax-safearray->list Ma) pts)))) (vla-delete ss) (setq Mi (apply (function mapcar) (cons 'min pts)) Ma (apply (function mapcar) (cons 'max pts))) (vla-put-closed (vla-addLightWeightPolyline (if (zerop (vla-get-ActiveSpace doc)) (if (eq :vlax-true (vla-get-mspace doc)) (vla-get-ModelSpace doc) (vla-get-PaperSpace doc)) (vla-get-ModelSpace doc)) (variant (vlax-safearray-fill (safearray vlax-vbDouble '(0 . 7)) (list (car Mi) (cadr Mi) (car Mi) (cadr Ma) (car Ma) (cadr Ma) (car Ma) (cadr Mi))))) :vlax-true))) (princ)) Edit: Updated to include working through a viewport. Quote
sadhu Posted February 15, 2010 Posted February 15, 2010 Another way to box it: (defun c:BoxObj (/ ss obj ss doc Mi Ma pts) (vl-load-com) ;; Lee Mac ~ 11.02.10 (if (setq ss (ssget)) (progn (vlax-for obj (setq ss (vla-get-ActiveSelectionSet (setq doc (vla-get-ActiveDocument (vlax-get-acad-object))))) (vla-getBoundingbox obj 'Mi 'Ma) (setq pts (cons (vlax-safearray->list Mi) (cons (vlax-safearray->list Ma) pts)))) (vla-delete ss) (setq Mi (apply (function mapcar) (cons 'min pts)) Ma (apply (function mapcar) (cons 'max pts))) (vla-put-closed (vla-addLightWeightPolyline (if (zerop (vla-get-ActiveSpace doc)) (vla-get-PaperSpace doc) (vla-get-ModelSpace doc)) (variant (vlax-safearray-fill (safearray vlax-vbDouble '(0 . 7)) (list (car Mi) (cadr Mi) (car Mi) (cadr Ma) (car Ma) (cadr Ma) (car Ma) (cadr Mi))))) :vlax-true))) (princ)) for Lee Mac : BoxObj does not draw around selected objects - unless you intended some other use for it that I didn't understand. Any way what I am looking for is to draw a box around selected objects and number it. The numbering should be progressive / incremental and I should be able to continue numbering even after I close the drawing and reopen it later. I thought I could follow JohnM advice but I'm light years form coding ssget, vla- and stuff. So all help is appreciated. Quote
Recommended Posts
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.