Civil 3D 2012以后版本提供的曲面的.net API,通过.net API可以获得TinSurface的所有三角形(TinSurfaceTriangle)信息,包含顶点(Vertex)和边(Edge)。但TinSurfaceTriangle对象没有提供表示该三角形法向量(normal)的函数方法,下面自己来实现一个。思路的利用小三角形的顶点信息构建一个AutoCAD 的plane实体,进而获取法向量:
Vector3d GetNormal(TinSurfaceTriangle triangle)
{
Point3d point1 = triangle.Vertex1.Location;
Point3d point2 = triangle.Vertex2.Location;
Point3d point3 = triangle.Vertex3.Location;
Vector3d normal;
using (Plane plan = new Plane(
point1,
point1.GetVectorTo(point2),
point1.GetVectorTo(point3)))
{
normal = plan.Normal.GetNormal();
};
return normal;
}
另一种方法:
Vector3d GetNormal2(TinSurfaceTriangle triangle)
{
Point3d point1 = triangle.Vertex1.Location;
Point3d point2 = triangle.Vertex2.Location;
Point3d point3 = triangle.Vertex3.Location;
Vector3d v1 = point1.GetVectorTo(point2).GetNormal();
Vector3d v2 = point1.GetVectorTo(point3).GetNormal();
Vector3d normal = v2.CrossProduct(v1).GetNormal();
return normal;
}
下面是对曲面操作的一个测试函数:
[CommandMethod("PrintSurfaceInfo")]
public void PrintSurfaceInfo()
{
ObjectId surfaceId = ObjectId.Null;
do
{
surfaceId = this.PromptForTinSurface();
}
while (surfaceId == ObjectId.Null);
Database db = CurrentEditor.Document.Database;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
TinSurface surface = trans.GetObject(surfaceId, OpenMode.ForRead) as TinSurface;
int triCount = surface.Triangles.Count;
StringBuilder msg = new StringBuilder();
msg.Append("\nSurface triangle count: " + triCount.ToString());
foreach (TinSurfaceTriangle tri in surface.Triangles)
{
msg.Append(GetTriangleInfo(tri));
}
CurrentEditor.WriteMessage(msg.ToString());
}
}
string GetTriangleInfo(TinSurfaceTriangle triangle)
{
StringBuilder sb = new StringBuilder();
sb.Append("\n");
sb.Append("\nPoint1 : " + triangle.Vertex1.Location.ToString());
sb.Append("\nPoint2 : " + triangle.Vertex2.Location.ToString());
sb.Append("\nPoint3 : " + triangle.Vertex3.Location.ToString());
sb.Append("\nNormal : " + GetNormal2(triangle).ToString());
return sb.ToString();
}
Vector3d GetNormal(TinSurfaceTriangle triangle)
{
Point3d point1 = triangle.Vertex1.Location;
Point3d point2 = triangle.Vertex2.Location;
Point3d point3 = triangle.Vertex3.Location;
Vector3d normal;
using (Plane plan = new Plane(
point1,
point2.GetVectorTo(point1),
point3.GetVectorTo(point1)))
{
normal = plan.Normal;
};
return normal;
}
ObjectId PromptForTinSurface()
{
string promptMsg = "\nSelect a Tin Surface";
string rejectMsg = "\n The surface you selected is not Tin Surface";
PromptEntityOptions opts = new PromptEntityOptions(promptMsg);
opts.SetRejectMessage(rejectMsg);
opts.AddAllowedClass(typeof(TinSurface), false);
PromptEntityResult entRes = CurrentEditor.GetEntity(opts);
if (entRes.Status == PromptStatus.OK)
{
return entRes.ObjectId;
}
return ObjectId.Null;
}
CivilDocument CivilDoc {
get{
return CivilApplication.ActiveDocument;
}
}
Editor CurrentEditor {
get{
return Application.DocumentManager.MdiActiveDocument.Editor;
}
}