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