获取Civil 3D 三角网曲面TinSurface中每个小三角形的法向量

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;
            }
        }
 
 

Related Posts Plugin for WordPress, Blogger...