1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: ModelAPI_Tools.cpp
4 // Created: 20 Jul 2016
5 // Author: Natalia ERMOLAEVA
7 #include "ModelGeomAlgo_Point2D.h"
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>
15 #include <ModelGeomAlgo_Shape.h>
17 #include <GeomAPI_ShapeIterator.h>
19 #include <GeomAlgoAPI_ShapeTools.h>
20 #include <GeomDataAPI_Point2D.h>
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>
30 //#define DEBUG_POINT_INSIDE_SHAPE
31 #ifdef DEBUG_POINT_INSIDE_SHAPE
36 #pragma warning(disable : 4996) // for sprintf
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)
45 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
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>();
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());
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());
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)
79 FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject);
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;
103 if (isSkippedAttribute)
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);
116 if (aPointAttr.get()) {
117 theAttributes.insert(aPointAttr);
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);
134 void appendPoint(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
135 const std::shared_ptr<ModelAPI_Result>& theResult,
136 ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject)
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;
156 if (thePointToAttributeOrObject.find(thePoint) != thePointToAttributeOrObject.end())
157 thePointToAttributeOrObject.at(thePoint).second.push_back(theResult);
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);
164 #ifdef DEBUG_POINT_INSIDE_SHAPE
165 std::cout << "["<< thePoint->x() << ", " << thePoint->y() << "," << thePoint->z() << "]";
170 void appendShapePoints(const GeomShapePtr& theShape,
171 const std::shared_ptr<ModelAPI_Result>& theResult,
172 ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject)
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);
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);
192 case GeomAPI_Shape::COMPOUND: {
193 for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) {
194 appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject);
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)
207 #ifdef DEBUG_POINT_INSIDE_SHAPE
208 std::cout << "ModelGeomAlgo_Point2D::getPointsIntersectedShape" << std::endl;
210 GeomShapePtr aFeatureShape;
212 std::set<ResultPtr> anEdgeShapes;
213 ModelGeomAlgo_Shape::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
214 if (anEdgeShapes.empty())
216 aFeatureShape = (*anEdgeShapes.begin())->shape();
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())
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);
231 if (anEdgeShapes.empty())
233 ResultPtr aResult = *anEdgeShapes.begin();
234 GeomShapePtr aShape = aResult->shape();
236 GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape);
237 #ifdef DEBUG_POINT_INSIDE_SHAPE
238 int aPrevSize = thePointToAttributeOrObject.size();
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;
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)
254 std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
256 PointToRefsMap aRefsMap;
257 getPointsIntersectedShape(theBaseFeature, theFeatures, aRefsMap);
259 for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
260 aPointIt != aRefsMap.end(); aPointIt++)
261 aPoints.push_back(aPointIt->first);
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)
274 #ifdef DEBUG_POINT_INSIDE_SHAPE
275 std::cout << "ModelGeomAlgo_Point2D::getPointsInsideShape:" << std::endl;
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);
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);
293 #ifdef DEBUG_POINT_INSIDE_SHAPE
294 std::cout << " " << anAttribute->owner()->data()->name() << ": " << anAttribute->id()
295 << "[" << aPoint->x() << ", " << aPoint->y() << ", " << aPoint->z() << "]"
300 #ifdef DEBUG_POINT_INSIDE_SHAPE
301 std::cout << " " << anAttribute->owner()->data()->name() << ": " << anAttribute->id()
302 << "OUT of shape" << std::endl;
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)
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;
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)
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);
343 else if (anEdge->isCircle() || anEdge->isArc()) {
344 std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
345 theProjectedPoint = aCircle->project(thePoint);
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);
356 std::string doubleToString(double theValue)
358 std::string aValueStr;
360 int n = sprintf(aBuf, "%g", theValue);
361 aValueStr = std::string(aBuf);
366 std::string ModelGeomAlgo_Point2D::getPontAttributesInfo(
367 const std::shared_ptr<ModelAPI_Feature>& theFeature,
368 const std::set<std::shared_ptr<ModelAPI_Attribute> >& theAttributesOnly)
372 std::list<AttributePtr> anAttrs = theFeature->data()->attributes(
373 GeomDataAPI_Point2D::typeId());
374 std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
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()) {
384 anInfo.append(" " + getPointAttributeInfo(anAttribute));
390 std::string ModelGeomAlgo_Point2D::getPointAttributeInfo(
391 const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
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()) + ")");
404 anInfo.append(theAttribute->id() + ": " + aValue);