Can I do normal window selection without the TypedValue, DXFCode crap?

Can I do normal window selection without the TypedValue, DXFCode crap?

vroom74
Participant Participant
1,112 Views
8 Replies
Message 1 of 9

Can I do normal window selection without the TypedValue, DXFCode crap?

vroom74
Participant
Participant

Hi Guys!

 

I'm tryiing to do a little application and for that I would like to make a normal window selection (the green/blue type) and get different object types from this selection.

 

So windowing on lot of objects and get only blocks or lines (for example lines, 2dpolys and 3d polys together) and etc. This is what a want.

 

I'm not an expert, I found a dxf code way, here it is, This is working, but I would have a more elegant way.

 

public static ObjectIdCollection promptForPointsByWindow()
        {
            //actual ACAD doc and editor
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            //Az Editor beállítása
            Editor acEd = acDoc.Editor;

            //defining the object filter
            TypedValue[] TypVal = new TypedValue[1];
            TypVal.SetValue(new TypedValue((int)DxfCode.Start, "POINT"), 0);

            // filter to the selset
            SelectionFilter SelFilt = new SelectionFilter(TypVal);

            //user input get selection
            PromptSelectionResult pSelRes = acEd.GetSelection(SelFilt);

            SelectionSet selSet = pSelRes.Value;

             ObjectIdCollection points = new ObjectIdCollection(selSet.GetObjectIds());

            //write out count()
            Application.ShowAlertDialog("A kiválasztott pontok száma: " + selSet.Count.ToString());

            return points;

        }

Do you have a normal easy way to do it? Like AllowedTypes = .....

 

 THX

0 Likes
Accepted solutions (1)
1,113 Views
8 Replies
Replies (8)
Message 2 of 9

_gile
Consultant
Consultant
Accepted solution

Hi,

 

This is the way selection filters work and it's not crap because it allows much more than only fiter by entity type.

You can see an example and some explanations in this thread.

 

Another way should be handling the Editor.SelectionAdded event.

Here's an exemple to filter measurable curves as in the upper example (arc, circle, ellipse, polyline (2d or 3d) and splines).

 

            var allowed = new HashSet<string>
            {
                "AcDbArc",
                "AcDbCircle",
                "AcDbEllipse",
                "AcDbLine",
                "AcDbPolyline",
                "AcDb2dPolyline",
                "AcDb3dPolyline",
                "AcDbSpline"
            };

            SelectionAddedEventHandler filter = (_, e) =>
            {
                var objs = e.AddedObjects;
                for (int i = 0; i < objs.Count; i++)
                {
                    if (!allowed.Contains(objs[i].ObjectId.ObjectClass.Name))
                        e.Remove(i);
                }
            };

            ed.SelectionAdded += filter;
            var selection = ed.GetSelection();
            ed.SelectionAdded -= filter;


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 9

vroom74
Participant
Participant

Thank you for you quick answer. Its working. 😄

 

Finally, I accepted the dxfCode way based on your TotalLengthOfSelectedObjects solution, but I'll try event based method.

 

I'm a really beginner at programming, Sometimes i found autocad.net system very complicated and not logical (for me) 😉

 

BIG THANK YOU AGAIN

0 Likes
Message 4 of 9

5thSth
Advocate
Advocate

you can try force casting it like this;

Lets say you want to catch polyline;


foreach (entity ent in selection)

{

   Polyline poly = ent as Polyline;
   if (poly != 0)

   {

      do something.... (in your case add to new selection set)

   }

 

}

 

you can then create your own selection set based on your criteria.

0 Likes
Message 5 of 9

_gile
Consultant
Consultant

@5thSth,

 

This won't work:

if (poly != 0)

It should have been:

if (poly != null)

 

Anyway, it's much more efficient to test the ObjectId.ObjectClass before opening the ObjectId:

 

If (id.ObjectClass == RXObject.GetClass(typeof(Polyline)))
{
    var poly = (Polyline)tr.GetObject (id, OpenMode.ForRead);
    // do something with the polyline
}

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 9

ActivistInvestor
Mentor
Mentor
Hi _gile.

Your example that uses an equality comparison is somewhat different from using the C# 'as' operator on the managed wrapper, which will succeed with derived types as well. To do the equivalent with RXClass you would use the IsDerivedFrom() member.

Of course, it all depends on if you want to include derived types or not.
0 Likes
Message 7 of 9

_gile
Consultant
Consultant

@ActivistInvestor,

 

You are right, to mimic the selection filter, I should have written:

if (id.ObjectClass.DxfName == "LWPOLYLINE")

which also filters any custom entities that are derived from Polyline.

 

 

But, in my opinion, the main difference (and this is what I wanted to point out) is that testing the ObjectId type avoids opening the DBObject if it is not of the required type.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 8 of 9

ActivistInvestor
Mentor
Mentor
@_gile,

Yes, and IsDerivedFrom() also doesn't need a managed wrapper. It also has an additional benefit of being able to match derived custom objects that don't have managed wrappers, which the C# 'as' operator will not match.
Message 9 of 9

5thSth
Advocate
Advocate

thanks @_gile for the RXObject approach. so far took it for granted.

 

you and Kean have been priceless for me when it comes to learning .net and c#.

0 Likes