000

Index Labels

Show/Hide Segments of a Polyline With Overrule

.
I saw a question posted in AutoCAD .NET forum asking "if it's possible to create a polyline with invisible segment" here. The question raised my curiosity of thinking how do I do it. Right away, I thought Overrule would be the easy approach to do it. Thus the code shows in this article.

Some explanations. To make things simple, I decide to draw a polyline with multiple segments (e.g. with more than 2 vertices) so that every other segment is visible; also, the Overrule would only apply to polylines that are on certain layer; and the Overrule itself can be turn on or off, regardless if there is other custom Overrule taking effect.

Here is the code:

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
 
[assembly: CommandClass(typeof(HidePartialPLine.MyCommands))]
 
namespace HidePartialPLine
{
    public class MyCommands 
    {
        private const string OR_LAYER="Overruled_PLine";
        private static MyPLineOverrule _myOR=null;
 
        [CommandMethod("MyOR")]
        public static void ToggleMyOverrule()
        {
            Document dwg = Application.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;
 
            if (_myOR==null) 
            {
                _myOR=new MyPLineOverrule();
                _myOR.StartOverrule();
                ed.WriteMessage("\nMyPLineOverrule is on.\n");
            }
            else
            {
                if (!_myOR.OverruleOn) 
                {
                    _myOR.StartOverrule();
                    ed.WriteMessage("\nMyPLineOverrule is on.\n");
                }
                else
                {
                    _myOR.StopOverrule();
                    ed.WriteMessage("\nMyPLineOverrule is off.\n");
                }
            }    
        }
 
        [CommandMethod("SetOR")]
        public static void SetMyOverruleToPolyline()
        {
            Document dwg = Application.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;
 
            ObjectId id = SelectPolyline(ed);
            if (id == ObjectId.Null)
            {
                ed.WriteMessage("\n*Cancel*\n");
                return;
            }
 
            SetPolylineLayer(id, OR_LAYER, dwg.Database);
        }
 
        #region private methods
 
        private static ObjectId SelectPolyline(Editor ed)
        {
            PromptEntityOptions opt=new PromptEntityOptions("\nPick a polyline");
            opt.SetRejectMessage("You must pick a polyline. ");
            opt.AddAllowedClass(
                typeof(Autodesk.AutoCAD.DatabaseServices.Polyline),true);
 
            PromptEntityResult res=ed.GetEntity(opt);
            if (res.Status==PromptStatus.OK)
            {
                return res.ObjectId;
            }
            else
            {
                return ObjectId.Null;
            }
        }
 
        private static void SetPolylineLayer(
            ObjectId entId, string layerName, Database db)
        {
            using (Transaction tran = db.TransactionManager.StartTransaction())
            {
                Entity ent = (Entity)tran.GetObject(entId, OpenMode.ForRead);
                if (ent.Layer.ToUpper() != OR_LAYER.ToUpper())
                {
                    ent.UpgradeOpen();
                    ent.Layer = OR_LAYER;
                }
                tran.Commit();
            }
        }
 
        #endregion
    }
 
    public class MyPLineOverrule : DrawableOverrule
    {
        private const string OR_LAYER = "Overruled_PLine";
        private bool _overruling=false;
        private bool _oldOverruling=false;
 
        public MyPLineOverrule()
        {
            _overruling=false;
        }
 
        public bool OverruleOn
        {
            get { return _overruling; }
        }
 
        public void StartOverrule()
        {
            _overruling=true;
            _oldOverruling = Overrule.Overruling;
 
            Overrule.AddOverrule(RXObject.GetClass(
                typeof(Autodesk.AutoCAD.DatabaseServices.Polyline)), 
                this, false);
 
            //Set custom filter, so that code in overriden IsApplicable() 
            //will run to do the filtering
            this.SetCustomFilter();
 
            Overrule.Overruling=true;
 
            Application.DocumentManager.MdiActiveDocument.Editor.Regen();
        }
 
        public void StopOverrule()
        {
            _overruling = false;
 
            //Cause Overrule redraw the polyline to its original shape
            //before the overrule is stopped
            Application.DocumentManager.MdiActiveDocument.Editor.Regen();
 
            Overrule.RemoveOverrule(RXObject.GetClass(
                typeof(Autodesk.AutoCAD.DatabaseServices.Polyline)), this);
 
            Overrule.Overruling=_oldOverruling;
        }
 
        #region Override overrule methods
 
        public override bool  IsApplicable(RXObject overruledSubject)
        {
            //Only apply this overrule to polyline on layer "Overruled_PLine"
            Entity ent=overruledSubject as Entity;
            return ent.Layer.ToUpper() == OR_LAYER.ToUpper();
        }
 
        public override bool  WorldDraw(Drawable drawable, WorldDraw wd)
        {
            Autodesk.AutoCAD.DatabaseServices.Polyline pl = drawable
                as Autodesk.AutoCAD.DatabaseServices.Polyline;
 
            //If the polyline only has one segment, draw itself
            if (pl.NumberOfVertices < 3)
            {
                return base.WorldDraw(drawable, wd);
            }
 
            if (_overruling)
            {
                //Get polyline's vertices
                Point3d[] pts = new Point3d[pl.NumberOfVertices];
                for (int i = 0; i < pl.NumberOfVertices; i++)
                {
                    pts[i] = pl.GetPoint3dAt(i);
                }
 
                //Draw every other segement
                int n = 0;
                while (n < pts.Length)
                {
                    wd.Geometry.WorldLine(pts[n], pts[n + 1]);
                    n += 2;
                }
 
                return true;
            }
            else
            {
                return base.WorldDraw(drawable, wd);
            }
        }
 
        #endregion
    }
}

The code pretty much explains itself. To test the code, I started AutoCAD, created a layer named as "Overruled_PLine". Then I drew a few polylines on layer 0. After the code being "netload"ed, I can toggle MyPLineOverrule on/off. When it is on, move polyline to layer "Overruled_PLine" will make the segments of a polyline visible/invisible alternately.

The effect can be watched in this video clip.

Blog Archive

Labels

3D Modeling 3D Sketch Inventor AI Design AI in Manufacturing AI Tools Architecture Artificial Intelligence AutoCAD AutoCAD advice AutoCAD Basics AutoCAD Beginners AutoCAD Civil3D AutoCAD commands AutoCAD efficiency AutoCAD features AutoCAD File Management AutoCAD Layer AutoCAD learning AutoCAD print settings AutoCAD productivity AutoCAD Teaching AutoCAD Techniques AutoCAD tips AutoCAD training. AutoCAD tricks AutoCAD Tutorial AutoCAD workflow AutoCAD Xref Autodesk Autodesk 2025 Autodesk AI Tools Autodesk AutoCAD Autodesk Fusion 360 Autodesk Inventor Autodesk Inventor Frame Generator Autodesk Inventor iLogic Autodesk Recap Autodesk Revit Autodesk Software Autodesk Video Automation Automation Tutorial Basic Commands Basics Beginner Beginner Tips BIM BIM Implementation Block Editor ByLayer CAD comparison CAD Design CAD File Size Reduction CAD line thickness CAD Optimization CAD Productivity CAD software clean CAD file cleaning command Cloud Collaboration command abbreviations Construction Technology Contraints Create resizable blocks CTB STB Data Reference Data Shortcut design software Design Workflow Digital Design Digital Twin Drafting Standards Drawing Automation Dref Dynamic Block Dynamic Block AutoCAD Dynamic Blocks Dynamic doors Dynamic windows eco design editing commands energy efficiency Engineering Engineering Design Engineering Innovation Engineering Technology engineering tools Excel Express Tools External Reference Fast Structural Design Fusion 360 Generative Design green building Grips heavy CAD file Heavy CAD Files iLogic Industry 4.0 Insight Inventor API Inventor Drawing Template Inventor Frame Generator Inventor Graphics Issues Inventor IDW Inventor Tips Keyboard Shortcuts Learn AutoCAD Machine Learning in CAD maintenance command Management Manufacturing Innovation Metal Structure ObjectARX .NET API Organization OVERKILL OVERKILL AutoCAD Palette PDF Plot Style AutoCAD Practice Drawing Printing Quality professional printing Professional Tips PTC Creo PURGE PURGE AutoCAD ReCap reduce CAD file size Resizable Block Revit Revit Best Practices Revit Workflow Ribbon screen shortcut keys Shortcuts Siemens NX Sketch Small Firms Smart Block Smart Factory SolidWorks Steel Structure Design sustainability Sustainable Manufacturing toolbar Tutorial User Interface (UI) Workbook Workspace XLS Xref