To draw a 3dpolyline by point list

devitg
Advisor
Advisor

To draw a 3dpolyline by point list

devitg
Advisor
Advisor

Hi all user, How I can make a 3DPOLY by a points list as follow , please give 3 ways , by COMMAND, ENTMAKE, and VLA-ADD3DPOLY.

Thanks in advance 

 

 

(setq pt-list '((0.0 0.0 0.0) (120.0 0.0 75.0) (120.0 64.0873 150.0) (0.0 64.0873 75.0)) )

 

0 Likes
Reply
Accepted solutions (2)
1,063 Views
16 Replies
Replies (16)

ВeekeeCZ
Consultant
Consultant
Accepted solution

One way or another. Have fun.

 

(setq pt-list '((0.0 0.0 0.0) (120.0 0.0 75.0) (120.0 64.0873 150.0) (0.0 64.0873 75.0)))


(defun c:onewaytogo ()
  (command "_.3dpoly")
  (foreach pt pt-list (command "_non" pt))
  (command "")
  )


(defun c:secondwaytogo ()
  (entmake '((0 . "POLYLINE") (70 . 8)))
  (foreach pt pt-list (entmake (list '(0 . "VERTEX") '(70 . 32) (cons 10 pt))))
  (entmake '((0 . "SEQEND")))
  )


(defun c:thirdwaytogo ()
  (setq pts (apply 'append pt-list))
  (vla-Add3DPoly
    (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
    (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length pts)))) pts)
    ))


(defun c:thirdwaybyfollowinghelp ()
    ;; This example creates a 3 segment 3D polyline in model space.
    (setq acadObj (vlax-get-acad-object))
    (setq doc (vla-get-ActiveDocument acadObj))

    (setq pts (apply 'append pt-list))
    ;; Create the array of points
    (setq points (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length pts)))))
    (vlax-safearray-fill points pts
    )  
    
    ;; Create a 3D polyline in model space
    (setq modelSpace (vla-get-ModelSpace doc))  
    (setq polyObj (vla-Add3DPoly modelSpace points))
    ;(vla-ZoomAll acadObj)
)

(defun c:fourthwaytogo ()
  (vlax-invoke
    (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
    'add3dpoly
    (apply 'append pt-list)
    ))

 

Kent1Cooper
Consultant
Consultant

Don't forget the question of whether or not the result should be closed.

Kent Cooper, AIA

devitg
Advisor
Advisor

@Kent1Cooper , Hi Kent , not at this case .

It will be OPEN. 

0 Likes

devitg
Advisor
Advisor

@ВeekeeCZ Thanks .  

0 Likes

devitg
Advisor
Advisor

@ВeekeeCZ Thanks a lot, it helps me to understand some questions I had about all these ways to do .

0 Likes

devitg
Advisor
Advisor

@ВeekeeCZ Hi, given your good will to help us , please give some hints to use 

 

VLAX-INVOKE 

 

As to get PROPIERTIES, or to apply METHOD.

This , solve it for METHOD.

 

(vlax-invoke
    (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
    'add3dpoly
    (apply 'append pt-list)
    )

 

But I not get propierties like 

 

  (setq 3dpol-xyz (group-by-num/list-num(VLAX-SAFEARRAY->LIST (VLAX-VARIANT-VALUE (VLA-GET-COORDINATES 3dpol)))3))

 

3DPOLY is an OBJECT I tried with 

 

  (setq 3dpol-xyz (vlax-invoke 'coordinates 3dpol))
it return 
  ; error: bad argument type: VLA-OBJECT COORDINATES

Neither have any result with 

(setq 3dpol-xyz (vlax-invoke  3dpol 'coordinates))

  Thanks, in advance.

I like to handle vla-objects , but for some task I need  ENTities  data .

As to do an SSGET FENCE 

 

(setq point-ss (ssget "F" 3dpol-xyz (list (cons 0 "point") (cons 8 CLAYER))))

 

 

 

 

 

0 Likes

ВeekeeCZ
Consultant
Consultant

The simplest way how to get coordinates is

 

(vlax-get 3dpol 'coordinates)
>> (213.735 267.599 250.021 267.599 250.021 237.729 213.735 237.729)

 

That way you don't need to deal with variants and safearrays.

devitg
Advisor
Advisor

@ВeekeeCZ  Ok, but then I need to group the coordinates to xyz, x1y1z1, abd so on, to use it at a ssget "F" 

I have a defun to group-by-num 

Thanks for your help

 

 

 

 

0 Likes

daniel_cadext
Advisor
Advisor

You can use a COM selection set, it’s already formatted.

Python, but you can do this in lisp.

 

import traceback
from pyrx_impx import Rx, Ge, Gi, Db, Ap, Ed, Ax

def PyRxCmd_xdoit() -> None:
    try:
        axApp = Ax.getApp()
        axDoc = axApp.ActiveDocument
        entsel = axDoc.Utility.GetEntity("\nPick it like you mean it: ")
        pl = Ax.IAcad3DPolyline(entsel[0])
        axSs = axDoc.SelectionSets.Add("AXTBLSS")
        axSs.SelectByPolygon(
            Ax.constants.acSelectionSetFence, 
            pl.Coordinates, 
            [0], ["ACAD_TABLE"])
        
        print(axSs.Count)
    except Exception as err:
        traceback.print_exception(err)
    finally:
        axSs.Delete()

 

ss.png

 

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes

devitg
Advisor
Advisor

@daniel_cadext , Sorry I do not understand it. Please clear me. 

0 Likes

Kent1Cooper
Consultant
Consultant

@devitg wrote:

.... then I need to group the coordinates to xyz, x1y1z1, abd so on, to use it at a ssget "F"  ....


This topic started with a list of points to use to draw a 3D Polyline.  Now you want to extract the vertices of a 3D Polyline to use for Fence selection?  Just use the original list of points -- there's no need for the middle-man Polyline.  Am I missing something?  Are there two separate goals here, un-related?

Kent Cooper, AIA
0 Likes

ВeekeeCZ
Consultant
Consultant
Accepted solution

Then try this example

 

(defun group-by-three (lst / rtn)
  (if lst (repeat (/ (length lst) 3)
	    (setq rtn (cons (list (car lst) (cadr lst) (caddr lst)) rtn)
		  lst (cdddr lst))))
  rtn)


(defun c:Fencesel ()
  (setq ent (car (entsel "Select 3dpolyline: ")))
  (setq obj (vlax-ename->vla-object ent))
  (setq coo (vlax-get obj 'coordinates))
  (setq xyz (group-by-three coo))
  (setq pts (ssget "_F" xyz (list '(0 . "point") (cons 8 (getvar 'clayer)))))
  (if pts (sslength pts))
  )

 

devitg
Advisor
Advisor

@Kent1Cooper  it is part a whole lsp . 

 

 

 

0 Likes

daniel_cadext
Advisor
Advisor

"Sorry I do not understand it. Please clear me. "

 

I meant use vla-get-SelectionSets instead of ssget since you’re already using ActiveX

In this case 'coordinates should already be formatted correctly

https://help.autodesk.com/view/OARX/2022/ENU/?guid=GUID-D8002585-5D08-45E2-AF6C-6E894FA3D463

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes

ronjonp
Advisor
Advisor

@ВeekeeCZ  Might as well tidy up the code with localized variables and check that the selection is valid right?

(defun c:fencesel (/ group-by-three coo ent obj pts xyz)
  (defun group-by-three	(lst / rtn)
    (if	lst
      (repeat (/ (length lst) 3)
	(setq rtn (cons (list (car lst) (cadr lst) (caddr lst)) rtn)
	      lst (cdddr lst)
	)
      )
    )
    rtn
  )
  (if (and (setq ent (car (entsel "Select 3dpolyline: ")))
	   (setq obj (vlax-ename->vla-object ent))
	   (vlax-property-available-p obj 'coordinates)
	   (setq coo (vlax-get obj 'coordinates))
      )
    (progn (setq xyz (group-by-three coo))
	   (setq pts (ssget "_F" xyz (list '(0 . "point") (cons 8 (getvar 'clayer)))))
	   (if pts
	     (sslength pts)
	   )
    )
  )
  (princ)
)
0 Likes

Sea-Haven
Mentor
Mentor

Another check 2d 3d points

 

; convert now to xyz
(defun co-ords2xy (xyz / )
(setq co-ordsxy '())
(if (= xyz 2)
(progn
(setq I 0)
(repeat (/ (length co-ords) 2)
(setq xy (list (nth i co-ords)(nth (+ I 1) co-ords) ))
(setq co-ordsxy (cons xy co-ordsxy))
(setq I (+ I 2))
)
)
)
(if (= xyz 3)
(progn
(setq I 0)
(repeat (/ (length co-ords) 3)
(setq xy (list (nth i co-ords)(nth (+ I 1) co-ords)(nth (+ I 2) co-ords) ))
(setq co-ordsxy (cons xy co-ordsxy))
(setq I (+ I 3))
)
)
)
)

(setq obj (vlax-ename->vla-object (car  (entsel "Pick obj"))))

(setq co-ords (vlax-get obj 'coordinates))
(cond 
  (( = (vla-get-objectname obj) "AcDb2dPolyline")(co-ords2xy 2))
  (( = (vla-get-objectname obj) "AcDb3dPolyline")(co-ords2xy 3))
)
(princ co-ordsxy)
0 Likes