Example #1
0
        /// <summary>
        /// 导出扁平的贴花或者叫纹理(DecalFlat)adj. (flat) 光滑均匀的;(陆地)平坦的;(水面)平静的;无坡度的;扁的;
        /// </summary>
        /// <param name="element"></param>
        private void ExportDecalFlat(Element element)
        {
            ModelGeometry exportedGeometry = new ModelGeometry();

            exportedGeometry.Transform = transformationStack.Peek();
            GeometryElement arg_2F_0 = element.get_Geometry(Geometry_Options);

            exportedGeometry.Points = new List <XYZ>(4);
            using (IEnumerator <GeometryObject> enumerator = arg_2F_0.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    Line line = (Line)enumerator.Current;
                    if (!(line == null))
                    {
                        exportedGeometry.Points.Add(line.Origin);
                        if (exportedGeometry.Points.Count >= 4)
                        {
                            break;
                        }
                    }
                }
            }
            if (exportedGeometry.Points.Count != 4)
            {
                return;
            }
            exportedGeometry.Indices = new List <int>(6);
            exportedGeometry.Indices.Add(0);
            exportedGeometry.Indices.Add(2);
            exportedGeometry.Indices.Add(1);
            exportedGeometry.Indices.Add(0);
            exportedGeometry.Indices.Add(3);
            exportedGeometry.Indices.Add(2);
            exportedGeometry.Uvs = new List <UV>(4);
            exportedGeometry.Uvs.Add(new UV(0.0, 1.0));
            exportedGeometry.Uvs.Add(new UV(1.0, 1.0));
            exportedGeometry.Uvs.Add(new UV(1.0, 0.0));
            exportedGeometry.Uvs.Add(new UV(0.0, 0.0));
            exportedGeometry.CalculateNormals(false);
            exportedGeometry.MakeDoubleSided();
            int num = this.currentDecalMaterialId;

            currentDecalMaterialId = num + 1;
            ElementId elementId = new ElementId(num);

            decalMaterialIdToDecal.Add(elementId, element);
            Tuple <Document, ElementId> tuple = new Tuple <Document, ElementId>(documentStack.Peek(), elementId);

            ChangeCurrentMaterial(tuple);
            documentAndMaterialIdToGeometries[tuple].Add(exportedGeometry);
        }
Example #2
0
        private void WriteXmlGeometrySourceNormals(int documentAndMaterialIdHash, IList <ModelGeometry> geometries)
        {
            Func <ModelGeometry, int> arg_20_1;

            if ((arg_20_1 = Inner.T__18_0) == null)
            {
                arg_20_1 = (Inner.T__18_0 = new Func <ModelGeometry, int>(Inner.T.b__18_0));
            }
            //计算法线数量
            int num = geometries.Sum(arg_20_1);

            //source节点属性
            this.sb.AppendFormat("<source id=\"geom-{0}-normals\">\n", documentAndMaterialIdHash);
            //float_array节点属性
            this.sb.AppendFormat("<float_array id=\"geom-{0}-normals-array\" count=\"{1}\">\n", documentAndMaterialIdHash, num * 3);
            using (IEnumerator <ModelGeometry> enumerator = geometries.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    ModelGeometry geometry = enumerator.Current;
                    if (!geometry.Transform.IsIdentity)
                    {
                        Parallel.For(0, geometry.Normals.Count, delegate(int iNormal)
                        {
                            geometry.Normals[iNormal] = geometry.Transform.OfVector(geometry.Normals[iNormal]);
                        });
                    }
                    for (int i = 0; i < geometry.Normals.Count; i++)
                    {
                        XYZ xYZ = geometry.Normals[i];
                        this.sb.AppendFormat(CultureInfo.InvariantCulture.NumberFormat, "{0:0.###} {1:0.###} {2:0.###} ", new object[]
                        {
                            xYZ.X,
                            xYZ.Y,
                            xYZ.Z
                        });
                    }
                }
            }
            this.sb.Append("</float_array>\n");
            this.sb.Append("<technique_common>\n");
            this.sb.AppendFormat("<accessor source=\"#geom-{0}-normals-array\" count=\"{1}\" stride=\"3\">\n", documentAndMaterialIdHash, num);
            this.sb.Append("<param name=\"X\" type=\"float\"/>\n");
            this.sb.Append("<param name=\"Y\" type=\"float\"/>\n");
            this.sb.Append("<param name=\"Z\" type=\"float\"/>\n");
            this.sb.Append("</accessor>\n");
            this.sb.Append("</technique_common>\n");
            this.sb.Append("</source>\n");
        }
Example #3
0
        /// <summary>
        /// 导出有弧度弯曲的贴花DecalCurved
        /// </summary>
        /// <param name="element"></param>
        private void ExportDecalCurved(Element element)
        {
            ModelGeometry exportedGeometry = new ModelGeometry();

            exportedGeometry.Transform = transformationStack.Peek();
            GeometryElement expr_23  = element.get_Geometry(Geometry_Options);
            Arc             arc      = expr_23.ToArray()[1] as Arc;
            Curve           arg_49_0 = expr_23.ToArray()[3] as Arc;

            XYZ[] array  = arc.Tessellate().ToArray <XYZ>();
            XYZ[] array2 = arg_49_0.Tessellate().ToArray();
            exportedGeometry.Points = new List <XYZ>(array.Length + array2.Length);
            exportedGeometry.Uvs    = new List <UV>(array.Length + array2.Length);
            for (int i = 0; i < array.Length; i++)
            {
                exportedGeometry.Points.Add(array[i]);
                exportedGeometry.Uvs.Add(new UV(1f - i * (1f / (array.Length - 1)), 1.0));
            }
            for (int j = 0; j < array2.Length; j++)
            {
                exportedGeometry.Points.Add(array2[j]);
                exportedGeometry.Uvs.Add(new UV(j * (1f / (array.Length - 1)), 0.0));
            }
            exportedGeometry.Indices = new List <int>((array.Length - 1) * 6);
            for (int k = 0; k < array.Length - 1; k++)
            {
                exportedGeometry.Indices.Add(k);
                exportedGeometry.Indices.Add(k + 1);
                exportedGeometry.Indices.Add(array.Length * 2 - k - 1);
                exportedGeometry.Indices.Add(k + 1);
                exportedGeometry.Indices.Add(array.Length * 2 - k - 2);
                exportedGeometry.Indices.Add(array.Length * 2 - k - 1);
            }
            exportedGeometry.CalculateNormals(false);
            exportedGeometry.MakeDoubleSided();
            int num = this.currentDecalMaterialId;

            currentDecalMaterialId = num + 1;
            ElementId elementId = new ElementId(num);

            decalMaterialIdToDecal.Add(elementId, element);
            Tuple <Document, ElementId> tuple = new Tuple <Document, ElementId>(documentStack.Peek(), elementId);

            ChangeCurrentMaterial(tuple);
            documentAndMaterialIdToGeometries[tuple].Add(exportedGeometry);
        }
Example #4
0
        private void ExportSolid(Solid solid)
        {
            SolidOrShellTessellationControls solidOrShellTessellationControls = new SolidOrShellTessellationControls
            {
                LevelOfDetail      = userSetting.LevelOfDetail / 30.0,
                Accuracy           = 0.1,
                MinAngleInTriangle = 0.0001,
                MinExternalAngleBetweenTriangles = 1.0
            };

            try
            {
                TriangulatedSolidOrShell triangulatedSolidOrShell = SolidUtils.TessellateSolidOrShell(solid, solidOrShellTessellationControls);
                int shellComponentCount = triangulatedSolidOrShell.ShellComponentCount;
                for (int i = 0; i < shellComponentCount; i++)
                {
                    TriangulatedShellComponent shellComponent = triangulatedSolidOrShell.GetShellComponent(i);
                    ModelGeometry exportedGeometry            = new ModelGeometry
                    {
                        Transform = transformationStack.Peek(),
                        Points    = new List <XYZ>(shellComponent.VertexCount)
                    };
                    for (int num = 0; num != shellComponent.VertexCount; num++)
                    {
                        exportedGeometry.Points.Add(shellComponent.GetVertex(num));
                    }
                    exportedGeometry.Indices = new List <int>(shellComponent.TriangleCount * 3);
                    for (int j = 0; j < shellComponent.TriangleCount; j++)
                    {
                        TriangleInShellComponent triangle = shellComponent.GetTriangle(j);
                        exportedGeometry.Indices.Add(triangle.VertexIndex0);
                        exportedGeometry.Indices.Add(triangle.VertexIndex1);
                        exportedGeometry.Indices.Add(triangle.VertexIndex2);
                    }
                    exportedGeometry.CalculateNormals(false);
                    exportedGeometry.CalculateUVs(true, false);
                    ElementId materialElementId       = solid.Faces.get_Item(0).MaterialElementId;
                    Tuple <Document, ElementId> tuple = new Tuple <Document, ElementId>(documentStack.Peek(), materialElementId);
                    ChangeCurrentMaterial(tuple);
                    documentAndMaterialIdToGeometries[tuple].Add(exportedGeometry);
                }
            }
            catch (Exception)
            {
            }
        }
Example #5
0
        /// <summary>
        /// 当输出3d面的镶嵌多边形时,将调用此方法。
        /// </summary>
        /// <param name="polymesh">表示多边形网格拓扑的节点</param>
        void IExportContext.OnPolymesh(PolymeshTopology polymesh)
        {
            ModelGeometry exportedGeometry = new ModelGeometry
            {
                Points                = polymesh.GetPoints(),
                Normals               = polymesh.GetNormals(),
                Uvs                   = polymesh.GetUVs(),
                Transform             = transformationStack.Peek(),
                DistributionOfNormals = polymesh.DistributionOfNormals,
                Indices               = new List <int>(polymesh.GetFacets().Count * 3)
            };

            if (exportedGeometry.Transform.IsConformal && exportedGeometry.Transform.HasReflection)
            {
                using (IEnumerator <PolymeshFacet> enumerator = polymesh.GetFacets().GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        PolymeshFacet current = enumerator.Current;
                        exportedGeometry.Indices.Add(current.V1);
                        exportedGeometry.Indices.Add(current.V3);
                        exportedGeometry.Indices.Add(current.V2);
                    }
                    goto Fine;
                }
            }
            foreach (PolymeshFacet current2 in polymesh.GetFacets())
            {
                exportedGeometry.Indices.Add(current2.V1);
                exportedGeometry.Indices.Add(current2.V2);
                exportedGeometry.Indices.Add(current2.V3);
            }
Fine:
            if (isElementDoubleSided)
            {
                exportedGeometry.MakeDoubleSided();
            }
            documentAndMaterialIdToGeometries[currentDocumentAndMaterialId].Add(exportedGeometry);
        }
Example #6
0
 internal int b__21_2(ModelGeometry item)
 {
     return(item.Normals.Count);
 }
Example #7
0
 internal int b__21_1(ModelGeometry item)
 {
     return(item.Points.Count);
 }
Example #8
0
 internal int b__21_0(ModelGeometry item)
 {
     return(item.Indices.Count);
 }
Example #9
0
        private void WriteXmlGeometryTrianglesWithMap(int documentAndMaterialIdHash, IList <ModelGeometry> geometries)
        {
            Func <ModelGeometry, int> arg_20_1;

            if ((arg_20_1 = Inner.T__21_0) == null)
            {
                arg_20_1 = (Inner.T__21_0 = new Func <ModelGeometry, int>(Inner.T.b__21_0));
            }
            int num = geometries.Sum(arg_20_1) / 3;

            this.sb.AppendFormat("<triangles count=\"{0}\" material=\"material-{1}\">\n", num, documentAndMaterialIdHash);
            Func <ModelGeometry, int> arg_65_1;

            if ((arg_65_1 = Inner.T__21_1) == null)
            {
                arg_65_1 = (Inner.T__21_1 = new Func <ModelGeometry, int>(Inner.T.b__21_1));
            }
            int arg_91_0 = geometries.Sum(arg_65_1);
            Func <ModelGeometry, int> arg_8A_1;

            if ((arg_8A_1 = Inner.T__21_2) == null)
            {
                arg_8A_1 = (Inner.T__21_2 = new Func <ModelGeometry, int>(Inner.T.b__21_2));
            }
            int num2 = geometries.Sum(arg_8A_1);

            if (arg_91_0 == num2)
            {
                this.sb.AppendFormat("<input offset=\"0\" semantic=\"VERTEX\" source=\"#geom-{0}-vertices\"/>\n", documentAndMaterialIdHash);
                this.sb.AppendFormat("<input offset=\"0\" semantic=\"TEXCOORD\" source=\"#geom-{0}-map\" set=\"0\"/>\n", documentAndMaterialIdHash);
                this.sb.AppendFormat("<input offset=\"0\" semantic=\"NORMAL\" source=\"#geom-{0}-normals\"/>\n", documentAndMaterialIdHash);
                this.sb.Append("<p>\n");
                int num3 = 0;
                using (IEnumerator <ModelGeometry> enumerator = geometries.GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        ModelGeometry current = enumerator.Current;
                        for (int i = 0; i < current.Indices.Count; i++)
                        {
                            this.sb.AppendFormat("{0} ", current.Indices[i] + num3);
                        }
                        num3 += current.Points.Count;
                    }
                    goto IL_2D3;
                }
            }
            this.sb.AppendFormat("<input offset=\"0\" semantic=\"VERTEX\" source=\"#geom-{0}-vertices\"/>\n", documentAndMaterialIdHash);
            this.sb.AppendFormat("<input offset=\"0\" semantic=\"TEXCOORD\" source=\"#geom-{0}-map\" set=\"0\"/>\n", documentAndMaterialIdHash);
            this.sb.AppendFormat("<input offset=\"1\" semantic=\"NORMAL\" source=\"#geom-{0}-normals\"/>\n", documentAndMaterialIdHash);
            this.sb.Append("<p>\n");
            int num4 = 0;
            int num5 = 0;

            foreach (ModelGeometry current2 in geometries)
            {
                switch (current2.DistributionOfNormals)
                {
                case 0:
                    for (int j = 0; j < current2.Indices.Count; j++)
                    {
                        this.sb.AppendFormat("{0} {1} ", current2.Indices[j] + num4, current2.Indices[j] + num5);
                    }
                    break;

                case (DistributionOfNormals)1:
                case (DistributionOfNormals)2:
                    for (int k = 0; k < current2.Indices.Count; k++)
                    {
                        this.sb.AppendFormat("{0} {1} ", current2.Indices[k] + num4, num5);
                    }
                    break;
                }
                num4 += current2.Points.Count;
                num5 += current2.Normals.Count;
            }
IL_2D3:
            this.sb.Append("</p>\n");
            this.sb.Append("</triangles>\n");
        }
Example #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="documentAndMaterialIdHash">定义Source的唯一ID</param>
        /// <param name="geometries"></param>
        private void WriteXmlGeometrySourcePositions(int documentAndMaterialIdHash, IList <ModelGeometry> geometries)
        {
            Func <ModelGeometry, int> arg_20_1;

            if ((arg_20_1 = Inner.T__17_0) == null)
            {
                arg_20_1 = (Inner.T__17_0 = new Func <ModelGeometry, int>(Inner.T.b__17_0));
            }
            //计算顶点数
            int num = geometries.Sum(arg_20_1);

            //source 节点属性
            this.sb.AppendFormat("<source id=\"geom-{0}-positions\">\n", documentAndMaterialIdHash);
            //source节点下的float_array节点属性
            this.sb.AppendFormat("<float_array id=\"geom-{0}-positions-array\" count=\"{1}\">\n", documentAndMaterialIdHash, num * 3);

            /*	定义一个范围,在范围结束时处理对象。
             * 场景:
             * 当在某个代码段中使用了类的实例,而希望无论因为什么原因,只要离开了这个代码段就自动调用这个类实例的Dispose。
             * 要达到这样的目的,用try...catch来捕捉异常也是可以的,但用using也很方便。//*/
            using (IEnumerator <ModelGeometry> enumerator = geometries.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    ModelGeometry geometry = enumerator.Current;
                    //恒等变换不会改变它所应用的点或向量。
                    if (!geometry.Transform.IsIdentity)
                    {
                        //Parallel.For方法,主要用于处理针对数组元素的并行操作(数据的并行) fromInclusive:
                        //     开始索引(含)。
                        //
                        //   toExclusive:
                        //     结束索引(不含)。
                        //
                        //   body:
                        //     将为每个迭代调用一次的委托。
                        //
                        // 返回结果:
                        //     包含有关已完成的循环部分的信息的结构。
                        Parallel.For(0, geometry.Points.Count, delegate(int iPoint)
                        {
                            //将变换应用于点并返回结果。

                            /*Revit 提供了Transform类来做二次开发时的坐标转换。 你可以给Transform对象进行赋值,构造一个变换矩阵。
                             * 然后使用这个变化矩阵把给定的坐标点的坐标转成目标坐标系。
                             *
                             * 初始化Transform,设置其目标坐标系的三个方向向量BasisX,BasisY,BasisZ的值。
                             * 获得转换矩阵后,可以用Transform.OfPOint(XYZ pt) 把目标点坐标转换到新坐标系的坐标。
                             * 也可以用Transform.OfVector(XYZ vector) 对向量进行坐标转换。
                             *
                             * 注:这里转换后点坐标或向量的单位与输入点或向量的单位相同。默认Revit API所使用的坐标单位都是英尺。
                             *
                             * 当然你可以使用第三方的代码做纯粹的坐标转换功能。
                             *
                             * Revit API的一些函数需要坐标转换时,都需要Transform类型的。 */
                            geometry.Points[iPoint] = geometry.Transform.OfPoint(geometry.Points[iPoint]);
                        });
                    }
                    for (int i = 0; i < geometry.Points.Count; i++)
                    {
                        XYZ xYZ = geometry.Points[i];
                        ///  参数:
                        //   provider:
                        //     一个提供区域性特定的格式设置信息的对象。
                        //
                        //   format:
                        //     复合格式字符串(请参见“备注”)。
                        //
                        //   args:
                        //     要设置其格式的对象的数组。
                        //
                        // 返回结果:
                        //     完成追加操作后对此实例的引用。 完成追加操作后,此实例包含执行该操作之前已存在的任何数据,
                        //     并且有一个 format 的副本作为后缀,其中任何格式规范都由相应对象参数的字符串表示形式替换。

                        //{0:0.###} 格式化字符串
                        this.sb.AppendFormat(CultureInfo.InvariantCulture.NumberFormat, "{0:0.###} {1:0.###} {2:0.###} ", new object[]
                        {
                            xYZ.X,
                            xYZ.Y,
                            xYZ.Z
                        });
                    }
                }
            }
            //float_array 节点结束
            this.sb.Append("</float_array>\n");
            this.sb.Append("<technique_common>\n");
            //访问器节点
            this.sb.AppendFormat("<accessor source=\"#geom-{0}-positions-array\" count=\"{1}\" stride=\"3\">\n", documentAndMaterialIdHash, num);
            this.sb.Append("<param name=\"X\" type=\"float\"/>\n");
            this.sb.Append("<param name=\"Y\" type=\"float\"/>\n");
            this.sb.Append("<param name=\"Z\" type=\"float\"/>\n");
            //访问器节点结束
            this.sb.Append("</accessor>\n");
            this.sb.Append("</technique_common>\n");
            this.sb.Append("</source>\n");
        }
Example #11
0
 internal int GetNormalsCount(ModelGeometry item)
 {
     return(item.Normals.Count);
 }
Example #12
0
 internal int GetPointCount(ModelGeometry item)
 {
     return(item.Points.Count);
 }
Example #13
0
        private void GeometrySourcePositions(int documentAndMaterialIdHash, IList <ModelGeometry> geometries, string nodename)
        {
            float_array            position_float_array      = new float_array();
            float_array            normal_float_array        = new float_array();
            float_array            uv_float_array            = new float_array();
            sourceTechnique_common position_technique_common = new sourceTechnique_common();
            sourceTechnique_common normal_technique_common   = new sourceTechnique_common();
            sourceTechnique_common uv_technique_common       = new sourceTechnique_common();



            Func <ModelGeometry, int> getCount;

            if ((getCount = common.T_PointCount) == null)
            {
                getCount = common.T_PointCount = new Func <ModelGeometry, int>(common.T.GetPointCount);
            }
            //这是统计geometries - {0} - Pooints - count 数值的和
            //应该统计 某项中 Pooints的和

            //[0] 算是一个几何体,我们要得到几何体下面的Potints的数量,然后乘以3 得到坐标的数量。
            // geometries
            //     [0]:物体模型
            //         Points: 点对象
            //             [0]:包含XYZ的坐标
            int num = geometries.Sum(getCount);


            // 现在我有了一个数据模型,我要对这个数据模型进行操作!!!
            // geometries - geometry - mesh - source - float_array
            // 思路,迭代geometries列表,从索引为 0 的第一个ModelGeometry对象geometry获取属性为Point的数量,乘以3得到坐标数量。



            var geometriesPonits = geometries.Select(t => t.Points).ToList();
            int num1             = geometriesPonits.Count;



            library_geometries library_Geometries = new library_geometries
            {
                geometry = new geometry[geometries.Count] //创建library_geometries中存在的多个geometry对象数组
            };



            mesh[] geomMesh = new mesh[geometries.Count];

            //setting source
            //geomMesh.source[0].id = "geom-" + documentAndMaterialIdHash + "-positions";
            //position_float_array.id = "geom-" + documentAndMaterialIdHash + "-positions-array";
            position_float_array.count = (ulong)(num * 3);//这里有问题3876了都



            using (IEnumerator <ModelGeometry> enumerator = geometries.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    ModelGeometry geometry = enumerator.Current;
                    if (!geometry.Transform.IsIdentity)
                    {
                        Parallel.For(0, geometry.Points.Count, delegate(int iPoint)
                        {
                            geometry.Points[iPoint] = geometry.Transform.OfPoint(geometry.Points[iPoint]);
                        });
                    }
                    for (int i = 0; i < geometry.Points.Count; i++)
                    {
                        XYZ xYZ = geometry.Points[i];
                        position_float_array.Values = new double[]
                        {
                            xYZ.X,
                            xYZ.Y,
                            xYZ.Z
                        };
                        // TODO
                    }
                }
            }

            position_technique_common.accessor               = new accessor();
            position_technique_common.accessor.param         = new param[3];
            position_technique_common.accessor.param[0]      = new param();
            position_technique_common.accessor.param[1]      = new param();
            position_technique_common.accessor.param[2]      = new param();
            position_technique_common.accessor.source        = "#" + position_float_array.id;
            position_technique_common.accessor.count         = 3;
            position_technique_common.accessor.stride        = 3;
            position_technique_common.accessor.param[0].name = "X";
            position_technique_common.accessor.param[0].type = "float";
            position_technique_common.accessor.param[1].name = "Y";
            position_technique_common.accessor.param[1].type = "float";
            position_technique_common.accessor.param[2].name = "Z";
            position_technique_common.accessor.param[2].type = "float";
        }
Example #14
0
        private void ExportSolid2(Solid solid)
        {
            foreach (Face face in solid.Faces)
            {
                if (!(face.Equals(null)))
                {
                    Mesh mesh = face.Triangulate(userSetting.LevelOfDetail / 15.0);
                    if (!(mesh.Equals(null)) && !mesh.Visibility.Equals(Visibility.Invisible))
                    {
                        ModelGeometry exportedGeometry = new ModelGeometry();

                        // 设置坐标系
                        exportedGeometry.Transform = transformationStack.Peek();
                        exportedGeometry.Points    = new List <XYZ>(mesh.Vertices);
                        exportedGeometry.Indices   = new List <int>(mesh.NumTriangles * 3);

                        //指示此转换是否为保形的布尔值。指示此转换是否产生反射的布尔值。反射变换会更改坐标系的惯用性。
                        if (exportedGeometry.Transform.IsConformal && exportedGeometry.Transform.HasReflection)
                        {
                            for (int i = 0; i < mesh.NumTriangles; i++)
                            {
                                MeshTriangle meshTriangle = mesh.get_Triangle(i);
                                exportedGeometry.Indices.Add((int)meshTriangle.get_Index(0));
                                exportedGeometry.Indices.Add((int)meshTriangle.get_Index(2));
                                exportedGeometry.Indices.Add((int)meshTriangle.get_Index(1));
                            }
                        }
                        else
                        {
                            for (int j = 0; j < mesh.NumTriangles; j++)
                            {
                                MeshTriangle meshTriangle2 = mesh.get_Triangle(j);
                                exportedGeometry.Indices.Add((int)meshTriangle2.get_Index(0));
                                exportedGeometry.Indices.Add((int)meshTriangle2.get_Index(1));
                                exportedGeometry.Indices.Add((int)meshTriangle2.get_Index(2));
                            }
                        }
                        ModelGeometry TGeometry = exportedGeometry;

                        //计算模型法线
                        TGeometry.CalculateNormals(TGeometry.Transform.IsConformal && exportedGeometry.Transform.HasReflection);

                        exportedGeometry.CalculateUVs(true, false);

                        //判断是不是反正双面实体
                        if (face.IsTwoSided)
                        {
                            exportedGeometry.MakeDoubleSided();
                        }

                        //将当前元素面的材质ID放入元组中(文档,元素材质ID)
                        ElementId materialElementId       = face.MaterialElementId;
                        Tuple <Document, ElementId> tuple = new Tuple <Document, ElementId>(documentStack.Peek(), materialElementId);

                        //加入元组索引
                        ChangeCurrentMaterial(tuple);

                        //用元组索引将模型加入到模型数据池
                        documentAndMaterialIdToGeometries[tuple].Add(exportedGeometry);
                    }
                }
            }
        }