[每日一码] 获取块的XCLIP边界
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);
}
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.x, pts.y);
AcGePoint2d p3(pts.x, pts.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;
pt3d = pt2d; pt3d = pt2d; pt3d = 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.x = pts3d.x;
pts.y = pts3d.y;
if (i == 0)
xfelev = pts3d.z;
// Should be identical to within roundoff
assert(fabs(xfelev - pts3d.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);
}
页:
[1]