Author Topic: Find if objects are on top of each other (text, attributes)  (Read 9101 times)

0 Members and 1 Guest are viewing this topic.

T.Willey

  • Needs a day job
  • Posts: 5251
Find if objects are on top of each other (text, attributes)
« on: October 29, 2007, 06:50:30 PM »
I was trying to find a way to find what objects are on top of each other, so I went with the method
'BoundingBoxIntersectWith' to test two entities.  It looked like it worked, but upon more testing it doesn't do what I want.  Then I went with just the 'IntersectWith' method, but that doesn't work either.  I'm at a lose, as I can't use points because they don't always share a point.

Any help is appreciated.  Attached is a pic showing my problem; as it returns they do not intersect.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

LE

  • Guest
Re: Find if objects are on top of each other (text, attributes)
« Reply #1 on: October 29, 2007, 06:55:44 PM »
Tim;

Do not know if we can use from C# the ARX class AcDbMPolygon - in there you will find methods that work for what you are trying to implement.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #2 on: October 29, 2007, 06:57:47 PM »
Tim;

Do not know if we can use from C# the ARX class AcDbMPolygon - in there you will find methods that work for what you are trying to implement.
Not sure Luis.  Let me do some research, and get back to you.  Thanks.

Edit:  Looks like you can, now to just find out how to use it.  Thanks.
« Last Edit: October 29, 2007, 07:03:32 PM by T.Willey »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

LE

  • Guest
Re: Find if objects are on top of each other (text, attributes)
« Reply #3 on: October 29, 2007, 06:58:43 PM »
The other, there is one function I wrote in C# it is available in show your stuff to verify if a point is inside of a closed area, if you are looking to check for four points, then, it can be easy to adapt...

Let me check where is that - I'll be back

Here:

http://www.theswamp.org/index.php?topic=17222.msg209140#msg209140
« Last Edit: October 29, 2007, 07:01:06 PM by LE »

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #4 on: October 29, 2007, 07:37:56 PM »
The other, there is one function I wrote in C# it is available in show your stuff to verify if a point is inside of a closed area, if you are looking to check for four points, then, it can be easy to adapt...

Let me check where is that - I'll be back

Here:

http://www.theswamp.org/index.php?topic=17222.msg209140#msg209140
I just downloaded it, and was looking at the stuff you and Alexander Rivilis were doing here.  I think I will need more time, so I will put this off till tomorrow when I might... might be able to dig into it.  Thanks again Luis.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #5 on: October 30, 2007, 12:01:48 PM »
The only way I see how to use MPolygon is:
1: Get the bounding of the text object
2: Create 4 points (3d) from the points returned by step 1
3: Create 4 Vetex2d from the points in step 2
4: Create a Polyline2d from the vertexes in step 3 (not sure how yet since it wants ObjectId's to add a vertex, but I assume when you create a vertex it will create an ObjectId even if it isn't added to the database)
5: Create an MPolygon from the polyline in step 4
6: Repeat steps 1 and 2 while testing to see if they are inside of the MPolygon returned in step 5

Is this the correct way?  Or is there a shorter more concise method I'm missing?  Or an understanding I'm not understanding?

Thanks.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

LE

  • Guest
Re: Find if objects are on top of each other (text, attributes)
« Reply #6 on: October 30, 2007, 12:11:59 PM »
The only way I see how to use MPolygon is:
1: Get the bounding of the text object
2: Create 4 points (3d) from the points returned by step 1
3: Create 4 Vetex2d from the points in step 2
4: Create a Polyline2d from the vertexes in step 3 (not sure how yet since it wants ObjectId's to add a vertex, but I assume when you create a vertex it will create an ObjectId even if it isn't added to the database)
5: Create an MPolygon from the polyline in step 4
6: Repeat steps 1 and 2 while testing to see if they are inside of the MPolygon returned in step 5

Is this the correct way?  Or is there a shorter more concise method I'm missing?  Or an understanding I'm not understanding?

Thanks.

Tim;

I have done something similar in ObjectARX, if I had a chance today, I will try to write something -

This is in general what I do:

- Make a selection set of using a filter for Mtext/Text

- On each item make a crossing selection set again using a filter for Mtext/text - and before removing the item, so is not get selected in this new one. (many times I use the bounding box, but I calculate an smaller diagonal using both corner points - just to make sure only object that are in the area are selected)

- If there is a selection, then grab the two corner bounding points and use the point inside function, to test if they are inside of the main bounding box that you can have in ObjectARX as a temporary - without even needed to be drawn on the data base - I guess this can be done also in C#)

- If both points pass the test, then I can do something with that object.

It is making any sense?

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #7 on: October 30, 2007, 12:32:38 PM »
It is making any sense?
Yes, but I don't think I can use that method since I am looking at attributes also.  Unless you can select nested items with C#.  It kind of sounds like I have to do it the way I described, unless there is a way to create an MPolygon by using the two points of the object bounding box?  I will look into this option, as if it could be done this way it will mean less code.

Thanks Luis.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

LE

  • Guest
Re: Find if objects are on top of each other (text, attributes)
« Reply #8 on: October 30, 2007, 12:39:59 PM »
Yes, but I don't think I can use that method since I am looking at attributes also.  Unless you can select nested items with C#.  It kind of sounds like I have to do it the way I described, unless there is a way to create an MPolygon by using the two points of the object bounding box?  I will look into this option, as if it could be done this way it will mean less code.

Tim;

Means that they can be, placed blocks/with/attributes below or on top of each other?

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #9 on: October 30, 2007, 12:51:18 PM »
Yes, but I don't think I can use that method since I am looking at attributes also.  Unless you can select nested items with C#.  It kind of sounds like I have to do it the way I described, unless there is a way to create an MPolygon by using the two points of the object bounding box?  I will look into this option, as if it could be done this way it will mean less code.

Tim;

Means that they can be, placed blocks/with/attributes below or on top of each other?
Yup.  The drawing was done in Italy, and they put a bunch of text/attribute objects on top of each other for all the other languages.  I'm trying to find the one that is English, and put the others on a layer that is frozen.  I had it done mostly, but found some that were not doing it correctly, and found this to be the problem.

The code I have done so far is posted here.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #10 on: October 30, 2007, 01:39:40 PM »
Here is the code I was trying
Code: [Select]
public bool IsEntityWithin (Entity Ent1, Entity Ent2) {

Extents3d bbEnt1 = Ent1.GeomExtents;
Extents3d bbEnt2 = Ent2.GeomExtents;
Point3d tempPt1 = bbEnt1.MinPoint;
Point3d tempPt2 = bbEnt1.MaxPoint;
Point3d tempPt3 = bbEnt2.MinPoint;
Point3d tempPt4 = bbEnt2.MaxPoint;

Point3d Pt1 = new Point3d(tempPt2.X, tempPt1.Y, tempPt1.Z);
Point3d Pt2 = new Point3d(tempPt1.X, tempPt2.Y, tempPt1.Z);
Point3d Pt3 = new Point3d(tempPt4.X, tempPt3.Y, tempPt3.Z);
Point3d Pt4 = new Point3d(tempPt3.X, tempPt4.Y, tempPt3.Z);

Vertex2d V1 = new Vertex2d();
Vertex2d V2 = new Vertex2d();
Vertex2d V3 = new Vertex2d();
Vertex2d V4 = new Vertex2d();
V1.Position = tempPt1;
V2.Position = Pt1;
V3.Position = tempPt2;
V4.Position = Pt2;

Polyline2d tempPline = new Polyline2d();
tempPline.AppendVertex(V1);
tempPline.AppendVertex(V2);
tempPline.AppendVertex(V3);
tempPline.AppendVertex(V4);
tempPline.Closed = true;

MPolygon mpol = new MPolygon();
mpol.AppendLoopFromBoundary(tempPline, true, 0.01);

Point3dCollection tempPtCol = new Point3dCollection();
tempPtCol.Add(tempPt3);
tempPtCol.Add(tempPt4);
tempPtCol.Add(Pt3);
tempPtCol.Add(Pt4);

foreach(Point3d tempPt in tempPtCol) {
IntegerCollection tempIntCol = mpol.IsPointInsideMPolygon(tempPt, 0.0001);
if(tempIntCol.Count.Equals(1) && !tempIntCol.Contains(-1))
   return true;
}
return false;
}
It doesn't work, and this is the message
Quote
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Autodesk.AutoCAD.Runtime.Exception: eNoDatabase
   at Autodesk.AutoCAD.Runtime.Interop.ThrowExceptionForErrorStatus(Int32 errorStatus)
   at Autodesk.AutoCAD.DatabaseServices.Polyline2d.AppendVertex(Vertex2d vertexToAppend)
On the line that is trying to AppendVertex.  I tried to put it in a transaction, and add the vertex objects to the database, but that didn't work either.

I'm at a lose as to how to fix this, or get it to work another way.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #11 on: October 30, 2007, 02:52:40 PM »
Okay.  I got it to work for the most part, but one thing is holding me back now (from more testing).  This statement in the Arx help
Quote
Unimplemented at the AcDbEntity level, this method is intended to be overridden in derived classes.
Which is causing me problems since I'm using that property of the Entity type.  How can I get the true bounding box of my entities?
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #12 on: October 30, 2007, 03:14:43 PM »
Okay, here is how I did it, and it seems to work.
Found how to do it here, on the Adesk Ng.
Code: [Select]
public bool IsEntityWithin (Entity Ent1, Entity Ent2) {

        Document Doc = acadApp.DocumentManager.MdiActiveDocument;
        Database Db = Doc.Database;
        Point3d tempPt1;
        Point3d tempPt3;
    RXClass tempRxc1 = Ent1.GetRXClass();
    if (string.Compare(tempRxc1.DxfName, "TEXT").Equals(0)) {
    DBText tempText = Ent1 as DBText;
    tempPt1 = tempText.Position;
    }
    else {
    AttributeReference tempAttRef = Ent1 as AttributeReference;
    tempPt1 = tempAttRef.Position;
    }
    RXClass tempRxc2 = Ent2.GetRXClass();
    if (string.Compare(tempRxc2.DxfName, "TEXT").Equals(0)) {
    DBText tempText = Ent2 as DBText;
    tempPt3 = tempText.Position;
    }
    else {
    AttributeReference tempAttRef = Ent2 as AttributeReference;
    tempPt3 = tempAttRef.Position;
    }
        using (Transaction Trans = Db.TransactionManager.StartTransaction()) {
        Extents3d bbEnt1;
        Extents3d bbEnt2;
        try {
bbEnt1 = Ent1.GeomExtents;
bbEnt2 = Ent2.GeomExtents;
Point3d tempPt2 = bbEnt1.MaxPoint;
Point3d tempPt4 = bbEnt2.MaxPoint;

Point3d Pt1 = new Point3d(tempPt2.X, tempPt1.Y, tempPt1.Z);
Point3d Pt2 = new Point3d(tempPt1.X, tempPt2.Y, tempPt1.Z);
Point3d Pt3 = new Point3d(tempPt4.X, tempPt3.Y, tempPt3.Z);
Point3d Pt4 = new Point3d(tempPt3.X, tempPt4.Y, tempPt3.Z);

Point3dCollection PlinePts = new Point3dCollection();
PlinePts.Add(tempPt1);
PlinePts.Add(Pt1);
PlinePts.Add(tempPt2);
PlinePts.Add(Pt2);

DoubleCollection DblCol = new DoubleCollection();
DblCol.Add(0.0);
DblCol.Add(0.0);
DblCol.Add(0.0);
DblCol.Add(0.0);

Polyline2d tempPline = new Polyline2d(Poly2dType.SimplePoly, PlinePts, tempPt1.Z, true, 0.0, 0.0, DblCol);

        BlockTable bt = (BlockTable)Trans.GetObject(Db.BlockTableId, OpenMode.ForRead);
        BlockTableRecord btr = (BlockTableRecord)Trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
        btr.AppendEntity(tempPline);
Trans.AddNewlyCreatedDBObject(tempPline, true);
//Trans.Commit();

MPolygon mpol = new MPolygon();
mpol.AppendLoopFromBoundary(tempPline, true, 0.01);

Point3dCollection tempPtCol = new Point3dCollection();
tempPtCol.Add(tempPt3);
tempPtCol.Add(tempPt4);
tempPtCol.Add(Pt3);
tempPtCol.Add(Pt4);

foreach(Point3d tempPt in tempPtCol) {
IntegerCollection tempIntCol = mpol.IsPointInsideMPolygon(tempPt, 0.0001);
if(tempIntCol.Count.Equals(1) && !tempIntCol.Contains(-1))
    return true;
}
}
        catch {}
        }
return false;
}
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

LE

  • Guest
Re: Find if objects are on top of each other (text, attributes)
« Reply #13 on: October 30, 2007, 03:50:34 PM »
Tim;

Means you have the routine working, then?

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #14 on: October 30, 2007, 03:58:31 PM »
Tim;

Means you have the routine working, then?
Yup. Now I just need to tweak it so it will run faster.  I have done some, but still more can be done to speed it up.

Thanks for your help Luis.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

LE

  • Guest
Re: Find if objects are on top of each other (text, attributes)
« Reply #15 on: October 30, 2007, 07:05:57 PM »
Yup. Now I just need to tweak it so it will run faster.  I have done some, but still more can be done to speed it up.

:)

MickD

  • King Gator
  • Posts: 3637
  • (x-in)->[process]->(y-out) ... simples!
Re: Find if objects are on top of each other (text, attributes)
« Reply #16 on: October 30, 2007, 07:12:21 PM »
Another way might be to create a region out of each bbox, do a boolean intersection on them and see if a result is returned (the result if they overlap). If an error is returned it there is probably no intersection (or check error code to be sure). If you do get something returned you could also grab its bbox if required.
Just a thought...

edit: this will only work in 2d on the same plane of course.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Find if objects are on top of each other (text, attributes)
« Reply #17 on: October 30, 2007, 07:29:41 PM »
Another way might be to create a region out of each bbox, do a boolean intersection on them and see if a result is returned (the result if they overlap). If an error is returned it there is probably no intersection (or check error code to be sure). If you do get something returned you could also grab its bbox if required.
Just a thought...

edit: this will only work in 2d on the same plane of course.
The problem was trying to get the bbox.  It would not return the correct bbox, so I found a way to do it, but it doesn't work quite right either.  If you have letters that hang below the imaginary line it does not reflect that, but it works for what I need.  Mine only works for one plane now, at least I think it only works for one plane, and that is good enough for what I need.  Thanks for the idea.  I love seeing more than one way to solve a problem.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.