//-------------------------------------------------------------------------------------------------- public static bool GetCenteredPlaneFromFace(TopoDS_Face face, out Pln plane) { var brepAdaptor = new BRepAdaptor_Surface(face, true); if (brepAdaptor.GetGeomType() != GeomAbs_SurfaceType.GeomAbs_Plane) { Messages.Error("Selected face is not a plane type surface."); plane = Pln.XOY; return(false); } double centerU = brepAdaptor.FirstUParameter() + (brepAdaptor.LastUParameter() - brepAdaptor.FirstUParameter()) / 2; double centerV = brepAdaptor.FirstVParameter() + (brepAdaptor.LastVParameter() - brepAdaptor.FirstVParameter()) / 2; var centerPnt = brepAdaptor.Value(centerU, centerV); var pos = brepAdaptor.Plane().Position; var dir = brepAdaptor.Plane().Position.Direction; if (face.Orientation() == TopAbs_Orientation.TopAbs_REVERSED) { dir.Reverse(); } if (pos.Direction.DotCross(pos.XDirection, pos.YDirection) < 0) { dir.Reverse(); } plane = new Pln(centerPnt, dir); return(true); }
/// <summary> /// triangulate using the opencascade's triangulation /// </summary> /// <param name="shape">input shape</param> /// <param name="deflection">parameter to define the maximum angle</param> /// <returns>a list of faces</returns> public List <Face> Triangulation(TopoDS_Shape shape, double deflection) { List <Face> faces = new List <Face>(); BRepMesh.BRepMesh_IncrementalMesh im = new BRepMesh.BRepMesh_IncrementalMesh(shape, deflection); // 0.7 it controls the number of triangles im.Perform(); if (im.IsDone()) { for (TopExp_Explorer aFaceExplorer = new TopExp_Explorer(im.Shape(), TopAbs_ShapeEnum.TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()) { TopoDS_Face face = TopoDS.TopoDS.ToFace(aFaceExplorer.Current()); TopLoc.TopLoc_Location L = new TopLoc.TopLoc_Location(); Poly_Triangulation tri = BRep.BRep_Tool.Triangulation(face, ref L); bool isDone = true; if (isDone) { Poly_Array1OfTriangle triangles = tri.Triangles(); TColgp_Array1OfPnt nodes = tri.Nodes(); for (int i = tri.Triangles().Lower(); i < tri.Triangles().Upper() + 1; i++) { Poly_Triangle triangle = triangles.Value(i); int node1 = 0, node2 = 0, node3 = 0; triangle.Get(ref node1, ref node2, ref node3); gp_Pnt v1 = nodes.Value(node1); gp_Pnt v2 = nodes.Value(node2); gp_Pnt v3 = nodes.Value(node3); // don't forget about face orientation :) Face f = new Face(new List <gp_Pnt> { v1, v2, v3 }) { orientation = face.Orientation() }; faces.Add(f); } } } } mesh = new MyMesh(faces); return(faces); }
//-------------------------------------------------------------------------------------------------- /// <summary> /// Searches for the face of a shape, and find the parallel face, both by area comparison /// </summary> public static (TopoDS_Face face, Pln?plane, TopoDS_Face opFace, Pln?opPlane) FindFaceByAreaSize(TopoDS_Shape shape, Func <double, double, bool> comparer) { TopoDS_Face foundFace = null; Pln? foundPlane = null; TopoDS_Face opFace = null; Pln? opPlane = null; // Find the longest face double faceArea = Double.NaN; var faceInfos = new List <(TopoDS_Face face, double area, Pln plane)>(); var faces = shape.Faces(); foreach (var face in faces) { var brepAdaptor = new BRepAdaptor_Surface(face); if (brepAdaptor.GetGeomType() != GeomAbs_SurfaceType.GeomAbs_Plane) { continue; } var area = face.Area(); var plane = brepAdaptor.Plane(); if (face.Orientation() == TopAbs_Orientation.TopAbs_REVERSED) { plane.Position.ZReverse(); } faceInfos.Add((face, area, plane)); if (foundFace != null && foundFace.IsSame(face)) { // Same edge with another orientation if (foundFace.Orientation() == TopAbs_Orientation.TopAbs_REVERSED && face.Orientation() == TopAbs_Orientation.TopAbs_FORWARD) { // Prefer forward edges foundFace = face; } continue; } if (foundFace == null || comparer(area, faceArea)) { foundFace = face; faceArea = area; foundPlane = plane; } } if (foundPlane != null) { // Find opposite edge faceArea = Double.NaN; foreach (var fi in faceInfos) { if (ReferenceEquals(fi.face, foundFace)) { continue; } if (!fi.plane.Axis.IsParallel(foundPlane.Value.Axis, 0.00001)) { continue; } if (opFace == null || comparer(fi.area, faceArea)) { opFace = fi.face; faceArea = fi.area; opPlane = fi.plane; } } } return(foundFace, foundPlane, opFace, opPlane); }