Ignore objects in a selection set based on coordinates
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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();
}
}
}
}