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_EntityWrapper.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 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
23 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
24 static EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
25 PlaneGCSSolver_Storage* theStorage,
26 std::list<GCSConstraintPtr>& theArcConstraints);
29 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
30 PlaneGCSSolver_Storage* theStorage)
31 : PlaneGCSSolver_AttributeBuilder(theStorage)
35 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
36 : PlaneGCSSolver_AttributeBuilder(theStorage)
40 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
41 AttributePtr theAttribute)
43 EntityWrapperPtr anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
45 myAttributes[theAttribute] = anAttr;
49 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
51 EntityWrapperPtr aResult;
53 aResult = myStorage->entity(theFeature);
57 // Process SketchPlugin features only
58 std::shared_ptr<SketchPlugin_Feature> aFeature =
59 std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
63 // Verify the feature by its kind
64 const std::string& aFeatureKind = aFeature->getKind();
66 if (aFeatureKind == SketchPlugin_Line::ID())
67 aResult = createLine(myAttributes);
69 else if (aFeatureKind == SketchPlugin_Circle::ID())
70 aResult = createCircle(myAttributes);
72 else if (aFeatureKind == SketchPlugin_Arc::ID())
73 aResult = createArc(myAttributes, myStorage, myFeatureConstraints);
74 // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
75 else if (aFeatureKind == SketchPlugin_Point::ID() ||
76 aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
77 AttributeEntityMap::const_iterator anIt = myAttributes.begin();
78 for (; anIt != myAttributes.end(); ++anIt)
79 if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
80 aResult = anIt->second;
85 if (aResult && !myStorage)
86 aResult->setExternal(true);
96 // ============== Auxiliary functions =====================================
97 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
99 std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
101 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
102 for (; anIt != theAttributes.end(); ++anIt) {
103 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
104 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
108 if (anIt->first->id() == SketchPlugin_Line::START_ID())
109 aNewLine->p1 = *(aPoint->point());
110 else if (anIt->first->id() == SketchPlugin_Line::END_ID())
111 aNewLine->p2 = *(aPoint->point());
114 return EntityWrapperPtr(new PlaneGCSSolver_EntityWrapper(aNewLine));
117 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
119 std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
121 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
122 for (; anIt != theAttributes.end(); ++anIt) {
123 if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
124 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
125 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
126 aNewCircle->center = *(aPoint->point());
128 else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
129 ScalarWrapperPtr aScalar =
130 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
131 aNewCircle->rad = aScalar->scalar();
135 return EntityWrapperPtr(new PlaneGCSSolver_EntityWrapper(aNewCircle));
138 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
140 return theStorage ? theStorage->createParameter() : (new double(0));
143 EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
144 PlaneGCSSolver_Storage* theStorage,
145 std::list<GCSConstraintPtr>& theArcConstraints)
147 std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
149 // Base attributes of arc (center, start and end points)
150 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
151 for (; anIt != theAttributes.end(); ++anIt) {
152 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
153 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
157 if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
158 aNewArc->center = *(aPoint->point());
159 else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
160 aNewArc->start = *(aPoint->point());
161 else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
162 aNewArc->end = *(aPoint->point());
165 // Additional atrtributes of arc necessary for PlaneGCS solver
166 // (start and end angles, radius)
167 aNewArc->startAngle = createParameter(theStorage);
168 aNewArc->endAngle = createParameter(theStorage);
169 aNewArc->rad = createParameter(theStorage);
171 static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
172 std::shared_ptr<GeomAPI_Pnt2d> aCenter(
173 new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
174 std::shared_ptr<GeomAPI_Pnt2d> aStart(
175 new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
177 *aNewArc->rad = aStart->distance(aCenter);
179 std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
180 *aNewArc->startAngle = OX->angle(aDir);
182 aDir = std::shared_ptr<GeomAPI_Dir2d>(
183 new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
184 *aNewArc->endAngle = OX->angle(aDir);
187 // Additional constaints to fix arc's extra DoF (if the arc is not external):
188 // 1. distances from center till start and end points are equal to radius
189 theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
190 aNewArc->center, aNewArc->start, aNewArc->rad)));
191 theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
192 aNewArc->center, aNewArc->end, aNewArc->rad)));
193 // 2. angles of start and end points should be equal to the arc angles
194 theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
195 aNewArc->center, aNewArc->start, aNewArc->startAngle)));
196 theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
197 aNewArc->center, aNewArc->end, aNewArc->endAngle)));
200 return EntityWrapperPtr(new PlaneGCSSolver_EntityWrapper(aNewArc));