public static Surface ToRhinoSurface(NXOpen.Face face, out bool parametricOrientation) { FaceEx.FaceData faceData = face.GetData(); parametricOrientation = faceData.NormalReversed; switch (faceData.FaceType) { case NXOpen.Face.FaceType.Planar: return(ToRhinoPlaneSurface(face)); case NXOpen.Face.FaceType.Conical: return(ToRhinoConicalSurface(face, faceData)); case NXOpen.Face.FaceType.Cylindrical: return(ToRhinoCylindricalSurface(face, faceData)); case NXOpen.Face.FaceType.SurfaceOfRevolution: return(ToRhinoRevSurface(face, faceData)); case NXOpen.Face.FaceType.Spherical: case NXOpen.Face.FaceType.Blending: return(ToRhinoSphereSurface(face)); default: return(FromBsurf(face)); } }
static NurbsSurface ToRhinoCylindricalSurface(NXOpen.Face face, FaceEx.FaceData faceData) { NXOpen.Point3d top; // 圆柱顶点 double radius; // 圆柱半径 NXOpen.Point3d bottom; // 圆柱底面中心点 var faceBoundingBox = face.GetAlignedBoundingBox(faceData.Direction); double totalHeight = faceBoundingBox.Height; // 圆柱总高度 if (face.GetEdges().Length == 2 && face.GetEdges().All(obj => obj.SolidEdgeType == NXOpen.Edge.EdgeType.Circular)) { // 未修剪的圆柱 TheUfSession.Eval.Initialize2(face.GetEdges()[0].Tag, out var edgeEvaluator); TheUfSession.Eval.AskArc(edgeEvaluator, out var arc1); TheUfSession.Eval.Free(edgeEvaluator); TheUfSession.Eval.Initialize2(face.GetEdges()[1].Tag, out edgeEvaluator); TheUfSession.Eval.AskArc(edgeEvaluator, out var arc2); TheUfSession.Eval.Free(edgeEvaluator); if (arc2.center.ToPoint3d().Subtract(arc1.center.ToPoint3d()).GetUnitVector().EqualsTo(faceData.Direction.GetUnitVector())) { bottom = arc1.center.ToPoint3d(); } else { bottom = arc2.center.ToPoint3d(); } top = bottom.Move(faceBoundingBox.HeightDirection, totalHeight); radius = arc1.radius; } else { var topExtremePt = WorkPart.MeasureManager.MeasureRectangularExtreme(face, faceBoundingBox.HeightDirection, faceBoundingBox.LengthDirection, faceBoundingBox.WidthDirection); var distToFacePoint = topExtremePt.DistanceTo(faceData.Point, faceData.Direction); top = faceData.Point.Move(faceBoundingBox.HeightDirection, distToFacePoint); bottom = top.Move(faceBoundingBox.HeightDirection.Reverse(), totalHeight); radius = faceData.Radius; } Circle baseCircle = new Circle(new Plane(bottom.ToRhino(), faceBoundingBox.HeightDirection.ToRhino()), radius); var cyl = new Rhino.Geometry.Cylinder(baseCircle, totalHeight); return(cyl.ToNurbsSurface()); }
static RevSurface ToRhinoConicalSurface(NXOpen.Face face, FaceEx.FaceData faceData) { double totalHeight; // 圆锥总高度 NXOpen.Point3d top; // 圆锥顶点 double radius; // 锥底半径 var faceBoundingBox = face.GetAlignedBoundingBox(faceData.Direction); if (face.GetEdges().Length == 1 && face.GetEdges()[0].SolidEdgeType == NXOpen.Edge.EdgeType.Circular) { // 无修剪的锥形 TheUfSession.Eval.Initialize2(face.GetEdges()[0].Tag, out var edgeEvaluator); TheUfSession.Eval.AskArc(edgeEvaluator, out var arc); TheUfSession.Eval.Free(edgeEvaluator); NXOpen.Point3d bottom = arc.center.ToPoint3d(); // 锥底中心点 totalHeight = faceBoundingBox.Height; top = bottom.Move(faceBoundingBox.HeightDirection, totalHeight); radius = arc.radius; } else { var tangentOfHalfAngle = Math.Tan(faceData.RadiusData); top = faceData.Point.Move(faceBoundingBox.HeightDirection, faceData.Radius / tangentOfHalfAngle); totalHeight = faceBoundingBox.Height + faceData.Radius / Math.Tan(faceData.RadiusData); radius = faceData.Radius + faceBoundingBox.Height * tangentOfHalfAngle; } var cone = new Cone(new Plane(top.ToRhino(), faceBoundingBox.HeightDirection.Reverse().ToRhino()), totalHeight, radius); return(cone.ToRevSurface()); // var curve = new LineCurve(outerPointOnCircle.ToRhino(), top.ToRhino()); // return RevSurface.Create(curve, new Line(bottom.ToRhino(), top.ToRhino()), 0.0, Math.PI * 2.0); }
static RevSurface ToRhinoRevSurface(NXOpen.Face face, FaceEx.FaceData faceData) { var bodyFeatures = face.GetBody().GetFeatures(); var revolveFeature = bodyFeatures.FirstOrDefault(obj => obj is NXOpen.Features.Revolve); Curve faceSectionCurve = default; double startRadian = 0.0; double endRadian = Math.PI * 2; if (revolveFeature != null) { NXOpen.Features.RevolveBuilder revolveBuilder = WorkPart.Features.CreateRevolveBuilder(revolveFeature); revolveBuilder.Section.GetOutputCurves(out var sectionCurves); startRadian = revolveBuilder.Limits.StartExtend.Value.Value * Math.PI / 180.0; endRadian = revolveBuilder.Limits.EndExtend.Value.Value * Math.PI / 180.0; revolveBuilder.Destroy(); for (int i = 0; i < sectionCurves.Length; i++) { var baseCurve = sectionCurves[i] as NXOpen.IBaseCurve; var curveMidPt = baseCurve.GetPoint(0.5); if (curveMidPt.DistanceTo(face.Tag).Distance < DistanceTolerance) { faceSectionCurve = baseCurve.ToRhinoCurve(); break; } } } else { var faceBoundingBox = face.GetAlignedBoundingBox(faceData.Direction); var point1 = faceData.Point.Move(faceData.Direction, faceBoundingBox.Height * 1.5); var faceMidPoint = face.GetPoint(); // 求与旋转方向垂直,并且位于面上的方向 var verticalDirection = faceData.Direction.CrossProduct(faceMidPoint.Subtract(faceData.Point)).CrossProduct(faceData.Direction); var point2 = point1.Move(verticalDirection, faceBoundingBox.Length * 1.5); var point3 = point2.Move(faceData.Direction.Reverse(), faceBoundingBox.Height * 3); var point4 = point3.Move(verticalDirection.Reverse(), faceBoundingBox.Length * 1.5); NXOpen.Session.UndoMarkId undoMarkId = TheSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Calc Rev Profile"); NXOpen.Body fourPointSurface = WorkPart.Features.CreateFourPointSurface(point1, point2, point3, point4); try { NXOpen.Features.IntersectionCurve intersectionCurveFeature = WorkPart.Features.CreateIntersectionCurve(fourPointSurface.GetFaces(), face); faceSectionCurve = (intersectionCurveFeature.GetEntities()[0] as NXOpen.Curve).ToRhino(); intersectionCurveFeature.Delete(); fourPointSurface.Delete(); } catch (Exception) { TheSession.UndoToMark(undoMarkId, "Calc Rev Profile"); Console.WriteLine($"无法创建面 {face.Tag} 的交线"); return(null); } finally { TheSession.DeleteUndoMark(undoMarkId, "Calc Rev Profile"); } } return(RevSurface.Create(faceSectionCurve, new Line(faceData.Point.ToRhino(), faceData.Point.Move(faceData.Direction, 10.0).ToRhino()), startRadian, endRadian)); }