/// <summary> /// 将楼梯中所有与选择的表面相同方向的面上都生成面层 /// </summary> /// <param name="docTran"> </param> /// <param name="elem"> 用来生成面层的单元。此函数会搜索此单元中所有与 baseFace 同法向的面,并进行面层的绘制 </param> /// <param name="pickedFace"> 楼梯中用来生成面层的那个面</param> /// <param name="faceOp"> 生成面层的选项</param> /// <param name="transf"> </param> /// <returns></returns> private IList <DirectShape> ExtendToFacesWithSameNormal(Transaction docTran, Element elem, PlanarFace pickedFace, FaceOptions faceOp, Transform transf) { IList <DirectShape> directShapes = new List <DirectShape>(); // 值中的false 表示solid 是 Family中的solid,后期还要再进行一次transform才能变换 Familyinstance 所对应的位置 Dictionary <Solid, bool> solids = GeoHelper.GetSolidsInModel(elem, GeoHelper.SolidVolumnConstraint.Positive); foreach (Solid solid in solids.Keys) { foreach (Face face in solid.Faces) { if ((face is PlanarFace)) { PlanarFace planarFace = (PlanarFace)face; if (GeoHelper.IsSameDirection(planarFace.FaceNormal, transf.OfVector(pickedFace.FaceNormal))) { DirectShape ds = ConstructSurfaceFromPlanarFace(docTran, planarFace, faceOp, Transform.Identity); if (ds != null) { directShapes.Add(ds); } } } } } return(directShapes); }
/// <summary> /// 判断当前创建出来的那个实体是否与其他单元相交,如果相交,则在原实体中剪除相交的部分,如果没有相交,则直接返回原实体集合(集合中的元素个数与原 originalSolids 集合中元素个数相同)。 /// </summary> /// <param name="directShape"></param> /// <param name="originalSolids"> directShape 所对应的实体,由于 ExecuteBooleanOperationModifyingOriginalSolid 函数中的 OriginalSolid /// 不能是直接从Revit的Element中得到的,所以要将前面通过轮廓拉伸出来的实体作为参数传入。</param> /// <param name="hasIntersect"></param>剪切后的实体的体积有可能不大于 0 啊 /// <returns> 返回的集合中的元素个数与原 originalSolids 集合中元素个数相同。剪切后的实体的体积有可能不大于 0 .</returns> private IList <Solid> ExcludeIntersect(DirectShape directShape, IList <Solid> originalSolids, out bool hasIntersect) { // 应用过滤器,在整个文档中搜索与指定Element相交的Element FilteredElementCollector collector = new FilteredElementCollector(directShape.Document); ElementIntersectsElementFilter elementFilter = new ElementIntersectsElementFilter(element: directShape, inverted: false); collector.WherePasses(elementFilter); // 排除面层本身 collector.Excluding(new ElementId[] { directShape.Id }); if (!collector.Any()) { // 说明没有相交的部分 hasIntersect = false; return(originalSolids); } hasIntersect = true; // 将与其相交的实体进行剪切操作 bool promptWhileError = false; foreach (Element interSectElem in collector) { var interSectSolids = GeoHelper.GetSolidsInModel(interSectElem, GeoHelper.SolidVolumnConstraint.Positive).Keys; // 与面层对象相交的 Element 中所有的实体 for (int i = 0; i < originalSolids.Count; i++) { Solid originalS = originalSolids[i]; foreach (Solid interSectS in interSectSolids) { try { // 在原实体中减去相交的部分 BooleanOperationsUtils.ExecuteBooleanOperationModifyingOriginalSolid(originalS, interSectS, BooleanOperationsType.Difference); } catch (Exception ex) { if (promptWhileError) { // 在剪切时如果不能剪切,则不剪切。 DialogResult res = MessageBox.Show("实体剪切时出现错误,可能的原因是面层与模型中的其他实体有细微交叉," + "以致剪切后的实体出现细小锯齿。\n\r (忽略此细微交叉对于面层算量并无明显影响)。" + " \n\r 点击“是”以忽略并继续,点击“否”不再提示。", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button2); promptWhileError = (res != DialogResult.No); } } } // 剪切后的实体的体积有可能不大于 0 啊 originalSolids[i] = originalS; // 将剪切完成后的 Solid 再赋值回集合中 } } return(originalSolids); }
public List <PlanarFace> GetMeshedFaces() { Mesh mesh = GetMesh(); TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(false); List <XYZ> args = new List <XYZ>(3); XYZ[] triangleCorners = new XYZ[3]; for (int i = 0; i < mesh.NumTriangles; ++i) { MeshTriangle triangle = mesh.get_Triangle(i); triangleCorners[0] = triangle.get_Vertex(0); triangleCorners[1] = triangle.get_Vertex(1); triangleCorners[2] = triangle.get_Vertex(2); TessellatedFace tesseFace = new TessellatedFace(triangleCorners, ElementId.InvalidElementId); if (builder.DoesFaceHaveEnoughLoopsAndVertices( tesseFace)) { builder.AddFace(tesseFace); } } builder.CloseConnectedFaceSet(); TessellatedShapeBuilderResult result = builder.Build( TessellatedShapeBuilderTarget.AnyGeometry, TessellatedShapeBuilderFallback.Mesh, ElementId.InvalidElementId); var geo = result.GetGeometricalObjects(); var solids = GeoHelper.GetSolidsInModel(geo, GeoHelper.SolidVolumnConstraint.Any); var faces = GeoHelper.GetSurfaces(solids.Keys); return(faces.OfType <PlanarFace>().ToList()); }