View Full Version : How do I offset 3d Polyline

6th Jan 2006, 02:10 pm
Hello everybody! How do I offset 3D polyline?

6th Jan 2006, 07:21 pm
You can't (thus the response "Cannot offset that object."). I doubt AutoCAD can offset any 3d object.

6th Jan 2006, 08:08 pm
There are two third-party solutions you may wish to consider.

The first is by a company called DotSoft. They offer, for a fee, a 3D Polyline routine that does a number of things, among them, offset a 3D polyline. You can find their website at www.dotsoft.com.

The second is at a website called "Freecadapps". They deal in freeware and shareware. You can download a copy of Geotools.exe which contains Tool #19 - a mix of 3D polyline editting tools including the ability to offset such a linetype. You can find their website at www.freecadapps.com.

I cannot vouch for the validity or reliability of either company as I have no direct personal experience with either of them. But if you have a dire need to possess such a routine then by all means investigate thoroughly and make an informed decision. Good luck.

6th Jan 2006, 08:41 pm
You can't (thus the response "Cannot offset that object."). I doubt AutoCAD can offset any 3d object.

Same ere I gave this ago and had no luck, I also looked at the links above this post and also had no luck :(

7th Jan 2006, 12:35 am
To member "deelay".

I'm sorry to hear you had no luck. I always make it a point to confirm any links to make sure they work.

Re: DotSoft. At the main web page click on AutoCAD (at the top of your screen), then Products, then Productivity and finally click on ToolPac. Keep in mind this site charges for their routines. ToolPac 9.0 will cost you $195.

Re: freecadapps. Try this more direct link. I was able to download the necessary file.


Please post if you are still experiencing trouble finding the referenced sites or the specific information I have mentioned. I will endeavor to help as best I can. Good luck.

7th Jan 2006, 01:04 am
Its ok ReMark
Got there and both links work, not tried the free one yet 2 see if it offsets a 3d polyline though. i'll have a go tomorrow

9th Jan 2006, 08:34 am
Thank you everybody. I will try downloading both the programs.

10th Jan 2006, 06:30 am
[...] i'll have a go tomorrow

Dont Delay Do It 2day

:D Ok, I posted this just for fun. It has nothing to do with the topic. :D

Joe Kycek
28th Jan 2009, 12:30 pm
'I wrote this sub a few years back, it is used for
'offsetting a 3dpoly, both horizontally and vertically, onto
'a specific layer.

' SubName: Offset3dPoly
' Author: Joe Kycek, Date: 3/24/02
' Scope: Offset a 3dPoly with horizontal and vertical distances.
' Requirements:
' a) A 3dpoly object
' b) A horizontal offset distance from the 3dpoly to
' the new 3dpoly.
' c) A vertical offset distance from the 3dpoly to
' the new 3dpoly.
' d) A layer for the new 3dpoly.
' Return:
' i) A new 3dpoly object.
' 1) A positive horizontal distance value offsets to the Right.
' 2) A positive vertical distance value offsets vertically Up.
' 3) Just like the regular Offset command in AutoCad: Offsets
' that do not mathematically fit, may bring unexpected results.
' This sub uses the AutoCad offset function to achieve a part
' of its goals. So the rules regarding the standard
' AutoCad offset command apply.
Sub Offset3dPoly( _
o3dpoly As Acad3DPolyline, _
dDistanceHorizontal As Double, _
dDistanceVertical As Double, _
s3dPolyLayer As String, _
o3dpolynew As Acad3DPolyline)

Dim v2dPoly As Variant
Dim v3dPoly As Variant
Dim v3dPolyFlat As Variant
Dim o2dPoly As AcadPolyline
Dim o2dPolyOffset As AcadPolyline
Dim StartX As Double
Dim StartY As Double
Dim StartZ As Double
Dim EndX As Double
Dim EndY As Double
Dim EndZ As Double
Dim i As Integer
On Error GoTo 10

'Get the 3dpolys' coordinate array.
v3dPoly = o3dpoly.Coordinates
v3dPolyFlat = o3dpoly.Coordinates

'With the 3dpolys' coordinate array; flatten
'the z elevations to 0, so we can create a 2dpoly.
For i = 0 To ((UBound(v3dPolyFlat) + 1) / 3) - 1
v3dPolyFlat(3 * i + 2) = 0

'get the 3dpolys starting and ending coordinates
'to be used later for checking.
StartX = v3dPoly(0)
StartY = v3dPoly(1)
StartZ = v3dPoly(2)
EndX = v3dPoly(UBound(v3dPoly) - 2)
EndY = v3dPoly(UBound(v3dPoly) - 1)
EndZ = v3dPoly(UBound(v3dPoly))

'Create a 2dPoly with the same x,y coordinates as the 3dpoly.
'Use this object later; for offsetting.
Set o2dPoly = ThisDrawing.ModelSpace.AddPolyline(v3dPolyFlat)

'If the 3dpoly is closed, or the 3dpoly's start and end coordinates are
'the same; then close the 2dpoly object: for offseting.
If o3dpoly.Closed = True _
Or _
StartX = EndX And StartY = EndY And StartZ = EndZ Then
o2dPoly.Closed = True
End If

'The api does not support a zero 2dpoly offset. But we could
'be creating a new 3dpoly that is vertically straight up or down from
'the original 3dpoly, with no offset,
'so... an if statement is needed here;

If dDistanceHorizontal <> 0 Then

'Create a 2dpoly object array; by the offset distance supplied.
v2dPoly = o2dPoly.offSet(dDistanceHorizontal)

'Create a new 2dPoly object from the object array.
Set o2dPolyOffset = v2dPoly(0)

'Get the offsetted 2dpoly coordinates
v2dPoly = o2dPolyOffset.Coordinates

'delete the offsetted 2dpoly.
Set o2dPolyOffset = Nothing


'the horizontal offset is 0, so use the non-offsetted
'coordinates from the the new 2dpoly.
v2dPoly = o2dPoly.Coordinates

End If

'Next, Modify the offsetted 2dpolys' coordinates; by adding the
'original 3dpoly's z elevations plus the supplied Vertical additive.
For i = 0 To ((UBound(v2dPoly) + 1) / 3) - 1
v2dPoly(3 * i + 2) = v3dPoly(3 * i + 2) + dDistanceVertical

'Create the new 3dPoly.
Set o3dpolynew = ThisDrawing.ModelSpace.Add3DPoly(v2dPoly)

'if the 2dpoly is closed, then close the new 3dpoly
If o2dPoly.Closed = True Then
o3dpolynew.Closed = True
End If

'Set the layer for the new 3dPoly.
o3dpolynew.Layer = s3dPolyLayer


'delete the 2dpoly.
Set o2dPoly = Nothing

End Sub

28th Jan 2009, 12:44 pm
Well that's one way to introduce yourself with a first post.

Welcome to the CADTutor forum. Perhaps you should post this in the AutoLISP forum.

Joe Kycek
28th Jan 2009, 03:07 pm
Thanks, but:
Why should I post this code in the Lisp Forum?

Joe Kycek
13th Feb 2009, 12:52 pm
Private Sub CreateAWall()
Dim o3dpoly As Acad3DPolyline
Dim o3dpolynew As Acad3DPolyline

'This is just one example on how to use the
'Offset3dPoly sub, from a form.

'Lets create a 10' foot high wall that is 1' foot thick and is
'5' feet away from the original 3dpoly picked; and follows
'the picked 3dpolys' elevations.


On Error GoTo 10

'Pick the 3dpoly (I am using my own custom getentity utility)
Set o3dpoly = GetEntityByFilter("3D PolyLine", "3DPOLYLINE")

'let the Offset3dPoly sub do the work:
Offset3dPoly o3dpoly, 5, 0, "0", o3dpolynew
Offset3dPoly o3dpolynew, 0, 10, "0", o3dpolynew
Offset3dPoly o3dpolynew, 1, 0, "0", o3dpolynew
Offset3dPoly o3dpolynew, 0, -10, "0", o3dpolynew


Set o3dpoly = Nothing
Set o3dpolynew = Nothing


End Sub

21st Nov 2009, 02:33 am
Hi, I wish to use the sub routine mentioned on this thread (I need to offset some 3D Polylines), so can someone please explain how I use it within ACAD 2009? What extension do I save the text in, or do I need to do something different?

Thanks in advance.

13th Dec 2009, 09:00 pm
I have the same problem as workster. I have got other LISP codes to work but cant seem to get this to work? Is it a LISP or something different? Someone please help.

24th Jan 2010, 06:54 pm
I know its four years later, but you can use the Rectangular Array command for 3d objects. Just set your Rows to 1, Columns to however many object you want, Row offset to 0", Column offset to desired offset, and angle to desired angle. It works fine for me. Good luck and i hope im not too late.

Joe Kycek
13th Mar 2010, 11:59 am
:)Has anyone tried the code?

26th May 2010, 04:01 pm
The code looks like its VB

The rec array is just a copy of the object, and not really an offset...

I personally think an offset of an 3d line (or object is not possible) without first converting it to a 2d, and once it is converted to 2d, do an offset and set vertices to old z values.This will give you the feel as it has been off setted, but I don't think that is mathematically correct...

(Btw this could be achieved by a program, be it LISP or com)


I think most people will settle for a copy of the 3d object in a certain direction and length.

Joe Kycek
2nd Jun 2010, 02:05 pm

I had a bit of time on the weekend, so I
developed a gui for my Offset3dPoly code.
The code is in autocad vba dvb format.
I tested the code in civil3d 2008 & civil3d 2010.
Hope it helps.

Joe Kycek
2nd Jun 2010, 05:06 pm
Oops, forgot to add an autocad command line
'command' for it... So once the vba is run once; the
command "op3" is available at the command line to
re-open the dialogbox. So uploading a new file.

3rd Jun 2010, 08:21 am
thanks, I'll give it a try...

3rd Jun 2010, 08:44 am
Ok, I gave it a try.

I'm having a problem:

On running this code it gives me the error it cand find the library:

'set to uppercase
FilterStr = StrConv(ObjType, vbUpperCase)
ObjectStr = StrConv(objEnt.ObjectName, vbUpperCase)
ObjectStr2 = ObjectStr
ObjectStr = Mid(ObjectStr, InStr(1, ObjectStr, "DB", 1) + 2)I'm not used to vba, (I like vbnet or C#) :)

Do I need a reference here, an import or using, that points to that library?

5th Jun 2010, 01:47 pm
Some times ago I made my version of Offset3d.lsp

8th Jun 2010, 08:27 am
Some times ago I made my version of Offset3d.lsp

this works like a charm, thanks

7th Jan 2011, 01:53 am
Very useful. Thank you very much for sharing.

7th Jan 2011, 10:50 am
For people with AutoCAD Civil 3D there is a native 3D offset command _AeccOffsetFeature which is the 3D offset command.

12th Feb 2015, 10:27 am
To make this work I made a form with a command button and 2 text boxes, textboxZ and textboxV. I added this code to the command_click event of the command button:

Private Sub CommandButton1_Click()
Dim picked3dPoly As Acad3DPolyline
Dim old3dPoly As Acad3DPolyline
' Begin the selection
Dim returnObj As AcadObject
Dim basePnt As Variant

On Error Resume Next

' The following example waits for a selection from the user
ThisDrawing.Utility.GetEntity returnObj, basePnt, "Select a 3D Polyline object"

If Err <> 0 Then
MsgBox "Program ended.", , "GetEntity Example"
Exit Sub
If (returnObj.EntityName = "AcDb3dPolyline") Then

Set picked3dPoly = returnObj
z# = Val(TextBoxZ.Text)
h# = Val(TextBoxH.Text)
Call Offset3dPoly(picked3dPoly, h#, z#, "0", old3dPoly)
End If
End If


End Sub

12th Feb 2015, 10:31 am
Forgot to add that the Offset3dPoly subroutine code must be added to the General section of the form code

12th Feb 2015, 10:33 am
Sorry textboxH not textboxV