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>
31 #pragma warning(disable : 4996) // for sprintf
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)
40 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
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>();
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());
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());
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)
74 FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject);
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;
98 if (isSkippedAttribute)
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);
111 if (aPointAttr.get()) {
112 theAttributes.insert(aPointAttr);
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);
129 void appendPoint(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
130 const std::shared_ptr<ModelAPI_Result>& theResult,
131 ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject)
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;
151 if (thePointToAttributeOrObject.find(thePoint) != thePointToAttributeOrObject.end())
152 thePointToAttributeOrObject.at(thePoint).second.push_back(theResult);
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);
162 void appendShapePoints(const GeomShapePtr& theShape,
163 const std::shared_ptr<ModelAPI_Result>& theResult,
164 ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject)
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);
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);
184 case GeomAPI_Shape::COMPOUND: {
185 for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) {
186 appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject);
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)
199 GeomShapePtr aFeatureShape;
201 std::set<ResultPtr> anEdgeShapes;
202 ModelGeomAlgo_Shape::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
203 if (anEdgeShapes.empty())
205 aFeatureShape = (*anEdgeShapes.begin())->shape();
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())
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);
220 if (anEdgeShapes.empty())
222 ResultPtr aResult = *anEdgeShapes.begin();
223 GeomShapePtr aShape = aResult->shape();
225 GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape);
226 appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject);
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)
235 std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
237 PointToRefsMap aRefsMap;
238 getPointsIntersectedShape(theBaseFeature, theFeatures, aRefsMap);
240 for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
241 aPointIt != aRefsMap.end(); aPointIt++)
242 aPoints.push_back(aPointIt->first);
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)
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);
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);
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)
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;
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)
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);
310 else if (anEdge->isCircle() || anEdge->isArc()) {
311 std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
312 theProjectedPoint = aCircle->project(thePoint);
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);
323 std::string doubleToString(double theValue)
325 std::string aValueStr;
327 int n = sprintf(aBuf, "%g", theValue);
328 aValueStr = std::string(aBuf);
333 std::string ModelGeomAlgo_Point2D::getPontAttributesInfo(
334 const std::shared_ptr<ModelAPI_Feature>& theFeature,
335 const std::set<std::shared_ptr<ModelAPI_Attribute> >& theAttributesOnly)
339 std::list<AttributePtr> anAttrs = theFeature->data()->attributes(
340 GeomDataAPI_Point2D::typeId());
341 std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
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()) {
351 anInfo.append(" " + getPointAttributeInfo(anAttribute));
357 std::string ModelGeomAlgo_Point2D::getPointAttributeInfo(
358 const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
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()) + ")");
371 anInfo.append(theAttribute->id() + ": " + aValue);