//-------------------------------------------------------------------------------------------------- public static Dictionary <TopoDS_Face, TopoDS_Edge> FindConnectedFaces(TopoDS_Shape shape, TopoDS_Face face) { var list = new Dictionary <TopoDS_Face, TopoDS_Edge>(); // Get map of all faces with their ancestors var faceMap = new TopTools_IndexedDataMapOfShapeListOfShape(50); TopExp.MapShapesAndAncestors(shape, TopAbs_ShapeEnum.TopAbs_EDGE, TopAbs_ShapeEnum.TopAbs_FACE, faceMap); foreach (var edge in face.Edges()) { var faceList = faceMap.FindFromKey(edge).ToList(); foreach (var connectedFace in faceList) { if (connectedFace.IsSame(face)) { continue; } if (list.Keys.Any(f => connectedFace.IsSame(f))) { continue; } list.Add(connectedFace.ToFace(), edge); } } return(list); }
//-------------------------------------------------------------------------------------------------- public IEnumerable <TopoDS_Edge> FindValidEdges(TopoDS_Shape sourceShape) { var analysis = new ShapeAnalysis_Edge(); var mapOfEdgesToFaces = new TopTools_IndexedDataMapOfShapeListOfShape(1); TopExp.MapShapesAndAncestors(sourceShape, TopAbs_ShapeEnum.TopAbs_EDGE, TopAbs_ShapeEnum.TopAbs_FACE, mapOfEdgesToFaces); foreach (var edge in sourceShape.Edges()) { var valid = true; var faces = mapOfEdgesToFaces.FindFromKey(edge).ToList(); // Check if we have no face if (faces.Count == 0) { continue; } // Check if it is a seam edge foreach (var face in faces) { if (analysis.IsSeam(edge, face.ToFace())) { valid = false; break; } } if (valid) { yield return(edge); } } }
//-------------------------------------------------------------------------------------------------- public static TopoDS_Face FindConnectedFace(TopoDS_Shape shape, TopoDS_Face face, TopoDS_Edge sharedEdge) { // Get map of all faces with their ancestors var faceMap = new TopTools_IndexedDataMapOfShapeListOfShape(50); TopExp.MapShapesAndAncestors(shape, TopAbs_ShapeEnum.TopAbs_EDGE, TopAbs_ShapeEnum.TopAbs_FACE, faceMap); foreach (var edge in face.Edges()) { if (edge.IsSame(sharedEdge)) { var faceList = faceMap.FindFromKey(edge).ToList(); foreach (var connectedFace in faceList) { if (connectedFace.IsSame(face)) { continue; } return(connectedFace.ToFace()); } } } return(null); }
//-------------------------------------------------------------------------------------------------- public static List <TopoDS_Shape> FindEdgesByVertex(TopoDS_Shape shape, TopoDS_Vertex vertex) { // Get map of all faces with their ancestors var edgeMap = new TopTools_IndexedDataMapOfShapeListOfShape(4); TopExp.MapShapesAndAncestors(shape, TopAbs_ShapeEnum.TopAbs_VERTEX, TopAbs_ShapeEnum.TopAbs_EDGE, edgeMap); return(edgeMap.FindFromKey(vertex).ToList()); }
//-------------------------------------------------------------------------------------------------- /// <summary> /// Searches for adjacent faces /// </summary> public static (TopoDS_Face face1, TopoDS_Face face2) FindAdjacentFaces(TopoDS_Shape shape, TopoDS_Edge edgeShape) { // Create a Map of Edge and connected Faces var mapOfEdgesToFaces = new TopTools_IndexedDataMapOfShapeListOfShape(1); TopExp.MapShapesAndAncestors(shape, TopAbs_ShapeEnum.TopAbs_EDGE, TopAbs_ShapeEnum.TopAbs_FACE, mapOfEdgesToFaces); var faces = mapOfEdgesToFaces.FindFromKey(edgeShape).ToList(); var face1 = faces.Count > 0 ? faces[0].ToFace() : null; var face2 = faces.Count > 1 ? faces[1].ToFace() : null; return(face1, face2); }
//-------------------------------------------------------------------------------------------------- /// <summary> /// Searches for the smallest and biggest adjacent face /// </summary> public static (TopoDS_Face smallestFace, TopoDS_Face largestFace) FindSmallestAndLargestAdjacentFaces(TopoDS_Shape shape, TopoDS_Edge edgeShape) { // Create a Map of Edge and connected Faces var mapOfEdgesToFaces = new TopTools_IndexedDataMapOfShapeListOfShape(1); TopExp.MapShapesAndAncestors(shape, TopAbs_ShapeEnum.TopAbs_EDGE, TopAbs_ShapeEnum.TopAbs_FACE, mapOfEdgesToFaces); var faceDict = new Dictionary <TopoDS_Face, double>(); var faces = mapOfEdgesToFaces.FindFromKey(edgeShape).ToList(); foreach (var face in faces) { var gprops = new GProp_GProps(); BRepGProp.SurfaceProperties(face, gprops, false); faceDict.Add(face.ToFace(), gprops.Mass()); } if (!faceDict.Any()) { return(null, null); } var min = faceDict.First(); var max = min; foreach (var kvp in faceDict.Skip(1)) { if (kvp.Value < min.Value) { min = kvp; } if (kvp.Value > max.Value) { max = kvp; } } return(min.Key, max.Key); }
/// <summary> /// Apply fillet on a list of wires. The common endpoints of wires are considered the fillet vertexes. /// </summary> private static TopoDSWire ApplyFilletOnWires(IEnumerable <SceneSelectedEntity> filletNodes, double radius, int filletChamferType) { // This method processes only fillet2D and chamfer2D operations if ((filletChamferType != (int)FilletChamferTypes.SimpleFillet2D) && (filletChamferType != (int)FilletChamferTypes.SimpleChamfer2D)) { return(null); } try { // Make a face fom the wires var wires = new List <SceneSelectedEntity>(); foreach (var node in filletNodes) { wires.Add(node); } var face = MakeFaceFunction.ComposeWires(wires, true); if ((face == null) || (face.IsNull)) { return(null); } var fillet = new BRepFilletAPIMakeFillet2d(); // Initialize a fillet with the face made from the 2 wires fillet.Init(face); // Fillet the common vertexes Node previousNode = null; foreach (var node in filletNodes) { if (previousNode != null) { var wire1 = previousNode.Get <NamedShapeInterpreter>().Shape; var wire2 = node.Node.Get <NamedShapeInterpreter>().Shape; var listOfCommonVertex = GeomUtils.CommonVertexes(wire1, wire2); if (listOfCommonVertex.Count >= 1) { foreach (var vertex in listOfCommonVertex) { if (filletChamferType == (int)FilletChamferTypes.SimpleFillet2D) { // If the operation is a fillet fillet.AddFillet(vertex, radius); } else { // Map all edges to faces var map = new TopToolsIndexedDataMapOfShapeListOfShape(1); TopExp.MapShapesAndAncestors(wire1, TopAbsShapeEnum.TopAbs_VERTEX, TopAbsShapeEnum.TopAbs_EDGE, map); // Locate an ancestor face for (var i = 1; i <= map.Extent; i++) { var localVertex = TopoDS.Vertex(map.FindKey(i)); if (!vertex.IsSame(localVertex)) { continue; } // We found an ancestor edge var edge = TopoDS.Edge(map.FindFromIndex(i).First); // Add the vertex and edge on the chamfer algorithm //fillet.AddChamfer(TopoDS.Edge(edge), TopoDS.Edge(edge2), radius, radius); fillet.AddChamfer(TopoDS.Edge(edge), vertex, radius, GeomUtils.DegreesToRadians(45)); } } } } else { return(null); } } previousNode = node.Node; } // Test if the operation succeeded if (fillet.Status != ChFi2dConstructionError.ChFi2d_IsDone) { return(null); } var shape = fillet.Shape; if ((shape == null) || (shape.IsNull)) { return(null); } var aMap = new TopToolsIndexedMapOfShape(1); TopExp.MapShapes(fillet.Shape, TopAbsShapeEnum.TopAbs_WIRE, aMap); if (aMap.Extent != 1) { return(null); } var newWire = new BRepBuilderAPIMakeWire(); var ex = new BRepToolsWireExplorer(TopoDS.Wire(aMap.FindKey(1))); for (; ex.More; ex.Next()) { newWire.Add(ex.Current); } return(newWire.Wire); } catch (Exception ex) { Log.Error("Apply Fillet2D error: " + ex.Message); } return(null); }
//-------------------------------------------------------------------------------------------------- protected Dictionary <TopoDS_Edge, TopoDS_Face> FindReferenceFaces(TopoDS_Shape sourceShape, IEnumerable <TopoDS_Edge> edges, bool reverseOrientation) { var dict = new Dictionary <TopoDS_Edge, TopoDS_Face> (); // Create a Map of Edges and connected Faces var mapOfEdgesToFaces = new TopTools_IndexedDataMapOfShapeListOfShape(1); TopExp.MapShapesAndAncestors(sourceShape, TopAbs_ShapeEnum.TopAbs_EDGE, TopAbs_ShapeEnum.TopAbs_FACE, mapOfEdgesToFaces); foreach (var edge in edges) { if (dict.ContainsKey(edge)) { continue; } TopoDS_Face face = null; var faces = mapOfEdgesToFaces.FindFromKey(edge).ToList(); if (faces.Count == 0) { continue; } var lastSize = 0.0; foreach (var faceShape in faces) { var gprops = new GProp_GProps(); BRepGProp.SurfaceProperties(faceShape, gprops, false); var size = gprops.Mass() * (reverseOrientation ? -1.0 : 1.0); // Init with the first face if (face == null) { face = faceShape.ToFace(); lastSize = size; continue; } // Take the biggest face. if (size < lastSize) { continue; } if (size > lastSize) { face = faceShape.ToFace(); lastSize = size; continue; } // If all faces are of equal size, take forward orientated face as reference for distance if (faceShape.Orientation() == (reverseOrientation ? TopAbs_Orientation.TopAbs_REVERSED : TopAbs_Orientation.TopAbs_FORWARD)) { face = faceShape.ToFace(); lastSize = size; } } dict.Add(edge, face); } return(dict); }
private static TopoDSShape ApplyFillet(double thickness, TopoDSShape body, int edgeNumber, int operationType) { try { // Create fillet var aEdgeExplorer = new TopExpExplorer(body, TopAbsShapeEnum.TopAbs_EDGE, TopAbsShapeEnum.TopAbs_SHAPE); var number = 1; TopoDSShape shape = null; while (aEdgeExplorer.More) { if ((edgeNumber == 0) || (edgeNumber == number)) { var anEdge = TopoDS.Edge(aEdgeExplorer.Current); if (operationType == (int)FilletChamferTypes.SimpleFillet) { var fillet = new BRepFilletAPIMakeFillet(body, ChFi3dFilletShape.ChFi3d_Rational); // Add edge to fillet algorithm fillet.Add(thickness, anEdge); // Check if valid contour try { if (fillet.StripeStatus(fillet.Contour(anEdge)) != ChFiDSErrorStatus.ChFiDS_Ok) { return(null); } } catch (Exception) { Log.Info("Exception on applying fillet"); } shape = fillet.Shape; } else { var chamfer = new BRepFilletAPIMakeChamfer(body); var aMap = new TopToolsIndexedDataMapOfShapeListOfShape(1); TopExp.MapShapesAndAncestors(body, TopAbsShapeEnum.TopAbs_EDGE, TopAbsShapeEnum.TopAbs_FACE, aMap); // Locate an ancestor face for (var i = 1; i < aMap.Extent; i++) { var localEdge = TopoDS.Edge(aMap.FindKey(i)); if (!anEdge.IsSame(localEdge)) { continue; } // We found an ancestor face var face = TopoDS.Face(aMap.FindFromIndex(i).First); // Add the edge and face on the chmafer algorithm chamfer.Add(thickness, thickness, anEdge, face); } shape = chamfer.Shape; } } aEdgeExplorer.Next(); number++; } // Check the shape validity if ((shape == null) || (shape.IsNull)) { return(null); } return(shape); } catch (Exception ex) { Log.Info("Apply fillet error: " + ex.Message); } return(null); }