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 namespace ModelGeomAlgo_Point2D {
35 std::shared_ptr<GeomDataAPI_Point2D> getPointOfRefAttr(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 getPointsOfReference(const std::shared_ptr<ModelAPI_Object>& theObject,
66 const std::string& theReferenceFeatureKind,
67 std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
68 const std::string& theObjectFeatureKind,
69 const std::string& theObjectFeatureAttribute,
70 const bool isSkipFeatureAttributes)
73 FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject);
75 const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
76 std::set<AttributePtr>::const_iterator aIt;
77 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
78 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
79 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
80 if (aRefFeature->getKind() == theReferenceFeatureKind) {
81 std::list<AttributePtr> anAttributes =
82 aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
83 std::list<AttributePtr>::iterator anIter = anAttributes.begin(), aLast = anAttributes.end();
84 bool isSkippedAttribute = false;
85 if (isSkipFeatureAttributes) {
86 for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) {
87 AttributeRefAttrPtr aRefAttribute =
88 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
89 if (aRefAttribute.get() && !aRefAttribute->isObject()) {
90 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr =
91 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttribute->attr());
92 FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner());
93 isSkippedAttribute = aSourceFeature == anAttributeFeature;
97 if (isSkippedAttribute)
100 // it searches the first point of AttributeRefAtt
101 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
102 for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) {
103 AttributeRefAttrPtr aRefAttribute =
104 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
105 if (aRefAttribute.get()) {
106 aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(),
107 theObjectFeatureKind, theObjectFeatureAttribute);
110 if (aPointAttr.get()) {
111 theAttributes.insert(aPointAttr);
116 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
117 if (aFeature.get()) {
118 const std::list<std::shared_ptr<ModelAPI_Result> > aResults = aFeature->results();
119 std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
120 for (; aRIter != aResults.cend(); aRIter++) {
121 ResultPtr aResult = *aRIter;
122 getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind,
123 theObjectFeatureAttribute);
128 void appendPoint(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
129 const std::shared_ptr<ModelAPI_Result>& theResult,
130 PointToRefsMap& thePointToAttributeOrObject)
132 if (thePointToAttributeOrObject.find(thePoint) != thePointToAttributeOrObject.end())
133 thePointToAttributeOrObject.at(thePoint).second.push_back(theResult);
135 std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
136 std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
137 anObjects.push_back(theResult);
138 thePointToAttributeOrObject[thePoint] = std::make_pair(anAttributes, anObjects);
142 void appendShapePoints(const GeomShapePtr& theShape,
143 const std::shared_ptr<ModelAPI_Result>& theResult,
144 PointToRefsMap& thePointToAttributeOrObject)
149 switch (theShape->shapeType()) {
150 case GeomAPI_Shape::VERTEX: {
151 std::shared_ptr<GeomAPI_Vertex> aVertex =
152 std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(theShape));
153 std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
154 appendPoint(aPnt, theResult, thePointToAttributeOrObject);
157 case GeomAPI_Shape::EDGE: {
158 std::shared_ptr<GeomAPI_Edge> anEdge =
159 std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(theShape));
160 appendPoint(anEdge->firstPoint(), theResult, thePointToAttributeOrObject);
161 appendPoint(anEdge->lastPoint(), theResult, thePointToAttributeOrObject);
164 case GeomAPI_Shape::COMPOUND: {
165 for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) {
166 appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject);
174 void getPointsIntersectedShape(const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
175 const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
176 PointToRefsMap& thePointToAttributeOrObject)
178 GeomShapePtr aFeatureShape;
180 std::set<ResultPtr> anEdgeShapes;
181 ModelGeomAlgo_Shape::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
182 if (anEdgeShapes.empty())
184 aFeatureShape = (*anEdgeShapes.begin())->shape();
187 std::list<std::shared_ptr<ModelAPI_Feature> >::const_iterator anIt = theFeatures.begin(),
188 aLast = theFeatures.end();
189 for (; anIt != aLast; anIt++) {
190 FeaturePtr aFeature = *anIt;
191 if (aFeature.get() == theBaseFeature.get())
193 if (aFeature.get()) {
194 std::set<ResultPtr> anEdgeShapes;
195 ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
196 if (anEdgeShapes.empty())
198 ResultPtr aResult = *anEdgeShapes.begin();
199 GeomShapePtr aShape = aResult->shape();
201 GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape);
202 appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject);
207 void getPointsInsideShape(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
208 const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
209 const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
210 const std::shared_ptr<GeomAPI_Dir>& theDirX,
211 const std::shared_ptr<GeomAPI_Dir>& theDirY,
212 PointToRefsMap& thePointToAttributeOrObject)
214 std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
215 aLast = theAttributes.end();
216 for (; anIt != aLast; anIt++) {
217 std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
218 std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
219 std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
220 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
221 if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
222 if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end())
223 thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute);
225 std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
226 std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
227 anAttributes.push_back(anAttribute);
228 thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects);
234 void getPointsInsideShape_p(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
235 const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
236 const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
237 const std::shared_ptr<GeomAPI_Dir>& theDirX,
238 const std::shared_ptr<GeomAPI_Dir>& theDirY,
239 std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
240 std::map<std::shared_ptr<GeomDataAPI_Point2D>,
241 std::shared_ptr<GeomAPI_Pnt> >& theAttributeToPoint)
243 std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
244 aLast = theAttributes.end();
245 for (; anIt != aLast; anIt++) {
246 std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
247 std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
248 std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
249 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
250 if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
251 thePoints.push_back(aProjectedPoint);
252 theAttributeToPoint[anAttribute] = aProjectedPoint;
257 bool isPointOnEdge(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
258 const std::shared_ptr<GeomAPI_Pnt>& thePoint,
259 std::shared_ptr<GeomAPI_Pnt>& theProjectedPoint)
261 bool isInside = false;
262 if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
263 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theBaseShape));
264 if (anEdge->isLine()) {
265 std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
266 theProjectedPoint = aLine->project(thePoint);
268 else if (anEdge->isCircle() || anEdge->isArc()) {
269 std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
270 theProjectedPoint = aCircle->project(thePoint);
272 if (theProjectedPoint.get()) {
273 std::shared_ptr<GeomAPI_Vertex> aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(),
274 theProjectedPoint->y(), theProjectedPoint->z()));
275 isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape);
281 std::string doubleToString(double theValue)
283 std::string aValueStr;
285 int n = sprintf(aBuf, "%g", theValue);
286 aValueStr = std::string(aBuf);
291 std::string getPontAttributesInfo(const std::shared_ptr<ModelAPI_Feature>& theFeature,
292 const std::set<std::shared_ptr<ModelAPI_Attribute> >& theAttributesOnly)
296 std::list<AttributePtr> anAttrs = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
297 std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
299 for(; anIt != aLast; anIt++) {
300 AttributePtr anAttribute = *anIt;
301 if (anAttribute.get() && (theAttributesOnly.empty() ||
302 theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) {
303 if (!anInfo.empty()) {
307 anInfo.append(" " + getPointAttributeInfo(anAttribute));
313 std::string getPointAttributeInfo(const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
316 std::string aValue = "not defined";
317 std::string aType = theAttribute->attributeType();
318 if (aType == GeomDataAPI_Point2D::typeId()) {
319 std::shared_ptr<GeomDataAPI_Point2D> aPoint =
320 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
321 if (aPoint.get() && aPoint->isInitialized()) {
322 aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+
323 doubleToString(aPoint->y()) + ")");
326 anInfo.append(theAttribute->id() + ": " + aValue);
331 } // namespace ModelGeomAlgo_Point2D