Author Topic: Offset  (Read 6647 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: Offset
« Reply #15 on: January 05, 2010, 06:21:02 PM »
Nice work Sean !

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Offset
« Reply #16 on: January 09, 2010, 04:12:29 PM »
an offset function, based on Sean's version but updated for 3d
Code: [Select]
        [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