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 <GeomAPI_ShapeIterator.h>
17 #include <GeomAlgoAPI_ShapeTools.h>
18 #include <GeomDataAPI_Point2D.h>
20 #include <GeomAPI_Pnt.h>
21 #include <GeomAPI_Pnt2d.h>
22 #include <GeomAPI_Vertex.h>
23 #include <GeomAPI_Dir.h>
24 #include <GeomAPI_Edge.h>
25 #include <GeomAPI_Lin.h>
26 #include <GeomAPI_Circ.h>
29 #pragma warning(disable : 4996) // for sprintf
32 namespace ModelGeomAlgo_Point2D {
33 std::shared_ptr<GeomDataAPI_Point2D> getPointOfRefAttr(ModelAPI_Feature* theFeature,
34 const std::string& theAttribute,
35 const std::string& theObjectFeatureKind,
36 const std::string& theObjectFeatureAttribute)
38 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
40 /// essential check as it is called in openGl thread
41 if (!theFeature || !theFeature->data().get() || !theFeature->data()->isValid())
42 return std::shared_ptr<GeomDataAPI_Point2D>();
45 std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
46 ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute));
47 if(anAttr.get() && anAttr->isInitialized()) {
48 aFeature = ModelAPI_Feature::feature(anAttr->object());
50 bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() &&
51 !theObjectFeatureAttribute.empty() &&
52 aFeature->getKind() == theObjectFeatureKind;
53 if(aFeatureOfObjectKind)
54 aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
55 aFeature->data()->attribute(theObjectFeatureAttribute));
56 else if (anAttr->attr())
57 aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
63 void getPointsOfReference(const std::shared_ptr<ModelAPI_Object>& theObject,
64 const std::string& theReferenceFeatureKind,
65 std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
66 const std::string& theObjectFeatureKind,
67 const std::string& theObjectFeatureAttribute,
68 const bool isSkipFeatureAttributes)
71 FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject);
73 const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
74 std::set<AttributePtr>::const_iterator aIt;
75 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
76 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
77 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
78 if (aRefFeature->getKind() == theReferenceFeatureKind) {
79 std::list<AttributePtr> anAttributes =
80 aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
81 std::list<AttributePtr>::iterator anIter = anAttributes.begin(), aLast = anAttributes.end();
82 bool isSkippedAttribute = false;
83 if (isSkipFeatureAttributes) {
84 for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) {
85 AttributeRefAttrPtr aRefAttribute =
86 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
87 if (aRefAttribute.get() && !aRefAttribute->isObject()) {
88 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr =
89 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttribute->attr());
90 FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner());
91 isSkippedAttribute = aSourceFeature == anAttributeFeature;
95 if (isSkippedAttribute)
98 // it searches the first point of AttributeRefAtt
99 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
100 for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) {
101 AttributeRefAttrPtr aRefAttribute =
102 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
103 if (aRefAttribute.get()) {
104 aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(),
105 theObjectFeatureKind, theObjectFeatureAttribute);
108 if (aPointAttr.get()) {
109 theAttributes.insert(aPointAttr);
114 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
115 if (aFeature.get()) {
116 const std::list<std::shared_ptr<ModelAPI_Result> > aResults = aFeature->results();
117 std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
118 for (; aRIter != aResults.cend(); aRIter++) {
119 ResultPtr aResult = *aRIter;
120 getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind,
121 theObjectFeatureAttribute);
126 void appendPoint(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
127 const std::shared_ptr<ModelAPI_Result>& theResult,
128 PointToRefsMap& thePointToAttributeOrObject)
130 if (thePointToAttributeOrObject.find(thePoint) != thePointToAttributeOrObject.end())
131 thePointToAttributeOrObject.at(thePoint).second.push_back(theResult);
133 std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
134 std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
135 anObjects.push_back(theResult);
136 thePointToAttributeOrObject[thePoint] = std::make_pair(anAttributes, anObjects);
140 void appendShapePoints(const GeomShapePtr& theShape,
141 const std::shared_ptr<ModelAPI_Result>& theResult,
142 PointToRefsMap& thePointToAttributeOrObject)
147 switch (theShape->shapeType()) {
148 case GeomAPI_Shape::VERTEX: {
149 std::shared_ptr<GeomAPI_Vertex> aVertex =
150 std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(theShape));
151 std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
152 appendPoint(aPnt, theResult, thePointToAttributeOrObject);
155 case GeomAPI_Shape::EDGE: {
156 std::shared_ptr<GeomAPI_Edge> anEdge =
157 std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(theShape));
158 appendPoint(anEdge->firstPoint(), theResult, thePointToAttributeOrObject);
159 appendPoint(anEdge->lastPoint(), theResult, thePointToAttributeOrObject);
162 case GeomAPI_Shape::COMPOUND: {
163 for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) {
164 appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject);
172 void getPointsIntersectedShape(const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
173 const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
174 PointToRefsMap& thePointToAttributeOrObject)
176 GeomShapePtr aFeatureShape;
178 std::set<ResultPtr> anEdgeShapes;
179 ModelAPI_Tools::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
180 if (anEdgeShapes.empty())
182 aFeatureShape = (*anEdgeShapes.begin())->shape();
185 std::list<std::shared_ptr<ModelAPI_Feature> >::const_iterator anIt = theFeatures.begin(),
186 aLast = theFeatures.end();
187 for (; anIt != aLast; anIt++) {
188 FeaturePtr aFeature = *anIt;
189 if (aFeature.get() == theBaseFeature.get())
191 if (aFeature.get()) {
192 std::set<ResultPtr> anEdgeShapes;
193 ModelAPI_Tools::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
194 if (anEdgeShapes.empty())
196 ResultPtr aResult = *anEdgeShapes.begin();
197 GeomShapePtr aShape = aResult->shape();
199 GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape);
200 appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject);
205 void getPointsInsideShape(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
206 const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
207 const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
208 const std::shared_ptr<GeomAPI_Dir>& theDirX,
209 const std::shared_ptr<GeomAPI_Dir>& theDirY,
210 PointToRefsMap& thePointToAttributeOrObject)
212 std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
213 aLast = theAttributes.end();
214 for (; anIt != aLast; anIt++) {
215 std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
216 std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
217 std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
218 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
219 if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
220 if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end())
221 thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute);
223 //std::list< std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
224 //anAttributes.push_back(anAttribute);
225 //thePointToAttributeOrObject.insert(aProjectedPoint, anAttributes);
227 std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
228 std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
229 anAttributes.push_back(anAttribute);
230 thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects);
232 //thePoints.push_back(aProjectedPoint);
233 //theAttributeToPoint[anAttribute] = aProjectedPoint;
238 void getPointsInsideShape_p(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
239 const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
240 const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
241 const std::shared_ptr<GeomAPI_Dir>& theDirX,
242 const std::shared_ptr<GeomAPI_Dir>& theDirY,
243 std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
244 std::map<std::shared_ptr<GeomDataAPI_Point2D>,
245 std::shared_ptr<GeomAPI_Pnt> >& theAttributeToPoint)
247 std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
248 aLast = theAttributes.end();
249 for (; anIt != aLast; anIt++) {
250 std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
251 std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
252 std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
253 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
254 if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
255 thePoints.push_back(aProjectedPoint);
256 theAttributeToPoint[anAttribute] = aProjectedPoint;
261 bool isPointOnEdge(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
262 const std::shared_ptr<GeomAPI_Pnt>& thePoint,
263 std::shared_ptr<GeomAPI_Pnt>& theProjectedPoint)
265 bool isInside = false;
266 if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
267 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theBaseShape));
268 if (anEdge->isLine()) {
269 std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
270 theProjectedPoint = aLine->project(thePoint);
272 else if (anEdge->isCircle() || anEdge->isArc()) {
273 std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
274 theProjectedPoint = aCircle->project(thePoint);
276 if (theProjectedPoint.get()) {
277 std::shared_ptr<GeomAPI_Vertex> aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(),
278 theProjectedPoint->y(), theProjectedPoint->z()));
279 isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape);
285 std::string doubleToString(double theValue)
287 std::string aValueStr;
289 int n = sprintf(aBuf, "%g", theValue);
290 aValueStr = std::string(aBuf);
295 std::string getPontAttributesInfo(const std::shared_ptr<ModelAPI_Feature>& theFeature,
296 const std::set<std::shared_ptr<ModelAPI_Attribute> >& theAttributesOnly)
300 std::list<AttributePtr> anAttrs = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
301 std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
303 for(; anIt != aLast; anIt++) {
304 AttributePtr anAttribute = *anIt;
305 if (anAttribute.get() && (theAttributesOnly.empty() ||
306 theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) {
307 if (!anInfo.empty()) {
311 anInfo.append(" " + getPointAttributeInfo(anAttribute));
317 std::string getPointAttributeInfo(const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
320 std::string aValue = "not defined";
321 std::string aType = theAttribute->attributeType();
322 if (aType == GeomDataAPI_Point2D::typeId()) {
323 std::shared_ptr<GeomDataAPI_Point2D> aPoint =
324 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
325 if (aPoint.get() && aPoint->isInitialized()) {
326 aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+
327 doubleToString(aPoint->y()) + ")");
330 anInfo.append(theAttribute->id() + ": " + aValue);
335 } // namespace ModelGeomAlgo_Point2D