int OCCEdge::createArc(OCCVertex *start, OCCVertex *end, OCCStruct3d center) { try { gp_Pnt aP1(start->X(), start->Y(), start->Z()); gp_Pnt aP2(center.x, center.y, center.z); gp_Pnt aP3(end->X(), end->Y(), end->Z()); Standard_Real Radius = aP1.Distance(aP2); gce_MakeCirc MC(aP2,gce_MakePln(aP1, aP2, aP3).Value(), Radius); const gp_Circ& Circ = MC.Value(); Standard_Real Alpha1 = ElCLib::Parameter(Circ, aP1); Standard_Real Alpha2 = ElCLib::Parameter(Circ, aP3); Handle(Geom_Circle) C = new Geom_Circle(Circ); Handle(Geom_TrimmedCurve) arc = new Geom_TrimmedCurve(C, Alpha1, Alpha2, false); this->setShape(BRepBuilderAPI_MakeEdge(arc, start->vertex, end->vertex)); } catch(Standard_Failure &err) { Handle_Standard_Failure e = Standard_Failure::Caught(); const Standard_CString msg = e->GetMessageString(); if (msg != NULL && strlen(msg) > 1) { setErrorMessage(msg); } else { setErrorMessage("Failed to create arc"); } return 0; } return 1; }
// Returns an upper or lower point on the wing profile in // dependence of parameter xsi, which ranges from 0.0 to 1.0. // For xsi = 0.0 point is equal to leading edge, for xsi = 1.0 // point is equal to trailing edge. If fromUpper is true, a point // on the upper profile is returned, otherwise from the lower. gp_Pnt CCPACSWingProfile::GetPoint(double xsi, bool fromUpper) { Update(); if (xsi < 0.0 || xsi > 1.0) { throw CTiglError("Error: Parameter xsi not in the range 0.0 <= xsi <= 1.0 in CCPACSWingProfile::GetPoint", TIGL_ERROR); } if (xsi < Precision::Confusion()) { return GetLEPoint(); } if ((1.0 - xsi) < Precision::Confusion()) { return GetTEPoint(); } gp_Pnt chordPoint3d = GetChordPoint(xsi); gp_Pnt2d chordPoint2d(chordPoint3d.X(), chordPoint3d.Z()); gp_Pnt le3d = GetLEPoint(); gp_Pnt te3d = GetTEPoint(); gp_Pnt2d le2d(le3d.X(), le3d.Z()); gp_Pnt2d te2d(te3d.X(), te3d.Z()); // Normal vector on chord line gp_Vec2d normalVec2d(-(le2d.Y() - te2d.Y()), (le2d.X() - te2d.X())); // Compute 2d line normal to chord line Handle(Geom2d_Line) line2d = new Geom2d_Line(chordPoint2d, gp_Dir2d(normalVec2d)); // Define xz-plane for curve projection gp_Pln xzPlane = gce_MakePln(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0), gp_Pnt(0.0, 0.0, 1.0)); // Loop over all edges of the wing profile curve and try to find intersection points std::vector<gp_Pnt2d> ipnts2d; TopoDS_Edge edge; if (fromUpper) { edge = GetUpperWire(); } else { edge = GetLowerWire(); } Standard_Real firstParam; Standard_Real lastParam; // get curve and trim it - trimming is important, else it will be infinite Handle(Geom_Curve) curve3d = BRep_Tool::Curve(edge, firstParam, lastParam); curve3d = new Geom_TrimmedCurve(curve3d, firstParam, lastParam); // Convert 3d curve to 2d curve lying in the xz-plane Handle(Geom2d_Curve) curve2d = GeomAPI::To2d(curve3d, xzPlane); // Check if there are intersection points between line2d and curve2d Geom2dAPI_InterCurveCurve intersection(line2d, curve2d); for (int n = 1; n <= intersection.NbPoints(); n++) { ipnts2d.push_back(intersection.Point(n)); } if (ipnts2d.size() == 1) { // There is only one intesection point with the wire gp_Pnt2d ipnt2d = ipnts2d[0]; gp_Pnt ipnt3d(ipnt2d.X(), 0.0, ipnt2d.Y()); return ipnt3d; } else if (ipnts2d.size() > 1) { // There are one or more intersection points with the wire. Find the // points with the minimum and maximum y-values. gp_Pnt2d minYPnt2d = ipnts2d[0]; gp_Pnt2d maxYPnt2d = minYPnt2d; for (std::vector<gp_Pnt2d>::size_type i = 1; i < ipnts2d.size(); i++) { gp_Pnt2d currPnt2d = ipnts2d[i]; if (currPnt2d.Y() < minYPnt2d.Y()) { minYPnt2d = currPnt2d; } if (currPnt2d.Y() > maxYPnt2d.Y()) { maxYPnt2d = currPnt2d; } } gp_Pnt maxYPnt3d(maxYPnt2d.X(), 0.0, maxYPnt2d.Y()); gp_Pnt minYPnt3d(minYPnt2d.X(), 0.0, minYPnt2d.Y()); if (fromUpper) { return maxYPnt3d; } return minYPnt3d; } throw CTiglError("Error: No intersection point found in CCPACSWingProfile::GetPoint", TIGL_NOT_FOUND); }