[CommandMethod("PFSolid", CommandFlags.NoPaperSpace | CommandFlags.UsePickSet | CommandFlags.Redraw)]
public static void PFSolid()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null) return;
ObjectId[] selection = ....; // Список выбраных заранее объектов или запрос
if (selection == null)
return;
using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead);
BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
int count = 0;
foreach (ObjectId entId in selection)
{
if (entId.IsNull || entId.IsErased || !entId.IsValid || entId.ObjectClass != dbPolyFaceMesh) continue;
PolyFaceMesh pfm = (PolyFaceMesh)tr.GetObject(entId, OpenMode.ForRead);
if (pfm == null) continue;
count++;
Point3dCollection vertexArray;
Int32Collection faceArray;
if (!GetPolyFaceMeshData(pfm, out vertexArray, out faceArray))
return;
/*We create an in-memory mesh and convert mesh to solid*/
SubDMesh subDMesh = new SubDMesh();
subDMesh.SetSubDMesh(vertexArray, faceArray, 0);
/*Now convert to Solid using CONVTOSOLID API*/
/*We will restrict to polygonal solid, we set false for smoothness, so not to abuse CPU*/
Solid3d solid = subDMesh.ConvertToSolid(false, true);
solid.SetPropertiesFrom(pfm);
ms.AppendEntity(solid);
tr.AddNewlyCreatedDBObject(solid, true);
/*Delete pfm*/
pfm.UpgradeOpen();
pfm.Erase();
}
tr.Commit();
.... отчет о проделанной работе по count
}
}
/*Get the Mesh data, not accounted for Color and Material of Faces*/
static bool GetPolyFaceMeshData(PolyFaceMesh mesh, out Point3dCollection vertexArray, out Int32Collection faceArray)
{
vertexArray = new Point3dCollection();
faceArray = new Int32Collection();
if (mesh == null || mesh.IsErased || mesh.Database == null) return false;
Transaction tr = mesh.Database.TransactionManager.TopTransaction;
if (tr == null) return false;
foreach (ObjectId id in mesh)
{
if (id.IsNull || id.IsErased || !id.IsValid) continue;
DBObject obj = tr.GetObject(id, OpenMode.ForRead);
if (obj is PolyFaceMeshVertex)
{
PolyFaceMeshVertex vertex = (PolyFaceMeshVertex)obj;
vertexArray.Add(vertex.Position);
}
else if (obj is FaceRecord)
{
FaceRecord face = (FaceRecord)obj;
int count = 0;
short[] indices = new short[4];
for (short i = 0; i < 4; i++)
{
indices[i] = face.GetVertexAt(i);
if (indices[i] == 0)
break;
count++;
}
// Quick triangle test by checking if the first vertex
// is the same as the last vertex
if (count == 4 && (Math.Abs(indices[0]) == Math.Abs(indices[3])))
count = 3;
// Per face record can be a triangle or quad
if (count > 2)
{
faceArray.Add(count);
for (int i = 0; i < count; i++)
faceArray.Add((short)(Math.Abs(indices[i]) - 1));
}
}
}
return true;
}