Salome HOME
Fix for the issue #1755 : for now the sketch solver receives all modified entities...
[modules/shaper.git] / src / ModelGeomAlgo / ModelGeomAlgo_Point2D.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        ModelAPI_Tools.cpp
4 // Created:     20 Jul 2016
5 // Author:      Natalia ERMOLAEVA
6
7 #include "ModelGeomAlgo_Point2D.h"
8
9 #include <ModelAPI_Feature.h>
10 #include <ModelAPI_Result.h>
11 #include <ModelAPI_AttributeRefAttr.h>
12
13 #include <GeomAlgoAPI_ShapeTools.h>
14 #include <GeomDataAPI_Point2D.h>
15
16 #include <GeomAPI_Pnt.h>
17 #include <GeomAPI_Pnt2d.h>
18 #include <GeomAPI_Vertex.h>
19 #include <GeomAPI_Dir.h>
20 #include <GeomAPI_Edge.h>
21 #include <GeomAPI_Lin.h>
22 #include <GeomAPI_Circ.h>
23
24 #ifdef WIN32
25 #pragma warning(disable : 4996) // for sprintf
26 #endif
27
28 namespace ModelGeomAlgo_Point2D {
29   std::shared_ptr<GeomDataAPI_Point2D> getPointOfRefAttr(ModelAPI_Feature* theFeature,
30                                                          const std::string& theAttribute,
31                                                          const std::string& theObjectFeatureKind,
32                                                          const std::string& theObjectFeatureAttribute)
33   {
34     std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
35
36     /// essential check as it is called in openGl thread
37     if (!theFeature || !theFeature->data().get() || !theFeature->data()->isValid())
38       return std::shared_ptr<GeomDataAPI_Point2D>();
39
40     FeaturePtr aFeature;
41     std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
42         ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute));
43     if(anAttr.get() && anAttr->isInitialized()) {
44       aFeature = ModelAPI_Feature::feature(anAttr->object());
45       if (aFeature.get()) {
46         bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() &&
47                                     !theObjectFeatureAttribute.empty() &&
48                                     aFeature->getKind() == theObjectFeatureKind;
49         if(aFeatureOfObjectKind)
50             aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
51                                     aFeature->data()->attribute(theObjectFeatureAttribute));
52         else if (anAttr->attr())
53           aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
54       }
55     }
56     return aPointAttr;
57   }
58
59   void getPointsOfReference(const std::shared_ptr<ModelAPI_Object>& theObject,
60                             const std::string& theReferenceFeatureKind,
61                             std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
62                             const std::string& theObjectFeatureKind,
63                             const std::string& theObjectFeatureAttribute,
64                             const bool isSkipFeatureAttributes)
65   {
66     // find by feature
67     FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject);
68
69     const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
70     std::set<AttributePtr>::const_iterator aIt;
71     for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
72       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
73       FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
74       if (aRefFeature->getKind() == theReferenceFeatureKind) {
75         std::list<AttributePtr> anAttributes =
76                          aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
77         std::list<AttributePtr>::iterator anIter = anAttributes.begin(), aLast = anAttributes.end();
78         bool isSkippedAttribute = false;
79         if (isSkipFeatureAttributes) {
80           for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) {
81             AttributeRefAttrPtr aRefAttribute =
82               std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
83             if (aRefAttribute.get() && !aRefAttribute->isObject()) {
84               std::shared_ptr<GeomDataAPI_Point2D> aPointAttr =
85                              std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttribute->attr());
86               FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner());
87               isSkippedAttribute = aSourceFeature == anAttributeFeature;
88             }
89           }
90         }
91         if (isSkippedAttribute)
92           continue;
93
94         // it searches the first point of AttributeRefAtt
95         std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
96         for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) {
97           AttributeRefAttrPtr aRefAttribute =
98             std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
99           if (aRefAttribute.get()) {
100             aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(),
101                          theObjectFeatureKind, theObjectFeatureAttribute);
102           }
103         }
104         if (aPointAttr.get()) {
105           theAttributes.insert(aPointAttr);
106         }
107       }
108     }
109     // find by results
110     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
111     if (aFeature.get()) {
112       const std::list<std::shared_ptr<ModelAPI_Result> > aResults = aFeature->results();
113       std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
114       for (; aRIter != aResults.cend(); aRIter++) {
115         ResultPtr aResult = *aRIter;
116         getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind,
117                              theObjectFeatureAttribute);
118       }
119     }
120   }
121
122   void getPointsInsideShape(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
123                             const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
124                             const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
125                             const std::shared_ptr<GeomAPI_Dir>& theDirX,
126                             const std::shared_ptr<GeomAPI_Dir>& theDirY,
127                             std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
128                             std::map<std::shared_ptr<GeomDataAPI_Point2D>,
129                                      std::shared_ptr<GeomAPI_Pnt> >& theAttributeToPoint)
130   {
131     std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
132                                                             aLast = theAttributes.end();
133     for (; anIt != aLast; anIt++) {
134       std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
135       std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
136       std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
137       std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
138       if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
139         thePoints.push_back(aProjectedPoint);
140         theAttributeToPoint[anAttribute] = aProjectedPoint;
141       }
142     }
143   }
144
145   bool isPointOnEdge(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
146                      const std::shared_ptr<GeomAPI_Pnt>& thePoint,
147                      std::shared_ptr<GeomAPI_Pnt>& theProjectedPoint)
148   {
149     bool isInside = false;
150     if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
151       std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theBaseShape));
152       if (anEdge->isLine()) {
153         std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
154         theProjectedPoint = aLine->project(thePoint);
155       }
156       else if (anEdge->isCircle() || anEdge->isArc()) {
157         std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
158         theProjectedPoint = aCircle->project(thePoint);
159       }
160       if (theProjectedPoint.get()) {
161         std::shared_ptr<GeomAPI_Vertex> aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(),
162                                                   theProjectedPoint->y(), theProjectedPoint->z()));
163         isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape);
164       }
165     }
166     return isInside;
167   }
168
169   std::string doubleToString(double theValue)
170   {
171     std::string aValueStr;
172     char aBuf[50];
173     int n = sprintf(aBuf, "%g", theValue);
174     aValueStr = std::string(aBuf);
175     return aValueStr;
176   }
177
178   std::string getPontAttributesInfo(const std::shared_ptr<ModelAPI_Feature>& theFeature,
179                                     const std::set<std::shared_ptr<ModelAPI_Attribute> >& theAttributesOnly)
180   {
181     std::string anInfo;
182
183     std::list<AttributePtr> anAttrs = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
184     std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
185
186     for(; anIt != aLast; anIt++) {
187       AttributePtr anAttribute = *anIt;
188       if (anAttribute.get() && (theAttributesOnly.empty() ||
189           theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) {
190       if (!anInfo.empty()) {
191         anInfo.append(", ");
192         anInfo.append("\n");
193       }
194       anInfo.append("    " + getPointAttributeInfo(anAttribute));
195       }
196     }
197     return anInfo;
198   }
199
200   std::string getPointAttributeInfo(const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
201   {
202     std::string anInfo;
203     std::string aValue = "not defined";
204     std::string aType = theAttribute->attributeType();
205     if (aType == GeomDataAPI_Point2D::typeId()) {
206       std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
207                                                                                       theAttribute);
208       if (aPoint.get() && aPoint->isInitialized()) {
209         aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+ doubleToString(aPoint->y()) + ")");
210       }
211     }
212     anInfo.append(theAttribute->id() + ": " + aValue);
213
214     return anInfo;
215   }
216
217 } // namespace ModelGeomAlgo_Point2D