Salome HOME
bce4d90d627523ce8debaf1e6a26df40cbd58d2a
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_AttributeBuilder.cpp
1 // Copyright (C) 2014-2019  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_AngleWrapper.h>
21 #include <PlaneGCSSolver_AttributeBuilder.h>
22 #include <PlaneGCSSolver_PointArrayWrapper.h>
23 #include <PlaneGCSSolver_PointWrapper.h>
24 #include <PlaneGCSSolver_ScalarWrapper.h>
25 #include <PlaneGCSSolver_ScalarArrayWrapper.h>
26 #include <PlaneGCSSolver_BooleanWrapper.h>
27
28 #include <GeomAPI_Pnt2d.h>
29 #include <GeomDataAPI_Point2D.h>
30 #include <GeomDataAPI_Point2DArray.h>
31 #include <ModelAPI_AttributeDouble.h>
32 #include <ModelAPI_AttributeDoubleArray.h>
33 #include <ModelAPI_AttributeInteger.h>
34 #include <SketchPlugin_BSpline.h>
35 #include <SketchPlugin_ConstraintAngle.h>
36 #include <SketchPlugin_MultiRotation.h>
37
38 PlaneGCSSolver_AttributeBuilder::PlaneGCSSolver_AttributeBuilder(
39     PlaneGCSSolver_Storage* theStorage)
40   : PlaneGCSSolver_EntityBuilder(theStorage)
41 {
42 }
43
44 PlaneGCSSolver_AttributeBuilder::PlaneGCSSolver_AttributeBuilder(const StoragePtr& theStorage)
45   : PlaneGCSSolver_EntityBuilder(
46         std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(theStorage).get())
47 {
48 }
49
50 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
51 {
52   return theStorage ? theStorage->createParameter() : (new double(0));
53 }
54
55 static EntityWrapperPtr createBoolean(const AttributePtr& theAttribute)
56 {
57   BooleanWrapperPtr aWrapper;
58   AttributeBooleanPtr aBoolean =
59       std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttribute);
60   if (aBoolean)
61     aWrapper = BooleanWrapperPtr(new PlaneGCSSolver_BooleanWrapper(aBoolean->value()));
62   return aWrapper;
63 }
64
65 static EntityWrapperPtr createScalar(const AttributePtr&     theAttribute,
66                                      PlaneGCSSolver_Storage* theStorage)
67 {
68   double aValue = 0.0;
69   AttributeDoublePtr aDouble = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
70   if (aDouble)
71     aValue = aDouble->isInitialized() ? aDouble->value() : 0.0;
72   else {
73     AttributeIntegerPtr anInt = std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(theAttribute);
74     if (anInt)
75       aValue = anInt->isInitialized() ? anInt->value() : 0.0;
76     else
77       return EntityWrapperPtr();
78   }
79
80   ScalarWrapperPtr aWrapper;
81   // following attributes should be converted from degrees to radians
82   //  - value of the Angle constraint
83   //  - angle of the Multi-Rotation constraint
84   FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
85   if ((theAttribute->id() == SketchPlugin_Constraint::VALUE() &&
86       anOwner->getKind() == SketchPlugin_ConstraintAngle::ID()) ||
87      (theAttribute->id() == SketchPlugin_MultiRotation::ANGLE_ID() &&
88       anOwner->getKind() == SketchPlugin_MultiRotation::ID()))
89     aWrapper = ScalarWrapperPtr(new PlaneGCSSolver_AngleWrapper(createParameter(theStorage)));
90   else if (anOwner->getKind() == SketchPlugin_BSpline::ID() &&
91            theAttribute->id() == SketchPlugin_BSpline::DEGREE_ID())
92     // Degree of B-spline is not processed by the solver
93     aWrapper = ScalarWrapperPtr(new PlaneGCSSolver_ScalarWrapper(createParameter(nullptr)));
94   else
95     aWrapper = ScalarWrapperPtr(new PlaneGCSSolver_ScalarWrapper(createParameter(theStorage)));
96
97   aWrapper->setValue(aValue);
98   return aWrapper;
99 }
100
101 static EntityWrapperPtr createScalarArray(const AttributePtr&     theAttribute,
102                                           PlaneGCSSolver_Storage* theStorage)
103 {
104   class ArrayAttribute {
105   public:
106     ArrayAttribute(AttributePtr theAttribute)
107     {
108       myDouble = std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(theAttribute);
109       myInteger = std::dynamic_pointer_cast<ModelAPI_AttributeIntArray>(theAttribute);
110     }
111
112     bool isInitialized() const
113     {
114       return (myDouble && myDouble->isInitialized()) || (myInteger && myInteger->isInitialized());
115     }
116
117     int size() const
118     {
119       return myDouble.get() ? myDouble->size() : myInteger->size();
120     }
121
122     double value(const int theIndex) const
123     {
124       return myDouble.get() ? myDouble->value(theIndex) : myInteger->value(theIndex);
125     }
126
127   private:
128     AttributeDoubleArrayPtr myDouble;
129     AttributeIntArrayPtr myInteger;
130   } anArray(theAttribute);
131
132   if (!anArray.isInitialized())
133     return EntityWrapperPtr();
134
135   PlaneGCSSolver_Storage* aStorage = theStorage;
136   // Weights, knots and multiplicities of B-spline curve are not processed by the solver
137   FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
138   if (anOwner->getKind() == SketchPlugin_BSpline::ID() &&
139       (theAttribute->id() == SketchPlugin_BSpline::WEIGHTS_ID() ||
140        theAttribute->id() == SketchPlugin_BSpline::KNOTS_ID() ||
141        theAttribute->id() == SketchPlugin_BSpline::MULTS_ID()))
142     aStorage = 0;
143
144   int aSize = anArray.size();
145   GCS::VEC_pD aParameters;
146   aParameters.reserve(aSize);
147   for (int index = 0; index < aSize; ++index) {
148     double* aParam = createParameter(aStorage);
149     *aParam = anArray.value(index);
150     aParameters.push_back(aParam);
151   }
152
153   return EntityWrapperPtr(new PlaneGCSSolver_ScalarArrayWrapper(aParameters));
154 }
155
156 static PointWrapperPtr createPoint(const GeomPnt2dPtr& thePoint, PlaneGCSSolver_Storage* theStorage)
157 {
158   GCSPointPtr aNewPoint(new GCS::Point);
159
160   aNewPoint->x = createParameter(theStorage);
161   aNewPoint->y = createParameter(theStorage);
162   if (thePoint) {
163     *(aNewPoint->x) = thePoint->x();
164     *(aNewPoint->y) = thePoint->y();
165   }
166
167   return PointWrapperPtr(new PlaneGCSSolver_PointWrapper(aNewPoint));
168 }
169
170 static EntityWrapperPtr createPoint(const AttributePtr&     theAttribute,
171                                     PlaneGCSSolver_Storage* theStorage)
172 {
173   std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
174       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
175   if (!aPoint2D)
176     return EntityWrapperPtr();
177
178   GeomPnt2dPtr aPnt;
179   if (aPoint2D->isInitialized())
180     aPnt = aPoint2D->pnt();
181
182   return createPoint(aPnt, theStorage);
183 }
184
185 static EntityWrapperPtr createPointArray(const AttributePtr& theAttribute,
186                                          PlaneGCSSolver_Storage* theStorage)
187 {
188   std::shared_ptr<GeomDataAPI_Point2DArray> aPointArray =
189       std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(theAttribute);
190   if (!aPointArray)
191     return EntityWrapperPtr();
192
193   int aSize = aPointArray->size();
194
195   std::vector<PointWrapperPtr> aPointWrappers;
196   aPointWrappers.reserve(aSize);
197   for (int index = 0; index < aSize; ++index)
198     aPointWrappers.push_back(createPoint(aPointArray->pnt(index), theStorage));
199
200   return EntityWrapperPtr(new PlaneGCSSolver_PointArrayWrapper(aPointWrappers));
201 }
202
203 EntityWrapperPtr PlaneGCSSolver_AttributeBuilder::createAttribute(
204     AttributePtr theAttribute)
205 {
206   EntityWrapperPtr aResult;
207   if (myStorage)
208     aResult = myStorage->entity(theAttribute);
209   if (!aResult)
210     aResult = createPoint(theAttribute, myStorage);
211   if (!aResult)
212     aResult = createScalar(theAttribute, myStorage);
213   if (!aResult)
214     aResult = createBoolean(theAttribute);
215   if (!aResult)
216     aResult = createPointArray(theAttribute, myStorage);
217   if (!aResult)
218     aResult = createScalarArray(theAttribute, myStorage);
219   if (aResult && !myStorage)
220     aResult->setExternal(true);
221   return aResult;
222 }