1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <PlaneGCSSolver_FeatureBuilder.h>
21 #include <PlaneGCSSolver_EdgeWrapper.h>
22 #include <PlaneGCSSolver_PointWrapper.h>
23 #include <PlaneGCSSolver_ScalarWrapper.h>
25 #include <SketchPlugin_Arc.h>
26 #include <SketchPlugin_Circle.h>
27 #include <SketchPlugin_IntersectionPoint.h>
28 #include <SketchPlugin_Line.h>
29 #include <SketchPlugin_Point.h>
31 #include <GeomAPI_Dir2d.h>
32 #include <GeomAPI_Pnt2d.h>
33 #include <GeomAPI_XY.h>
35 static bool isAttributeApplicable(const std::string& theAttrName,
36 const std::string& theOwnerName);
38 static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
39 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
40 static EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
41 PlaneGCSSolver_Storage* theStorage);
44 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
45 PlaneGCSSolver_Storage* theStorage)
46 : PlaneGCSSolver_AttributeBuilder(theStorage)
50 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
51 : PlaneGCSSolver_AttributeBuilder(theStorage)
55 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
56 AttributePtr theAttribute)
58 FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
59 EntityWrapperPtr anAttr;
60 if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
61 anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
63 myAttributes[theAttribute] = anAttr;
67 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
69 EntityWrapperPtr aResult;
71 aResult = myStorage->entity(theFeature);
75 // Process SketchPlugin features only
76 std::shared_ptr<SketchPlugin_Feature> aFeature =
77 std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
81 // Verify the feature by its kind
82 const std::string& aFeatureKind = aFeature->getKind();
84 if (aFeatureKind == SketchPlugin_Line::ID())
85 aResult = createLine(myAttributes);
87 else if (aFeatureKind == SketchPlugin_Circle::ID())
88 aResult = createCircle(myAttributes);
90 else if (aFeatureKind == SketchPlugin_Arc::ID())
91 aResult = createArc(myAttributes, myStorage);
92 // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
93 else if (aFeatureKind == SketchPlugin_Point::ID() ||
94 aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
95 AttributeEntityMap::const_iterator anIt = myAttributes.begin();
96 for (; anIt != myAttributes.end(); ++anIt)
97 if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
98 aResult = anIt->second;
103 if (aResult && !myStorage)
104 aResult->setExternal(true);
106 myAttributes.clear();
114 // ============== Auxiliary functions =====================================
115 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
117 std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
119 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
120 for (; anIt != theAttributes.end(); ++anIt) {
121 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
122 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
126 if (anIt->first->id() == SketchPlugin_Line::START_ID())
127 aNewLine->p1 = *(aPoint->point());
128 else if (anIt->first->id() == SketchPlugin_Line::END_ID())
129 aNewLine->p2 = *(aPoint->point());
132 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewLine));
135 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
137 std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
139 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
140 for (; anIt != theAttributes.end(); ++anIt) {
141 if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
142 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
143 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
144 aNewCircle->center = *(aPoint->point());
146 else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
147 ScalarWrapperPtr aScalar =
148 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
149 aNewCircle->rad = aScalar->scalar();
153 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewCircle));
156 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
158 return theStorage ? theStorage->createParameter() : (new double(0));
161 EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
162 PlaneGCSSolver_Storage* theStorage)
164 std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
166 // Base attributes of arc (center, start and end points)
167 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
168 for (; anIt != theAttributes.end(); ++anIt) {
169 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
170 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
174 if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
175 aNewArc->center = *(aPoint->point());
176 else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
177 aNewArc->start = *(aPoint->point());
178 else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
179 aNewArc->end = *(aPoint->point());
182 // Additional atrtributes of arc necessary for PlaneGCS solver
183 // (start and end angles, radius)
184 aNewArc->startAngle = createParameter(theStorage);
185 aNewArc->endAngle = createParameter(theStorage);
186 aNewArc->rad = createParameter(theStorage);
188 static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
189 std::shared_ptr<GeomAPI_Pnt2d> aCenter(
190 new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
191 std::shared_ptr<GeomAPI_Pnt2d> aStart(
192 new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
194 *aNewArc->rad = aStart->distance(aCenter);
196 std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
197 *aNewArc->startAngle = OX->angle(aDir);
199 aDir = std::shared_ptr<GeomAPI_Dir2d>(
200 new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
201 *aNewArc->endAngle = OX->angle(aDir);
203 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewArc));
206 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
208 if (theOwnerName == SketchPlugin_Arc::ID()) {
209 return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
210 theAttrName == SketchPlugin_Arc::START_ID() ||
211 theAttrName == SketchPlugin_Arc::END_ID();
213 else if (theOwnerName == SketchPlugin_Circle::ID()) {
214 return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
215 theAttrName == SketchPlugin_Circle::RADIUS_ID();
217 else if (theOwnerName == SketchPlugin_Line::ID()) {
218 return theAttrName == SketchPlugin_Line::START_ID() ||
219 theAttrName == SketchPlugin_Line::END_ID();
222 // suppose that all remaining features are points
223 return theAttrName == SketchPlugin_Point::COORD_ID();