[每日一码] (4)获得准确的AcDb3dSolid的包围盒
void asdkasdktightboundbox(){
ads采用name eName;
ads采用point pt;
if( RTNORM != acedEntSel("\nPlease select a solid ", eName, pt ))
return;
AcDbObjectId id;
acdbGetObjectId( id, eName );
AcDb3dSolid*pSolid = NULL;
acdbOpenObject(pSolid, id, AcDb::kForRead );
if( pSolid == NULL ) {
acutPrintf("\nObject not a solid");
return;
}
double volume;
AcGePoint3d centroid;
double momInertia;
double prodInertia;
double prinMoments;
AcGeVector3d prinAxes;
double radiiGyration;
AcDbExtents extents;
Acad::ErrorStatus es;
es = pSolid->getMassProp(
volume,
centroid,
momInertia,
prodInertia,
prinMoments,
prinAxes,
radiiGyration,
extents);
AcGePoint3d max = extents.maxPoint();
AcGePoint3d min = extents.minPoint();
int xAxis, zAxis;
double bigVol = (max.x - min.x ) * ( max. y - min.y ) * (max.z - min.z);
acutPrintf("\ncalculated original box ");
acutPrintf("\nvolume %e", bigVol );
acutPrintf("\nOriginal box is %e the size of the object", bigVol/volume );
// some work to make x the largest prin axis, and z the smallest.
if(prinMoments > prinMoments )
{
xAxis = 0;
zAxis = 1;
}
else
{
xAxis = 1;
zAxis = 0;
}
if(prinMoments > prinMoments )
zAxis =2;
else if(prinMoments < prinMoments )
xAxis = 2;
AcGeMatrix3d mat;
AcGeVector3d yAxisVec = prinAxes.crossProduct( prinAxes);
mat.setCoordSystem( centroid, prinAxes, yAxisVec, prinAxes);
acutPrintf("\nxAxis %e %e %e", prinAxes.x, prinAxes.y,prinAxes.z);
acutPrintf("\nyAxis %e %e %e", yAxisVec.x, yAxisVec.y, yAxisVec.z);
acutPrintf("\nzAxis %e %e %e", prinAxes.x, prinAxes.y,prinAxes.z);
AcDbEntity*pNewEnt = NULL;
es = pSolid->getTransformedCopy( mat.inverse(), pNewEnt );
if( pNewEnt == NULL )
{
acutPrintf("\nCannot transform solid");
acutPrintf("\nError: %s", acadErrorStatusText(es));
pSolid->close();
return;
}
AcDbExtents newExtents;
pNewEnt->getGeomExtents( newExtents );
delete pNewEnt;
//delete pNewEnt;
max = newExtents.maxPoint();
min = newExtents.minPoint();
double deltaX = (max.x - min.x );
double deltaY = ( max. y - min.y );
double deltaZ = (max.z - min.z );
double smallVol = deltaX * deltaY * deltaZ;
acutPrintf("\ncalculated smaller box ");
acutPrintf("\nvolume %e", smallVol );
acutPrintf("\nAligned box is %e the size of the object", smallVol/volume );
acutPrintf("\nOriginal box is %e the size of the aligned box", bigVol/smallVol);
AcDb3dSolid*pNewSolid = new AcDb3dSolid;
pNewSolid->createBox(deltaX, deltaY, deltaZ );
AcGePoint3d newBoxCenter = min + 0.5 * (max - min);
pNewSolid->transformBy( mat * AcGeMatrix3d::translation( newBoxCenter - AcGePoint3d::kOrigin ) );
AcDbBlockTableRecord*pRecord;
acdbOpenObject(pRecord, pSolid->ownerId(), AcDb::kForWrite );
pSolid->close();
if( pRecord == NULL )
{
acutPrintf("\nCannot open BTR");
delete pNewSolid;
return;
}
pRecord->appendAcDbEntity(pNewSolid);
pNewSolid->close();
pRecord->close();
}
页:
[1]