Salome HOME
Issue #17347: B-Splines in Sketcher
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_GeoExtensions.cpp
1 // Copyright (C) 2019-2020  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <PlaneGCSSolver_GeoExtensions.h>
21
22 #include <GeomAPI_BSpline2d.h>
23 #include <GeomAPI_Pnt2d.h>
24 #include <GeomAPI_XY.h>
25
26 #include <cmath>
27
28 namespace GCS
29 {
30
31 DeriVector2 BSplineImpl::Value(double u, double du, double* derivparam)
32 {
33   if (!isCacheValid())
34     rebuildCache();
35
36   std::shared_ptr<GeomAPI_Pnt2d> aValue;
37   std::shared_ptr<GeomAPI_XY> aDeriv;
38   myCurve->D1(u, aValue, aDeriv);
39
40   return DeriVector2(aValue->x(), aValue->y(), aDeriv->x() * du, aDeriv->y() * du);
41 }
42
43 BSplineImpl* BSplineImpl::Copy()
44 {
45   return new BSplineImpl(*this);
46 }
47
48
49 bool BSplineImpl::isCacheValid() const
50 {
51   // curve has to be initialized
52   bool isValid = myCurve.get() && !myCurve->isNull();
53
54   static const double THE_TOLERANCE = 1.e-7;
55   // compare poles
56   isValid = isValid && poles.size() == myCachedPoles.size();
57   std::list<GeomPnt2dPtr>::const_iterator aCachePIt = myCachedPoles.begin();
58   GCS::VEC_P::const_iterator aPolesIt = poles.begin();
59   for (; isValid && aPolesIt != poles.end(); ++aPolesIt, ++aCachePIt) {
60     isValid = isValid && fabs((*aCachePIt)->x() - *aPolesIt->x) < THE_TOLERANCE
61                       && fabs((*aCachePIt)->y() - *aPolesIt->y) < THE_TOLERANCE;
62   }
63
64   // compare weights
65   isValid = isValid && weights.size() == myCachedWeights.size();
66   std::list<double>::const_iterator aCacheWIt = myCachedWeights.begin();
67   GCS::VEC_pD::const_iterator aWeightsIt = weights.begin();
68   for (; isValid && aWeightsIt != weights.end(); ++aWeightsIt, ++aCacheWIt)
69     isValid = isValid && fabs(*aCacheWIt - **aWeightsIt) < THE_TOLERANCE;
70
71   return isValid;
72 }
73
74 void BSplineImpl::rebuildCache()
75 {
76   myCachedPoles.clear();
77   myCachedWeights.clear();
78
79   for (GCS::VEC_P::iterator anIt = poles.begin(); anIt != poles.end(); ++anIt)
80     myCachedPoles.push_back(GeomPnt2dPtr(new GeomAPI_Pnt2d(*anIt->x, *anIt->y)));
81   for (GCS::VEC_pD::iterator anIt = weights.begin(); anIt != weights.end(); ++anIt)
82     myCachedWeights.push_back(**anIt);
83
84   myCurve.reset(new GeomAPI_BSpline2d(myCachedPoles, myCachedWeights, degree, periodic));
85 }
86
87 } // namespace GCS