From: mpv Date: Wed, 12 Dec 2018 13:36:49 +0000 (+0300) Subject: Allow sketch work with trimmed curve-arcs X-Git-Tag: End2018~72 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a36dc3bdc0503158c453605807b2c5205f03d52c;p=modules%2Fshaper.git Allow sketch work with trimmed curve-arcs --- diff --git a/lcov_reports.sh b/lcov_reports.sh index 5474115e4..325d8908b 100755 --- a/lcov_reports.sh +++ b/lcov_reports.sh @@ -50,7 +50,7 @@ genhtml covDirect --output-directory lcov_htmlDirect -q # prepare Else report cp -f covfile covElse # remove all plugins data except the needed -NEED='BuildPlugin CollectionPlugin Config ConstructionPlugin Events ExchangePlugin FeaturesPlugin GDMLPlugin GeomData GeomDataAPLI GeomValidators InitializationPlugin Model_ ModelAPI ModelGeomAlgo ParametersPlugin PartSetPlugin PrimitivesPlugin Selector SketchPlugin SketchSolver' +NEED='BuildPlugin CollectionPlugin Config ConstructionPlugin Events ExchangePlugin FeaturesPlugin GDMLPlugin GeomData GeomDataAPI GeomValidators InitializationPlugin Model_ ModelAPI ModelGeomAlgo ParametersPlugin PartSetPlugin PrimitivesPlugin Selector SketchPlugin SketchSolver' for MASK in $ALL; do if ! [[ " $NEED " =~ " $MASK " ]]; then lcov -r covElse *${MASK}* --output-file covElse_res -q diff --git a/src/GeomAPI/GeomAPI_Edge.cpp b/src/GeomAPI/GeomAPI_Edge.cpp index 01c98124c..7966720d3 100644 --- a/src/GeomAPI/GeomAPI_Edge.cpp +++ b/src/GeomAPI/GeomAPI_Edge.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -79,15 +80,29 @@ bool GeomAPI_Edge::isLine() const return false; } +/// extracts a circle curve from the arbitrary curve, returns null is it is different type +static Handle(Geom_Circle) circ(const Handle(Geom_Curve) theCurve) +{ + Handle(Geom_Circle) aResult = Handle(Geom_Circle)::DownCast(theCurve); + if (!aResult.IsNull()) + return aResult; + // check this may be a trimmed curve that contains circle inside + Handle(Geom_TrimmedCurve) aTrimmed = Handle(Geom_TrimmedCurve)::DownCast(theCurve); + while(!aTrimmed.IsNull()) { + aResult = Handle(Geom_Circle)::DownCast(aTrimmed->BasisCurve()); + if (!aResult.IsNull()) + return aResult; + aTrimmed = Handle(Geom_TrimmedCurve)::DownCast(aTrimmed->BasisCurve()); + } + return aResult; // null, not circle +} + bool GeomAPI_Edge::isCircle() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); double aFirst, aLast; Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast); - if (aCurve.IsNull()) // degenerative edge - return false; - if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle))) - { + if (!circ(aCurve).IsNull()) { // Check the difference of first and last parameters to be equal to the curve period if (Abs(aLast - aFirst - aCurve->Period()) < Precision::PConfusion()) return true; @@ -100,10 +115,7 @@ bool GeomAPI_Edge::isArc() const const TopoDS_Shape& aShape = const_cast(this)->impl(); double aFirst, aLast; Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast); - if (aCurve.IsNull()) // degenerative edge - return false; - if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle))) - { + if (!circ(aCurve).IsNull()) { // Check the difference of first and last parameters is not equal the curve period if (Abs(aLast - aFirst - aCurve->Period()) >= Precision::PConfusion()) return true; @@ -148,15 +160,13 @@ std::shared_ptr GeomAPI_Edge::circle() const const TopoDS_Shape& aShape = const_cast(this)->impl(); double aFirst, aLast; Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast); - if (!aCurve.IsNull()) { - Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast(aCurve); - if (!aCirc.IsNull()) { - gp_Pnt aLoc = aCirc->Location(); - std::shared_ptr aCenter(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); - gp_Dir anAxis = aCirc->Axis().Direction(); - std::shared_ptr aDir(new GeomAPI_Dir(anAxis.X(), anAxis.Y(), anAxis.Z())); - return std::shared_ptr(new GeomAPI_Circ(aCenter, aDir, aCirc->Radius())); - } + Handle(Geom_Circle) aCirc = circ(aCurve); + if (!aCirc.IsNull()) { + gp_Pnt aLoc = aCirc->Location(); + std::shared_ptr aCenter(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); + gp_Dir anAxis = aCirc->Axis().Direction(); + std::shared_ptr aDir(new GeomAPI_Dir(anAxis.X(), anAxis.Y(), anAxis.Z())); + return std::shared_ptr(new GeomAPI_Circ(aCenter, aDir, aCirc->Radius())); } return std::shared_ptr(); // not circle } @@ -175,7 +185,7 @@ std::shared_ptr GeomAPI_Edge::ellipse() const return aEllipse; } } - return std::shared_ptr(); // not elipse + return std::shared_ptr(); // not ellipse } std::shared_ptr GeomAPI_Edge::line() const @@ -265,21 +275,22 @@ bool GeomAPI_Edge::isInPlane(std::shared_ptr thePlane) const gp_Pnt aLastPnt = aCurve->Value(aLast); inPlane = aPlane.SquareDistance(aFirstPnt) < Precision::SquareConfusion() && aPlane.SquareDistance(aLastPnt) < Precision::SquareConfusion(); - } else if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle))) { - // check the center on the plane and normals are collinear - Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast(aCurve); - gp_Pnt aCenter = aCirc->Location(); - Standard_Real aDot = aPlane.Axis().Direction().Dot(aCirc->Axis().Direction()); - inPlane = aPlane.SquareDistance(aCenter) < Precision::SquareConfusion() && - Abs(Abs(aDot) - 1.0) < Precision::Confusion(); } else { - // three points checking - gp_Pnt aFirstPnt = aCurve->Value(aFirst); - gp_Pnt aMidPnt = aCurve->Value((aFirst + aLast) / 2.); - gp_Pnt aLastPnt = aCurve->Value(aLast); - inPlane = aPlane.SquareDistance(aFirstPnt) < Precision::SquareConfusion() && - aPlane.SquareDistance(aMidPnt) < Precision::SquareConfusion() && - aPlane.SquareDistance(aLastPnt) < Precision::SquareConfusion(); + Handle(Geom_Circle) aCirc = circ(aCurve); + if (!aCirc.IsNull()) { + gp_Pnt aCenter = aCirc->Location(); + Standard_Real aDot = aPlane.Axis().Direction().Dot(aCirc->Axis().Direction()); + inPlane = aPlane.SquareDistance(aCenter) < Precision::SquareConfusion() && + Abs(Abs(aDot) - 1.0) < Precision::Confusion(); + } else { + // three points checking + gp_Pnt aFirstPnt = aCurve->Value(aFirst); + gp_Pnt aMidPnt = aCurve->Value((aFirst + aLast) / 2.); + gp_Pnt aLastPnt = aCurve->Value(aLast); + inPlane = aPlane.SquareDistance(aFirstPnt) < Precision::SquareConfusion() && + aPlane.SquareDistance(aMidPnt) < Precision::SquareConfusion() && + aPlane.SquareDistance(aLastPnt) < Precision::SquareConfusion(); + } } return inPlane; }