1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
20 #include "ModelGeomAlgo_Point2D.h"
22 #include <ModelAPI_Feature.h>
23 #include <ModelAPI_Result.h>
24 #include <ModelAPI_AttributeRefAttr.h>
25 #include <ModelAPI_CompositeFeature.h>
26 #include <ModelAPI_Tools.h>
28 #include <ModelGeomAlgo_Shape.h>
30 #include <GeomAPI_ShapeIterator.h>
32 #include <GeomAlgoAPI_ShapeTools.h>
33 #include <GeomDataAPI_Point2D.h>
35 #include <GeomAPI_Pnt.h>
36 #include <GeomAPI_Pnt2d.h>
37 #include <GeomAPI_Vertex.h>
38 #include <GeomAPI_Dir.h>
39 #include <GeomAPI_Edge.h>
40 #include <GeomAPI_Lin.h>
41 #include <GeomAPI_Circ.h>
43 //#define DEBUG_POINT_INSIDE_SHAPE
44 #ifdef DEBUG_POINT_INSIDE_SHAPE
49 #pragma warning(disable : 4996) // for sprintf
52 std::shared_ptr<GeomDataAPI_Point2D> ModelGeomAlgo_Point2D::getPointOfRefAttr(
53 ModelAPI_Feature* theFeature,
54 const std::string& theAttribute,
55 const std::string& theObjectFeatureKind,
56 const std::string& theObjectFeatureAttribute)
58 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
60 /// essential check as it is called in openGl thread
61 if (!theFeature || !theFeature->data().get() || !theFeature->data()->isValid())
62 return std::shared_ptr<GeomDataAPI_Point2D>();
65 std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
66 ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute));
67 if(anAttr.get() && anAttr->isInitialized()) {
68 aFeature = ModelAPI_Feature::feature(anAttr->object());
70 bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() &&
71 !theObjectFeatureAttribute.empty() &&
72 aFeature->getKind() == theObjectFeatureKind;
73 if(aFeatureOfObjectKind)
74 aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
75 aFeature->data()->attribute(theObjectFeatureAttribute));
76 else if (anAttr->attr())
77 aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
83 void ModelGeomAlgo_Point2D::getPointsOfReference(
84 const std::shared_ptr<ModelAPI_Object>& theObject,
85 const std::string& theReferenceFeatureKind,
86 std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
87 const std::string& theObjectFeatureKind,
88 const std::string& theObjectFeatureAttribute,
89 const bool isSkipFeatureAttributes)
92 FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject);
94 const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
95 std::set<AttributePtr>::const_iterator aIt;
96 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
97 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
98 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
99 if (aRefFeature->getKind() == theReferenceFeatureKind) {
100 std::list<AttributePtr> anAttributes =
101 aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
102 std::list<AttributePtr>::iterator anIter = anAttributes.begin(), aLast = anAttributes.end();
103 bool isSkippedAttribute = false;
104 if (isSkipFeatureAttributes) {
105 for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) {
106 AttributeRefAttrPtr aRefAttribute =
107 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
108 if (aRefAttribute.get() && !aRefAttribute->isObject()) {
109 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr =
110 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttribute->attr());
111 FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner());
112 isSkippedAttribute = aSourceFeature == anAttributeFeature;
116 if (isSkippedAttribute)
119 // it searches the first point of AttributeRefAtt
120 std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
121 for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) {
122 AttributeRefAttrPtr aRefAttribute =
123 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
124 if (aRefAttribute.get()) {
125 aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(),
126 theObjectFeatureKind, theObjectFeatureAttribute);
129 if (aPointAttr.get()) {
130 theAttributes.insert(aPointAttr);
135 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
136 if (aFeature.get()) {
137 const std::list<std::shared_ptr<ModelAPI_Result> > aResults = aFeature->results();
138 std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
139 for (; aRIter != aResults.cend(); aRIter++) {
140 ResultPtr aResult = *aRIter;
141 getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind,
142 theObjectFeatureAttribute);
147 void appendPoint(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
148 const std::shared_ptr<ModelAPI_Result>& theResult,
149 ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject)
151 bool aPointFound = false;
152 FeaturePtr aPointFeature = ModelAPI_Feature::feature(theResult);
153 // check if the given point is already in the container in attribute list
154 for (ModelGeomAlgo_Point2D::PointToRefsMap::const_iterator
155 anIt = thePointToAttributeOrObject.begin();
156 anIt != thePointToAttributeOrObject.end() && !aPointFound; anIt++) {
157 std::shared_ptr<GeomAPI_Pnt> aPoint = anIt->first;
158 if (aPoint->isEqual(thePoint)) {
159 std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes = anIt->second.first;
160 for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
161 anAttrIt != anAttributes.end() && !aPointFound; anAttrIt++) {
162 AttributePtr anAttribute = *anAttrIt;
163 aPointFound = ModelAPI_Feature::feature(anAttribute->owner()) == aPointFeature;
169 if (thePointToAttributeOrObject.find(thePoint) != thePointToAttributeOrObject.end())
170 thePointToAttributeOrObject.at(thePoint).second.push_back(theResult);
172 std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
173 std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
174 anObjects.push_back(theResult);
175 thePointToAttributeOrObject[thePoint] = std::make_pair(anAttributes, anObjects);
177 #ifdef DEBUG_POINT_INSIDE_SHAPE
178 std::cout << "["<< thePoint->x() << ", " << thePoint->y() << "," << thePoint->z() << "]";
183 void appendShapePoints(const GeomShapePtr& theShape,
184 const std::shared_ptr<ModelAPI_Result>& theResult,
185 ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject)
190 switch (theShape->shapeType()) {
191 case GeomAPI_Shape::VERTEX: {
192 std::shared_ptr<GeomAPI_Vertex> aVertex =
193 std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(theShape));
194 std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
195 appendPoint(aPnt, theResult, thePointToAttributeOrObject);
198 case GeomAPI_Shape::EDGE: {
199 std::shared_ptr<GeomAPI_Edge> anEdge =
200 std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(theShape));
201 appendPoint(anEdge->firstPoint(), theResult, thePointToAttributeOrObject);
202 appendPoint(anEdge->lastPoint(), theResult, thePointToAttributeOrObject);
205 case GeomAPI_Shape::COMPOUND: {
206 for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) {
207 appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject);
215 void ModelGeomAlgo_Point2D::getPointsIntersectedShape(
216 const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
217 const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
218 PointToRefsMap& thePointToAttributeOrObject)
220 #ifdef DEBUG_POINT_INSIDE_SHAPE
221 std::cout << "ModelGeomAlgo_Point2D::getPointsIntersectedShape" << std::endl;
223 GeomShapePtr aFeatureShape;
225 std::set<ResultPtr> anEdgeShapes;
226 ModelGeomAlgo_Shape::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
227 if (anEdgeShapes.empty())
229 aFeatureShape = (*anEdgeShapes.begin())->shape();
232 std::list<std::shared_ptr<ModelAPI_Feature> >::const_iterator anIt = theFeatures.begin(),
233 aLast = theFeatures.end();
234 for (; anIt != aLast; anIt++) {
235 FeaturePtr aFeature = *anIt;
236 if (aFeature.get() == theBaseFeature.get())
238 if (aFeature.get()) {
239 std::set<ResultPtr> anEdgeShapes;
240 ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
241 if (anEdgeShapes.empty())
242 ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::VERTEX, anEdgeShapes);
244 if (anEdgeShapes.empty())
246 ResultPtr aResult = *anEdgeShapes.begin();
247 GeomShapePtr aShape = aResult->shape();
249 GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape);
250 #ifdef DEBUG_POINT_INSIDE_SHAPE
251 int aPrevSize = thePointToAttributeOrObject.size();
253 appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject);
254 #ifdef DEBUG_POINT_INSIDE_SHAPE
255 if (aPrevSize != thePointToAttributeOrObject.size())
256 std::cout << " <- appendShapePoints"
257 << thePointToAttributeOrObject.size() - aPrevSize << std::endl;
263 std::list<std::shared_ptr<GeomAPI_Pnt> > ModelGeomAlgo_Point2D::getSetOfPntIntersectedShape(
264 const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
265 const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures)
267 std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
269 PointToRefsMap aRefsMap;
270 getPointsIntersectedShape(theBaseFeature, theFeatures, aRefsMap);
272 for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
273 aPointIt != aRefsMap.end(); aPointIt++)
274 aPoints.push_back(aPointIt->first);
279 void ModelGeomAlgo_Point2D::getPointsInsideShape(
280 const std::shared_ptr<GeomAPI_Shape> theBaseShape,
281 const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
282 const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
283 const std::shared_ptr<GeomAPI_Dir>& theDirX,
284 const std::shared_ptr<GeomAPI_Dir>& theDirY,
285 PointToRefsMap& thePointToAttributeOrObject)
287 #ifdef DEBUG_POINT_INSIDE_SHAPE
288 std::cout << "ModelGeomAlgo_Point2D::getPointsInsideShape:" << std::endl;
290 std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
291 aLast = theAttributes.end();
292 for (; anIt != aLast; anIt++) {
293 std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
294 std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
295 std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
296 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
297 if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
298 if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end())
299 thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute);
301 std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
302 std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
303 anAttributes.push_back(anAttribute);
304 thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects);
306 #ifdef DEBUG_POINT_INSIDE_SHAPE
307 std::cout << " " << anAttribute->owner()->data()->name() << ": " << anAttribute->id()
308 << "[" << aPoint->x() << ", " << aPoint->y() << ", " << aPoint->z() << "]"
313 #ifdef DEBUG_POINT_INSIDE_SHAPE
314 std::cout << " " << anAttribute->owner()->data()->name() << ": " << anAttribute->id()
315 << "OUT of shape" << std::endl;
321 void ModelGeomAlgo_Point2D::getPointsInsideShape_p(
322 const std::shared_ptr<GeomAPI_Shape> theBaseShape,
323 const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
324 const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
325 const std::shared_ptr<GeomAPI_Dir>& theDirX,
326 const std::shared_ptr<GeomAPI_Dir>& theDirY,
327 std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
328 std::map<std::shared_ptr<GeomDataAPI_Point2D>,
329 std::shared_ptr<GeomAPI_Pnt> >& theAttributeToPoint)
331 std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
332 aLast = theAttributes.end();
333 for (; anIt != aLast; anIt++) {
334 std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
335 std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
336 std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
337 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
338 if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
339 thePoints.push_back(aProjectedPoint);
340 theAttributeToPoint[anAttribute] = aProjectedPoint;
345 bool ModelGeomAlgo_Point2D::isPointOnEdge(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
346 const std::shared_ptr<GeomAPI_Pnt>& thePoint,
347 std::shared_ptr<GeomAPI_Pnt>& theProjectedPoint)
349 bool isInside = false;
350 if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
351 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theBaseShape));
352 if (anEdge->isLine()) {
353 std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
354 theProjectedPoint = aLine->project(thePoint);
356 else if (anEdge->isCircle() || anEdge->isArc()) {
357 std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
358 theProjectedPoint = aCircle->project(thePoint);
360 if (theProjectedPoint.get()) {
361 std::shared_ptr<GeomAPI_Vertex> aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(),
362 theProjectedPoint->y(), theProjectedPoint->z()));
363 isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape);
369 std::string doubleToString(double theValue)
371 std::string aValueStr;
373 int n = sprintf(aBuf, "%g", theValue);
374 aValueStr = std::string(aBuf);
379 std::string ModelGeomAlgo_Point2D::getPontAttributesInfo(
380 const std::shared_ptr<ModelAPI_Feature>& theFeature,
381 const std::set<std::shared_ptr<ModelAPI_Attribute> >& theAttributesOnly)
385 std::list<AttributePtr> anAttrs = theFeature->data()->attributes(
386 GeomDataAPI_Point2D::typeId());
387 std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
389 for(; anIt != aLast; anIt++) {
390 AttributePtr anAttribute = *anIt;
391 if (anAttribute.get() && (theAttributesOnly.empty() ||
392 theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) {
393 if (!anInfo.empty()) {
397 anInfo.append(" " + getPointAttributeInfo(anAttribute));
403 std::string ModelGeomAlgo_Point2D::getPointAttributeInfo(
404 const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
407 std::string aValue = "not defined";
408 std::string aType = theAttribute->attributeType();
409 if (aType == GeomDataAPI_Point2D::typeId()) {
410 std::shared_ptr<GeomDataAPI_Point2D> aPoint =
411 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
412 if (aPoint.get() && aPoint->isInitialized()) {
413 aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+
414 doubleToString(aPoint->y()) + ")");
417 anInfo.append(theAttribute->id() + ": " + aValue);