1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: PlaneGCSSolver_AttributeBuilder.cpp
4 // Created: 10 Feb 2017
5 // Author: Artem ZHIDKOV
7 #include <PlaneGCSSolver_FeatureBuilder.h>
8 #include <PlaneGCSSolver_EdgeWrapper.h>
9 #include <PlaneGCSSolver_PointWrapper.h>
10 #include <PlaneGCSSolver_ScalarWrapper.h>
12 #include <SketchPlugin_Arc.h>
13 #include <SketchPlugin_Circle.h>
14 #include <SketchPlugin_IntersectionPoint.h>
15 #include <SketchPlugin_Line.h>
16 #include <SketchPlugin_Point.h>
18 #include <GeomAPI_Dir2d.h>
19 #include <GeomAPI_Pnt2d.h>
20 #include <GeomAPI_XY.h>
22 static bool isAttributeApplicable(const std::string& theAttrName,
23 const std::string& theOwnerName);
25 static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
26 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
27 static EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
28 PlaneGCSSolver_Storage* theStorage);
31 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
32 PlaneGCSSolver_Storage* theStorage)
33 : PlaneGCSSolver_AttributeBuilder(theStorage)
37 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
38 : PlaneGCSSolver_AttributeBuilder(theStorage)
42 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
43 AttributePtr theAttribute)
45 FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
46 EntityWrapperPtr anAttr;
47 if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
48 anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
50 myAttributes[theAttribute] = anAttr;
54 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
56 EntityWrapperPtr aResult;
58 aResult = myStorage->entity(theFeature);
62 // Process SketchPlugin features only
63 std::shared_ptr<SketchPlugin_Feature> aFeature =
64 std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
68 // Verify the feature by its kind
69 const std::string& aFeatureKind = aFeature->getKind();
71 if (aFeatureKind == SketchPlugin_Line::ID())
72 aResult = createLine(myAttributes);
74 else if (aFeatureKind == SketchPlugin_Circle::ID())
75 aResult = createCircle(myAttributes);
77 else if (aFeatureKind == SketchPlugin_Arc::ID())
78 aResult = createArc(myAttributes, myStorage);
79 // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
80 else if (aFeatureKind == SketchPlugin_Point::ID() ||
81 aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
82 AttributeEntityMap::const_iterator anIt = myAttributes.begin();
83 for (; anIt != myAttributes.end(); ++anIt)
84 if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
85 aResult = anIt->second;
90 if (aResult && !myStorage)
91 aResult->setExternal(true);
101 // ============== Auxiliary functions =====================================
102 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
104 std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
106 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
107 for (; anIt != theAttributes.end(); ++anIt) {
108 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
109 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
113 if (anIt->first->id() == SketchPlugin_Line::START_ID())
114 aNewLine->p1 = *(aPoint->point());
115 else if (anIt->first->id() == SketchPlugin_Line::END_ID())
116 aNewLine->p2 = *(aPoint->point());
119 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewLine));
122 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
124 std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
126 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
127 for (; anIt != theAttributes.end(); ++anIt) {
128 if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
129 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
130 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
131 aNewCircle->center = *(aPoint->point());
133 else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
134 ScalarWrapperPtr aScalar =
135 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
136 aNewCircle->rad = aScalar->scalar();
140 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewCircle));
143 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
145 return theStorage ? theStorage->createParameter() : (new double(0));
148 EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
149 PlaneGCSSolver_Storage* theStorage)
151 std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
153 // Base attributes of arc (center, start and end points)
154 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
155 for (; anIt != theAttributes.end(); ++anIt) {
156 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
157 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
161 if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
162 aNewArc->center = *(aPoint->point());
163 else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
164 aNewArc->start = *(aPoint->point());
165 else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
166 aNewArc->end = *(aPoint->point());
169 // Additional atrtributes of arc necessary for PlaneGCS solver
170 // (start and end angles, radius)
171 aNewArc->startAngle = createParameter(theStorage);
172 aNewArc->endAngle = createParameter(theStorage);
173 aNewArc->rad = createParameter(theStorage);
175 static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
176 std::shared_ptr<GeomAPI_Pnt2d> aCenter(
177 new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
178 std::shared_ptr<GeomAPI_Pnt2d> aStart(
179 new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
181 *aNewArc->rad = aStart->distance(aCenter);
183 std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
184 *aNewArc->startAngle = OX->angle(aDir);
186 aDir = std::shared_ptr<GeomAPI_Dir2d>(
187 new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
188 *aNewArc->endAngle = OX->angle(aDir);
190 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewArc));
193 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
195 if (theOwnerName == SketchPlugin_Arc::ID()) {
196 return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
197 theAttrName == SketchPlugin_Arc::START_ID() ||
198 theAttrName == SketchPlugin_Arc::END_ID();
200 else if (theOwnerName == SketchPlugin_Circle::ID()) {
201 return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
202 theAttrName == SketchPlugin_Circle::RADIUS_ID();
204 else if (theOwnerName == SketchPlugin_Line::ID()) {
205 return theAttrName == SketchPlugin_Line::START_ID() ||
206 theAttrName == SketchPlugin_Line::END_ID();
209 // suppose that all remaining features are points
210 return theAttrName == SketchPlugin_Point::COORD_ID();