]> SALOME platform Git repositories - modules/shaper.git/blob - src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp
Salome HOME
Merge branch 'master' into cgt/devCEA
[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 #include <ModelAPI_CompositeFeature.h>
13 #include <ModelAPI_Tools.h>
14
15 #include <ModelGeomAlgo_Shape.h>
16
17 #include <GeomAPI_ShapeIterator.h>
18
19 #include <GeomAlgoAPI_ShapeTools.h>
20 #include <GeomDataAPI_Point2D.h>
21
22 #include <GeomAPI_Pnt.h>
23 #include <GeomAPI_Pnt2d.h>
24 #include <GeomAPI_Vertex.h>
25 #include <GeomAPI_Dir.h>
26 #include <GeomAPI_Edge.h>
27 #include <GeomAPI_Lin.h>
28 #include <GeomAPI_Circ.h>
29
30 #ifdef WIN32
31 #pragma warning(disable : 4996) // for sprintf
32 #endif
33
34 std::shared_ptr<GeomDataAPI_Point2D> ModelGeomAlgo_Point2D::getPointOfRefAttr(
35                                                   ModelAPI_Feature* theFeature,
36                                                   const std::string& theAttribute,
37                                                   const std::string& theObjectFeatureKind,
38                                                   const std::string& theObjectFeatureAttribute)
39 {
40   std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
41
42   /// essential check as it is called in openGl thread
43   if (!theFeature || !theFeature->data().get() || !theFeature->data()->isValid())
44     return std::shared_ptr<GeomDataAPI_Point2D>();
45
46   FeaturePtr aFeature;
47   std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
48       ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute));
49   if(anAttr.get() && anAttr->isInitialized()) {
50     aFeature = ModelAPI_Feature::feature(anAttr->object());
51     if (aFeature.get()) {
52       bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() &&
53                                   !theObjectFeatureAttribute.empty() &&
54                                   aFeature->getKind() == theObjectFeatureKind;
55       if(aFeatureOfObjectKind)
56           aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
57                                   aFeature->data()->attribute(theObjectFeatureAttribute));
58       else if (anAttr->attr())
59         aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
60     }
61   }
62   return aPointAttr;
63 }
64
65 void ModelGeomAlgo_Point2D::getPointsOfReference(
66                             const std::shared_ptr<ModelAPI_Object>& theObject,
67                             const std::string& theReferenceFeatureKind,
68                             std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
69                             const std::string& theObjectFeatureKind,
70                             const std::string& theObjectFeatureAttribute,
71                             const bool isSkipFeatureAttributes)
72 {
73   // find by feature
74   FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject);
75
76   const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
77   std::set<AttributePtr>::const_iterator aIt;
78   for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
79     std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
80     FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
81     if (aRefFeature->getKind() == theReferenceFeatureKind) {
82       std::list<AttributePtr> anAttributes =
83                         aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
84       std::list<AttributePtr>::iterator anIter = anAttributes.begin(), aLast = anAttributes.end();
85       bool isSkippedAttribute = false;
86       if (isSkipFeatureAttributes) {
87         for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) {
88           AttributeRefAttrPtr aRefAttribute =
89             std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
90           if (aRefAttribute.get() && !aRefAttribute->isObject()) {
91             std::shared_ptr<GeomDataAPI_Point2D> aPointAttr =
92                             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttribute->attr());
93             FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner());
94             isSkippedAttribute = aSourceFeature == anAttributeFeature;
95           }
96         }
97       }
98       if (isSkippedAttribute)
99         continue;
100
101       // it searches the first point of AttributeRefAtt
102       std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
103       for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) {
104         AttributeRefAttrPtr aRefAttribute =
105           std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
106         if (aRefAttribute.get()) {
107           aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(),
108                         theObjectFeatureKind, theObjectFeatureAttribute);
109         }
110       }
111       if (aPointAttr.get()) {
112         theAttributes.insert(aPointAttr);
113       }
114     }
115   }
116   // find by results
117   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
118   if (aFeature.get()) {
119     const std::list<std::shared_ptr<ModelAPI_Result> > aResults = aFeature->results();
120     std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
121     for (; aRIter != aResults.cend(); aRIter++) {
122       ResultPtr aResult = *aRIter;
123       getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind,
124                             theObjectFeatureAttribute);
125     }
126   }
127 }
128
129 void appendPoint(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
130                    const std::shared_ptr<ModelAPI_Result>& theResult,
131                    ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject)
132 {
133   bool aPointFound = false;
134   FeaturePtr aPointFeature = ModelAPI_Feature::feature(theResult);
135   // check if the given point is already in the container in attribute list
136   for (ModelGeomAlgo_Point2D::PointToRefsMap::const_iterator
137                   anIt = thePointToAttributeOrObject.begin();
138                   anIt != thePointToAttributeOrObject.end() && !aPointFound; anIt++) {
139     std::shared_ptr<GeomAPI_Pnt> aPoint = anIt->first;
140     if (aPoint->isEqual(thePoint)) {
141       std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes = anIt->second.first;
142       for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
143           anAttrIt != anAttributes.end() && !aPointFound; anAttrIt++) {
144         AttributePtr anAttribute = *anAttrIt;
145         aPointFound = ModelAPI_Feature::feature(anAttribute->owner()) == aPointFeature;
146       }
147     }
148   }
149
150   if (!aPointFound) {
151     if (thePointToAttributeOrObject.find(thePoint) != thePointToAttributeOrObject.end())
152       thePointToAttributeOrObject.at(thePoint).second.push_back(theResult);
153     else {
154       std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
155       std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
156       anObjects.push_back(theResult);
157       thePointToAttributeOrObject[thePoint] = std::make_pair(anAttributes, anObjects);
158     }
159   }
160 }
161
162 void appendShapePoints(const GeomShapePtr& theShape,
163                        const std::shared_ptr<ModelAPI_Result>& theResult,
164                        ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject)
165 {
166   if (!theShape.get())
167     return;
168
169   switch (theShape->shapeType()) {
170     case GeomAPI_Shape::VERTEX: {
171       std::shared_ptr<GeomAPI_Vertex> aVertex =
172         std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(theShape));
173       std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
174       appendPoint(aPnt, theResult, thePointToAttributeOrObject);
175     }
176     break;
177     case GeomAPI_Shape::EDGE: {
178       std::shared_ptr<GeomAPI_Edge> anEdge =
179         std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(theShape));
180       appendPoint(anEdge->firstPoint(), theResult, thePointToAttributeOrObject);
181       appendPoint(anEdge->lastPoint(), theResult, thePointToAttributeOrObject);
182     }
183     break;
184     case GeomAPI_Shape::COMPOUND: {
185       for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) {
186         appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject);
187       }
188     }
189     break;
190     default: break;
191   }
192 }
193
194 void ModelGeomAlgo_Point2D::getPointsIntersectedShape(
195                         const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
196                         const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
197                         PointToRefsMap& thePointToAttributeOrObject)
198 {
199   GeomShapePtr aFeatureShape;
200   {
201     std::set<ResultPtr> anEdgeShapes;
202     ModelGeomAlgo_Shape::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
203     if (anEdgeShapes.empty())
204       return;
205     aFeatureShape = (*anEdgeShapes.begin())->shape();
206   }
207
208   std::list<std::shared_ptr<ModelAPI_Feature> >::const_iterator anIt = theFeatures.begin(),
209                                                                 aLast = theFeatures.end();
210   for (; anIt != aLast; anIt++) {
211     FeaturePtr aFeature = *anIt;
212     if (aFeature.get() == theBaseFeature.get())
213       continue;
214     if (aFeature.get()) {
215       std::set<ResultPtr> anEdgeShapes;
216       ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
217       if (anEdgeShapes.empty())
218         ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::VERTEX, anEdgeShapes);
219
220       if (anEdgeShapes.empty())
221         continue;
222       ResultPtr aResult = *anEdgeShapes.begin();
223       GeomShapePtr aShape = aResult->shape();
224
225       GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape);
226       appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject);
227     }
228   }
229 }
230
231 std::list<std::shared_ptr<GeomAPI_Pnt> > ModelGeomAlgo_Point2D::getSetOfPntIntersectedShape(
232                   const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
233                   const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures)
234 {
235   std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
236
237   PointToRefsMap aRefsMap;
238   getPointsIntersectedShape(theBaseFeature, theFeatures, aRefsMap);
239
240   for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
241        aPointIt != aRefsMap.end(); aPointIt++)
242     aPoints.push_back(aPointIt->first);
243
244   return aPoints;
245 }
246
247 void ModelGeomAlgo_Point2D::getPointsInsideShape(
248                         const std::shared_ptr<GeomAPI_Shape> theBaseShape,
249                         const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
250                         const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
251                         const std::shared_ptr<GeomAPI_Dir>& theDirX,
252                         const std::shared_ptr<GeomAPI_Dir>& theDirY,
253                         PointToRefsMap& thePointToAttributeOrObject)
254 {
255   std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
256                                                           aLast = theAttributes.end();
257   for (; anIt != aLast; anIt++) {
258     std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
259     std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
260     std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
261     std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
262     if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
263       if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end())
264         thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute);
265       else {
266         std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
267         std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
268         anAttributes.push_back(anAttribute);
269         thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects);
270       }
271     }
272   }
273 }
274
275 void ModelGeomAlgo_Point2D::getPointsInsideShape_p(
276                             const std::shared_ptr<GeomAPI_Shape> theBaseShape,
277                             const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
278                             const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
279                             const std::shared_ptr<GeomAPI_Dir>& theDirX,
280                             const std::shared_ptr<GeomAPI_Dir>& theDirY,
281                             std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
282                             std::map<std::shared_ptr<GeomDataAPI_Point2D>,
283                                      std::shared_ptr<GeomAPI_Pnt> >& theAttributeToPoint)
284 {
285   std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
286                                                           aLast = theAttributes.end();
287   for (; anIt != aLast; anIt++) {
288     std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
289     std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
290     std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
291     std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
292     if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
293       thePoints.push_back(aProjectedPoint);
294       theAttributeToPoint[anAttribute] = aProjectedPoint;
295     }
296   }
297 }
298
299 bool ModelGeomAlgo_Point2D::isPointOnEdge(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
300                      const std::shared_ptr<GeomAPI_Pnt>& thePoint,
301                      std::shared_ptr<GeomAPI_Pnt>& theProjectedPoint)
302 {
303   bool isInside = false;
304   if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
305     std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theBaseShape));
306     if (anEdge->isLine()) {
307       std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
308       theProjectedPoint = aLine->project(thePoint);
309     }
310     else if (anEdge->isCircle() || anEdge->isArc()) {
311       std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
312       theProjectedPoint = aCircle->project(thePoint);
313     }
314     if (theProjectedPoint.get()) {
315       std::shared_ptr<GeomAPI_Vertex> aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(),
316                                                 theProjectedPoint->y(), theProjectedPoint->z()));
317       isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape);
318     }
319   }
320   return isInside;
321 }
322
323 std::string doubleToString(double theValue)
324 {
325   std::string aValueStr;
326   char aBuf[50];
327   int n = sprintf(aBuf, "%g", theValue);
328   aValueStr = std::string(aBuf);
329   return aValueStr;
330 }
331
332 #ifdef _DEBUG
333 std::string ModelGeomAlgo_Point2D::getPontAttributesInfo(
334                     const std::shared_ptr<ModelAPI_Feature>& theFeature,
335                     const std::set<std::shared_ptr<ModelAPI_Attribute> >& theAttributesOnly)
336 {
337   std::string anInfo;
338
339   std::list<AttributePtr> anAttrs = theFeature->data()->attributes(
340                                                           GeomDataAPI_Point2D::typeId());
341   std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
342
343   for(; anIt != aLast; anIt++) {
344     AttributePtr anAttribute = *anIt;
345     if (anAttribute.get() && (theAttributesOnly.empty() ||
346         theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) {
347     if (!anInfo.empty()) {
348       anInfo.append(", ");
349       anInfo.append("\n");
350     }
351     anInfo.append("    " + getPointAttributeInfo(anAttribute));
352     }
353   }
354   return anInfo;
355 }
356
357 std::string ModelGeomAlgo_Point2D::getPointAttributeInfo(
358                               const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
359 {
360   std::string anInfo;
361   std::string aValue = "not defined";
362   std::string aType = theAttribute->attributeType();
363   if (aType == GeomDataAPI_Point2D::typeId()) {
364     std::shared_ptr<GeomDataAPI_Point2D> aPoint =
365       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
366     if (aPoint.get() && aPoint->isInitialized()) {
367       aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+
368                             doubleToString(aPoint->y()) + ")");
369     }
370   }
371   anInfo.append(theAttribute->id() + ": " + aValue);
372
373   return anInfo;
374 }
375 #endif