Jump to content

2 points polyline or lwpolyline by VL


devitg

Recommended Posts

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 

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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 .  

 

 

  

Link to comment
Share on other sites

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 . 

 

 

 

 

  

 

 

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by ymg3
Link to comment
Share on other sites

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))

 

Link to comment
Share on other sites

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)
)

 

  • Agree 1
Link to comment
Share on other sites

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 by marko_ribar
Link to comment
Share on other sites

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

 

 

Link to comment
Share on other sites

@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)

 

Link to comment
Share on other sites

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 by marko_ribar
Link to comment
Share on other sites

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 by lastknownuser
  • Agree 1
Link to comment
Share on other sites

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

 

 

Link to comment
Share on other sites

45 minutes ago, marko_ribar said:

@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 )

 

 

 

 

 

 

 

 

 

 

 

Link to comment
Share on other sites

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.

  • Agree 1
Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...