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

How to select entities in a fence-type selection?

15 REPLIES 15
Reply
Message 1 of 16
Sinc
2969 Views, 15 Replies

How to select entities in a fence-type selection?

I would like to select all entities that cross a 3D-Polyline, in order from start of the 3D-Polyline to the end.

I walked the 3D-Polyline and collected all its vertex locations into a Point3DCollection, and then used this as an argument to Editor.SelectFence(), but I am not getting the desired results.

There are two problems with Editor.SelectFence() that make it useless:

1) Entities must be visible on-screen in order to be selected.
2) Entities that do not have continuous linetypes are not selected if the crossing point is in a "gap" in the linetype.

Is there any way around these issues? For example, a version of Editor.SelectFence() that works directly on the DB rather than on the objects that are currently visible on-screen?
Sinc
15 REPLIES 15
Message 2 of 16
Anonymous
in reply to: Sinc

Why not using a crossing selection from the start & end points and add the objects that intersect your path object to a new selection set.
Message 3 of 16
Sinc
in reply to: Sinc

The order of objects is important, and a Fence selection does exactly what I want, except for the problems I mentioned.

Using a crossing selection that goes from start point to end point of my entity would potentially select many more things, and would also lose the selection order.

In this particular case, I've discovered that if I zoom the screen so that the entire polyline is visible, then I can get around the first problem. And as it turns out, this actually ends up being a convenient addition to the routine I am working on. So that part works out.

As for the inability to select items that do not have continuous linetypes, that is a bug that has always existed for Autocad fence selections. And after all this time, I'm guessing there is little hope of ever seeing it fixed. But in this particular case, it probably doesn't matter too much.

Net result is I think I've gotten the Fence selection to work "well enough" for the purpose at-hand.
Sinc
Message 4 of 16
cadMeUp
in reply to: Sinc

Is the 3D-Polyline that you are using rectangular or non-rectangular?

You may want to try using editor.SelectCrossingPolygon().
That should be able to select any 'off screen' ent's plus if the crossing cuts through the gap in a line
without a solid line type.

Have you tried playing with the different options using the AutoCAD command 'SELECT'?
You might be able to find the best option that way. It seems using the 'CPolygon' option,
which I believe relates to the 'SelectCrossingPolygon' method, would be the best choice in this case.

I think most of AutoCAD's selection methods will not select entities that are moved (panned off screen)
while in selection mode:
>> In this particular case, I've discovered that if I zoom the screen so that the entire polyline is visible,
>> then I can get around the first problem

One exception of course would be the 'SelectAll' method which does exactly as stated.
But I also find some other exceptions to this like the 'SELECT' command's 'CPolygon' option.
Message 5 of 16
Anonymous
in reply to: Sinc

I'm afraid all of those suggestions lead to the
same outcome, for the same reason.

Fence/Window/Polygon selection is done against
display primitives in the DCS, and is accurate only
to a single display coordinate.

That means objects that don't actually intersect
the fence/polygon may still be selected when
zoomed out far enough, because their geometry
converges on the same display coordinate as the
magnification decreases. IOW, if you zoom out
far enough, every object in the current space can
be within a single display pixel.

So, zooming out can select things that actually
don't intersect the selection geometry, and
zooming in can result in objects being outside of
the view and unselectable. And, there is the still
problem of non-continuous linetypes, which none
of these methods can mitigate.

Without access to the display information AutoCAD
uses to do selection (would be nice, but I doubt it
will ever happen), the only way to be completely
accurate is through analytical methods that operate
on projections of the objects in the DCS. If all of
the objects are in the same plane along with the
selection geometry then it becomes a little easier,
but I don't know if that's the case here or not.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5780498@discussion.autodesk.com...
Is the 3D-Polyline that you are using rectangular or non-rectangular?

You may want to try using editor.SelectCrossingPolygon().
That should be able to select any 'off screen' ent's plus if the crossing cuts through the gap in a line
without a solid line type.

Have you tried playing with the different options using the AutoCAD command 'SELECT'?
You might be able to find the best option that way. It seems using the 'CPolygon' option,
which I believe relates to the 'SelectCrossingPolygon' method, would be the best choice in this case.

I think most of AutoCAD's selection methods will not select entities that are moved (panned off screen)
while in selection mode:
>> In this particular case, I've discovered that if I zoom the screen so that the entire polyline is visible,
>> then I can get around the first problem

One exception of course would be the 'SelectAll' method which does exactly as stated.
But I also find some other exceptions to this like the 'SELECT' command's 'CPolygon' option.
Message 6 of 16
Anonymous
in reply to: Sinc

Here is one function I ported from ARX to C# from my library

See if helps.

Steps:
1. Open the attached drawing (or yours).
2. For this test, make a selection set of the path object.
3. Zoom Out as far as possible.
4. Call the command GETORDER and use the 'P' previous selection.
4. Zoom Extents.

The function, will select only the objects that cross the path, for the test these objects are change in color, and returns a list of dist-points & dist-entity[id].

[code]
static public void getEntitiesInOrder(string sObjCurve)
{
Database db = HostApplicationServices.WorkingDatabase;
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Point3dCollection ints = new Point3dCollection();
Point3dCollection points = new Point3dCollection();
SortedList distpoint = new SortedList();
SortedList distid = new SortedList();
TypedValue[] filterValue; SelectionFilter filter; PromptSelectionResult res;
filterValue = new TypedValue[1] { new TypedValue((int)DxfCode.Start, sObjCurve) };
filter = new SelectionFilter(filterValue);
res = ed.GetSelection(filter);

if (res.Status == PromptStatus.OK && res.Value.Count > 0)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
foreach (ObjectId id in res.Value.GetObjectIds())
{
Curve pPoly = tr.GetObject(id, OpenMode.ForRead, false) as Curve;
if (pPoly is Curve)
{
Point3d p0, p1;
p0 = pPoly.StartPoint;
p1 = pPoly.EndPoint;
Extents3d ebox = pPoly.GeometricExtents;
Point3d ll, ur;
ll = ebox.MinPoint;
ur = ebox.MaxPoint;
// select the crossing objects
filterValue = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LINE,ARC,LWPOLYLINE,POLYLINE,CIRCLE") };
filter = new SelectionFilter(filterValue);
res = ed.SelectCrossingWindow(ll, ur, filter);
if (res.Status == PromptStatus.OK && res.Value.Count > 0)
{
foreach (ObjectId ident in res.Value.GetObjectIds())
{
if (ident.Equals(id)) continue; //ignore the path object

Entity pEnt = tr.GetObject(ident, OpenMode.ForRead, false) as Entity;
if (pEnt is Entity)
{
pPoly.IntersectWith(pEnt, Intersect.OnBothOperands, ints, 0, 0);
if (ints.Count > 0)
{
for (int i = 0; i < ints.Count; i++)
{
if (!points.Contains(ints))
{
points.Add(ints);

// save distance and objectid of object that cross the path object
distid.Add(pPoly.GetDistAtPoint(ints), pEnt.ObjectId);
}
}
}
}
}
}
// we have some points to play with...
if (points.Count > 0)
{
points.Add(p0); // add the start and end points
points.Add(p1); // the sort is based using the starting point inside the sortedlist!

double dist;
for (int i = 0; i < points.Count; i++)
{
Point3d pt = points;
dist = pPoly.GetDistAtPoint(pt);
distpoint.Add(dist, pt); // do the sorting
}

ed.WriteMessage("\nDistance and Points: ");

foreach (KeyValuePair kvp in distpoint)
{
ed.WriteMessage("\nDistance = {0}, Point = {1}", kvp.Key, kvp.Value);
}

ed.WriteMessage("\nDistance and Entities: ");

int c = 1; //color test
foreach (KeyValuePair kvp in distid)
{
ed.WriteMessage("\nDistance = {0}, Entity = {1}", kvp.Key, kvp.Value.ToString());

Entity ent = tr.GetObject(kvp.Value, OpenMode.ForWrite, false) as Entity;
ent.ColorIndex = c; //color test

c++;
}
}//if points
}//if pPoly
}//foreach id
tr.Commit();
}
}
//cleaning...
ints.Clear();
points.Clear();
distpoint.Clear();
}

[CommandMethod("GETORDER")]
static public void testentsinorder()
{
getEntitiesInOrder("LINE"); //test with lines
}
[/code]

Output:

Distance and Points:
Distance = 0, Point = (21.5574468973974,16.2295411999676,0)
Distance = 14.1908675942083, Point = (34.1415805878428,22.7885275802971,0)
Distance = 38.7289809015161, Point = (55.9014128405577,34.1299871431571,0)
Distance = 50.2813723728079, Point = (66.1458068322563,39.4694759247564,0)
Distance and Entities:
Distance = 14.1908675942083, Entity = (2130264224)
Distance = 38.7289809015161, Entity = (2130264216)
Message 7 of 16
Anonymous
in reply to: Sinc

Here is the code again as HTML - the previous one does not display right...
Message 8 of 16
Sinc
in reply to: Sinc

Thanks Luis.

I had been thinking along similar lines. Unfortunately, while SelectCrossingWindow does not have the problem with linetypes that are not continuous, it has the same problem with visibility, i.e. if the objects are not visible on the screen they will not be selected. Same thing with SelectCrossingPolygon.

However, by adding some code that zooms the screen to the extents of the Polyline bounding box, then do something like in your code, then do a ZoomPrevious to return the display to the way the user had it, I think I have a winner. Pretty complicated and roundabout, but it works.

I think it may be time for Autodesk to revisit their selection algorithms. Once upon a time, it was doubtless a lot faster to select objects using the on-screen graphics. But these days, computers have gotten so much faster that I can't see it yielding any benefits anymore. It would be nice if Autodesk went back and fixed ALL their selection routines, so they no longer use the on-screen graphics for the selection, and no longer suffer from these issues.
Sinc
Message 9 of 16
Anonymous
in reply to: Sinc

You are welcome.

What is your routine doing? or for - why it is required to select objects that are not on the screen.
Message 10 of 16
Anonymous
in reply to: Sinc

>> I think it may be time for Autodesk to revisit their selection algorithms. Once upon a time, it was doubtless a lot faster to select objects using the on-screen graphics. But these days, computers have gotten so much faster that I can't see it yielding any benefits anymore. It would be nice if Autodesk went back and fixed ALL their selection routines, so they no longer use the on-screen graphics for the selection, and no longer suffer from these issues. <<

Sorry, have to disagree.

Once upon a time, there were no ACIS objects; true type text; regions; splines and various other 'complex' objects for which finding intersections is non-trivial and in some cases complicated.

Have you ever noticed how sluggish object selection/object snap can be in a large file with a lot of truetype text? The reason for that, is because AutoCAD handles selection of truetype text in ways that are similar to the way you are suggesting it should handle selection of everything (e.g., analytically).

Finding the intersections with display geometry vectors is trivial compared to doing it analytically, but even with that it can still take long, and that's why AutoCAD uses spatial indexing (oct-tree/quad-tree) of the display geometry.
Spatial indexing helps minimize the amount of display geometry that must be searched during object selection/osnap, and what makes it effective is that it allows AutoCAD to limit the search to only areas within the extents of a user specified region.

If you need to do that sort of thing, build a filtered selection containing only objects of elegible types and from that, reject those whose extents do not fall within the extents of your selection geometry. Finally, test what's left for intersections with the fence. I have code that does similar things in 50MB+ municipal utility map DWGs, with no significant performance issues.

It's difficult to sanction or advocate something that would penalize every end user only to make things a little easier for me, or any developer or script writer. That's kinda like the cart pulling the horse.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com
Message 11 of 16
dgorsman
in reply to: Sinc

Revisting the selection algorithms may not be the best thing to do. Remember, not everybody is running state-of-the-art hardware. In this case, "good enough" is good enough.
----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 12 of 16
cadMeUp
in reply to: Sinc

I am just curious about this, the entities that are within the selection area that you want to get, are they typically the same or can the selection be expected to contain different entities each time?
Message 13 of 16
Sinc
in reply to: Sinc

I'm not sure I completely buy that.

Witness the Crossing Window selection. This selection type actually appears to work on the drawing database - at least, it does not suffer the limitation that objects must be visible on-screen in order to be selected. And it selects items very quickly. After going into a good-sized C3D drawing (6MB) with a lot of objects, and doing a very large Crossing Polygon selection with lots of jogs, I still get an nearly-instantaneous response, even on rather old hardware (Athlon64 4000+ with old PC3200 DDR RAM).

The only weird part about Crossing Polygon is that each course of the polygon must be completely visible on-screen while selecting points. In other words, as I select each point of the Crossing Polygon, the point immediately preceding it must also be visible on-screen. All other points may be off-screen, but the one immediately preceding the current selection MUST be visible, or the polygon is drawn incorrectly. Then for the actual selection, it does not matter if objects are on-screen or not - everything inside the polygon is selected.

So, since it's so fast for something even more-complicated than a Fence selection, I still don't understand why Fence selection cannot be "fixed". Also, in my own (with help from Luis) exploration, it seems possible to create a user-created Fence selection routine that also has extremely adequate performance, even through the API. So again, I really don't see why this can't be "fixed".

And even if it should turn out that graphics primitives MUST be used, I'm also wondering if there might be a way to use transparency to get around the problem. In other words, instead of using a line that is broken into pieces for a hidden linetype, would it be possible to display this as a line that alternated between 0% and 100% transparency. Except, can display primitives that are 100% transparent still be selected? And would it even be feasible to display a line as an object that alternates between 0% and 100% transparency?

In any case, even if the overall UI is not fixed, it seems like it would be VERY possible to add an analytical SelectFence method to the Database. This would give a working option to API programmers. But like I said, I'm not convinced that this is something that can't be fixed for the product at large.
Sinc
Message 14 of 16
Sinc
in reply to: Sinc

The general issue arises when the user is being very-selective about items being picked.

When items are tightly-spaced, and the user needs a lot of precision when picking the point, it is common to zoom in to the area in-question. However, if you zoom in too far, so that the previous point you picked is no longer on-screen, the Fence selection gets messed up.

And it is very easy for the beginning of the Fence to end up off-screen by the time the user hits the end. If this happens, the user must zoom back out before finishing the selection, because any items that are off-screen will not be selected, even if they are crossed by the Fence.
Sinc
Message 15 of 16
Anonymous
in reply to: Sinc

>> The only weird part about Crossing Polygon is that each course of the polygon must be completely visible on-screen while selecting points.<<

Right, that's because it analyzes the display geometry while the segment is visible so that you can pan and zoom while selecting, but that doesn't change the fact that it still operates on display geometry, and hence, is only precise to a single pixel at the magnification that was current when the segement was visible.

>> So, since it's so fast for something even more-complicated than a Fence selection, I still don't understand why Fence selection cannot be "fixed". Also, in my own (with help from Luis) exploration, it seems possible to create a user-created Fence selection routine that also has extremely adequate performance, even through the API. So again, I really don't see why this can't be "fixed". <<

Because it's not broken?

You're confusing two different things. Object selection is not the same as 2D/3D interference detection; point/boundry classification; and boundary/boundary classification, at full floating-point precision.

The difficulty of doing any of the latter three depends largely on the nature of the objects involved, and as mentioned previously, it can be extremely complicated for something like a composite 3D ASCI solid, body or surface.

You're looking at the issue from only one perspective, a relatively simple one where you're dealing mostly with curves and curve-type objects, but not considering the implications on other types of applications that can involve large amounts of different, and far more complex object types.


--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com
Message 16 of 16
Sinc
in reply to: Sinc

>> Because it's not broken?

That's pretty subjective.

Fence selections do not work the way the user wants them to work. When attempting to select a bunch of lines using a Fence selection, the user does not want the selection to fail to get objects simply because it hits a gap in a custom linetype.

This may be a logical artifact of the decision to use graphic primitives for selection, but it still results in a product that doesn't work in the desired fashion. That's "broken" in my book, no matter how logical it is.

And it still seems like there should be some way to solve the problem. I'm still not convinced that it is an impossible problem to solve.

But I suppose there are a lot of other more-pressing issues... This bug has been around for so long that people are used to it. Just like the one where arcs have no inherent direction, which becomes very noticeable with custom linetypes. I don't expect to ever see that one fixed.
Sinc

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