Author Topic: offset problem in 3d space  (Read 858 times)

0 Members and 1 Guest are viewing this topic.

dussla

  • Bull Frog
  • Posts: 259
offset problem in 3d space
« on: September 29, 2012, 12:46:37 AM »
if you see my attach file

you can SEE  I  II   .

in 2d space  , offset command is good
but in 3d space , if i offset line ,   line  offset  in   2d  plane  only    ( see  l  )
i want   to offest   line  like circle ll   in 3d space

can you understand ?

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: offset problem in 3d space
« Reply #1 on: September 29, 2012, 01:00:07 AM »
AFAIK offset only works in 2D planes. You'll need to adjust your UCS before you offset, so it offsets into another direction. Even then, it would only work on entities which don't have their own OCS (e.g. PolyLines / Circles would ignore the current UCS and use their own original OCS).
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

ribarm

  • Water Moccasin
  • Posts: 2369
  • Marko Ribar, architect
Re: offset problem in 3d space
« Reply #2 on: September 29, 2012, 08:03:05 AM »
Once in past, I had a problem how to offset in 3d, but my problem was with 3dpolyline object, and I wrote this code...
Code: [Select]
(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)
)

If you have LWPOLYLINE like in your case, you can just use ordinary offset command, or if you have LINE object, you can use copy command and make copy of it in 3d space... Note that ordinary offset command works only in 2d and some relative UCS, so if you want 3d you'll probably need to make object in UCS where you want to make offset copy of that object... Like ordinary offset, my 3doffset also does offset, but in WCS - asks for horizontal distance between old and new 3dpoly, however with mine as all 3dpoly vertexes are in 3d, resulting 3dpoly is also in 3d... Maybe what I just explained is enough for you to complete the job without unnecessary questions that may rise up ab this problem... I agree with Irne - we don't know what should 3doffset quite do - if not the same as copy command...

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: offset problem in 3d space
« Reply #3 on: September 29, 2012, 10:16:51 AM »
I agree with Irne - we don't know what should 3doffset quite do - if not the same as copy command...
Exactly. Even offsetting a 3dPoly could have variants. E.g. (as I understand from your post) you could offset each vertex by a XY distance in the WCS - thus making an offset shape in WCS plan view while keeping all the Z values the same (sorry if I misinterpreted this).

Another alternative of a 3dPoly's offset might be that the new 3dPoly would have grown around the original's centroid.

But from the OP's example it looks much more like a line is copied at a specified X, Y and/or Z delta than an actual "offset". The point about the "offset" command is that it needs a distance perpendicular to the original's vertex. The perpendicular means it needs a plane to define the direction - otherwise you could think of it as generating a cylinder around each line with a radius equal to the offset distance (i.e. offset direction in any point around a 360 degree arc around the original). And I'm sure that's not the intention, definitely not if I look at your DWG.

If you mean that you need to pick the distance on a 3d object, then offset as if it's the plan-view distance only. I.e. the other way round: measure the 2d distance of 2 points in 3D space then use that as the offset distance. Then you might want to look at point filters. Else a lisp like the following might do well:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:Offset2D  (/ pt1 pt2 dist)
  2.   (initget 128)
  3.   (setq dist (cond ((not (setq pt1 (getpoint (strcat "Enter offset distance or pick start of measure point <"
  4.                                                      (rtos (getvar "OffsetDist"))
  5.                                                      ">: "))))
  6.                     (getvar "OffsetDist"))
  7.                    ((and (listp pt1) (setq pt2 (getpoint pt1 "\nPick endpoint of measure: ")))
  8.                     (distance (mapcar '+ pt1 '(0 0)) (mapcar '+ pt2 '(0 0))))
  9.                    ((distof pt1))))
  10.   (command "._OFFSET" dist)
  11.   (while (= (logand (getvar "CmdActive") 1) 1) (command pause))
  12.   (princ))

Edit: changed read to distof - so it allows for any form of manual distance entry.
« Last Edit: September 29, 2012, 10:24:31 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: offset problem in 3d space
« Reply #4 on: September 29, 2012, 10:37:44 AM »
BTW, If my last assumption is correct and you simply want a 2D representation of the actual 3D object(s) ... a more efficient method might be to use some built-in commands. Something like FlatShot / SolProf / SolView / Section.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.