-// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+// Copyright (C) 2014-2022 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#include <GeomAlgoAPI_Circ2dBuilder.h>
#include <BRep_Tool.hxx>
#include <ElCLib.hxx>
+#include <GccAna_Circ2d2TanOn.hxx>
#include <GccAna_Circ2d2TanRad.hxx>
#include <GccAna_Circ2d3Tan.hxx>
#include <GccAna_Circ2dTanCen.hxx>
// Provide different mechanisms to create circle:
// * by passing points
// * by tangent edges
+// * by transversal line
// * with specified radius
// * etc.
class CircleBuilder
}
}
+ void setTransversalLine(const std::shared_ptr<GeomAPI_Shape>& theLine)
+ {
+ if (!theLine)
+ return;
+
+ const TopoDS_Edge& anEdge = TopoDS::Edge(theLine->impl<TopoDS_Shape>());
+
+ double aFirst, aLast;
+ TopLoc_Location aLoc;
+ Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, myPlane, aLoc, aFirst, aLast);
+ myTransversalLine = CurveAdaptorPtr(new Geom2dAdaptor_Curve(aCurve, aFirst, aLast));
+ }
+
void setPassingPoints(const std::vector< std::shared_ptr<GeomAPI_Pnt2d> >& thePoints)
{
std::vector< std::shared_ptr<GeomAPI_Pnt2d> >::const_iterator aPIt;
case 1:
aResult = circleByPointAndTwoTangentCurves();
break;
- case 2:
- aResult = circleByTwoPointsAndTangentCurve();
+ case 2: {
+ if (myTransversalLine)
+ aResult = circleByTwoPointsAndTransversalLine();
+ else
+ aResult = circleByTwoPointsAndTangentCurve();
break;
+ }
case 3:
aResult = circleByThreePassingPoints();
break;
VectorOfGccLine aTgLine;
convertTangentCurvesToGccEnt(aTgCirc, aTgLine);
- if (aTgCirc.size() + aTgLine.size() != 3)
- return Circ2dPtr();
-
std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
- switch (aTgLine.size()) {
- case 0:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- *aTgCirc[0], *aTgCirc[1], *aTgCirc[2], Precision::Confusion()));
- break;
- case 1:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- *aTgCirc[0], *aTgCirc[1], *aTgLine[0], Precision::Confusion()));
- break;
- case 2:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- *aTgCirc[0], *aTgLine[0], *aTgLine[1], Precision::Confusion()));
- break;
- case 3:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- *aTgLine[0], *aTgLine[1], *aTgLine[0], Precision::Confusion()));
- break;
- default:
- break;
+ if (aTgCirc.size() + aTgLine.size() == 3) {
+ switch (aTgLine.size()) {
+ case 0:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgCirc[0], *aTgCirc[1], *aTgCirc[2], Precision::Confusion()));
+ break;
+ case 1:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgCirc[0], *aTgCirc[1], *aTgLine[0], Precision::Confusion()));
+ break;
+ case 2:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgCirc[0], *aTgLine[0], *aTgLine[1], Precision::Confusion()));
+ break;
+ case 3:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgLine[0], *aTgLine[1], *aTgLine[2], Precision::Confusion()));
+ break;
+ default:
+ break;
+ }
}
return getProperCircle(aCircleBuilder);
Circ2dPtr circleByPointAndTwoTangentCurves()
{
const gp_Pnt2d& aPoint = myPassingPoints[0];
- CurveAdaptorPtr aCurve1 = myTangentShapes[0];
- CurveAdaptorPtr aCurve2 = myTangentShapes[1];
- if (!aCurve1 || !aCurve2)
- return Circ2dPtr();
+
+ VectorOfGccCirc aTgCirc;
+ VectorOfGccLine aTgLine;
+ convertTangentCurvesToGccEnt(aTgCirc, aTgLine);
std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
- if (aCurve1->GetType() == GeomAbs_Line) {
- if (aCurve2->GetType() == GeomAbs_Line) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
- new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Line()),
- GccEnt::Unqualified(aCurve2->Line()),
- aPoint, Precision::Confusion()));
- } else if (aCurve2->GetType() == GeomAbs_Circle) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
- new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
- GccEnt::Unqualified(aCurve1->Line()),
- aPoint, Precision::Confusion()));
- }
- } else if (aCurve1->GetType() == GeomAbs_Circle) {
- if (aCurve2->GetType() == GeomAbs_Line) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
- new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Circle()),
- GccEnt::Unqualified(aCurve2->Line()),
- aPoint, Precision::Confusion()));
- } else if (aCurve2->GetType() == GeomAbs_Circle) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
- new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
- GccEnt::Unqualified(aCurve1->Circle()),
- aPoint, Precision::Confusion()));
+ if (aTgCirc.size() + aTgLine.size() == 2) {
+ switch (aTgLine.size()) {
+ case 0:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgCirc[0], *aTgCirc[1], aPoint, Precision::Confusion()));
+ break;
+ case 1:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgCirc[0], *aTgLine[0], aPoint, Precision::Confusion()));
+ break;
+ case 2:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgLine[0], *aTgLine[1], aPoint, Precision::Confusion()));
+ break;
+ default:
+ break;
}
}
const gp_Pnt2d& aPoint1 = myPassingPoints[0];
const gp_Pnt2d& aPoint2 = myPassingPoints[1];
CurveAdaptorPtr aCurve = myTangentShapes[0];
- if (!aCurve)
- return Circ2dPtr();
std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
- if (aCurve->GetType() == GeomAbs_Line) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- GccEnt::Unqualified(aCurve->Line()), aPoint1, aPoint2, Precision::Confusion()));
- } else if (aCurve->GetType() == GeomAbs_Circle) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- GccEnt::Unqualified(aCurve->Circle()), aPoint1, aPoint2, Precision::Confusion()));
+ if (aCurve) {
+ if (aCurve->GetType() == GeomAbs_Line) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ GccEnt::Unqualified(aCurve->Line()), aPoint1, aPoint2, Precision::Confusion()));
+ }
+ else if (aCurve->GetType() == GeomAbs_Circle) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ GccEnt::Unqualified(aCurve->Circle()), aPoint1, aPoint2, Precision::Confusion()));
+ }
}
return getProperCircle(aCircleBuilder);
}
+ Circ2dPtr circleByTwoPointsAndTransversalLine()
+ {
+ const gp_Pnt2d& aPoint1 = myPassingPoints[0];
+ const gp_Pnt2d& aPoint2 = myPassingPoints[1];
+
+ if (myTransversalLine && myTransversalLine->GetType() == GeomAbs_Line) {
+ GccAna_Circ2d2TanOn aCircleBuilder(aPoint1, aPoint2, myTransversalLine->Line(),
+ Precision::Confusion());
+ if (aCircleBuilder.NbSolutions() > 0)
+ return Circ2dPtr(new gp_Circ2d(aCircleBuilder.ThisSolution(1)));
+ }
+
+ return Circ2dPtr();
+ }
+
+
Circ2dPtr circleByRadiusAndTwoTangentCurves()
{
VectorOfGccCirc aTgCirc;
VectorOfGccLine aTgLine;
convertTangentCurvesToGccEnt(aTgCirc, aTgLine);
- if (aTgCirc.size() + aTgLine.size() != 2)
- return Circ2dPtr();
-
std::shared_ptr<GccAna_Circ2d2TanRad> aCircleBuilder;
- switch (aTgLine.size()) {
- case 0:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
- *aTgCirc[0], *aTgCirc[1], myRadius, Precision::Confusion()));
- break;
- case 1:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
- *aTgCirc[0], *aTgLine[0], myRadius, Precision::Confusion()));
- break;
- case 2:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
- *aTgLine[0], *aTgLine[1], myRadius, Precision::Confusion()));
- break;
- default:
- break;
+ if (aTgCirc.size() + aTgLine.size() == 2) {
+ switch (aTgLine.size()) {
+ case 0:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
+ *aTgCirc[0], *aTgCirc[1], myRadius, Precision::Confusion()));
+ break;
+ case 1:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
+ *aTgCirc[0], *aTgLine[0], myRadius, Precision::Confusion()));
+ break;
+ case 2:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
+ *aTgLine[0], *aTgLine[1], myRadius, Precision::Confusion()));
+ break;
+ default:
+ break;
+ }
}
return getProperCircle(aCircleBuilder);
std::shared_ptr<GeomAPI_Pnt2d> myCenter;
std::vector<gp_Pnt2d> myPassingPoints;
std::vector<CurveAdaptorPtr> myTangentShapes;
+ CurveAdaptorPtr myTransversalLine;
double myRadius;
std::shared_ptr<GeomAPI_Pnt2d> myClosestPoint;
};
myTangentShapes.push_back(theEdge);
}
+void GeomAlgoAPI_Circ2dBuilder::setTransversalLine(const std::shared_ptr<GeomAPI_Shape>& theEdge)
+{
+ if (theEdge->isEdge())
+ myTransversalLine = theEdge;
+}
+
void GeomAlgoAPI_Circ2dBuilder::addPassingPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
{
myPassingPoints.push_back(thePoint);
CircleBuilder aCircleBuilder(myPlane);
aCircleBuilder.setCenter(myCenter);
aCircleBuilder.setTangentCurves(myTangentShapes);
+ aCircleBuilder.setTransversalLine(myTransversalLine);
aCircleBuilder.setPassingPoints(myPassingPoints);
aCircleBuilder.setClosestPoint(myClosestPoint);
aCircleBuilder.setRadius(myRadius);