Ohnoto Posted March 18, 2011 Posted March 18, 2011 I'm trying to get a LISP working that will determine the distance of selected objects to the nearest line and then put that value into the corresponding property value, called "Offset". I have code for placing the value into the offset property, but I'm having problems with coming up on how to determine the distance from the block to nearest line. For determining the baseline, my code is: (defun EXAOS_CreateBaselineSet () (setq exaosBaselineSet (ssget "_X" (list (cons 0 "ARC,CIRCLE,ELLIPSE,LINE,LWPOLYLINE,POLYLINE,SPLINE") (cons 8 "GPS-ROAD,BASELINE,EOG,EOP,FOGLINE,FOC") ))) ) Now it is just figuring out how to get a distance from the insertion of the block to the nearest point of the baslineset above. Quote
Lee Mac Posted March 19, 2011 Posted March 19, 2011 Perhaps use the following function: (defun ShortestDistanceFromPointtoSet ( sset pt / i lst ) (vl-load-com) (if sset (repeat (setq i (sslength sset)) (setq lst (cons (distance pt (vlax-curve-getClosestPointto (ssname sset (setq i (1- i))) pt)) lst)) ) ) (car (vl-sort lst '<)) ) Call with a SelectionSet and Point (in WCS), e.g.: (defun c:test ( / ss pt ) (if (and (setq ss (ssget '((0 . "ARC,CIRCLE,ELLIPSE,*LINE")))) (setq pt (getpoint "\nSelect Point: ")) ) (print (ShortestDistanceFromPointtoSet ss (trans pt 1 0))) ) (princ) ) Quote
Ohnoto Posted March 21, 2011 Author Posted March 21, 2011 Thanks Lee, this has helped. I am getting an error with the code to insert the value into my block though, if anyone could be of assistance as to where and why. I select the block that is to have the distance applied to it, then the point, and I get an error of "error: ActiveX Server returned the error: unknown name: NAME". Also, is there a way to get it if I select multiple blocks at different distances, it would put in the distance value of each block, based on the insertion point, in the properties? Fiber Marker Test.dwg EXAOS_Main - 0039.LSP Quote
Lee Mac Posted March 21, 2011 Posted March 21, 2011 (edited) The SelectionSet containing the blocks was no longer the 'ActiveSelectionSet' after selecting the Curve Objects. Try this: (defun c:test ( / blocks di e i o pt s s1 s2 ) (vl-load-com) (setq blocks '("FIBER MARKER TUBE-STA") i -1) (if (and (setq s1 (ssget (list '(0 . "INSERT") (cons 2 (apply 'strcat (cons "`*U*" (mapcar '(lambda ( s ) (strcat "," s)) blocks))) ) ) ) ) (setq s2 (ssget "_X" (list (cons 0 "ARC,CIRCLE,ELLIPSE,LINE,*POLYLINE,SPLINE") (cons 8 "GPS-ROAD,BASELINE,EOG,EOP,FOGLINE,FOC") ) ) ) (setq pt (getpoint "\nSelect Point: ")) (setq di (ShortestDistanceFromPointtoSet s2 (trans pt 1 0))) ) (while (setq e (ssname s1 (setq i (1+ i)))) (if (and (vl-position (strcase (vlax-get-property (setq o (vlax-ename->vla-object e)) (if (vlax-property-available-p o 'EffectiveName) 'EffectiveName 'Name) ) ) blocks ) (eq (vla-get-isDynamicBlock o) :vlax-true) ) (LM:SetDynamicPropValue o "Offset" di) ) ) ) (princ) ) (defun ShortestDistanceFromPointtoSet ( sset pt / i lst ) (vl-load-com) (if sset (repeat (setq i (sslength sset)) (setq lst (cons (distance pt (vlax-curve-getClosestPointto (ssname sset (setq i (1- i))) pt)) lst)) ) ) (car (vl-sort lst '<)) ) ;;------------=={ Set Dynamic Property Value }==--------------;; ;; ;; ;; Modifies the value of a Dynamic Block Property ;; ;;------------------------------------------------------------;; ;; Author: Lee Mac, Copyright © 2010 - www.lee-mac.com ;; ;;------------------------------------------------------------;; ;; Arguments: ;; ;; block - VLA Dynamic Block Reference Object ;; ;; prop - Dynamic Block Property Name ;; ;; value - New value for Property ;; ;;------------------------------------------------------------;; ;; Returns: Value property was set to, else nil ;; ;;------------------------------------------------------------;; (defun LM:SetDynamicPropValue ( block prop value ) (vl-some (function (lambda ( _prop ) (if (eq prop (vla-get-propertyname _prop)) (progn (vla-put-value _prop (vlax-make-variant value (vlax-variant-type (vla-get-value _prop)) ) ) value ) ) ) ) (vlax-invoke block 'GetDynamicBlockProperties) ) ) Dynamic Block function taken from here. EDIT: Fixed variable names. Edited March 21, 2011 by Lee Mac Quote
Ohnoto Posted March 21, 2011 Author Posted March 21, 2011 I've got your site bookmarked . Very nice site, by the way! After using the code above, I am getting an error though "error: bad argument type: VLA-OBJECT nil" Quote
Lee Mac Posted March 21, 2011 Posted March 21, 2011 I've got your site bookmarked . Very nice site, by the way! Thanks! After using the code above, I am getting an error though "error: bad argument type: VLA-OBJECT nil" Oops! I changed the vlax-for loop, but didn't change the variable 'x'. Updated above ^^ Quote
Ohnoto Posted March 21, 2011 Author Posted March 21, 2011 Thanks, this works great! My only question now is: Is there a way to get it if I select multiple blocks at different distances, it would put in the distance value of each block, based on the insertion point, in the properties? Ideally, I'd like to be able to group select several blocks that may be at different distances away from the line, and it fill in each value, without selecting the block point. I tried doing (cdr (assoc 10 s1)) instead of it prompting for the get point of the block, but it didn't like that. That's an example my book used for getting center points. I tried a Google search, is there a place that has group codes listed for doing "cons" and "assoc"? Quote
Lee Mac Posted March 21, 2011 Posted March 21, 2011 is there a place that has group codes listed for doing "cons" and "assoc"? http://docs.autodesk.com/ACD/2011/ENU/filesDXF/WSfacf1429558a55de185c428100849a0ab7-5df0.htm I'll look at the code in a bit Quote
Lee Mac Posted March 21, 2011 Posted March 21, 2011 Quick modification, untested: (defun c:test ( / blocks di e i o pt s s1 s2 ) (vl-load-com) (setq blocks '("FIBER MARKER TUBE-STA") i -1) (if (and (setq s1 (ssget (list '(0 . "INSERT") (cons 2 (apply 'strcat (cons "`*U*" (mapcar '(lambda ( s ) (strcat "," s)) blocks))) ) ) ) ) (setq s2 (ssget "_X" (list (cons 0 "ARC,CIRCLE,ELLIPSE,LINE,*POLYLINE,SPLINE") (cons 8 "GPS-ROAD,BASELINE,EOG,EOP,FOGLINE,FOC") ) ) ) ) (while (setq e (ssname s1 (setq i (1+ i)))) (if (and (vl-position (strcase (vlax-get-property (setq o (vlax-ename->vla-object e)) (if (vlax-property-available-p o 'EffectiveName) 'EffectiveName 'Name) ) ) blocks ) (eq (vla-get-isDynamicBlock o) :vlax-true) (setq di (ShortestDistanceFromPointtoSet s2 (trans (cdr (assoc 10 (entget e))) e 0))) ) (LM:SetDynamicPropValue o "Offset" di) ) ) ) (princ) ) (defun ShortestDistanceFromPointtoSet ( sset pt / i lst ) (vl-load-com) (if sset (repeat (setq i (sslength sset)) (setq lst (cons (distance pt (vlax-curve-getClosestPointto (ssname sset (setq i (1- i))) pt)) lst)) ) ) (car (vl-sort lst '<)) ) ;;------------=={ Set Dynamic Property Value }==--------------;; ;; ;; ;; Modifies the value of a Dynamic Block Property ;; ;;------------------------------------------------------------;; ;; Author: Lee Mac, Copyright © 2010 - www.lee-mac.com ;; ;;------------------------------------------------------------;; ;; Arguments: ;; ;; block - VLA Dynamic Block Reference Object ;; ;; prop - Dynamic Block Property Name ;; ;; value - New value for Property ;; ;;------------------------------------------------------------;; ;; Returns: Value property was set to, else nil ;; ;;------------------------------------------------------------;; (defun LM:SetDynamicPropValue ( block prop value ) (vl-some (function (lambda ( _prop ) (if (eq prop (vla-get-propertyname _prop)) (progn (vla-put-value _prop (vlax-make-variant value (vlax-variant-type (vla-get-value _prop)) ) ) value ) ) ) ) (vlax-invoke block 'GetDynamicBlockProperties) ) ) Quote
Ohnoto Posted March 21, 2011 Author Posted March 21, 2011 Works perfectly!!! I owe you a drink, should I ever meet you. 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.