<?xml encoding=”UTF-8″>By Balaji Ramamoorthy
If you have a collection of subDMesh and wish to create a Solid from it, first convert each of those mesh to a surface. If the sufaces all put together form a closed volume, then a sculpted solid can be created from these surfaces. Here is a sample code snippet :
<span>// For SubDMesh </span><span> </span>
<span>#include</span><span> <span>"dbSubD.h"</span><span> </span></span>
<span>static</span><span> <span>void</span><span> AdskMeshToSolid()</span></span>
<span>{</span>
Acad::ErrorStatus es;
<span>int</span><span> ret;</span>
<span>// Select the meshes to create the solid from</span><span> </span>
AcArray<AcDbObjectId> meshIdArray;
<span>do</span><span> </span>
<span>{</span>
ads_name entName;
ads_point pt;
ret = acedEntSel(L<span>"Select a mesh : "</span><span> , </span>
entName, pt);
<span>if</span><span> (RTNORM != ret) </span>
<span>break</span><span> ;</span>
AcDbObjectId objId = AcDbObjectId::kNull;
<span>if</span><span> ( Acad::eOk != acdbGetObjectId(objId, entName)) </span>
<span>break</span><span> ;</span>
<span>if</span><span> (objId.objectClass() == AcDbSubDMesh::desc())</span>
<span>{</span>
meshIdArray.append(objId);
<span>}</span>
<span>}</span><span>while</span><span> (ret == RTNORM);</span>
<span>// Convert the meshes to surfaces</span><span> </span>
AcArray<AcDbEntity*> surfacesArray;
AcGeIntArray limits;
AcDbSurface *pSurface = NULL;
<span>for</span><span> (<span>int</span><span> mesh = 0; mesh < meshIdArray.length(); mesh++)</span></span>
<span>{</span>
AcDbEntity *pEntity = NULL;
<span>if</span><span> (acdbOpenAcDbEntity(pEntity, meshIdArray[mesh], </span>
AcDb::kForRead) != Acad::eOk)
<span>{</span>
<span>return</span><span> ; </span>
<span>}</span>
AcDbSubDMesh *pMesh = AcDbSubDMesh::cast(pEntity);
<span>if</span><span> (pMesh)</span>
<span>{</span>
es = pMesh->convertToSurface(
<span>false</span><span> , </span>
<span>false</span><span> , </span>
pSurface);
<span>if</span><span> (es != Acad::eOk)</span>
<span>return</span><span> ;</span>
<span>if</span><span> ( es == Acad::eOk && </span>
pSurface->isKindOf(AcDbSurface::desc()))
<span>{</span>
surfacesArray.append(pSurface);
<span>}</span>
<span>}</span>
pEntity->close();
<span>}</span>
<span>// Create a sculpted solid from surfaces</span><span> </span>
AcDb3dSolid *pSolid = <span>new</span><span> AcDb3dSolid();</span>
pSolid->setDatabaseDefaults();
es = pSolid->createSculptedSolid(
surfacesArray,
limits);
<span>if</span><span> (es == Acad::eOk)</span>
<span>{</span>
<span>// Add sculpted solid to the database </span><span> </span>
AcDbObjectId solidOid = AcDbObjectId::kNull;
postToDb(pSolid, &solidOid);
<span>// To show the newly created solid away</span><span> </span>
<span>// from the surfaces, we transform it..</span><span> </span>
AcDbEntity *pSolidEnt;
es = acdbOpenAcDbEntity(
pSolidEnt, solidOid, AcDb::kForWrite);
<span>if</span><span> (es == Acad::eOk &&</span>
pSolidEnt->isKindOf(AcDb3dSolid::desc()))
<span>{</span>
AcGeVector3d vec(15.0, 15.0, 0.0);
AcGeMatrix3d transform
= transform.setToTranslation(vec);
es = pSolidEnt->transformBy(transform);
pSolidEnt->close();
acutPrintf(
ACRX_T(<span>"Solid3d created from mesh !"</span><span> ));</span>
<span>}</span>
<span>else</span><span> </span>
<span>{</span>
acutPrintf(
ACRX_T(<span>"Solid3d creation failed !"</span><span> ));</span>
<span>}</span>
<span>}</span>
<span>else</span><span> </span>
<span>{</span>
acutPrintf(ACRX_T(<span>"Solid3d creation failed !"</span><span> ));</span>
<span>delete</span><span> pSolid;</span>
<span>}</span>
<span>// Cleanup</span><span> </span>
<span>// We do not need the surfaces anymore</span><span> </span>
<span>int</span><span> surfCnt = 0;</span>
<span>for</span><span> (;surfCnt < surfacesArray.length(); surfCnt++)</span>
<span>{</span>
AcDbEntity *pEnt = surfacesArray[surfCnt];
<span>delete</span><span> pEnt;</span>
<span>}</span>
<span>}</span>
<span>static</span><span> <span>void</span><span> postToDb( AcDbEntity* pEnt, AcDbObjectId *pOid) </span></span>
<span>{</span>
AcDbBlockTable* pBlockTable;
AcDbDatabase *pDb =
acdbHostApplicationServices()->workingDatabase();
pDb->getBlockTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord* pModelSpaceBTR = NULL;
pBlockTable->getAt(
ACDB_MODEL_SPACE,
pModelSpaceBTR,
AcDb::kForWrite);
AcDbObjectId oid = AcDbObjectId::kNull;
<span>if</span><span> (pOid != NULL)</span>
<span>{</span>
pModelSpaceBTR->appendAcDbEntity(*pOid, pEnt);
<span>}</span>
<span>else</span><span> </span>
<span>{</span>
pModelSpaceBTR->appendAcDbEntity(oid, pEnt);
<span>}</span>
pEnt->close();
pModelSpaceBTR->close();
pBlockTable->close();
<span>}</span>
Here is a screenshot of the output


Leave a Reply