|
[code] // Draw a red polyline by the given points etc. //-------------------------------------------------- static BOOL drawAPlineWithPropertiesFromBlockRef(AcGePoint2dArray pts, AcDbBlockReference* ref, double elevation, AcGeVector3d& normal) { AcDbPolyline *pl = new AcDbPolyline; AcDbObjectId owner; pl->setDatabaseDefaults(); pl->setClosed(Adesk::kTrue); pl->setThickness(0.0); if (ref != NULL) { owner=ref->ownerId(); pl->setPropertiesFrom(ref); } pl->setNormal(normal); for (int i=0; i < pts.length(); i++) { pl->addVertexAt(i, pts<i>); } pl->setElevation(elevation); pl->setColorIndex(1); // Red AcDbBlockTableRecord *rec=NULL; acdbOpenObject(rec, owner, AcDb::kForWrite); if (rec != NULL) { AcDbObjectId id; rec->appendAcDbEntity(id, pl); pl->close(); rec->close(); } else { delete pl; return false; } return true; } // End of drawAPlineWithPropertiesFromBlockRef() // Get the boundary from a Block Reference given by the blk parameter. // Transform that boundary to the WCS. //------------------------------------------------------------------- static BOOL GetBlockClippingPolyline(ads_name blk) { BOOL ret = FALSE; AcDbBlockReference *ref = NULL; AcDbObjectId insId = AcDbObjectId::kNull; acdbGetObjectId(insId, blk); if (acdbOpenObject(ref, insId, AcDb::kForRead) != Acad::eOk) return ret; // Find the clipping object (AcDbSpatialFilter) in the ExtDict of the BlockRef AcDbObjectId extDicId = ref->extensionDictionary(); if( extDicId == AcDbObjectId::kNull ) return ret; AcDbDictionary *extDict=NULL, *acadFilterDict=NULL; if (acdbOpenObject(extDict, extDicId, AcDb::kForRead) != Acad::eOk) return ret; Acad::ErrorStatus err = extDict->getAt(_T("ACAD_FILTER"), (AcDbObject*&)acadFilterDict, AcDb::kForRead); extDict->close(); if( err != Acad::eOk ) return ret; AcDbSpatialFilter *filter=NULL; err = acadFilterDict->getAt(_T("SPATIAL"), (AcDbObject*&)filter, AcDb::kForRead); acadFilterDict->close(); if ( err != Acad::eOk) return ret; // Get the transform matrix stored in the XClip boundary AcGeMatrix3d xformInBoundary = filter->getClipSpaceToWCSMatrix( xformInBoundary ); // and the transform of the BlockRef at the time when the Filter was set AcGeMatrix3d xformRefOrig = filter->getOriginalInverseBlockXform( xformRefOrig ); // Get the transform matrix that the current BlockRef has, so, we can find the difference // with the xformRefOrig AcGeMatrix3d refMatrix = ref->blockTransform(); refMatrix = refMatrix.postMultBy(xformRefOrig ); // Calculate the final transform matrix which applies to the points // returned from filter->getDefinition(). AcGeMatrix3d finalMatrix = refMatrix.postMultBy(xformInBoundary); AcGePoint2dArray pts; AcGePoint3dArray pts3d; AcGeVector3d normal; double elevation = 0, frontClip = 0, backClip = 0; Adesk::Boolean enabled = false; // Get all boundary points if (filter->getDefinition(pts, normal, elevation, frontClip, backClip, enabled) == Acad::eOk) { // Rectanglar boundary if (pts.length() == 2) { AcGePoint2d p1(pts[1].x, pts[0].y); AcGePoint2d p3(pts[0].x, pts[1].y); pts.insertAt(1, p1); pts.insertAt(3, p3); } // Transform all points with the transform matrix we calculated for(int i=0; i<pts.length(); i++) { AcGePoint2d pt2d; AcGePoint3d pt3d; pt2d = pts<i>; pt3d[0] = pt2d[0]; pt3d[1] = pt2d[1]; pt3d[2] = 0; pt3d.transformBy(finalMatrix); pts3d.append(pt3d); } } // Get the new normal and new ECS information for the polyline. AcGeVector3d xfnorm = normal.transformBy(finalMatrix); AcGeMatrix3d plineECS; AcDbPolyline* pline = new AcDbPolyline(); pline->setNormal(xfnorm); pline->getEcs(plineECS); delete pline; pline = NULL; AcGeMatrix3d plineECSInv = plineECS.inverse(); double xfelev = 0.0; for (int i = 0; i < pts.length(); i++) { pts<i>.x = pts3d<i>.x; pts<i>.y = pts3d<i>.y; if (i == 0) xfelev = pts3d<i>.z; // Should be identical to within roundoff assert(fabs(xfelev - pts3d<i>.z) < 1.0e-10); } // Show the boundary drawAPlineWithPropertiesFromBlockRef(pts, ref, xfelev, xfnorm); filter->close(); ref->close(); return true; } // End of GetBlockClippingPolyline() // "MClip" test command for the GetBlockClippingPolyline() function. static void MMRCplusplus_MClip(void) { ads_name en; AcGePoint3d pt; if (acedEntSel(_T("\nSelect an INSERT clipped by XCLIP command: "), en, asDblArray(pt)) != RTNORM) { acutPrintf(_T("\nNothing selected")); return; } assert(GetBlockClippingPolyline(en)==TRUE); }[/code] |
|