Jump to content

Offseting 3D Polyline


Recommended Posts

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!

Link to post
Share on other sites

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.

Link to post
Share on other sites

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 by GP_
Link to post
Share on other sites

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.

Link to post
Share on other sites

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.

Link to post
Share on other sites
marko_ribar

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.

Link to post
Share on other sites
marko_ribar

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

Link to post
Share on other sites

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

Link to post
Share on other sites

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 by Hrcko
Link to post
Share on other sites
  • 5 months later...
mkranthikittu

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

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

Link to post
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
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...