Hrcko Posted August 13, 2014 Posted August 13, 2014 Hi! In the help section for OFFSET command 3D Polyline is not specified as the object that can be Offset-ed. Is there some tip how to offset 3D Polyline in the plane where the polyline is located? Thank you! Quote
Dadgad Posted August 14, 2014 Posted August 14, 2014 As you said, it can't be Offset, as a 3D Polyline, but if you explode it, or a copy of it, the resulting line CAN be offset. If need be you could then trace over the offset LINE to create the 3D Polyline which presumably you prefer. Not perfect, but as a workaround, I hope it helps you. Quote
GP_ Posted August 14, 2014 Posted August 14, 2014 (edited) Try this: ; Offset a 3dPoly with horizontal and vertical distances ; 15 August 2014 - Gian Paolo Cattaneo (defun c:o3 ( / *error* 3dp p ogt) (defun *error* ( msg ) (setvar 'offsetgaptype ogt) (vla-endundomark (vla-get-activedocument (vlax-get-acad-object))) (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")) (princ (strcat "\nError: " msg)) ) (princ) ) (vla-startundomark (vla-get-activedocument (vlax-get-acad-object))) (setq ogt (getvar 'offsetgaptype)) (setvar 'offsetgaptype 0) (or op (setq op 0.00)) (or oz (setq oz 0.00)) (while (progn (setq 3dp (car (entsel "\nSelect the 3D polyline to offset"))) (if (not (eq "AcDb3dPolyline" (vlax-get (vlax-ename->vla-object 3dp) 'ObjectName))) (progn (alert "This is not a 3D Polyline") t ) ) ) ) (if 3dp (progn (while (progn (initget (+ 2 4)) (setq op (cond ( (getdist (strcat "\nOffset Distance (horizontal) <" (rtos op 2 2)">: ")) ) ( op ) ) ) (if (= op 0.) (progn (alert "The horizontal offset distance must be greater than zero") t ) ) ) ) (setq oz (cond ( (getdist (strcat "\nOffset Distance (vertical) <" (rtos oz 2 2)">: ")) ) ( oz ) ) ) (setq p (getpoint "\nSpecify point on side to offset ")) (off3DP 3dp op oz p) ) ) (setvar 'offsetgaptype ogt) (vla-endundomark (vla-get-activedocument (vlax-get-acad-object))) (princ) ) ;******************* Offset 3D Polyline ********************; ; ; ; obj [ENAME] - entity name ; ; d_o [REAL] - horizontal offset distance ; ; d_z [REAL] - vertical offset distance ; ; p_of [list] - point on side to offset ; ; ; ; ----------------------------------------------------------; ; (off3DP (car (entsel)) 2.15 -2.00 '(3 4 0)) ; ; ----------------------------------------------------------; ; author: Gian Paolo Cattaneo - 30.03.2013 ; ;***********************************************************; (defun off3DP ( obj d_o d_z p_of / EL Lv PL2 PL3 Lv Lv1 Lv2 n_of obj_of) (if (and (eq "AcDb3dPolyline" (vlax-get (vlax-ename->vla-object obj) 'ObjectName)) (setq Lv (pl_coord obj)) (setq PL2 (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 (length Lv)) (cons 70 (if (vlax-curve-IsClosed obj) 1 0)) (cons 43 0.0) ) (mapcar '(lambda (x) (cons 10 x)) Lv) ) ) ) ) (progn (setq EL (entlast)) (vl-cmdf "_offset" d_o PL2 p_of "") (if (and (/= EL (setq PL3 (entlast))) (= (setq n_of (length (setq obj_of (e_next EL "LS")))) 1) ) (progn (setq Lv2 nil) (setq Lv1 (pl_coord PL3)) (entdel PL2) (entdel PL3) (mapcar '(lambda ( a b ) (setq Lv2 (cons (list (car b) (cadr b) (+ d_z (caddr a))) Lv2)) ) Lv Lv1 ) (setq Lv2 (reverse Lv2)) (entmake (list '(0 . "POLYLINE") '(10 0.0 0.0 0.0) (assoc 8 (entget obj)) (assoc 70 (entget obj)) ) ) (repeat (length Lv2) (entmake (list (cons 0 "VERTEX") (cons 10 (CAR Lv2)) (cons 70 32) ) ) (setq Lv2 (cdr Lv2)) ) (entmake '((0 . "SEQEND"))) t ) (progn (entdel PL2) (if (> n_of 1) (repeat n_of (entdel (car obj_of)) (setq obj_of (cdr obj_of)) ) ) nil ) ) ) ) ) ;***********************************************************; (defun pl_coord (# / p m) (setq p (if (vlax-curve-IsClosed #) (fix (vlax-curve-getEndParam #)) (1+ (fix (vlax-curve-getEndParam #))) ) ) (while (/= 0 p) (setq m (cons (vlax-curve-getPointAtParam # (setq p (1- p))) m)) ) ) ;***********************************************************; (defun e_next (entL mode / next) (if (= mode "SS") (setq next (ssadd))) (if (/= entL (entlast)) (while (setq entL (entnext entL)) (if (entget entL) (cond ( (= mode "LS") (setq next (cons entL next)) ) ( (= mode "SS") (setq next (ssadd entL next)) ) ) ) ) ) next ) (vl-load-com) ;***********************************************************; (prompt "\n ") (prompt "\n ") (princ "\n\\U+00AB Offset 3D Polyline - Type \"o3\" to run [url="file://\\U+00BB"]\\U+00BB[/url]") (princ) Edited August 15, 2014 by GP_ Quote
Tyke Posted August 14, 2014 Posted August 14, 2014 You can offset a 3D polyline in Civil 3D and MAP using the OFFSETFEATURE command, but I don't know if that command is present in Mechanical. Quote
Hrcko Posted August 14, 2014 Author Posted August 14, 2014 Thank you gentlemen! GP_ I am the beginner with AutoCAD and I don't know how to use your code. First I must read Help to see what to do with it. Is this LISP? I need the keyword for the search. Quote
Tyke Posted August 14, 2014 Posted August 14, 2014 Yes Hrcko that is LISP. Take a look at Lee Mac's website where he has some great information on starting out with LISP. Here's the link www.lee-mac.com Quote
marko_ribar Posted August 14, 2014 Posted August 14, 2014 This is my old one, but I've found it... Try it, maybe it can help for what you need... (defun c:3doffset-3dpoly ( / ent entA entcoordlst pt3d pt2d entvertlst3d entvertlst2d pto d 2dplo 2dpln 2dplncoordlst 2dplnvertlst3d ptx pty ptz ptxlst ptylst ptzlst 3dplnvertlst3d ) (setq oscmd (getvar 'osmode)) (setvar 'osmode 0) (setq ent (car (entsel "\nSelect 3D Polyline - 3dpline must not have vertical segments"))) (vl-load-com) (setq entA (vlax-ename->vla-object ent)) (setq entcoordlst (vlax-safearray->list (vlax-variant-value (vla-get-Coordinates entA)))) (repeat (/ (length entcoordlst) 3) (setq pt3d (list (car entcoordlst) (cadr entcoordlst) (caddr entcoordlst))) (setq pt2d (list (car entcoordlst) (cadr entcoordlst) 0 )) (repeat 3 (setq entcoordlst (cdr entcoordlst)) ) (setq entvertlst3d (cons pt3d entvertlst3d)) (setq entvertlst2d (cons pt2d entvertlst2d)) ) (setq entvertlst3d (reverse entvertlst3d)) (setq entvertlst2d (reverse entvertlst2d)) (command "pline") (foreach pt entvertlst2d (command pt)) (command "") (command "ucs" "w") (command "plan" "") (setq pto (getpoint "\nPick point for side for 3doffset (in/out) : ")) (setq pto (list (car pto) (cadr pto) 0)) (setq d (getdist "\nInput horizontal distance for 3doffset (2 points) : ")) (setq 2dplo (entlast)) (command "offset" d (entlast) pto "") (entdel 2dplo) (setq 2dpln (entlast)) (setq 2dplnA (vlax-ename->vla-object 2dpln)) (setq 2dplncoordlst (vlax-safearray->list (vlax-variant-value (vla-get-Coordinates 2dplnA)))) (repeat (/ (length 2dplncoordlst) 2) (setq pt3d (list (car 2dplncoordlst) (cadr 2dplncoordlst) 0 )) (repeat 2 (setq 2dplncoordlst (cdr 2dplncoordlst)) ) (setq 2dplnvertlst3d (cons pt3d 2dplnvertlst3d)) ) (setq 2dplnvertlst3d (reverse 2dplnvertlst3d)) (entdel 2dpln) (repeat (length 2dplnvertlst3d) (setq ptx (car (car 2dplnvertlst3d))) (setq pty (cadr (car 2dplnvertlst3d))) (setq 2dplnvertlst3d (cdr 2dplnvertlst3d)) (setq ptxlst (cons ptx ptxlst)) (setq ptylst (cons pty ptylst)) ) (setq ptxlst (reverse ptxlst)) (setq ptylst (reverse ptylst)) (repeat (length entvertlst3d) (setq ptz (caddr (car entvertlst3d))) (setq entvertlst3d (cdr entvertlst3d)) (setq ptzlst (cons ptz ptzlst)) ) (setq ptzlst (reverse ptzlst)) (repeat (length ptzlst) (setq ptn (list (car ptxlst) (car ptylst) (car ptzlst))) (setq ptxlst (cdr ptxlst)) (setq ptylst (cdr ptylst)) (setq ptzlst (cdr ptzlst)) (setq 3dplnvertlst3d (cons ptn 3dplnvertlst3d)) ) (setq 3dplnvertlst3d (reverse 3dplnvertlst3d)) (command "3dpoly") (foreach pt 3dplnvertlst3d (command pt)) (command "") (setvar 'osmode oscmd) (princ) ) After you copy+paste code into notepad, choose saveas and type 3doffset-3dpoly.lsp... Then start ACAD and type appload and choose 3doffset-3dpoly.lsp... After lisp was loaded just type 3doffset-3dpoly to start it... Alternatively, you don't have to use appload command, but click on lisp and press ctrl+c (copy), then go to CAD drawing interface and press ctrl+v (paste) => lisp will be loaded - there you can see last loaded (defun function ( args / vars )) - you'll see c:3doffset-3dpoly, that means that command function 3doffset-3dpoly was loaded... Then type 3doffset-3dpoly to start and follow procedure the routine asks during execution process... I hope I've explained well... The same procedure you can apply with GP's code... Only difference you'll have to start it with test and during copy+paste lisp into CAD interface you'll see last loaded defun (e_next) function, but in fact all previously written defuns were loaded at the same time, so you can then start it with test - first (defun c:test ( / vars ))... Of course then follow prompts asked by working routine that is in execution... HTH, M.R. 1 Quote
Hrcko Posted August 14, 2014 Author Posted August 14, 2014 Marko, thank you for the detail instruction on loading LISP code. I will try it. Tyke gave me useful link for LISP. Quote
marko_ribar Posted August 14, 2014 Posted August 14, 2014 Probaj, ako nesto nije jasno ti slobodno pitaj... Inace, moja rutina je predvidjena za otvorene 3d polilinije, ali radi i sa zatvorenim... Inace ofsetovanje 3d polilinije u sustini nije moguce - 3d ofset bi bio nesto kao kopiranje za neki vektor... U mom slucaju 3d polilinija se proicira na WCS ravan, pa se ofsetuje 2d polilinija, pa se vrate sve koordinate novoj 3d poliliniji ali sa z koordinatiom preuzetom od originalne 3d polilinije - horizontalno ofsetovanje... Ovo mi je ranije trebalo za kalkulaciju preseka terena i 3d objekta cije su ivice ustvari 3d polilinija - na taj nacin moze se odrediti usek i nasip zemljanih radova - samo treba znati koristiti loft komandu i solid modeling operacije : subtrakcija, intersekcija, unija... Quote
Hrcko Posted August 14, 2014 Author Posted August 14, 2014 Marko, I tried your code, but it ended with error because the name Coordinates was not defined. (ActiveX Server returned error: unknown name: Coordinates) GP_, your code runs without error, but I can not obtain offset-ed polyline. Thank you for the kindness and help. I must learn more about LISP programming. Quote
GP_ Posted August 15, 2014 Posted August 15, 2014 GP_, your code runs without error, but I can not obtain offset-ed polyline. (vl-load-com)..... Updated code at post # 3 Quote
Hrcko Posted August 15, 2014 Author Posted August 15, 2014 (edited) Hi, GP! I tried new code, but I still can't get offset-ed polyline. I also tried with AutoCAD 14. I am missing something. I am uploading the command as Marko said (post #7). Is it OK? Thank you for the help. Edited August 16, 2014 by Hrcko Quote
mkranthikittu Posted February 6, 2015 Posted February 6, 2015 Hi Sir, Please can you help me i am new to this cad tutor i need a help in auto cad MAP 2011 Quote
mkranthikittu Posted February 6, 2015 Posted February 6, 2015 Sir's In this lisp i need small modification sir i want to draw more ofsets at a time can you help me sir (defun c:of (/ foo AT:GetSel _pnts _pline _lwpline _dist e1 e2) ;; Draw (LW)Polyline between two selected curves (at midpoint of vertices). ;; Alan J. Thompson, 09.29.10 (vl-load-com) (defun foo (e) (and (wcmatch (cdr (assoc 0 (entget (car e)))) "LINE,*POLYLINE,SPLINE") (not (vlax-curve-isClosed (car e))) ) ) (defun AT:GetSel (meth msg fnc / ent) ;; meth - selection method (entsel, nentsel, nentselp) ;; msg - message to display (nil for default) ;; fnc - optional function to apply to selected object ;; Ex: (AT:GetSel entsel "\nSelect arc: " (lambda (x) (eq (cdr (assoc 0 (entget (car x)))) "ARC"))) ;; Alan J. Thompson, 05.25.10 (while (progn (setvar 'ERRNO 0) (setq ent (meth (cond (msg) ("\nSelect object: ") ) ) ) (cond ((eq (getvar 'ERRNO) 7) (princ "\nMissed, try again.")) ((eq (type (car ent)) 'ENAME) (if (and fnc (not (fnc ent))) (princ "\nInvalid object!") ) ) ) ) ) ent ) (defun _pnts (e / p l) (if e (cond ((wcmatch (cdr (assoc 0 (entget e))) "ARC,LINE,SPLINE") (list (vlax-curve-getStartPoint e) (vlax-curve-getEndPoint e)) ) ((wcmatch (cdr (assoc 0 (entget e))) "*POLYLINE") (repeat (setq p (1+ (fix (vlax-curve-getEndParam e)))) (setq l (cons (vlax-curve-getPointAtParam e (setq p (1- p))) l)) ) ) ) ) ) (defun _pline (lst) (if (and (> (length lst) 1) (entmakex '((0 . "POLYLINE") (10 0. 0. 0.) (70 . )) (foreach x lst (entmakex (list '(0 . "VERTEX") (cons 10 x) '(70 . 32)))) ) (cdr (assoc 330 (entget (entmakex '((0 . "SEQEND")))))) ) ) (defun _lwpline (lst) (if (> (length lst) 1) (entmakex (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length lst)) (cons 70 (* (getvar 'plinegen) 128)) ) (mapcar (function (lambda (p) (list 10 (car p) (cadr p)))) lst) ) ) ) ) (defun _dist (a b) (distance (list (car a) (cadr a)) (list (car b) (cadr b)))) (if (and (setq e1 (_pnts (car (AT:GetSel entsel "\nSelect first open curve: " foo)))) (setq e2 (_pnts (car (AT:GetSel entsel "\nSelect next open curve: " foo)))) (not (initget 0 "Lwpolyline Polyline")) (setq *LBL:Opt* (cond ((getkword (strcat "\nSpecify line to draw: [Lwpolyline/Polyline] (cond (*LBL:Opt*) ((setq *LBL:Opt* "Lwpolyline")) ) ">: " ) ) ) (*LBL:Opt*) ) ) ) ((if (eq *LBL:Opt* "Lwpolyline") _lwpline _pline ) (vl-remove nil (mapcar (function (lambda (a b) (if (and a b (not (grdraw (trans a 0 1) (trans b 0 1) 1 1))) (mapcar (function (lambda (a b) (/ (+ a b) 2.))) a b) ) ) ) e1 (if ( (_dist (car e1) (last e2)) ) e2 (reverse e2) ) ) ) ) ) (princ) ) (defun c:FZ ( / i ss e zro ) (if (setq i -1 zro (ssadd) ss (ssget "_X" '((0 . "LWPOLYLINE")))) (while (setq e (ssname ss (setq i (1+ i)))) (and (equal 0.0 (vlax-curve-getDistatParam e (vlax-curve-getEndParam e)) 1e-14) (ssadd e zro)))) (sssetfirst nil zro) (princ)) Quote
Michael Nabatieh Posted October 28 Posted October 28 On 14/08/2014 at 08:22, GP_ said: Try this: ; Offset a 3dPoly with horizontal and vertical distances ; 15 August 2014 - Gian Paolo Cattaneo (defun c:o3 ( / *error* 3dp p ogt) (defun *error* ( msg ) (setvar 'offsetgaptype ogt) (vla-endundomark (vla-get-activedocument (vlax-get-acad-object))) (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")) (princ (strcat "\nError: " msg)) ) (princ) ) (vla-startundomark (vla-get-activedocument (vlax-get-acad-object))) (setq ogt (getvar 'offsetgaptype)) (setvar 'offsetgaptype 0) (or op (setq op 0.00)) (or oz (setq oz 0.00)) (while (progn (setq 3dp (car (entsel "\nSelect the 3D polyline to offset"))) (if (not (eq "AcDb3dPolyline" (vlax-get (vlax-ename->vla-object 3dp) 'ObjectName))) (progn (alert "This is not a 3D Polyline") t ) ) ) ) (if 3dp (progn (while (progn (initget (+ 2 4)) (setq op (cond ( (getdist (strcat "\nOffset Distance (horizontal) <" (rtos op 2 2)">: ")) ) ( op ) ) ) (if (= op 0.) (progn (alert "The horizontal offset distance must be greater than zero") t ) ) ) ) (setq oz (cond ( (getdist (strcat "\nOffset Distance (vertical) <" (rtos oz 2 2)">: ")) ) ( oz ) ) ) (setq p (getpoint "\nSpecify point on side to offset ")) (off3DP 3dp op oz p) ) ) (setvar 'offsetgaptype ogt) (vla-endundomark (vla-get-activedocument (vlax-get-acad-object))) (princ) ) ;******************* Offset 3D Polyline ********************; ; ; ; obj [ENAME] - entity name ; ; d_o [REAL] - horizontal offset distance ; ; d_z [REAL] - vertical offset distance ; ; p_of [list] - point on side to offset ; ; ; ; ----------------------------------------------------------; ; (off3DP (car (entsel)) 2.15 -2.00 '(3 4 0)) ; ; ----------------------------------------------------------; ; author: Gian Paolo Cattaneo - 30.03.2013 ; ;***********************************************************; (defun off3DP ( obj d_o d_z p_of / EL Lv PL2 PL3 Lv Lv1 Lv2 n_of obj_of) (if (and (eq "AcDb3dPolyline" (vlax-get (vlax-ename->vla-object obj) 'ObjectName)) (setq Lv (pl_coord obj)) (setq PL2 (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 (length Lv)) (cons 70 (if (vlax-curve-IsClosed obj) 1 0)) (cons 43 0.0) ) (mapcar '(lambda (x) (cons 10 x)) Lv) ) ) ) ) (progn (setq EL (entlast)) (vl-cmdf "_offset" d_o PL2 p_of "") (if (and (/= EL (setq PL3 (entlast))) (= (setq n_of (length (setq obj_of (e_next EL "LS")))) 1) ) (progn (setq Lv2 nil) (setq Lv1 (pl_coord PL3)) (entdel PL2) (entdel PL3) (mapcar '(lambda ( a b ) (setq Lv2 (cons (list (car b) (cadr b) (+ d_z (caddr a))) Lv2)) ) Lv Lv1 ) (setq Lv2 (reverse Lv2)) (entmake (list '(0 . "POLYLINE") '(10 0.0 0.0 0.0) (assoc 8 (entget obj)) (assoc 70 (entget obj)) ) ) (repeat (length Lv2) (entmake (list (cons 0 "VERTEX") (cons 10 (CAR Lv2)) (cons 70 32) ) ) (setq Lv2 (cdr Lv2)) ) (entmake '((0 . "SEQEND"))) t ) (progn (entdel PL2) (if (> n_of 1) (repeat n_of (entdel (car obj_of)) (setq obj_of (cdr obj_of)) ) ) nil ) ) ) ) ) ;***********************************************************; (defun pl_coord (# / p m) (setq p (if (vlax-curve-IsClosed #) (fix (vlax-curve-getEndParam #)) (1+ (fix (vlax-curve-getEndParam #))) ) ) (while (/= 0 p) (setq m (cons (vlax-curve-getPointAtParam # (setq p (1- p))) m)) ) ) ;***********************************************************; (defun e_next (entL mode / next) (if (= mode "SS") (setq next (ssadd))) (if (/= entL (entlast)) (while (setq entL (entnext entL)) (if (entget entL) (cond ( (= mode "LS") (setq next (cons entL next)) ) ( (= mode "SS") (setq next (ssadd entL next)) ) ) ) ) ) next ) (vl-load-com) ;***********************************************************; (prompt "\n ") (prompt "\n ") (princ "\n\\U+00AB Offset 3D Polyline - Type \"o3\" to run [url="file://\\U+00BB"]\\U+00BB[/url]") (princ) Hi ! Great lisp ! very useful. I want to know if there's a possibility to make the vertical distance variable ? I have a maximum allowed elevation, so I want to go through the vertices and check: if the vertex is bellow the maximum elevation I keep it as it is if the vertex is higher than the maximum elevation then the vertical distance should be decreased . Thanks in advance ! Quote
BIGAL Posted October 28 Posted October 28 (edited) If you look at a 3dpolyline you can get all the vertices, ie XYZ. (setq obj (vlax-ename->vla-object (car (entsel "Pick obj")))) (setq lst (vlax-get obj 'coordinates)) 2d pline Pick obj (-1.84666018392536 -4.58940053777991 -0.626942223989683 1.70546571522144 4.27996910908486 -0.0610223646853961 8.3597153888697 3.12146012848009) 3dpline Pick obj (-7.63681555695332 -5.20626939108071 0.0 -6.54327531701099 3.83646720844239 22.0 3.92947544243668 -1.49103652460998 0.0) So in 3dpoly you have a pattern of 3 items X Y Z, the 2 segment pline above has a Z of 22 as the mid vertice. You would read the values and look at each 3rd value and check is it greater than max so replace. (vlax-put obj 'coordinates newco-ords) I will leave it up to you to work out how to read through the lst. If you get stuck come back. Hint (repeat (/ (length lst) 3) Edited October 28 by BIGAL Quote
Michael Nabatieh Posted October 29 Posted October 29 8 hours ago, BIGAL said: If you look at a 3dpolyline you can get all the vertices, ie XYZ. (setq obj (vlax-ename->vla-object (car (entsel "Pick obj")))) (setq lst (vlax-get obj 'coordinates)) 2d pline Pick obj (-1.84666018392536 -4.58940053777991 -0.626942223989683 1.70546571522144 4.27996910908486 -0.0610223646853961 8.3597153888697 3.12146012848009) 3dpline Pick obj (-7.63681555695332 -5.20626939108071 0.0 -6.54327531701099 3.83646720844239 22.0 3.92947544243668 -1.49103652460998 0.0) So in 3dpoly you have a pattern of 3 items X Y Z, the 2 segment pline above has a Z of 22 as the mid vertice. You would read the values and look at each 3rd value and check is it greater than max so replace. (vlax-put obj 'coordinates newco-ords) I will leave it up to you to work out how to read through the lst. If you get stuck come back. Hint (repeat (/ (length lst) 3) Thanks for the reply ! I'll try to make it work 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.