/// <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); }
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"); }
/// <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); }
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) { } }
/// <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); }
internal int b__21_2(ModelGeometry item) { return(item.Normals.Count); }
internal int b__21_1(ModelGeometry item) { return(item.Points.Count); }
internal int b__21_0(ModelGeometry item) { return(item.Indices.Count); }
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"); }
/// <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"); }
internal int GetNormalsCount(ModelGeometry item) { return(item.Normals.Count); }
internal int GetPointCount(ModelGeometry item) { return(item.Points.Count); }
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"; }
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); } } } }