//-------------------------------------------------------------------------------------------------- protected TopoDS_Shape GetOperand2DFaces(int operandIndex, Pln?boundToPlane) { if (boundToPlane.HasValue) { GetOperand(operandIndex)?.BindToPlane(GetCoordinateSystem(), this, boundToPlane); } var sourceBrep = GetOperandBRep(operandIndex); if (sourceBrep == null) { return(null); } // Check if we already have faces var exp = new TopExp_Explorer(sourceBrep, TopAbs_ShapeEnum.TopAbs_FACE, TopAbs_ShapeEnum.TopAbs_SHAPE); if (exp.More()) { return(sourceBrep); } var baseFacesShape = TopoUtils.CreateFacesFromWires(sourceBrep, Pln.XOY); if (boundToPlane != null && baseFacesShape != null) { var trsf = new Trsf(boundToPlane.Value.Rotation(), boundToPlane.Value.Location.ToVec()); baseFacesShape = baseFacesShape.Moved(new TopLoc_Location(trsf)); } return(baseFacesShape); }
//-------------------------------------------------------------------------------------------------- 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); }
void eConsulta(SharpMap.Data.FeatureDataTable resultado) { try { if ((resultado as DataTable).Rows.Count > 0) { SharpMap.Data.FeatureDataRow fdr = TopoUtils.LocatePolygon2(this.ultimaPosicion, resultado); Estancia est = AdminMapas.RefrescaCapaInfoEst(this.Mapa, fdr[1].ToString()); this.actualizarPropiedades(est); this.tabControl1.SelectedTab = tpInfo; this.miVMapa.Refresh(); } } catch (Exception error) { System.Windows.Forms.MessageBox.Show(error.Message, "Error"); } }
//-------------------------------------------------------------------------------------------------- bool _AddSectionToResult(MakeContext context, Section section, Trsf transformation) { if (section.IsBendSection) { // Calculate k-factor and bend allowance // k = 0.65 + 0.5 * log(r/s) // This is DIN/ISO value range of 0..2 var thickness = section.BendParameter.Radii[0].Distance(section.BendParameter.Radii[1]).Abs(); var radius = Math.Min(section.BendParameter.Radii[0], section.BendParameter.Radii[1]); var kfac = (0.65 + 0.5 * Math.Log10(radius / thickness)).Clamp(0.0, 1.0); var bendAllowance = (radius + thickness * 0.5 * kfac) * section.BendParameter.AngleRad; if (context.DebugOutput) { Messages.Trace($"The bend section has following parameters: thickness {thickness} radius {radius} kfactor {kfac} angle {section.BendParameter.AngleRad} bend allowance {bendAllowance}."); } var axes = new [] { section.BendParameter.Axes[0], section.BendParameter.Axes[1] }; // Which side of the bend section is our in-side? // A point translated along the XDirection of the axis using one of the radii must be on the edge. var swapSign = 1.0; var edgeAdaptor = new BRepAdaptor_Curve(section.BendParameter.ConnectedInSharedEdges[0]); var pnt0 = axes[0].Location.Translated(axes[0].XDirection.ToVec() * section.BendParameter.Radii[0]); var pnt1 = axes[0].Location.Translated(axes[0].XDirection.ToVec() * section.BendParameter.Radii[1]); if (!(edgeAdaptor.Line().Contains(pnt0, 0.000001) || edgeAdaptor.Line().Contains(pnt1, 0.000001))) { swapSign = -1.0; axes[0].Rotate(section.BendParameter.Axes[0].Axis, section.BendParameter.AngleRad); axes[1].Rotate(section.BendParameter.Axes[1].Axis, section.BendParameter.AngleRad); } axes[0].Transform(transformation); axes[1].Transform(transformation); // Create no bend section, if kfac==0 if (kfac > 0.0) { // Reconstruct faces var pnts = new Pnt[4]; // Corner points of one section pnts[0] = axes[0].Location.Translated(axes[0].XDirection.ToVec() * section.BendParameter.Radii[0]); pnts[1] = axes[1].Location.Translated(axes[1].XDirection.ToVec() * section.BendParameter.Radii[0]); pnts[2] = axes[0].Location.Translated(axes[0].XDirection.ToVec() * section.BendParameter.Radii[1]); pnts[3] = axes[1].Location.Translated(axes[1].XDirection.ToVec() * section.BendParameter.Radii[1]); var extrudeVec = axes[0].YDirection.ToVec() * swapSign * bendAllowance; // Vector to extrude to the other section // Top/Bottom context.Sewer.Add(TopoUtils.MakeFace(new[] { pnts[0], pnts[0].Translated(extrudeVec), pnts[1].Translated(extrudeVec), pnts[1] })); context.Sewer.Add(TopoUtils.MakeFace(new[] { pnts[2], pnts[2].Translated(extrudeVec), pnts[3].Translated(extrudeVec), pnts[3] })); // Sides context.Sewer.Add(TopoUtils.MakeFace(new[] { pnts[0], pnts[0].Translated(extrudeVec), pnts[2].Translated(extrudeVec), pnts[2] })); context.Sewer.Add(TopoUtils.MakeFace(new[] { pnts[1], pnts[1].Translated(extrudeVec), pnts[3].Translated(extrudeVec), pnts[3] })); } // Create transform for connected sections var rotTrsf = new Trsf(axes[0].Axis, swapSign * -section.BendParameter.AngleRad); transformation.PreMultiply(rotTrsf); var dispTrsf = new Trsf(axes[0].YDirection.ToVec() * swapSign * bendAllowance); transformation.PreMultiply(dispTrsf); //section.Faces.ForEach(f => context.Sewer.Add(f)); } else { // Copy all faces to the result foreach (var face in section.Faces) { var transformedFace = face.Moved(new TopLoc_Location(transformation)); context.Sewer.Add(transformedFace); //context.Sewer.Add(face); } } // Process children foreach (var child in section.Children) { _AddSectionToResult(context, child, transformation); } return(true); }
//-------------------------------------------------------------------------------------------------- bool _DoThicken(MakeContext context) { // Do we need to thicken? if (context.AllWiresClosed && _StartCapping != CappingMode.None && _EndCapping != CappingMode.None) { return(true); } // Get tolerance var anaTolerance = new ShapeAnalysis_ShapeTolerance(); var tolerance = anaTolerance.Tolerance(context.Result, 1, TopAbs_ShapeEnum.TopAbs_SHAPE); // Get max of all var joinType = _ThickenCornerType == CornerType.Round ? GeomAbs_JoinType.GeomAbs_Arc : GeomAbs_JoinType.GeomAbs_Intersection; if (context.AllWiresClosed) { // Thicken Solid and remove Caps var removeFaceList = new TopTools_ListOfShape(); if (_StartCapping == CappingMode.None) { removeFaceList.Append(context.StartFace); } if (_EndCapping == CappingMode.None) { removeFaceList.Append(context.EndFace); } // Build thicken solid var makeThick = new BRepOffsetAPI_MakeThickSolid(); var thicknessSign = ThickenDirection == Direction.Inwards ? -1 : 1; makeThick.MakeThickSolidByJoin(context.Result, removeFaceList, Thickness * thicknessSign, tolerance, BRepOffset_Mode.BRepOffset_Skin, true, false, joinType); if (!makeThick.IsDone()) { Messages.Error($"Failed to thicken solid: {makeThick.MakeOffset().Error().ToString()}."); return(false); } context.Result = makeThick.Shape(); } else { // Thicken shell var shell = context.Result.Shells()[0]; if (shell == null) { Messages.Error("Generated shell is invalid."); return(false); } var makeThick = new BRepOffset_MakeOffset(); var thicknessSign = ThickenDirection == Direction.Inwards ? -1 : 1; makeThick.Initialize(shell, Thickness * thicknessSign, tolerance, BRepOffset_Mode.BRepOffset_Skin, true, false, joinType, true); makeThick.MakeOffsetShape(); if (!makeThick.IsDone()) { Messages.Error($"Failed converting shell to thick solid: {makeThick.Error().ToString()}."); return(false); } context.Result = makeThick.Shape(); TopoUtils.UpdateSolidOrientation(context.Result); } 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); }
//-------------------------------------------------------------------------------------------------- TopoDS_Shape _CreateProfile(TopoDS_Edge firstSpineEdge) { var firstSpineCurve = firstSpineEdge.Curve(out double firstParam, out double secondParam); if (firstSpineCurve == null) { return(null); } Pnt location = default; Vec edgeTangent = default; firstSpineCurve.D1(firstParam, ref location, ref edgeTangent); Pln plane = new Pln(location, edgeTangent.ToDir()); // Custom sketch if (_Profile == ProfileType.Custom) { return(_CreateProfileFromSketch(plane)); } // Presets var edges = _CreateProfileEdges(plane, _SizeX * 0.5, _SizeY * 0.5); if (_Debug_WriteoutProfile) { TopoDS_Builder builder = new(); TopoDS_Compound compound = new(); builder.MakeCompound(compound); foreach (var edge in edges) { builder.Add(compound, edge); } File.WriteAllBytes(@"_Debug_PipeProfile.brep", BRepExchange.WriteASCII(compound, false)); } BRepBuilderAPI_MakeWire wireMaker = new(); foreach (var edge in _CreateProfileEdges(plane, _SizeX * 0.5, _SizeY * 0.5)) { wireMaker.Add(edge); } TopoDS_Shape result = wireMaker.Wire(); if (_Profile == ProfileType.HollowCircle || _Profile == ProfileType.HollowRectangle) { var innerSizeX = _SizeX * 0.5 - _Thickness; var innerSizeY = _SizeY * 0.5 - _Thickness; if (innerSizeX > 0 && (_Flags.HasFlag(PipeFlags.SymmetricProfile) || innerSizeY > 0)) { TopoDS_Builder builder = new(); TopoDS_Compound compound = new(); builder.MakeCompound(compound); builder.Add(compound, result); wireMaker = new(); foreach (var edge in _CreateProfileEdges(plane, innerSizeX, innerSizeY)) { wireMaker.Add(edge); } builder.Add(compound, wireMaker.Wire()); result = compound; } } var face = TopoUtils.CreateFacesFromWires(result, plane); return(face); }