kwwong6 Posted April 26, 2012 Share Posted April 26, 2012 Hi pro guru. Anybody can help me how to write a lisp can create a boundary box with spline entity?:lol: Quote Link to comment Share on other sites More sharing options...
MSasu Posted April 26, 2012 Share Posted April 26, 2012 Not sure what you mean by "boundary box" - if is about "bounding box", then please check this routine written by Lee Mac. Quote Link to comment Share on other sites More sharing options...
kwwong6 Posted April 26, 2012 Author Share Posted April 26, 2012 Yes I mean like the routine written by Lee Mac. But this Lisp cannot correctly make the bounding box for the spline. I need is really close to the spline ==> "mean no gap". Thanks in advance. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 26, 2012 Share Posted April 26, 2012 Indeed, the BoundingBox method is inaccurate for Splines. An alternative approach might be to approximate the Spline using an appropriate point list, then calculate the bounds of such point list; though, this algorithm will undoubtedly be slower than the BoundingBox method. Here is an example to demonstrate this method (you will need to download my Entity to Point List function): (defun BoundingBox ( ent / l ) (if (setq l (LM:Entity->PointList ent)) (mapcar '(lambda ( a ) (apply 'mapcar (cons a l))) '(min max)) ) ) Quote Link to comment Share on other sites More sharing options...
MSasu Posted April 26, 2012 Share Posted April 26, 2012 Alternatively may create a copy in place of the spline, apply FLATTEN command on it and use Lee’s routine for bounding box; remove helper polyline just after. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 26, 2012 Share Posted April 26, 2012 Nice idea Mircea! Here is another method (excuse the messy code): (defun SplineBoundingBox ( ent / pt1 pt2 res var ) (if (setq ent (entmakex (entget ent))) (progn (setq var (mapcar 'getvar '(peditaccept cmdecho))) (mapcar 'setvar '(peditaccept cmdecho) '(1 0)) (command "_.pedit" ent 10 "") (mapcar 'setvar '(peditaccept cmdecho) var) (if (not (equal ent (setq ent (entlast)))) (progn (vla-getboundingbox (vlax-ename->vla-object ent) 'pt1 'pt2) (setq res (mapcar 'vlax-safearray->list (list pt1 pt2))) ) ) (entdel ent) ) ) res ) Test function: (defun c:test ( / bb en ) (princ "\nSelect a Spline: ") (if (setq en (ssget "_+.:E:S:L" '((0 . "SPLINE")))) (if (setq bb (SplineBoundingBox (ssname en 0))) (entmakex (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 4) (cons 70 1) (list 10 (caar bb) (cadar bb)) (list 10 (caadr bb) (cadar bb)) (list 10 (caadr bb) (cadadr bb)) (list 10 (caar bb) (cadadr bb)) ) ) (princ "\nUnable to retrieve Bounding Box.") ) ) (princ) ) (vl-load-com) (princ) Quote Link to comment Share on other sites More sharing options...
marko_ribar Posted April 27, 2012 Share Posted April 27, 2012 (edited) I think that Lee's code won't be correct for earlier versions of ACAD... If you don't need exactly but approx result, try this... (defun SplineBoundingBox ( ent / xmin xmax ymin ymax res cmde ) (setq cmde (getvar 'cmdecho)) (setvar 'cmdecho 0) (vl-cmdf "_.ucs" "w") (vl-cmdf "_.plan" "") (vl-cmdf "_.zoom" "o" ent "") (setq ymin (- (cadr (getvar 'viewctr)) (/ (getvar 'viewsize) 2.0)) ymax (+ (cadr (getvar 'viewctr)) (/ (getvar 'viewsize) 2.0))) (vl-cmdf "_.ucs" "z" 90) (vl-cmdf "_.plan" "") (vl-cmdf "_.zoom" "o" ent "") (setq xmax (- (car (trans (getvar 'viewctr) 1 0)) (/ (getvar 'viewsize) 2.0)) xmin (+ (car (trans (getvar 'viewctr) 1 0)) (/ (getvar 'viewsize) 2.0))) (vl-cmdf "_.zoom" "p") (vl-cmdf "_.zoom" "p") (vl-cmdf "_.zoom" "p") (vl-cmdf "_.zoom" "p") (vl-cmdf "_.zoom" "p") (vl-cmdf "_.ucs" "p") (vl-cmdf "_.ucs" "p") (setvar 'cmdecho cmde) (setq res (list (list xmin ymin 0.0) (list xmax ymax 0.0))) res ) (defun c:test ( / bb en ) (princ "\nSelect a Spline: ") (if (setq en (ssget "_+.:E:S:L" '((0 . "SPLINE")))) (if (setq bb (SplineBoundingBox (ssname en 0))) (entmakex (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 4) (cons 70 1) (list 10 (caar bb) (cadar bb)) (list 10 (caadr bb) (cadar bb)) (list 10 (caadr bb) (cadadr bb)) (list 10 (caar bb) (cadadr bb)) ) ) (princ "\nUnable to retrieve Bounding Box.") ) ) (princ) ) If you want exact results, consider converting SPLINE to POLYLINE like Mircea suggested or if you have A2010 or above (not sure for A2009) A2008 doesn't support - try SPLINEDIT -> Convert to polyline and obtain Bounding Box from pline - after remove dummy pline... If you have A2010 or above, then try also Lee's code - just checked on my A2012 and it worked... Also check this thread from theswamp... M.R. Edited April 27, 2012 by marko_ribar Quote Link to comment Share on other sites More sharing options...
kwwong6 Posted April 28, 2012 Author Share Posted April 28, 2012 Thank for Lee Mac and Marko Ribar Lisp. After try on my AutoCAD 2007, still cannot work well. Maybe my AutoCAD are version are too old. Both of your code cannot support. Anyway thank you both of you. I still need to find out how to break though it. Quote Link to comment Share on other sites More sharing options...
MSasu Posted April 28, 2012 Share Posted April 28, 2012 Please check this solution to convert the said spline to a polyline using your AutoCAD version. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 28, 2012 Share Posted April 28, 2012 Thank for Lee Mac and Marko Ribar Lisp. After try on my AutoCAD 2007, still cannot work well. Maybe my AutoCAD are version are too old. Both of your code cannot support. Anyway thank you both of you. I still need to find out how to break though it. kwwong6, As far as I know, the solution that I posted in reply#4 should work in AutoCAD 2007. Quote Link to comment Share on other sites More sharing options...
MSasu Posted April 28, 2012 Share Posted April 28, 2012 Lee, I'm afraid that PEDIT command of version 2007 doesn't support spline as input. Command: PEDITSelect polyline or [Multiple]: Object selected is not a polyline I think the programmatically alternative is to parse the spline entity with an appropriate defame and trace it with a polyline. Not sure to how to establish that defame size. Quote Link to comment Share on other sites More sharing options...
kwwong6 Posted April 28, 2012 Author Share Posted April 28, 2012 Ya! Lee Mac of course can work. But result are having small gap. I attach a drawing for you so see. Thanks. spline.zip Quote Link to comment Share on other sites More sharing options...
Lt Dan's legs Posted April 29, 2012 Share Posted April 29, 2012 (defun tracecurve ( obj di / cycle st ) (defun cycle ( st stp seg l ) (cond ( (< (+ st seg) stp ) (cycle (+ seg st) stp seg (cons (vlax-curve-getPointAtParam obj st) l) ) ) ( t (and (< st stp) (setq l (cons (vlax-curve-getPointAtParam obj st) l) ) ) (reverse (cons (vlax-curve-getPointAtParam obj stp) l) ) ) ) ) (if (and (not (minusp di))(not (zerop di)) (vl-position (vla-get-objectname (cond ( (eq 'ENAME (type obj))(vlax-ename->vla-object obj )) ( obj ) ) ) '("AcDbCircle" "AcDbArc" "AcDbEllipse" "AcDbSpline") ) ) (cycle (setq st (vlax-curve-getStartParam obj)) (vlax-curve-getEndParam obj) (- (vlax-curve-getParamAtDist obj 0.125) st) nil ) ) ) Modifying Lee Mac's suggestion, though I don't know why his way wouldn't work for you. (defun BoundingBox ( ent / l ) (if (setq l (tracecurve ent 0.125)) (mapcar '(lambda ( a ) (apply 'mapcar (cons a l))) '(min max)) ) ) Quote Link to comment Share on other sites More sharing options...
MSasu Posted April 29, 2012 Share Posted April 29, 2012 @kwwong6 and Lt Dan's legs: Are you both saying that Lee's code from post 6 is working on your AutoCAD 2007?!? Quote Link to comment Share on other sites More sharing options...
kwwong6 Posted April 29, 2012 Author Share Posted April 29, 2012 @kwwong6 and Lt Dan's legs: Are you both saying that Lee's code from post 6 is working on your AutoCAD 2007?!? Yes, no problem running on AutoCAD 2007. Just having small gap as I upload the attached drawing from post 12. Thank you very much for LT Dan's Legs. Your code really work!!!!! But if for multi select the spline, Can you modify your code? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 29, 2012 Share Posted April 29, 2012 Lee, I'm afraid that PEDIT command of version 2007 doesn't support spline as input. I think the programmatically alternative is to parse the spline entity with an appropriate defame and trace it with a polyline. Not sure to how to establish that defame size. MSasu, I was referring to post#4 in my last post, this solution does not involve the use of PEDIT Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 29, 2012 Share Posted April 29, 2012 Modifying Lee Mac's suggestion' date=' though I don't know why his way wouldn't work for you. (defun BoundingBox ( ent / l ) (if (setq l (tracecurve ent 0.125)) (mapcar '(lambda ( a ) (apply 'mapcar (cons a l))) '(min max)) ) ) [/quote'] But your 'tracecurve' is using linear steps; this will be far less accurate than the method used in my Entity to Point List function Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 29, 2012 Share Posted April 29, 2012 Ya! Lee Mac of course can work. But result are having small gap. I attach a drawing for you so see. Thanks. kwwong, You could never achieve an exact bounding box using this method since this method is approximating a continuous curve with a discrete number of points; for true accuracy, you would need an infinite number of points. You could of course increase the accuracy by increasing the number of points in the approximation, but at a severe loss in performance. Quote Link to comment Share on other sites More sharing options...
MSasu Posted April 29, 2012 Share Posted April 29, 2012 MSasu,I was referring to post#4 in my last post, this solution does not involve the use of PEDIT My mistake then. Sorry for inconvenience! Quote Link to comment Share on other sites More sharing options...
kwwong6 Posted April 29, 2012 Author Share Posted April 29, 2012 Thank you Lee Mac for you information. But code done by Lt Dan's legs really can work well for me. Anybody can make this code to multi select spline? Thanks in advance. Quote Link to comment Share on other sites More sharing options...
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.