找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 145|回复: 0

[每日一码] (4)获得准确的AcDb3dSolid的包围盒

[复制链接]

0

主题

0

回帖

26

积分

管理员

积分
26
发表于 2024-2-23 22:20:01 | 显示全部楼层 |阅读模式
  1. void asdkasdktightboundbox()
  2. {
  3.     ads采用name eName;
  4.     ads采用point pt;
  5.     if( RTNORM != acedEntSel("\nPlease select a solid ", eName, pt ))
  6.         return;
  7.     AcDbObjectId id;
  8.     acdbGetObjectId( id, eName );
  9.     AcDb3dSolid*pSolid = NULL;
  10.     acdbOpenObject(pSolid, id, AcDb::kForRead );
  11.     if( pSolid == NULL ) {
  12.         acutPrintf("\nObject not a solid");
  13.         return;
  14.     }
  15.     double volume;
  16.     AcGePoint3d centroid;
  17.     double momInertia[3];
  18.     double prodInertia[3];
  19.     double prinMoments[3];
  20.     AcGeVector3d prinAxes[3];
  21.     double radiiGyration[3];
  22.     AcDbExtents extents;
  23.     Acad::ErrorStatus es;
  24.     es = pSolid->getMassProp(
  25.                 volume,
  26.                 centroid,
  27.                 momInertia,
  28.                 prodInertia,
  29.                 prinMoments,
  30.                 prinAxes,
  31.                 radiiGyration,
  32.                 extents);
  33.     AcGePoint3d max = extents.maxPoint();
  34.     AcGePoint3d min = extents.minPoint();
  35.     int xAxis, zAxis;
  36.     double bigVol = (max.x - min.x ) * ( max. y - min.y ) * (max.z - min.z);
  37.     acutPrintf("\ncalculated original box ");
  38.     acutPrintf("\nvolume %e", bigVol );
  39.     acutPrintf("\nOriginal box is %e the size of the object", bigVol/volume );
  40.     // some work to make x the largest prin axis, and z the smallest.
  41.     if(prinMoments[0] > prinMoments[1] )
  42.     {
  43.         xAxis = 0;
  44.         zAxis = 1;
  45.     }
  46.     else
  47.     {
  48.         xAxis = 1;
  49.         zAxis = 0;
  50.     }
  51.     if(prinMoments[zAxis] > prinMoments[2] )
  52.         zAxis =  2;
  53.     else if(prinMoments[xAxis] < prinMoments[2] )
  54.         xAxis = 2;
  55.     AcGeMatrix3d mat;
  56.     AcGeVector3d yAxisVec = prinAxes[zAxis].crossProduct( prinAxes[xAxis]);
  57.     mat.setCoordSystem( centroid, prinAxes[xAxis], yAxisVec, prinAxes[zAxis]);
  58.     acutPrintf("\nxAxis %e %e %e", prinAxes[xAxis].x, prinAxes[xAxis].y,prinAxes[xAxis].z);
  59.     acutPrintf("\nyAxis %e %e %e", yAxisVec.x, yAxisVec.y, yAxisVec.z);
  60.     acutPrintf("\nzAxis %e %e %e", prinAxes[zAxis].x, prinAxes[zAxis].y,prinAxes[zAxis].z);
  61.     AcDbEntity*pNewEnt = NULL;
  62.     es = pSolid->getTransformedCopy( mat.inverse(), pNewEnt );
  63.     if( pNewEnt == NULL )
  64.     {
  65.         acutPrintf("\nCannot transform solid");
  66.         acutPrintf("\nError: %s", acadErrorStatusText(es));
  67.         pSolid->close();
  68.         return;
  69.     }
  70.     AcDbExtents newExtents;
  71.     pNewEnt->getGeomExtents( newExtents );
  72.     delete pNewEnt;
  73.     //delete pNewEnt;
  74.     max = newExtents.maxPoint();
  75.     min = newExtents.minPoint();
  76.     double deltaX = (max.x - min.x );
  77.     double deltaY = ( max. y - min.y );
  78.     double deltaZ = (max.z - min.z );
  79.     double smallVol = deltaX * deltaY * deltaZ;
  80.     acutPrintf("\ncalculated smaller box ");
  81.     acutPrintf("\nvolume %e", smallVol );
  82.     acutPrintf("\nAligned box is %e the size of the object", smallVol/volume );
  83.     acutPrintf("\nOriginal box is %e the size of the aligned box", bigVol/smallVol);
  84.     AcDb3dSolid*pNewSolid = new AcDb3dSolid;
  85.     pNewSolid->createBox(deltaX, deltaY, deltaZ );
  86.     AcGePoint3d newBoxCenter = min + 0.5 * (max - min);
  87.     pNewSolid->transformBy( mat * AcGeMatrix3d::translation( newBoxCenter - AcGePoint3d::kOrigin ) );
  88.     AcDbBlockTableRecord*pRecord;
  89.     acdbOpenObject(pRecord, pSolid->ownerId(), AcDb::kForWrite );
  90.     pSolid->close();
  91.     if( pRecord == NULL )
  92.     {
  93.         acutPrintf("\nCannot open BTR");
  94.         delete pNewSolid;
  95.         return;
  96.     }
  97.     pRecord->appendAcDbEntity(pNewSolid);
  98.     pNewSolid->close();   
  99.     pRecord->close();
  100. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2024-12-28 14:14 , Processed in 0.118928 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表