.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Ignore objects in a selection set based on coordinates

2 REPLIES 2
Reply
Message 1 of 3
vince1327
629 Views, 2 Replies

Ignore objects in a selection set based on coordinates

Hey Everyone,

 

I'm working on a command that lets me select polylines on a specific layer, then converts them to 3d solids. I'm having a slight issue where if a polyline has the same start and end coordinates (this happens in some of our drawings), then the command stops and I get an eDegenerateGeometry error. I want to modify my command so that it detects these objects, removes them from the selection set, and then notifies the users of their prescence so they can be removed manually. The last part i think I can handle, however I'm not sure how to modify either my filter or my routine to detect and ignore these objects. I'm assuming that since i'll want to record these objects to later notify the user, that i'd probably want to modify my routine. Any pointers or examples would be greatly appreciated. 

 

Cheers

Vince

 

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DataExtraction;
using Autodesk.AutoCAD.Colors;
using System.Windows.Forms;

namespace Convert3D
{

    public class Convert3D
    {
        [CommandMethod("test3d")]
        public void test()
        {
            
           
           
            // Go to if layer name doesn't exist
            Step1:

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            string sreslayer = "";
           
            
            ////////////////////////////////////////////////////////////////////////////////
            ////////////////////////// Get layer by selection //////////////////////////////
           
            Transaction trans = db.TransactionManager.StartTransaction();
            using (trans)
            {
                PromptSelectionOptions sopts = new PromptSelectionOptions();
                sopts.MessageForAdding = "Select an object on the layer you would like to modify";
                PromptSelectionResult layerres = doc.Editor.GetSelection(sopts);

                if (layerres.Status == PromptStatus.OK)
                {
                    foreach (ObjectId id in layerres.Value.GetObjectIds())
                    {
                        Entity acadent = (Entity)trans.GetObject(id, OpenMode.ForRead);

                        sreslayer = acadent.Layer;

                        ed.WriteMessage("The layer you have selected is " + sreslayer);
                    }

                }
            /////////////////////////////////////////////////////////////////////////////




                // This time we do check whether the layer exists

                LayerTable lt = (LayerTable)trans.GetObject(db.LayerTableId, OpenMode.ForRead);

                if (!lt.Has(sreslayer))
                {
                    ed.WriteMessage("\nLayer not found.");
                    ed.WriteMessage("\nTry Again.");
                    //If layername doesn't exist, re-run the command
                    goto Step1;
                }
              
            }
                    // Limits selection by layer and object type 
                    SelectionFilter filt = new SelectionFilter(new TypedValue[]{
                    new TypedValue(8,sreslayer), new TypedValue(0,"polyline")});
                


                    PromptSelectionResult res = ed.GetSelection(filt);
                    if (res.Status != PromptStatus.OK) return;
                    SelectionSet sset = res.Value;
                    Entity ent;


                    PromptDoubleOptions pdouble = new PromptDoubleOptions("\nEnter new diameter of pipe: ");
                    pdouble.AllowNegative = false;
                    pdouble.AllowZero = false;
                    PromptDoubleResult pres = ed.GetDouble(pdouble);

                    // radius of cylinder
                    double rad = pres.Value;


                    using (Transaction tr = doc.TransactionManager.StartTransaction())
                    {
                        //////////////////////////////////////////////////////////////////////////
                        //////////////////Creates a new 3d layer for the 3d solids///////////////
                        LayerTable acLyrTbl1 = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
                        LayerTableRecord acLyrTblRec = new LayerTableRecord();
                        // Check if the layer exists, if not create it, if so, continue on
                        if (acLyrTbl1.Has(sreslayer+"-3D") == true)
                        {
                            goto Step2;
                        }
                        if (acLyrTbl1.Has(sreslayer) == true)
                        {
                            // Assign the layer a name
                            acLyrTblRec.Name = sreslayer+"-3D";
                            acLyrTbl1.UpgradeOpen();
                            

                            // Append the new layer to the Layer table and the transaction
                            acLyrTbl1.Add(acLyrTblRec);
                            tr.AddNewlyCreatedDBObject(acLyrTblRec, true);
                        }

                        ///////////////////////////////////////////////////////////////////////////
                        Step2:

                        BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                        foreach (SelectedObject obj in sset)
                            
                        {
                            ent = tr.GetObject(obj.ObjectId, OpenMode.ForRead) as Entity;
                            if (ent == null)
                                return;
                            Polyline3d poly = ent as Polyline3d;
                            if (poly == null) return;
                            Point3d p1 = poly.GetPointAtParameter(poly.StartParam);
                            Point3d p2 = poly.GetPointAtParameter(poly.StartParam + 1.0);
                            Vector3d vec = (p2 - p1).GetNormal();
                            double height = p1.DistanceTo(p2);
                            Circle circ = new Circle(p1, vec, rad);

                            circ.Normal = vec;

                            ObjectId objId = btr.AppendEntity(circ);
                            // Set the layer in which to create the 3d solids
                            circ.Layer = sreslayer+"-3D";
                            tr.AddNewlyCreatedDBObject(circ, true);

                            // Get the boundary curves to create a region
                            DBObjectCollection regs = new DBObjectCollection();
                            regs.Add(circ);

                            // Create a region from the circle.


                            DBObjectCollection regions = new DBObjectCollection();
                            regions = Region.CreateFromCurves(regs);
                            if (regions.Count == 0)
                            {
                                ed.WriteMessage("\nFailed to create region\n");
                                return;
                            }
                            Region reg = (Region)regions[0];

                            // Extrude the region to create a solid.

                            Solid3d sol = new Solid3d();
                            sol.Layer = sreslayer + "-3D";
                            sol.RecordHistory = true;// optional
                            sol.ShowHistory = false;// optional
                            sol.ExtrudeAlongPath(reg, poly as Curve, 0.0);
                            ObjectId solId = ObjectId.Null;
                            solId = btr.AppendEntity(sol);
                            tr.AddNewlyCreatedDBObject(sol, true);

                            if (!circ.IsWriteEnabled) circ.UpgradeOpen();

                            circ.Erase();

                        }
                        tr.Commit();
                    
                    }

                }
            }
        }
    

 

2 REPLIES 2
Message 2 of 3
_gile
in reply to: vince1327

Hi,

 

You can use the Editor.SelectionAdded event to filter during the selection.

 

        [CommandMethod("Test", CommandFlags.Modal)]
        public void Test()
        {
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TypedValue[] filter = { new TypedValue(0, "LWPOLYLINE") };
                ed.SelectionAdded += ed_SelectionAdded;
                PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter));
                ed.SelectionAdded -= ed_SelectionAdded;
                if (psr.Status != PromptStatus.OK) return;
                ed.SetImpliedSelection(psr.Value);
                tr.Commit();
            }
        }

        void ed_SelectionAdded(object sender, SelectionAddedEventArgs e)
        {
            ObjectId[] ids = e.AddedObjects.GetObjectIds();
            for (int i = 0; i < ids.Length; i++)
            {
                using (Polyline pline = (Polyline)ids[i].Open(OpenMode.ForRead))
                {
                    if (pline.GetPoint2dAt(0).IsEqualTo(pline.GetPoint2dAt(pline.NumberOfVertices - 1)))
                        e.Remove(i);
                }
            }
        }

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 3
vince1327
in reply to: vince1327

Thanks for the example Gilles, I'll give it a shot

 

 

Is there any way that I can address this issue with an "if" statement here:

 

BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                       
foreach (SelectedObject obj in sset) {


Thanks Again
Vince

 

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost