]> 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(const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
195                         const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
196                         PointToRefsMap& thePointToAttributeOrObject)
197 {
198   GeomShapePtr aFeatureShape;
199   {
200     std::set<ResultPtr> anEdgeShapes;
201     ModelGeomAlgo_Shape::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
202     if (anEdgeShapes.empty())
203       return;
204     aFeatureShape = (*anEdgeShapes.begin())->shape();
205   }
206
207   std::list<std::shared_ptr<ModelAPI_Feature> >::const_iterator anIt = theFeatures.begin(),
208                                                                 aLast = theFeatures.end();
209   for (; anIt != aLast; anIt++) {
210     FeaturePtr aFeature = *anIt;
211     if (aFeature.get() == theBaseFeature.get())
212       continue;
213     if (aFeature.get()) {
214       std::set<ResultPtr> anEdgeShapes;
215       ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
216       if (anEdgeShapes.empty())
217         ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::VERTEX, anEdgeShapes);
218
219       if (anEdgeShapes.empty())
220         continue;
221       ResultPtr aResult = *anEdgeShapes.begin();
222       GeomShapePtr aShape = aResult->shape();
223
224       GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape);
225       appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject);
226     }
227   }
228 }
229
230 std::list<std::shared_ptr<GeomAPI_Pnt> > ModelGeomAlgo_Point2D::getSetOfPntIntersectedShape(
231                   const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
232                   const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures)
233 {
234   std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
235
236   PointToRefsMap aRefsMap;
237   getPointsIntersectedShape(theBaseFeature, theFeatures, aRefsMap);
238
239   for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
240        aPointIt != aRefsMap.end(); aPointIt++)
241     aPoints.push_back(aPointIt->first);
242
243   return aPoints;
244 }
245
246 void ModelGeomAlgo_Point2D::getPointsInsideShape(
247                         const std::shared_ptr<GeomAPI_Shape> theBaseShape,
248                         const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
249                         const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
250                         const std::shared_ptr<GeomAPI_Dir>& theDirX,
251                         const std::shared_ptr<GeomAPI_Dir>& theDirY,
252                         PointToRefsMap& thePointToAttributeOrObject)
253 {
254   std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
255                                                           aLast = theAttributes.end();
256   for (; anIt != aLast; anIt++) {
257     std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
258     std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
259     std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
260     std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
261     if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
262       if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end())
263         thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute);
264       else {
265         std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
266         std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
267         anAttributes.push_back(anAttribute);
268         thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects);
269       }
270     }
271   }
272 }
273
274 void ModelGeomAlgo_Point2D::getPointsInsideShape_p(
275                             const std::shared_ptr<GeomAPI_Shape> theBaseShape,
276                             const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
277                             const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
278                             const std::shared_ptr<GeomAPI_Dir>& theDirX,
279                             const std::shared_ptr<GeomAPI_Dir>& theDirY,
280                             std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
281                             std::map<std::shared_ptr<GeomDataAPI_Point2D>,
282                                      std::shared_ptr<GeomAPI_Pnt> >& theAttributeToPoint)
283 {
284   std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
285                                                           aLast = theAttributes.end();
286   for (; anIt != aLast; anIt++) {
287     std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
288     std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
289     std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
290     std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
291     if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
292       thePoints.push_back(aProjectedPoint);
293       theAttributeToPoint[anAttribute] = aProjectedPoint;
294     }
295   }
296 }
297
298 bool ModelGeomAlgo_Point2D::isPointOnEdge(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
299                      const std::shared_ptr<GeomAPI_Pnt>& thePoint,
300                      std::shared_ptr<GeomAPI_Pnt>& theProjectedPoint)
301 {
302   bool isInside = false;
303   if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
304     std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theBaseShape));
305     if (anEdge->isLine()) {
306       std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
307       theProjectedPoint = aLine->project(thePoint);
308     }
309     else if (anEdge->isCircle() || anEdge->isArc()) {
310       std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
311       theProjectedPoint = aCircle->project(thePoint);
312     }
313     if (theProjectedPoint.get()) {
314       std::shared_ptr<GeomAPI_Vertex> aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(),
315                                                 theProjectedPoint->y(), theProjectedPoint->z()));
316       isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape);
317     }
318   }
319   return isInside;
320 }
321
322 std::string doubleToString(double theValue)
323 {
324   std::string aValueStr;
325   char aBuf[50];
326   int n = sprintf(aBuf, "%g", theValue);
327   aValueStr = std::string(aBuf);
328   return aValueStr;
329 }
330
331 #ifdef _DEBUG
332 std::string ModelGeomAlgo_Point2D::getPontAttributesInfo(
333                     const std::shared_ptr<ModelAPI_Feature>& theFeature,
334                     const std::set<std::shared_ptr<ModelAPI_Attribute> >& theAttributesOnly)
335 {
336   std::string anInfo;
337
338   std::list<AttributePtr> anAttrs = theFeature->data()->attributes(
339                                                           GeomDataAPI_Point2D::typeId());
340   std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
341
342   for(; anIt != aLast; anIt++) {
343     AttributePtr anAttribute = *anIt;
344     if (anAttribute.get() && (theAttributesOnly.empty() ||
345         theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) {
346     if (!anInfo.empty()) {
347       anInfo.append(", ");
348       anInfo.append("\n");
349     }
350     anInfo.append("    " + getPointAttributeInfo(anAttribute));
351     }
352   }
353   return anInfo;
354 }
355
356 std::string ModelGeomAlgo_Point2D::getPointAttributeInfo(
357                               const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
358 {
359   std::string anInfo;
360   std::string aValue = "not defined";
361   std::string aType = theAttribute->attributeType();
362   if (aType == GeomDataAPI_Point2D::typeId()) {
363     std::shared_ptr<GeomDataAPI_Point2D> aPoint =
364       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
365     if (aPoint.get() && aPoint->isInitialized()) {
366       aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+
367                             doubleToString(aPoint->y()) + ")");
368     }
369   }
370   anInfo.append(theAttribute->id() + ": " + aValue);
371
372   return anInfo;
373 }
374 #endif