pyou Posted June 12 Posted June 12 (edited) 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 June 12 by pyou Quote
mhupp Posted June 13 Posted June 13 You would have to get 3 points start end and somewhere in the middle. then feed it into this. https://lee-mac.com/bulgeconversion.html#3ptbulge Quote
Danielm103 Posted June 13 Posted June 13 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 Quote
pyou Posted June 13 Author Posted June 13 (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 June 13 by pyou Quote
Danielm103 Posted June 15 Posted June 15 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) Quote
Danielm103 Posted June 15 Posted June 15 (edited) 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 June 15 by Danielm103 spelling Quote
pyou Posted June 15 Author Posted June 15 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. Quote
Danielm103 Posted June 15 Posted June 15 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 Quote
pyou Posted June 15 Author Posted June 15 (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 June 15 by pyou Quote
Danielm103 Posted June 15 Posted June 15 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 Quote
Tsuky Posted June 15 Posted June 15 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) ) 2 Quote
pyou Posted June 15 Author Posted June 15 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 Quote
Danielm103 Posted June 15 Posted June 15 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)) ) 1 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.