Jump to content

Recommended Posts

Posted

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 

Posted

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

Posted

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.

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

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

 

 

  

Posted

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 . 

 

 

 

 

  

 

 

 

Posted

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.

Posted (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 by ymg3
Posted

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

 

Posted

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
Posted (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 by marko_ribar
Posted
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

 

 

Posted

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

 

Posted (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 by marko_ribar
Posted (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 by lastknownuser
  • Agree 1
Posted
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

 

 

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

 

 

 

 

 

 

 

 

 

 

 

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

 

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