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,
29 std::list<GCSConstraintPtr>& theArcConstraints);
32 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
33 PlaneGCSSolver_Storage* theStorage)
34 : PlaneGCSSolver_AttributeBuilder(theStorage)
38 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
39 : PlaneGCSSolver_AttributeBuilder(theStorage)
43 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
44 AttributePtr theAttribute)
46 FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
47 EntityWrapperPtr anAttr;
48 if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
49 anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
51 myAttributes[theAttribute] = anAttr;
55 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
57 EntityWrapperPtr aResult;
59 aResult = myStorage->entity(theFeature);
63 // Process SketchPlugin features only
64 std::shared_ptr<SketchPlugin_Feature> aFeature =
65 std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
69 // Verify the feature by its kind
70 const std::string& aFeatureKind = aFeature->getKind();
72 if (aFeatureKind == SketchPlugin_Line::ID())
73 aResult = createLine(myAttributes);
75 else if (aFeatureKind == SketchPlugin_Circle::ID())
76 aResult = createCircle(myAttributes);
78 else if (aFeatureKind == SketchPlugin_Arc::ID())
79 aResult = createArc(myAttributes, myStorage, myFeatureConstraints);
80 // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
81 else if (aFeatureKind == SketchPlugin_Point::ID() ||
82 aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
83 AttributeEntityMap::const_iterator anIt = myAttributes.begin();
84 for (; anIt != myAttributes.end(); ++anIt)
85 if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
86 aResult = anIt->second;
91 if (aResult && !myStorage)
92 aResult->setExternal(true);
102 // ============== Auxiliary functions =====================================
103 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
105 std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
107 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
108 for (; anIt != theAttributes.end(); ++anIt) {
109 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
110 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
114 if (anIt->first->id() == SketchPlugin_Line::START_ID())
115 aNewLine->p1 = *(aPoint->point());
116 else if (anIt->first->id() == SketchPlugin_Line::END_ID())
117 aNewLine->p2 = *(aPoint->point());
120 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewLine));
123 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
125 std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
127 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
128 for (; anIt != theAttributes.end(); ++anIt) {
129 if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
130 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
131 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
132 aNewCircle->center = *(aPoint->point());
134 else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
135 ScalarWrapperPtr aScalar =
136 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
137 aNewCircle->rad = aScalar->scalar();
141 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewCircle));
144 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
146 return theStorage ? theStorage->createParameter() : (new double(0));
149 EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
150 PlaneGCSSolver_Storage* theStorage,
151 std::list<GCSConstraintPtr>& theArcConstraints)
153 std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
155 // Base attributes of arc (center, start and end points)
156 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
157 for (; anIt != theAttributes.end(); ++anIt) {
158 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
159 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
163 if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
164 aNewArc->center = *(aPoint->point());
165 else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
166 aNewArc->start = *(aPoint->point());
167 else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
168 aNewArc->end = *(aPoint->point());
171 // Additional atrtributes of arc necessary for PlaneGCS solver
172 // (start and end angles, radius)
173 aNewArc->startAngle = createParameter(theStorage);
174 aNewArc->endAngle = createParameter(theStorage);
175 aNewArc->rad = createParameter(theStorage);
177 static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
178 std::shared_ptr<GeomAPI_Pnt2d> aCenter(
179 new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
180 std::shared_ptr<GeomAPI_Pnt2d> aStart(
181 new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
183 *aNewArc->rad = aStart->distance(aCenter);
185 std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
186 *aNewArc->startAngle = OX->angle(aDir);
188 aDir = std::shared_ptr<GeomAPI_Dir2d>(
189 new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
190 *aNewArc->endAngle = OX->angle(aDir);
193 // Additional constaints to fix arc's extra DoF (if the arc is not external):
194 // 1. distances from center till start and end points are equal to radius
195 theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
196 aNewArc->center, aNewArc->start, aNewArc->rad)));
197 theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
198 aNewArc->center, aNewArc->end, aNewArc->rad)));
199 // 2. angles of start and end points should be equal to the arc angles
200 theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
201 aNewArc->center, aNewArc->start, aNewArc->startAngle)));
202 theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
203 aNewArc->center, aNewArc->end, aNewArc->endAngle)));
206 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewArc));
209 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
211 if (theOwnerName == SketchPlugin_Arc::ID()) {
212 return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
213 theAttrName == SketchPlugin_Arc::START_ID() ||
214 theAttrName == SketchPlugin_Arc::END_ID();
216 else if (theOwnerName == SketchPlugin_Circle::ID()) {
217 return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
218 theAttrName == SketchPlugin_Circle::RADIUS_ID();
220 else if (theOwnerName == SketchPlugin_Line::ID()) {
221 return theAttrName == SketchPlugin_Line::START_ID() ||
222 theAttrName == SketchPlugin_Line::END_ID();
225 // suppose that all remaining features are points
226 return theAttrName == SketchPlugin_Point::COORD_ID();