admin 发表于 2024-2-23 22:20:01

[每日一码] (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]
查看完整版本: [每日一码] (4)获得准确的AcDb3dSolid的包围盒