Let us look at a cool AutoCAD .NET coding gadget in this post. It uses the cool .NET Extension Method and the LINQ technology to filter out some AutoCAD entities from a selection set with a pretty complex filtering criteria, e.g. finding all circles with red or yellow color, with DASHED or DOT line type, on a unfrozen layer TEST, and having radiuses between 2.0 and 6.0 unit.
With the wonderful .NET LINQ technology handy, we do not have to care about all those unfriendly legacy stuffs such as TypedValue, DxfCode and SelectionFilter anymore. We can make the same work done more nicely, naturally and efficiently with less code in a single loop using the LINQ technology. And exactly the same code can apply to different AutoCAD Entity collections such as from Database, which case we have demonstrated before, and SelectionSet, which case we are going to demonstrate here.
Here we go.
private delegate bool InRange(double d);
[CommandMethod("TestLinqInAcadSelection")]
public static void TestLinqInAcadSelection_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
try
{
ObjectId[] ids = new ObjectId[0];
InRange inRange2to6 = r => { return r >= 2.0 && r <= 6.0; };
PromptSelectionResult selRes = ed.GetSelection();
if (selRes.Status == PromptStatus.OK)
{
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
var v = from ObjectId id in selRes.Value.GetObjectIds()
where GetEnt(tr, id) is Circle &&
(new int[] { 1, 3 }.Contains(tr.GetEnt(id).ColorIndex)) && //Color Red or Yellow
tr.GetEnt(id).Layer == "TEST" && //Layer 'TEST'
!(tr.GetObject(tr.GetEnt(id).LayerId, OpenMode.ForRead) as LayerTableRecord).IsFrozen && //Layer not frozen
(new string[] { "DASHED", "DOT" }.Contains(tr.GetEnt(id).Linetype)) && //Linetype Dashed or Dotted
inRange2to6((tr.GetEnt(id) as Circle).Radius) //Circle radius in the range [2.0, 6.0]
select id;
ids = v.ToArray();
tr.Commit();
}
}
ed.WriteMessage(string.Format("\nThere are {0} circles meeting the filtering criteria.", ids.Length));
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
Here is the .NET Extension Method to the AutoCAD .NET Transaction class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Windows;
namespace AcadNetAddinWizard_Namespace
{
public static class ExtensionMethods
{
private static Entity cachedEntity = null;
private static ObjectId cachedEntId = ObjectId.Null;
public static Entity GetEnt(this Transaction tr, ObjectId id)
{
if (cachedEntId != id || cachedEntity == null)
cachedEntity = tr.GetObject(id, OpenMode.ForRead) as Entity;
return cachedEntity;
}
}
}
Besides the cool LINQ and Extension Method technology, as can be seen, a few other wonderful modern .NET technologies have also been demonstrated such as LINQ, Lambda Expression and Delegate. Better, all these are not just for new thing show-off. Instead, each cool tech applied here has its own very reason!
In case some entities are selected and there are some circles meeting the filtering criteria in the returned selection set, the command may print out something onto the AutoCAD command line window as follows:
Command: TestLinqInAcadSelection
Select objects: Specify opposite corner: 268 found
Select objects:
There are 22 circles meeting the filtering criteria.
Enjoy it! More coding gadgets will be created and demonstrated in the future. Please stay tuned.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides various project wizards, item wizards, coders and widgets to help program AutoCAD .NET addins.
Posted by: |