devitg Posted March 24 Posted March 24 Hi all , I'm stuck here . Given start and end line points as VARIANTS how to make the new pline (defun lines-as-plines-by-vl () (VL-LOAD-COM) (SETQ ACAD-OBJ (VLAX-GET-ACAD-OBJECT)) ;_ el programa ACAD (SETQ ADOC (VLA-GET-ACTIVEDOCUMENT ACAD-OBJ)) ;_ el DWG que esta abierto- (SETQ MODEL (VLA-GET-MODELSPACE ADOC)) (setq line-ent (ssname (ssget "_:S+." '((0 . "line"))) 0)) (Setq line-obj (VLAX-ENAME->VLA-OBJECT line-ent)) (setq st-point (VLA-GET-STARTPOINT line-obj)) (setq en-point (VLA-GET-ENDPOINT line-obj)) (setq pline-obj (VLA-ADDLIGHTWEIGHTPOLYLINE model ;not know how to make vlax-make-safearray vlax-vbDouble st-point en-point)) ) ;_ end of VLA-ADDLIGHTWEIGHTPOLYLINE ) ;_ end of setq ) Thanks in advance Quote
marko_ribar Posted March 24 Posted March 24 Do you have to go through VLA-xxx.... Here is simple approach : (entmake (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 2) (cons 70 (* 128 (getvar (quote plinegen)))) (cons 38 0.0) (cons 10 st-point) (cons 10 en-point) (list 210 0.0 0.0 1.0) ) ) Of course, this is only for lines that lie in WCS, otherwise I guess you'll have to go throught building OCS Z axis 210 group code, supply it at the end of (entmake)... All in all things go messy when points are 3D as you'll have to use also (v^v) - cross product sub, (unit) sub function and still we don't know in what plane will lie LWPOLYLINE as you can put infinitely number of planes passing those 2 points that are in 3D... Quote
marko_ribar Posted March 24 Posted March 24 There is also this - going through command "pedit"... I've just tested and it worked for both 2d and 3d lines... (defun c:lines2lws ( / ss ) (prompt "\nSelect LINE entities on unlocked layer(s)...") (if (setq ss (ssget "_:L" (list (cons 0 "LINE")))) (if command-s (command-s "_.pedit" "_m" ss "" "") (vl-cmdf "_.pedit" "_m" ss "" "") ) ) (princ) ) Regards, M.R. Quote
Tsuky Posted March 24 Posted March 24 Quote ;not know how to make vlax-make-safearray vlax-vbDouble st-point en-point The conversion could be done like this in your code: (vlax-safearray->list (vlax-variant-value st-point)) but it would be simpler to do like this: (vlax-curve-getStartPoint line-ent) This will avoid a conversion in one direction then the other... Quote
devitg Posted March 24 Author Posted March 24 4 hours ago, devitg said: (setq st-point (VLA-GET-STARTPOINT line-obj)) (setq en-point (VLA-GET-ENDPOINT line-obj)) (setq pline-obj (VLA-ADDLIGHTWEIGHTPOLYLINE model ;not know how to make vlax-make-safearray vlax-vbDouble st-point en-point)) ) ;_ end of VLA-ADDLIGHTWEIGHTPOLYLINE ) ;_ end of setq Thanks @marko_ribar I just wish to do it by VL , not ENTMAKE , or ACAD command line . Just for learning. Thanks @Tsuky I will try . Quote
devitg Posted March 24 Author Posted March 24 Maybe I did a wrong question . As per Activex Reference guide Quote RetVal = object.AddLightWeightPolyline(VerticesList) It ask for VERTICES LIST , as follow Quote object Type: Block, ModelSpace, PaperSpace The objects this method applies to. VerticesList Access: Input-only Type: Variant (array of doubles) The array of 2D OCS coordinates specifying the vertices of the polyline. At least two points (four elements) are required for constructing a lightweight polyline. The array size must be a multiple of 2. So my question is how to populate the VERTICES LIST , whit. (setq st-point (VLA-GET-STARTPOINT line-obj)) (setq en-point (VLA-GET-ENDPOINT line-obj)) Don't worry about WCS or UCS . Quote
marko_ribar Posted March 24 Posted March 24 Maybe this sub can help you... (defun SafearrayVariant ( coords ) (vlax-make-variant (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length coords)))) coords ) ) ) HTH. M.R. Quote
ymg3 Posted March 24 Posted March 24 (edited) Here a snippet that does it. Originally by PNorman i modified the variable name. Note that the var *acspace must be defined. ymg (vl-load-com) (or *acdoc (setq *acdoc (vla-get-ActiveDocument (vlax-get-acad-object)))) (or *acutil (setq acutil (vla-get-Utility *acdoc))) (setq *acspace (if (= (getvar "CVPORT") 1) (vla-get-PaperSpace *acdoc) (vla-get-ModelSpace *acdoc) ) ) ;; addlwp by pnorman ; ;; ; ;; Add light weight polyline to model or paper space ; ;; ; ;; Global var *acspace must be defined ; ;; Requires subroutine UCS2WCS ; ;; ; (defun addlwp (pl / sa) (setq pl (UCS2WCS pl)) (setq pl (apply 'append pl)) (setq sa (vlax-make-safearray vlax-vbDouble (cons 0 (- (vl-list-length pl) 1)) ) ) (vlax-safearray-fill sa pl) (vla-addLightweightPolyline *acspace sa) ) ;; convert list of 2D or 3D points from UCS to WCS ; (defun UCS2WCS (pl) (setq pl (mapcar '(lambda (p) (trans p 1 0)) pl)) (setq pl (mapcar '(lambda (p) (list (float (car p)) (float (cadr p)))) pl ) ) ) Edited March 25 by ymg3 Quote
ymg3 Posted March 24 Posted March 24 To be more to the point with your question the point list is a list of list (setq p1 (list 10.0 20.0 0)) (setq p2 (list 35.0 48.0 0.0)) (setq pointlist (list p1 p2)) ;; so pointlist will be ((10.0 20.0 0) (35.0 48.0 0.0)) Quote
Tsuky Posted March 25 Posted March 25 If you want to avoid variants, you can do like this. The code is minimalist. (defun c:line2pline ( / AcDoc Space ss line-ent st-point en-point l_pt) (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)) Space (if (eq (getvar "CVPORT") 1) (vla-get-PaperSpace AcDoc) (vla-get-ModelSpace AcDoc) ) ) (while (setq ss (ssget "_:S+." '((0 . "LINE")))) (setq line-ent (ssname ss 0) st-point (vlax-curve-getStartPoint line-ent) en-point (vlax-curve-getEndPoint line-ent) l_pt (apply 'append (mapcar '(lambda (x) (list (car x) (cadr x))) (list st-point en-point))) ) (vlax-invoke Space 'AddLightWeightPolyline l_pt) (entdel line-ent) ) (prin1) ) 1 Quote
marko_ribar Posted March 25 Posted March 25 (edited) This part : (mapcar '(lambda (x) (list (car x) (cadr x))) (list st-point en-point)) Should just be : (list st-point en-point) [EDIT : Nevermind that, it looks that mapcar part is OK - you need just x and y coordinate, ommiting z one - apologise my mistake...] Edited March 25 by marko_ribar Quote
devitg Posted March 25 Author Posted March 25 12 hours ago, Tsuky said: If you want to avoid variants, you can do like this. The code is minimalist. @Tsuky I do not want to avoid VARIANT, why? Perche mi piache .[ because I like it] I want to make the lwpolyline by variant , the same way I can make a new LINE, or a CIRCLE, or a TEXT , with the variant . Please see the code, I can make a new LINE, a CIRCLE and a TEXT at ST-point Neither I can make a LWpolyline, or a Polyline, or a 3DPOLYLINE I run at ACAD 2019 (defun lines-as-plines-by-vl () (VL-LOAD-COM) (SETQ ACAD-OBJ (VLAX-GET-ACAD-OBJECT)) ;_ el programa ACAD (SETQ ADOC (VLA-GET-ACTIVEDOCUMENT ACAD-OBJ)) ;_ el DWG que esta abierto- (SETQ MODEL (VLA-GET-MODELSPACE ADOC)) (setq line-ent-ss (ssget "_x" '((0 . "line")))) (setq line-obj-ss (VLA-GET-ACTIVESELECTIONSET adoc)) (Setq line-obj (vla-item line-obj-ss 0)) (setq st-point (VLA-GET-STARTPOINT line-obj)) (setq en-point (VLA-GET-ENDPOINT line-obj)) (setq st-circle (VLA-ADDCIRCLE model st-point 10)) ;;#<VLA-OBJECT IAcadCircle 000002499a1446c8> (setq line-st-en (VLA-ADDLINE model st-point en-point)) ;;;#<VLA-OBJECT IAcadLine 000002499a144c68> (setq st-text (VLA-ADDTEXT model "start-point" st-point (getvar 'TEXTSIZE))) ;#<VLA-OBJECT IAcadText 00000249ac0e1f58> (setq pline-obj (VLA-ADDLIGHTWEIGHTPOLYLINE model (list st-point en-point) ) ;_ end of VLA-ADDLIGHTWEIGHTPOLYLINE ) ;_ end of setq ; error: lisp value has no coercion to VARIANT with this type: (#<variant 8197 ...> #<variant 8197 ...>) (setq pline-obj-01 (VLA-ADDLIGHTWEIGHTPOLYLINE model st-point en-point ) ;_ end of VLA-ADDLIGHTWEIGHTPOLYLINE ) ;_ end of setq ; error: Too many actual parameters (setq pline-obj-02 (VLA-ADDPOLYLINE model st-point en-point ) ;_ end of VLA-POLYLINE ) ;_ end of setq ; error: Too many actual parameters ) ;_ end of defun Quote
pkenewell Posted March 25 Posted March 25 @devitg The argument for a polyline has to be a single array structure with the coordinates as elements; it is not the same as a list. Use this function to convert a standard list of points into something that can be used in the vla-addlwpolyline function: ;|============================================================================== Function Name: (pjk-PointList->SafeArray) Arguments: plist = list; a list of points Usage Example: (pjk-PointList->SafeArray '((0.0 0.0 0.0)(1.0 1.0 0.0))) Returns: a VLA SafeArray type Description: This Function converts a list of Points into a SafeArray to plug into a Visual LISP ActiveX property. ================================================================================|; (defun pjk-PointList->SafeArray (plist / fl) (setq fl (apply 'append plist)) (vlax-make-variant (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length doubles)))) fl ) ) ) ;; End Function (pjk-PointList->SafeArray) Quote
marko_ribar Posted March 25 Posted March 25 (edited) Here, @devitg your example mod. to suit your needs... (defun lines-as-ents-by-vl ( / safearrayvariant acad-obj adoc model line-ent-ss line-obj-ss line-obj st-point en-point st-circle line-st-en st-text pline-obj-1 pline-obj-2 lst ) (vl-load-com) (defun safearrayvariant ( coords ) (vlax-make-variant (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length coords)))) coords ) ) ) (setq acad-obj (vlax-get-acad-object)) ;_ el programa ACAD (setq adoc (vla-get-activedocument acad-obj)) ;_ el DWG que esta abierto- (setq model (vla-get-modelspace adoc)) (setq line-ent-ss (ssget "_x" (list (cons 0 "line")))) (setq line-obj-ss (vla-get-activeselectionset adoc)) (setq line-obj (vla-item line-obj-ss 0)) (setq st-point (vla-get-startpoint line-obj)) (setq en-point (vla-get-endpoint line-obj)) (setq st-circle (vla-addcircle model st-point 10)) (setq lst (cons st-circle lst)) (setq line-st-en (vla-addline model st-point en-point)) (setq lst (cons line-st-en lst)) (if (= (getvar (quote textsize)) 0.0) (setvar (quote textsize) 2.5) ) (setq st-text (vla-addtext model "start-point" st-point (getvar (quote textsize)))) (setq lst (cons st-text lst)) (setq pline-obj-1 (vla-addlightweightpolyline model (safearrayvariant (apply (function append) (mapcar (function (lambda ( x ) (list (car x) (cadr x)))) (list (safearray-value (variant-value st-point)) (safearray-value (variant-value en-point)))))))) (setq lst (cons pline-obj-1 lst)) (setq pline-obj-2 (vla-addpolyline model (safearrayvariant (apply (function append) (list (safearray-value (variant-value st-point)) (safearray-value (variant-value en-point))))))) (setq lst (cons pline-obj-2 lst)) lst ) ;| : (lines-as-ents-by-vl) (#<VLA-OBJECT IAcadPolyline 000000004C23B8F0> #<VLA-OBJECT IAcadLWPolyline 000000004C23B970> #<VLA-OBJECT IAcadText 000000004C23B2F0> #<VLA-OBJECT IAcadLine 000000004C23B070> #<VLA-OBJECT IAcadCircle 000000004C23B670>) |; HTH. M.R. Edited March 25 by marko_ribar Quote
lastknownuser Posted March 25 Posted March 25 (edited) I think it has been well explained, but just to say this, here you are trying to make a polyline with just two points, think about the case where you have more points (which is usually the case with polylines), so the argument has to be a variant (array of doubles) Edited March 25 by lastknownuser 1 Quote
devitg Posted March 25 Author Posted March 25 19 hours ago, Tsuky said: If you want to avoid variants, you can do like this. The code is minimalist. @Tsuky I do not want to avoid VARIANT, why? Perche mi piache .[ because I like it] I want to make the lwpolyline by variant , the same way I can make a new LINE, or a CIRCLE, or a TEXT , with the variant . Please see the code, I can make a new LINE, a CIRCLE and a TEXT at ST-point Neither I can make a LWpolyline, or a Polyline, or a 3DPOLYLINE I run at ACAD 2019 (defun lines-as-plines-by-vl () (VL-LOAD-COM) (SETQ ACAD-OBJ (VLAX-GET-ACAD-OBJECT)) ;_ el programa ACAD (SETQ ADOC (VLA-GET-ACTIVEDOCUMENT ACAD-OBJ)) ;_ el DWG que esta abierto- (SETQ MODEL (VLA-GET-MODELSPACE ADOC)) (setq line-ent-ss (ssget "_x" '((0 . "line")))) (setq line-obj-ss (VLA-GET-ACTIVESELECTIONSET adoc)) (Setq line-obj (vla-item line-obj-ss 0)) (setq st-point (VLA-GET-STARTPOINT line-obj)) (setq en-point (VLA-GET-ENDPOINT line-obj)) (setq st-circle (VLA-ADDCIRCLE model st-point 10)) ;;#<VLA-OBJECT IAcadCircle 000002499a1446c8> (setq line-st-en (VLA-ADDLINE model st-point en-point)) ;;;#<VLA-OBJECT IAcadLine 000002499a144c68> (setq st-text (VLA-ADDTEXT model "start-point" st-point (getvar 'TEXTSIZE))) ;#<VLA-OBJECT IAcadText 00000249ac0e1f58> (setq pline-obj (VLA-ADDLIGHTWEIGHTPOLYLINE model (list st-point en-point) ) ;_ end of VLA-ADDLIGHTWEIGHTPOLYLINE ) ;_ end of setq ; error: lisp value has no coercion to VARIANT with this type: (#<variant 8197 ...> #<variant 8197 ...>) (setq pline-obj-01 (VLA-ADDLIGHTWEIGHTPOLYLINE model st-point en-point ) ;_ end of VLA-ADDLIGHTWEIGHTPOLYLINE ) ;_ end of setq ; error: Too many actual parameters (setq pline-obj-02 (VLA-ADDPOLYLINE model st-point en-point ) ;_ end of VLA-POLYLINE ) ;_ end of setq ; error: Too many actual parameters ) ;_ end of defun Quote
marko_ribar Posted March 25 Posted March 25 Please, review post : https://www.cadtutor.net/forum/topic/82523-2-points-polyline-or-lwpolyline-by-vl/?do=findComment&comment=634713 Regards, M.R. Quote
devitg Posted March 25 Author Posted March 25 45 minutes ago, marko_ribar said: Please, review post : https://www.cadtutor.net/forum/topic/82523-2-points-polyline-or-lwpolyline-by-vl/?do=findComment&comment=634713 Regards, M.R. @marko_ribar Just as a personal and own chose or will and wish I do not want to use COORDS , I want to use what the activex reference guide state Just a kid's whim. Quote AddLightWeightPolyline Method (ActiveX) object Type: Block, ModelSpace, PaperSpace The objects this method applies to. VerticesList Access: Input-only Type: Variant (array of doubles) The array of 2D OCS coordinates specifying the vertices of the polyline. At least two points (four elements) are required for constructing a lightweight polyline. The array size must be a multiple of 2. Of course I can use a previous defun to AddLightWeightPolyline , form point list ;;*//*/*/*/*/*/*/*/*/*/*/*/*/**/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/* (DEFUN DT:LIST-FLATTEN (LISTE /) (COND ((NULL LISTE) NIL) ((ATOM LISTE) (LIST LISTE)) (1 (APPEND (DT:LIST-FLATTEN (CAR LISTE)) (DT:LIST-FLATTEN (CDR LISTE)))) ) ) ;_ DT:LIST-FLATTEN ;;;(setq lst[['(915.33 476.258 913.419 573.61 844.641 623.24 817.894 564.066 915.33 476.258) ) ;;sola lista (list x1 y1 z 1 x2 y2 z2 .....xn yn zn) (DEFUN I:POINTS (PTLIST) (VL-LOAD-COM) (VLAX-SAFEARRAY-FILL (VLAX-MAKE-SAFEARRAY VLAX-VBDOUBLE (CONS 0 (1- (LENGTH PTLIST))) ) PTLIST ) ) ;_end defun i:Points ;;/------------------------------------------------------------------ ;;/------------------------------------------------------------------ (DEFUN LIST->2DPOLY (LISTA) (SETQ FLAT-LIST (DT:LIST-FLATTEN LISTA)) (SETQ SAF (I:POINTS FLAT-LIST)) (VLA-ADDLIGHTWEIGHTPOLYLINE MODEL SAF) ) ;;*------------------------------------------------------------------------------------------- DT:LIST-FLATTEN and I:POINT , are not mine . Thanks all you for your help. Hope I can get the way to use the points as VARIANTS , and not as ( LIST x y z ) Quote
lastknownuser Posted March 26 Posted March 26 8 hours ago, devitg said: I want to use what the activex reference guide state Just a kid's whim. And it states one argument, variant (array of doubles). Double is a number. Coordinates are defined by a number. So you have to "use" coordinates. From my understanding, and I'm not an expert I have only recently started digging deeper into Active X stuff, your st-point and en-point are variants right. So "vlax-make-safearray vlax-vbDouble st-point en-point" doesn't work, can't work. And afaik you can't make a variant (array of doubles) with variants st-point and en-point without getting their coordinates (that are - double), what you are here for some reason trying to avoid. To give a comparison with AutoLISP, its like wanting to create a line by only selecting two points with (car (entsel)). You get entity of each point, but you have to extract its coordinates to eventually create a line. If I'm wrong someone correct me of course. 1 Quote
devitg Posted March 26 Author Posted March 26 4 hours ago, lastknownuser said: If I'm wrong someone correct me of course. @lastknownuser I'm wrong. I will do the poly by point coordinates. Thanks. 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.