The TinSurface object has a Triangle property, which allow access to the list of triangles of the surface. But the TinVolumeSurface does not offer this property. The workaround is to use the COM version of this object, AeccTinVolumeSurface, which has a OutputTriangles property, that returns a array of doubles, but this need to be interpreted as points (XYZ coordinates).
On C# this property can be used with dynamic types, which allow late-binding of COM Interop types. To make the points, it’s a matter of playing with arrays.
At this sample you’ll find a Triangle and TriangleCollection classes to use this array of doubles. This sample also create AutoCAD Faces of each triangle, just for testing.
[CommandMethod("getTriangles")]
public static void CmdGetTriangles()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptEntityOptions peo = new PromptEntityOptions(
"\nSelect tin volume surface: ");
peo.SetRejectMessage("\nOnly tin volume surface");
peo.AddAllowedClass(typeof(TinVolumeSurface), true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;
Database db = Application.DocumentManager.
MdiActiveDocument.Database;
using (Transaction trans = db.TransactionManager.
StartOpenCloseTransaction())
{
TinVolumeSurface tvs = trans.GetObject(
per.ObjectId, OpenMode.ForRead) as TinVolumeSurface;
dynamic tvsCOM = tvs.AcadObject; // get the COM representation
TriangleCollection triangles =
new TriangleCollection(tvsCOM.OutputTriangles);
// for testing, let's create faces using the triangle data
BlockTableRecord currSpace = trans.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
foreach(Triangle t in triangles)
{
Face f = new Face(
t.Vertex1, t.Vertex2, t.Vertex3,
true, true, true, true);
currSpace.AppendEntity(f);
trans.AddNewlyCreatedDBObject(f, true);
}
trans.Commit();
}
}
public class TriangleCollection : List<Triangle>
{
public TriangleCollection(double[] arrayDoubles)
{
if (arrayDoubles.Length % 9 != 0)
throw new ArgumentException(
"Double array must have mulitple of 9 values.");
int numberOfDoubles = arrayDoubles.Length;
int numberOfPoints = numberOfDoubles / 3 / 3;
for (int p = 0; p < numberOfPoints; p++)
{
double[] pointValues = new double[9];
for (int v = 0; v < 9; v++)
pointValues[v] = arrayDoubles[p * 9 + v];
base.Add(new Triangle(pointValues));
}
}
}
public struct Triangle
{
private Point3d[] _points;
public Triangle(double[] values)
{
if (values.Length != 9) throw new ArgumentException(
"Double array must have 9 values.");
_points = new Point3d[3];
for (int p = 0; p < 3; p++)
_points[p] = new Point3d(
values[p * 3],
values[p * 3 + 1],
values[p * 3 + 2]);
}
public Point3d Vertex1 { get { return _points[0]; } }
public Point3d Vertex2 { get { return _points[1]; } }
public Point3d Vertex3 { get { return _points[2]; } }
}