//-------------------------------------------------------------------------------------------------- TopoDS_Face _MakeBendSectionFace(MakeContext context) { if (_Relief == ReliefFlags.None) { return(context.FlangeFace); } if (context.OppositeEdge == null) { Messages.Error("No opposite edge found for building relief."); return(null); } if (_Relief.HasFlag(Relief & ReliefFlags.Rectangular)) { // Get notch depth = half distance between both bend and op edge var distTool = new BRepExtrema_DistShapeShape(context.BendEdge, context.OppositeEdge); var notchDepth = distTool.Value() * 0.5; var notchVector = context.TopDirection.ToVec().Multiplied(-notchDepth); // Get edge points var points = new Pnt[4]; var bendEdgeAdaptor = new BRepAdaptor_Curve(context.BendEdge); points[0] = bendEdgeAdaptor.Value(bendEdgeAdaptor.FirstParameter()); points[1] = bendEdgeAdaptor.Value(bendEdgeAdaptor.LastParameter()); var opEdgeAdaptor = new BRepAdaptor_Curve(context.OppositeEdge); points[2] = opEdgeAdaptor.Value(opEdgeAdaptor.LastParameter()); points[3] = opEdgeAdaptor.Value(opEdgeAdaptor.FirstParameter()); // Move if (_Relief.HasFlag(ReliefFlags.OppositeSide)) { notchVector.Reverse(); points[2].Translate(notchVector); points[3].Translate(notchVector); } else { points[0].Translate(notchVector); points[1].Translate(notchVector); } // Make face return(TopoUtils.MakeFace(points)); } return(null); }
//-------------------------------------------------------------------------------------------------- bool _IsFaceOfBendSection(TopoDS_Face face, BendParameter bendParams) { if (bendParams == null) { bendParams = new BendParameter(); // Temporary usage } // Each face of a bend section has two circular edges var edges = face.Edges(); var foundCircularEdges = 0; foreach (var edge in edges) { var edgeAdaptor = new BRepAdaptor_Curve(edge); if (edgeAdaptor.GetGeomType() == GeomAbs_CurveType.GeomAbs_Circle) { foundCircularEdges++; if (bendParams.Edges[0] == null) { bendParams.Edges[0] = edge; bendParams.Axes[0] = edgeAdaptor.Circle().Position(); bendParams.Radii[0] = edgeAdaptor.Circle().Radius(); bendParams.AngleRad = edgeAdaptor.LastParameter() - edgeAdaptor.FirstParameter(); } else { if (!bendParams.Axes[0].Axis.IsCoaxial(edgeAdaptor.Circle().Axis(), 0.01f, 0.001f) || !bendParams.AngleRad.IsEqual(edgeAdaptor.LastParameter() - edgeAdaptor.FirstParameter(), 0.01)) { return(false); // Circular edge with unproper parameters detected } if (bendParams.Edges[1] == null) { // Second edge of bend surface bendParams.Edges[1] = edge; bendParams.Axes[1] = edgeAdaptor.Circle().Position(); break; } // Additional edges, find free place for (int edgeIndex = 0; edgeIndex < bendParams.Edges.Length; edgeIndex++) { if (bendParams.Edges[edgeIndex] == null) { bendParams.Edges[edgeIndex] = edge; break; } if (bendParams.Edges[edgeIndex].IsSame(edge)) { break; } } if (!edgeAdaptor.Circle().Radius().IsEqual(bendParams.Radii[0], 0.000001)) { bendParams.Radii[1] = edgeAdaptor.Circle().Radius(); } } } } // Coaxial circle edges not found, this is not a bend section if (foundCircularEdges != 2) { return(false); } return(true); }
//-------------------------------------------------------------------------------------------------- bool _MakeFlangeFace(MakeContext context) { if (_StartGap <= 0 && _EndGap <= 0) { context.FlangeFace = context.TargetFace; return(true); } // Get points from bend edge and opposite edge var points = new Pnt[4]; var bendEdgeAdaptor = new BRepAdaptor_Curve(context.BendEdge); points[0] = bendEdgeAdaptor.Value(bendEdgeAdaptor.FirstParameter()); points[1] = bendEdgeAdaptor.Value(bendEdgeAdaptor.LastParameter()); if (points[0].Distance(points[1]) <= (_StartGap + _EndGap)) { Messages.Error("The sum of start and end gap is higher than the length of the bending edge."); return(false); } if (context.OppositeEdge == null) { Messages.Error("No opposite edge found for building flange face."); return(false); } // Move vertices from bend edge to op edge var distTool = new BRepExtrema_DistShapeShape(context.BendEdge, context.OppositeEdge); var upVector = context.TopDirection.ToVec().Reversed() * distTool.Value(); points[2] = points[0].Translated(upVector); points[3] = points[1].Translated(upVector); // Sort points, Short edges must be 1->2 and 3->0 if (context.BendEdge.Orientation() == TopAbs_Orientation.TopAbs_REVERSED) { points.Swap(0, 1); } if (points[0].Distance(points[3]) > points[0].Distance(points[2])) { points.Swap(2, 3); } // Move if (_StartGap > 0) { var startVector = context.BendAxis.Direction.ToVec().Multiplied(_StartGap); points[0].Translate(startVector); points[3].Translate(startVector); } if (_EndGap > 0) { var endVector = context.BendAxis.Direction.ToVec().Multiplied(-_EndGap); points[1].Translate(endVector); points[2].Translate(endVector); } // Generate face and new edges context.FlangeFace = TopoUtils.MakeFace(points); if (context.FlangeFace == null) { Messages.Error("Failed making flange face with gaps."); return(false); } context.BendEdge = new BRepBuilderAPI_MakeEdge(points[0], points[1]).Edge(); context.OppositeEdge = new BRepBuilderAPI_MakeEdge(points[3], points[2]).Edge(); // Split original face to avoid problems with additional flanges on the same face TopoDS_Edge startGapEdge = null, endGapEdge = null; var splitOp = new BRepFeat_SplitShape(context.TargetShape); if (_StartGap > 0) { startGapEdge = new BRepBuilderAPI_MakeEdge(points[0], points[3]).Edge(); splitOp.Add(startGapEdge, context.TargetFace); } if (_EndGap > 0) { endGapEdge = new BRepBuilderAPI_MakeEdge(points[1], points[2]).Edge(); splitOp.Add(endGapEdge, context.TargetFace); } splitOp.Build(); if (!splitOp.IsDone()) { Messages.Error("Failed spliting gap edges into target face."); return(false); } UpdateModifiedSubshapes(context.TargetShape, splitOp); context.ModifiedTargetShape = splitOp.Shape(); // Update named shapes var splitFaceList = splitOp.Modified(context.TargetFace).ToList(); foreach (var splitShape in splitFaceList) { var edges = splitShape.Edges(); foreach (var edge in edges) { if (startGapEdge != null && context.StartGapFace == null && edge.Orientation() == splitShape.Orientation() && edge.IsSame(startGapEdge)) { context.StartGapFace = splitShape; break; } if (endGapEdge != null && context.EndGapFace == null && edge.Orientation() != splitShape.Orientation() && edge.IsSame(endGapEdge)) { context.EndGapFace = splitShape; break; } } } return(true); }
/// <summary> /// Searches for the longest edge of a shape, and find the longest parallel edge /// </summary> public static (TopoDS_Edge edge, Ax1?axis, TopoDS_Edge opEdge, Ax1?opAxis) FindLongestEdge(TopoDS_Shape shape) { TopoDS_Edge foundEdge = null; Ax1? foundAxis = null; TopoDS_Edge opEdge = null; Ax1? opAxis = null; // Find the longest edge to revolve around double edgeLen = -1; var edgeInfos = new List <(TopoDS_Edge edge, double len, Ax1 axis)>(); var edges = shape.Edges(); foreach (var edge in edges) { var brepAdaptor = new BRepAdaptor_Curve(edge); if (brepAdaptor.GetGeomType() != GeomAbs_CurveType.GeomAbs_Line) { break; } var v1 = brepAdaptor.Value(brepAdaptor.FirstParameter()); var v2 = brepAdaptor.Value(brepAdaptor.LastParameter()); var len = v1.Distance(v2); var axis = new Ax1(v1, new Vec(v1, v2).ToDir()); if (edge.Orientation() == TopAbs_Orientation.TopAbs_REVERSED) { axis.Reverse(); } edgeInfos.Add((edge, len, axis)); if (foundEdge != null && foundEdge.IsSame(edge)) { // Same edge with another orientation if (foundEdge.Orientation() == TopAbs_Orientation.TopAbs_REVERSED && edge.Orientation() == TopAbs_Orientation.TopAbs_FORWARD) { // Prefer forward edges foundEdge = edge; } continue; } if (len > edgeLen) { foundEdge = edge; edgeLen = len; foundAxis = axis; } } if (foundAxis != null) { // Find opposite edge edgeLen = -1; foreach (var ei in edgeInfos) { if (ei.edge == foundEdge) { continue; } if (!ei.axis.IsParallel(foundAxis.Value, 0.00001)) { continue; } if (ei.len > edgeLen) { opEdge = ei.edge; edgeLen = ei.len; opAxis = ei.axis; } } } return(foundEdge, foundAxis, opEdge, opAxis); }