// get normal direction of a triangle
        public Vector3D GetTriangleNormal(int n)
        {
            Triangle3D tri = GetTriangle(n);
            Point3D    pt0 = GetPoint(tri.n0);
            Point3D    pt1 = GetPoint(tri.n1);
            Point3D    pt2 = GetPoint(tri.n2);

            double dx1 = pt1.X - pt0.X;
            double dy1 = pt1.Y - pt0.Y;
            double dz1 = pt1.Z - pt0.Z;

            double dx2 = pt2.X - pt0.X;
            double dy2 = pt2.Y - pt0.Y;
            double dz2 = pt2.Z - pt0.Z;

            double vx = dy1 * dz2 - dz1 * dy2;
            double vy = dz1 * dx2 - dx1 * dz2;
            double vz = dx1 * dy2 - dy1 * dx2;

            double length = Math.Sqrt(vx * vx + vy * vy + vz * vz);

            return(new Vector3D(vx / length, vy / length, vz / length));
        }
 // set a triangle in this mesh
 public void SetTriangle(int n, Triangle3D triangle)
 {
     m_tris[n] = triangle;
 }
 public void SetTriangle(int i, int m0, int m1, int m2)
 {
     m_tris[i] = new Triangle3D(m0, m1, m2);
 }
        // set this ModelVisual3D object from a array of mesh3D objects
        private void SetModel(ArrayList meshs, Material backMaterial)
        {
            int nMeshNo = meshs.Count;

            if (nMeshNo == 0)
            {
                return;
            }

            MeshGeometry3D triangleMesh = new MeshGeometry3D();
            int            nTotalVertNo = 0;

            for (int j = 0; j < nMeshNo; j++)
            {
                Mesh3D mesh    = (Mesh3D)meshs[j];
                int    nVertNo = mesh.GetVertexNo();
                int    nTriNo  = mesh.GetTriangleNo();
                if ((nVertNo <= 0) || (nTriNo <= 0))
                {
                    continue;
                }

                double[] vx = new double[nVertNo];
                double[] vy = new double[nVertNo];
                double[] vz = new double[nVertNo];
                for (int i = 0; i < nVertNo; i++)
                {
                    vx[i] = vy[i] = vz[i] = 0;
                }

                // get normal of each vertex
                for (int i = 0; i < nTriNo; i++)
                {
                    Triangle3D tri = mesh.GetTriangle(i);
                    Vector3D   vN  = mesh.GetTriangleNormal(i);
                    int        n0  = tri.n0;
                    int        n1  = tri.n1;
                    int        n2  = tri.n2;

                    vx[n0] += vN.X;
                    vy[n0] += vN.Y;
                    vz[n0] += vN.Z;
                    vx[n1] += vN.X;
                    vy[n1] += vN.Y;
                    vz[n1] += vN.Z;
                    vx[n2] += vN.X;
                    vy[n2] += vN.Y;
                    vz[n2] += vN.Z;
                }
                for (int i = 0; i < nVertNo; i++)
                {
                    double length = Math.Sqrt(vx[i] * vx[i] + vy[i] * vy[i] + vz[i] * vz[i]);
                    if (length > 1e-20)
                    {
                        vx[i] /= length;
                        vy[i] /= length;
                        vz[i] /= length;
                    }
                    triangleMesh.Positions.Add(mesh.GetPoint(i));
                    Color color = mesh.GetColor(i);
                    Point mapPt = m_mapping.GetMappingPosition(color);
                    triangleMesh.TextureCoordinates.Add(new System.Windows.Point(mapPt.X, mapPt.Y));
                    triangleMesh.Normals.Add(new Vector3D(vx[i], vy[i], vz[i]));
                }

                for (int i = 0; i < nTriNo; i++)
                {
                    Triangle3D tri = mesh.GetTriangle(i);
                    int        n0  = tri.n0;
                    int        n1  = tri.n1;
                    int        n2  = tri.n2;

                    triangleMesh.TriangleIndices.Add(nTotalVertNo + n0);
                    triangleMesh.TriangleIndices.Add(nTotalVertNo + n1);
                    triangleMesh.TriangleIndices.Add(nTotalVertNo + n2);
                }
                nTotalVertNo += nVertNo;
            }
            //Material material = new DiffuseMaterial(new SolidColorBrush(Colors.Red));
            Material material = m_mapping.m_material;

            GeometryModel3D triangleModel = new GeometryModel3D(triangleMesh, material);

            triangleModel.Transform = new Transform3DGroup();
            if (backMaterial != null)
            {
                triangleModel.BackMaterial = backMaterial;
            }

            Content = triangleModel;
        }