an offset function, based on Sean's version but updated for 3d
[CommandMethod("NoPlotOffset")]
public static void NoPlotOffset()
{
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
PromptEntityOptions peo = new PromptEntityOptions("\nSelect object to offset");
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;
ObjectIdCollection ids = Offset(per.ObjectId);
if (ids.Count == 0) return;
//Use your layer function here
string layer=Layers.Layers.AddLayer("T-Invisible");
using (Transaction tr = db.TransactionManager.StartTransaction())
{
foreach (ObjectId id in ids)
{
Curve curve = (Curve)tr.GetObject(id, OpenMode.ForWrite);
curve.Layer = layer;
}
tr.Commit();
}
}
public static ObjectIdCollection Offset(ObjectId id)
{
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
ObjectIdCollection curveIds = new ObjectIdCollection();
if (!id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(Curve)))
|| id.ObjectClass == RXClass.GetClass(typeof(Leader)))
{
ed.WriteMessage("\nCannot offset that object");
return curveIds;
}
PromptDistanceOptions pdo = new PromptDistanceOptions("\nSpecify the offset distance:");
pdo.DefaultValue = Math.Abs((double)acadApp.GetSystemVariable("offsetdist"));
pdo.AllowZero = false;
PromptDoubleResult pdr = ed.GetDistance(pdo);
if (pdr.Status != PromptStatus.OK) return curveIds;
double offset = pdr.Value;
//To prevent snapping off screen.
Int16 OsmodeCurrent = (Int16)acadApp.GetSystemVariable("osmode");
acadApp.SetSystemVariable("osmode", 0);
PromptPointOptions ppo = new PromptPointOptions
("\nSpecify a point on side to offset:");
PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK) goto skip;
acadApp.SetSystemVariable("offsetdist", offset);
DBObjectCollection dbo =new DBObjectCollection();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Curve curve = (Curve)tr.GetObject(id, OpenMode.ForRead);
Point3d PickPt = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);
Vector3d v = ed.GetCurrentView().ViewDirection.GetNormal();
Plane plane;
try
{
plane = curve.GetPlane();
}
catch (System.Exception)
{
MessageBox.Show("The selected object cannot be offset."
+"To offset an object, all points in the object must be located in the same plane.",
"Offset-Object Is Non Planer",MessageBoxButtons.OK,MessageBoxIcon.Warning);
goto skip;
}
PickPt = PickPt.Project(plane, v);
Point3d ClosestPt = curve.GetClosestPointTo(PickPt, plane.Normal, false);
BlockTableRecord space = tr.GetObject
(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
double rot = Math.PI * 0.5;
if (curve.GetType() == typeof(Line))
rot = -rot;
Vector3d xaxis = plane.GetCoordinateSystem().Xaxis;
Vector3d v3d = curve.GetFirstDerivative(ClosestPt).RotateBy(rot, plane.Normal);
Double ang = v3d.GetAngleTo(ClosestPt.GetVectorTo(PickPt), xaxis);
if (ang > Math.PI * 0.5 && ang < (Math.PI * 2) - 0.00001)
dbo = curve.GetOffsetCurves(offset);
else
{
try
{
dbo = curve.GetOffsetCurves(-offset);
}
catch (System.Exception)
{
ed.WriteMessage("\nCannot offset that object");
goto skip;
}
}
if (dbo.Count == 0)
{
ed.WriteMessage("\nCannot offset that object");
goto skip;
}
foreach (Entity e in dbo)
{
curveIds.Add(space.AppendEntity(e));
tr.AddNewlyCreatedDBObject(e, true);
}
tr.Commit();
} //using
skip:
acadApp.SetSystemVariable("osmode", OsmodeCurrent);
return curveIds;
}// end Offset