I'm trying to find intersections between current drawing entities, and attached XREF entities.
So far I have made a function that enumerates all curve entities in the current drawing + XREF curve entities.
I'm using acedSSGet with :n and later acedSSNameX for iterating through nested entities, that is entities inside XREF.
So far so good, I got the objectIds, but when I try to call intersectWith, I get no intersection points, and intersectWith returns eOk.
This is my code, I do not know what else to try.
static void multi_select_nested_entity(AcDbObjectIdArray &iaElementsInXref) { // switch on the multi selection of nested entities setAllowDuplicateSelection(curDoc(), true); curDoc()->inputPointManager()->turnOnSubentityWindowSelection(); ads_name sset, eName; AcDbObjectId id; // in the mode "_:n" // if (RTNORM == acedSSGet(L"_:n", NULL, NULL, NULL, sset)) { std::set<AcDbObjectId> setIds; acutPrintf(L"\n"); long len = 0; acedSSLength(sset, &len); for (long i = 0; i < len; i++) { resbuf *rb = NULL; // ssnamex() returns all selected nested entities // if (RTNORM == acedSSNameX(&rb, sset, i)) { resbuf *rbWalk = rb; while (NULL != rbWalk) { if (RTENAME == rbWalk->restype) { eName[0] = rbWalk->resval.rlname[0]; eName[1] = rbWalk->resval.rlname[1]; if (Acad::eOk == acdbGetObjectId(id, eName)) { // acutPrintf(L"Entity %d: %x",i,id.asOldId()); AcDbEntity *pEnt; if (Acad::eOk ==acdbOpenObject(pEnt,id,AcDb::kForRead)) { if (pEnt->isKindOf(AcDbCurve::desc())) { acutPrintf(L"From XREF: (%s)\n", pEnt->isA()->name()); setIds.insert(id); } pEnt->close(); } else { acutPrintf(L"\nCouldn't open object"); } } //rbWalk = NULL; } //else { rbWalk = rbWalk->rbnext; } } acutRelRb(rb); } } acedSSFree(sset); set<AcDbObjectId>::iterator it; for (it = setIds.begin(); it != setIds.end(); ++it) { iaElementsInXref.append(*it); } } // swtich off setAllowDuplicateSelection(curDoc(), false); curDoc()->inputPointManager()->turnOffSubentityWindowSelection(); } // - ARSXTestXrefIntersect.test command (do not rename) static void ARSXTestXrefIntersecttest(void) { AcDbObjectIdArray iaElementsInXref; //find all entities multi_select_nested_entity(iaElementsInXref); for (int i=0; i < iaElementsInXref.length(); i++) { AcDbEntity *ptrEntA; if (acdbOpenAcDbEntity(ptrEntA, iaElementsInXref[i], AcDb::kForRead)==eOk) { for (int j = i + 1; j < iaElementsInXref.length(); j++) { AcDbEntity *ptrEntB; if (acdbOpenAcDbEntity(ptrEntB, iaElementsInXref[j], AcDb::kForRead)==eOk) { AcGePoint3dArray points; if (ptrEntA->intersectWith(ptrEntB, kOnBothOperands, points)==Acad::eOk) { for (int k=0; k < points.length(); k++) { //CARSCDraw::circle(points[k], k+1, AcGeVector3d(0,0,1)); acutPrintf(L"\nIntersection found at x=%.4f, y=%.4f", points[k].x, points[k].y); } } ptrEntB->close(); } } ptrEntA->close(); } } }
Solved! Go to Solution.
Solved by owenwengerd. Go to Solution.
Xref entities (actually any entities in a block) are transformed by a AcDbBlockReference entity before being displayed. If you want to calculate an intersection, you need to account for that transformation.
If you're not worried about performance, you may be able to use AcDbBlockReference::explode() to create transformed copies of the entities.