Jump to content

Arc to 3dPolyline


pyou

Recommended Posts

Hi 

 

Would it be possible to join chords to create 3dPolyline automatically? or ideally to convert arc to 3dPolyline in one hit?

 

Thank you for help

 

;;;Creates chords along curve w/ user entered divisions  LPS 2008-11

(defun c:test ();(/ oldecho obj div endpt totlen arclen chrdpt dist newpt)
(vl-load-com)
(setq oldecho (getvar "cmdecho")
     oldsnap (getvar "osmode")
     )
(setvar "cmdecho" 0)
(setvar "osmode" 0)  
(setq ent (entsel "\nPick arc: ")
    obj (vlax-ename->vla-object (car ent))
    div (getint "\nEnter number of chords: ")
    endpt (vlax-curve-getEndPoint obj)
    totlen (vlax-curve-getDistAtPoint obj endpt)
    arclen (/ totlen div)
    chrdpt (vlax-curve-getPointAtDist obj 0)
    dist 0
    )
(repeat div
  (setq newpt(vlax-curve-getPointatDist obj (+ arclen dist)))
  (command "line" chrdpt newpt "")
  (setq dist (+ arclen dist))
  (setq chrdpt newpt)
  );repeat
 (setvar "cmdecho" oldecho)
 (setvar "osmode" oldsnap)
 (princ)
 );defun

 

 

Edited by pyou
Link to comment
Share on other sites

You can get the point at param, say you have params [0 , 1]

Generate param intervals between 0 and 1. And use get point at param

Link to comment
Share on other sites

Posted (edited)

I have attached an example dwg. After drawing an arc I would like to convert it to 3d polyline.

 

To get 3d arc i use this great lisp by Lee Mac 

 

(defun c:Draw3dArc ( / p1 p2 p3 )
    (if
        (and
            (setq p1 (getpoint "\n1st Point: "))
            (setq p2 (getpoint "\n2nd Point: " p1))
            (setq p3 (getpoint "\n3rd Point: " p2))
        )
        (LM:3P-Arc
            (trans p1 1 0)
            (trans p2 1 0)
            (trans p3 1 0)
        )
    )
)
 
(defun LM:3P-Arc ( p1 p2 p3 / cn m1 m2 nv )
    (setq nv (v^v (mapcar '- p1 p2) (mapcar '- p3 p2))
          m1 (_mid p1 p2)
          m2 (_mid p2 p3)
    )
    (if (setq cn
            (inters
                (trans m1 0 1)
                (trans (mapcar '+ m1 (v^v (mapcar '- p1 p2) nv)) 0 1)
                (trans m2 0 1)
                (trans (mapcar '+ m2 (v^v (mapcar '- p3 p2) nv)) 0 1)
                nil
            )
        )
        (entmake
            (append
                (list
                   '(0 . "ARC")
                    (cons 010 (trans cn 1 nv))
                    (cons 040 (distance (trans cn 1 0) p1))
                    (cons 210 nv)
                )
                (if (LM:Clockwise-p p1 p2 p3)
                    (list
                        (cons 50 (angle (trans cn 1 nv) (trans p3 0 nv)))
                        (cons 51 (angle (trans cn 1 nv) (trans p1 0 nv)))
                    )
                    (list
                        (cons 50 (angle (trans cn 1 nv) (trans p1 0 nv)))
                        (cons 51 (angle (trans cn 1 nv) (trans p3 0 nv)))
                    )
                )
            )
        )
    )
)
                                         
(defun _mid ( a b )
    (mapcar '(lambda ( a b ) (/ (+ a b) 2.0)) a b)
)
 
;; Vector Cross Product  -  Lee Mac
;; Args: u,v - vectors in R^3
 
(defun v^v ( u v )
    (list
        (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
        (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
        (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
    )
)
 
;; Clockwise-p  -  Lee Mac
;; Returns T if p1,p2,p3 are clockwise oriented
 
(defun LM:Clockwise-p ( p1 p2 p3 )
    (< (* (- (car  p2) (car  p1)) (- (cadr p3) (cadr p1)))
       (* (- (cadr p2) (cadr p1)) (- (car  p3) (car  p1)))
    )
)

 

examle 3d arc.dwg

Edited by pyou
Link to comment
Share on other sites

if you want to try your luck at Python

 

import traceback
from pyrx_imp import Rx, Ge, Gi, Db, Ap, Ed

def PyRxCmd_doit() -> None:
    try:
        cdb = Db.curDb()
        esres = Ed.Editor.entSel("\nSelect: ", Db.Curve.desc())
        if esres[0] != Ed.PromptStatus.eOk:
            raise RuntimeError("Entsel Error {}: ".format(esres[0]))
        interval = 32# edit me
        dbc = Db.Curve(esres[1])
        gec = dbc.getAcGeCurve()
        smp = gec.getSamplePoints(interval)
        pl = Db.Polyline3d(Db.Poly3dType.k3dSimplePoly, smp[0], False)#not closed
        pl.setColorIndex(1)
        cdb.addToModelspace(pl)
    except Exception as err:
        traceback.print_exception(err)

 

arc.png.5640bdc006cacb9eca2e1247f8d4cd00.png

Link to comment
Share on other sites

 

BTW: getSamplePoints

 

"Returns the specified number of points on the curve. The points are equally spaced by parameter value. So if the interval of the curve [0,1] and numSample is 5, the parameter values of the returned points will be 0, 0.25, 0.5, 0.75, and 1."

 

So if you create a list of param intervals between [0, 1]

For each interval, get point at param, you should end up with a list of points at each param to make your polyline from

Edited by Danielm103
spelling
Link to comment
Share on other sites

11 hours ago, Danielm103 said:

 

BTW: getSamplePoints

 

"Returns the specified number of points on the curve. The points are equally spaced by parameter value. So if the interval of the curve [0,1] and numSample is 5, the parameter values of the returned points will be 0, 0.25, 0.5, 0.75, and 1."

 

So if you create a list of param intervals between [0, 1]

For each interval, get point at param, you should end up with a list of points at each param to make your polyline from

 

 

Thanks Daniel103 ,but I cant make it work as lisp code.

Link to comment
Share on other sites

27 minutes ago, pyou said:

 

 

Thanks Daniel103 ,but I cant make it work as lisp code.

 

have a look at  (vlax-curve-getPointAtParam curve-obj param)

use it in a loop where param is the interval between 0 and 1

 

 

 

Link to comment
Share on other sites

Posted (edited)
25 minutes ago, Danielm103 said:

 

have a look at  (vlax-curve-getPointAtParam curve-obj param)

use it in a loop where param is the interval between 0 and 1

 

 

 

 

(defun c:test ()
  (vl-load-com)
  (setq oldecho (getvar "cmdecho")
        oldsnap (getvar "osmode"))
  (setvar "cmdecho" 0)
  (setvar "osmode" 0)
  
  (if (and (setq ent (entsel "\nPick arc: "))
           (setq obj (vlax-ename->vla-object (car ent)))
           (setq div (getint "\nEnter number of chords: ")))
    (progn
      (setq endpt (vlax-curve-getEndPoint obj)
            totlen (vlax-curve-getDistAtPoint obj endpt)
            arclen (/ totlen div)
            chrdpt (vlax-curve-getPointAtDist obj 0)
            dist 0)
      
      (repeat div
        (setq newpt (vlax-curve-getPointAtDist obj (+ arclen dist)))
        (command "line" chrdpt newpt "")
        (setq dist (+ arclen dist))
        (setq chrdpt newpt))
      )
    (princ "\nInvalid input or selection.")
    )
  
  (setvar "cmdecho" oldecho)
  (setvar "osmode" oldsnap)
  (princ)
)

(defun PyRxCmd_doit ()
  (vl-load-com)
  (setq oldecho (getvar "cmdecho"))
  (setvar "cmdecho" 0)

  ;; Execute the Python script using vl-cmdf
  (vl-cmdf "python" "import traceback
from pyrx_imp import Rx, Ge, Gi, Db, Ap, Ed

def PyRxCmd_doit() -> None:
    try:
        cdb = Db.curDb()
        esres = Ed.Editor.entSel(\"\\nSelect: \", Db.Curve.desc())
        if esres[0] != Ed.PromptStatus.eOk:
            raise RuntimeError(\"Entsel Error {}: \".format(esres[0]))
        interval = 32  # Edit this value as needed
        dbc = Db.Curve(esres[1])
        gec = dbc.getAcGeCurve()
        smp = gec.getSamplePoints(interval)
        pl = Db.Polyline3d(Db.Poly3dType.k3dSimplePoly, smp[0], False)  # Not closed
        pl.setColorIndex(1)
        cdb.addToModelspace(pl)
    except Exception as err:
        traceback.print_exception(err)
")

  (setvar "cmdecho" oldecho)
  (princ)
)

 

 

nothing happens it just works as before.

Edited by pyou
Link to comment
Share on other sites

Sorry, you will have to wait for a lisp expert to chime in. If you have  

 

sp = vlax-curve-getStartParam
ep = vlax-curve-getEndParam

 

then you can make intervals param, I.e.

 

(/ (- ep sp ) 10)

 

for each param
    vlax-curve-getPointAtParam param

 

Link to comment
Share on other sites

With lisp, you can try this:

(defun bulge_pts (pt_cen pt_begin pt_end rad sens / inc ang nm p1 p2 lst)
  (setq
    inc (angle pt_cen (if (< sens 0.0) pt_end pt_begin))
    ang (+ (* 2.0 pi) (angle pt_cen (if (< sens 0.0) pt_begin pt_end)))
    nm (fix (/ (rem (- ang inc) (* 2.0 pi)) (/ (* pi 2.0) 36.0)))
  )
  (repeat nm
    (setq
      p1 (polar pt_cen inc rad)
      inc (+ inc (/ (* pi 2.0) 36.0))
      lst (append lst (list p1))
    )
  )
  (setq
    p2 (polar pt_cen ang rad)
    lst (append lst (list p2))
  )
  (if (< sens 0.0) (reverse lst) lst)
)
(defun c:arc2pl3D ( / ss AcDoc Space flag n ent dxf_ent name_layer lst)
  (princ "\nSelect arcs: ")
  (setq ss (ssget '((0 . "ARC"))))
  (cond
    (ss
      (setq
        AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))
        Space
        (if (= 1 (getvar "CVPORT"))
          (vla-get-PaperSpace AcDoc)
          (vla-get-ModelSpace AcDoc)
        )
      )
      (vla-startundomark AcDoc)
      (initget "Yes No")
      (if (eq (getkword "\nErase source arc [Yes/No]? <No>: ") "Yes")
        (setq flag T)
        (setq flag nil)
      )
      (repeat (setq n (sslength ss))
        (setq
          dxf_ent (entget (setq ent (ssname ss (setq n (1- n)))))
          name_layer (cdr (assoc 8 dxf_ent))
          lst
          (bulge_pts
            (cdr (assoc 10 dxf_ent))
            (polar (cdr (assoc 10 dxf_ent)) (cdr (assoc 50 dxf_ent)) (cdr (assoc 40 dxf_ent)))
            (polar (cdr (assoc 10 dxf_ent)) (cdr (assoc 51 dxf_ent)) (cdr (assoc 40 dxf_ent)))
            (cdr (assoc 40 dxf_ent))
            1
          )
        )
        (cond
          (lst
            (vla-put-Layer
              (vlax-invoke
                Space
                'Add3dPoly
                (apply
                  'append
                  (mapcar
                    '(lambda (x) (trans x (cdr (assoc 210 dxf_ent)) 0))
                    lst
                  )
                )
              )
              name_layer
            )
            (if flag (entdel ent))
          )
        )
      )
      (vla-endundomark AcDoc)
    )
    (T (princ "\nEmpty selection"))
  )
  (prin1)
)

 

  • Thanks 2
Link to comment
Share on other sites

9 minutes ago, Tsuky said:

With lisp, you can try this:

(defun bulge_pts (pt_cen pt_begin pt_end rad sens / inc ang nm p1 p2 lst)
  (setq
    inc (angle pt_cen (if (< sens 0.0) pt_end pt_begin))
    ang (+ (* 2.0 pi) (angle pt_cen (if (< sens 0.0) pt_begin pt_end)))
    nm (fix (/ (rem (- ang inc) (* 2.0 pi)) (/ (* pi 2.0) 36.0)))
  )
  (repeat nm
    (setq
      p1 (polar pt_cen inc rad)
      inc (+ inc (/ (* pi 2.0) 36.0))
      lst (append lst (list p1))
    )
  )
  (setq
    p2 (polar pt_cen ang rad)
    lst (append lst (list p2))
  )
  (if (< sens 0.0) (reverse lst) lst)
)
(defun c:arc2pl3D ( / ss AcDoc Space flag n ent dxf_ent name_layer lst)
  (princ "\nSelect arcs: ")
  (setq ss (ssget '((0 . "ARC"))))
  (cond
    (ss
      (setq
        AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))
        Space
        (if (= 1 (getvar "CVPORT"))
          (vla-get-PaperSpace AcDoc)
          (vla-get-ModelSpace AcDoc)
        )
      )
      (vla-startundomark AcDoc)
      (initget "Yes No")
      (if (eq (getkword "\nErase source arc [Yes/No]? <No>: ") "Yes")
        (setq flag T)
        (setq flag nil)
      )
      (repeat (setq n (sslength ss))
        (setq
          dxf_ent (entget (setq ent (ssname ss (setq n (1- n)))))
          name_layer (cdr (assoc 8 dxf_ent))
          lst
          (bulge_pts
            (cdr (assoc 10 dxf_ent))
            (polar (cdr (assoc 10 dxf_ent)) (cdr (assoc 50 dxf_ent)) (cdr (assoc 40 dxf_ent)))
            (polar (cdr (assoc 10 dxf_ent)) (cdr (assoc 51 dxf_ent)) (cdr (assoc 40 dxf_ent)))
            (cdr (assoc 40 dxf_ent))
            1
          )
        )
        (cond
          (lst
            (vla-put-Layer
              (vlax-invoke
                Space
                'Add3dPoly
                (apply
                  'append
                  (mapcar
                    '(lambda (x) (trans x (cdr (assoc 210 dxf_ent)) 0))
                    lst
                  )
                )
              )
              name_layer
            )
            (if flag (entdel ent))
          )
        )
      )
      (vla-endundomark AcDoc)
    )
    (T (princ "\nEmpty selection"))
  )
  (prin1)
)

 

 

Top quality as always! Thank you Tsuky

Link to comment
Share on other sites

something like this

 

(defun c:doit ( / doc ep i modelspace mp obj p points polyobj prms sapoints sp util)
  (vl-load-com)
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (setq util (vla-get-utility doc))
  (vla-getentity util 'obj 'ip "\nSelect Object: ")
  (setq prms '())
  (setq sp (vlax-curve-getStartParam obj))
  (setq ep (vlax-curve-getEndParam  obj))
  (setq mp (/ (- ep sp ) 31))
  (setq i mp)
  (setq prms (append prms (list sp)))
  (repeat 30
    (setq sp (+ i sp))
    (setq prms (append prms (list sp)))
  )
  (setq prms (append prms (list ep)))
  (setq points '())
  (foreach p prms
    (setq points (append points (vlax-curve-getPointAtParam obj p)))
  )
  (setq sapoints (vlax-make-safearray vlax-vbDouble (cons 0 (-(length points)1))))
  (vlax-safearray-fill sapoints points)  
  (setq modelSpace (vla-get-ModelSpace doc))  
  (setq polyObj (vla-Add3DPoly modelSpace sapoints))
)

 

pl.png.f3fd725f282a47efc49fdc368695a853.png

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