Salome HOME
Copyright update 2022
[modules/shaper.git] / src / ModelGeomAlgo / ModelGeomAlgo_Point2D.cpp
old mode 100755 (executable)
new mode 100644 (file)
index 70cd9cb..8278b21
@@ -1,8 +1,21 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        ModelAPI_Tools.cpp
-// Created:     20 Jul 2016
-// Author:      Natalia ERMOLAEVA
+// Copyright (C) 2014-2022  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
 
 #include "ModelGeomAlgo_Point2D.h"
 
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Lin.h>
 #include <GeomAPI_Circ.h>
+#include <GeomAPI_ShapeExplorer.h>
+
+//#define DEBUG_POINT_INSIDE_SHAPE
+#ifdef DEBUG_POINT_INSIDE_SHAPE
+#include <iostream>
+#endif
 
 #ifdef WIN32
 #pragma warning(disable : 4996) // for sprintf
@@ -156,6 +175,9 @@ void appendPoint(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
       anObjects.push_back(theResult);
       thePointToAttributeOrObject[thePoint] = std::make_pair(anAttributes, anObjects);
     }
+#ifdef DEBUG_POINT_INSIDE_SHAPE
+    std::cout << "["<< thePoint->x() << ", " << thePoint->y() << "," << thePoint->z() << "]";
+#endif
   }
 }
 
@@ -191,10 +213,14 @@ void appendShapePoints(const GeomShapePtr& theShape,
   }
 }
 
-void ModelGeomAlgo_Point2D::getPointsIntersectedShape(const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
+void ModelGeomAlgo_Point2D::getPointsIntersectedShape(
+                        const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
                         const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
                         PointToRefsMap& thePointToAttributeOrObject)
 {
+#ifdef DEBUG_POINT_INSIDE_SHAPE
+  std::cout << "ModelGeomAlgo_Point2D::getPointsIntersectedShape" << std::endl;
+#endif
   GeomShapePtr aFeatureShape;
   {
     std::set<ResultPtr> anEdgeShapes;
@@ -222,7 +248,15 @@ void ModelGeomAlgo_Point2D::getPointsIntersectedShape(const std::shared_ptr<Mode
       GeomShapePtr aShape = aResult->shape();
 
       GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape);
+#ifdef DEBUG_POINT_INSIDE_SHAPE
+      int aPrevSize = thePointToAttributeOrObject.size();
+#endif
       appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject);
+#ifdef DEBUG_POINT_INSIDE_SHAPE
+      if (aPrevSize != thePointToAttributeOrObject.size())
+        std::cout << " <- appendShapePoints"
+                  << thePointToAttributeOrObject.size() - aPrevSize << std::endl;
+#endif
     }
   }
 }
@@ -251,6 +285,9 @@ void ModelGeomAlgo_Point2D::getPointsInsideShape(
                         const std::shared_ptr<GeomAPI_Dir>& theDirY,
                         PointToRefsMap& thePointToAttributeOrObject)
 {
+#ifdef DEBUG_POINT_INSIDE_SHAPE
+  std::cout << "ModelGeomAlgo_Point2D::getPointsInsideShape:" << std::endl;
+#endif
   std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
                                                           aLast = theAttributes.end();
   for (; anIt != aLast; anIt++) {
@@ -258,7 +295,7 @@ void ModelGeomAlgo_Point2D::getPointsInsideShape(
     std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
     std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
     std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
-    if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
+    if (isInnerPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
       if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end())
         thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute);
       else {
@@ -267,6 +304,17 @@ void ModelGeomAlgo_Point2D::getPointsInsideShape(
         anAttributes.push_back(anAttribute);
         thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects);
       }
+#ifdef DEBUG_POINT_INSIDE_SHAPE
+      std::cout << "  " << anAttribute->owner()->data()->name() << ": " << anAttribute->id()
+                << "[" << aPoint->x() << ", " << aPoint->y() << ", " << aPoint->z() << "]"
+                << std::endl;
+#endif
+    }
+    else {
+#ifdef DEBUG_POINT_INSIDE_SHAPE
+      std::cout << "  " << anAttribute->owner()->data()->name() << ": " << anAttribute->id()
+                << "OUT of shape" << std::endl;
+#endif
     }
   }
 }
@@ -288,7 +336,7 @@ void ModelGeomAlgo_Point2D::getPointsInsideShape_p(
     std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
     std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
     std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
-    if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
+    if (isInnerPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
       thePoints.push_back(aProjectedPoint);
       theAttributeToPoint[anAttribute] = aProjectedPoint;
     }
@@ -301,15 +349,8 @@ bool ModelGeomAlgo_Point2D::isPointOnEdge(const std::shared_ptr<GeomAPI_Shape> t
 {
   bool isInside = false;
   if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
-    std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theBaseShape));
-    if (anEdge->isLine()) {
-      std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
-      theProjectedPoint = aLine->project(thePoint);
-    }
-    else if (anEdge->isCircle() || anEdge->isArc()) {
-      std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
-      theProjectedPoint = aCircle->project(thePoint);
-    }
+    GeomCurvePtr aCurve(new GeomAPI_Curve(theBaseShape->edge()));
+    theProjectedPoint = aCurve->project(thePoint);
     if (theProjectedPoint.get()) {
       std::shared_ptr<GeomAPI_Vertex> aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(),
                                                 theProjectedPoint->y(), theProjectedPoint->z()));
@@ -319,11 +360,33 @@ bool ModelGeomAlgo_Point2D::isPointOnEdge(const std::shared_ptr<GeomAPI_Shape> t
   return isInside;
 }
 
+
+bool ModelGeomAlgo_Point2D::isInnerPointOnEdge(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                     const std::shared_ptr<GeomAPI_Pnt>& thePoint,
+                     std::shared_ptr<GeomAPI_Pnt>& theProjectedPoint)
+{
+  bool isInside = isPointOnEdge(theBaseShape, thePoint, theProjectedPoint);
+  if (isInside) {
+    std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theBaseShape));
+    if (!anEdge->isClosed()) {
+      // check the point is not on the boundary
+      GeomVertexPtr aVertex(new GeomAPI_Vertex(theProjectedPoint->x(),
+          theProjectedPoint->y(), theProjectedPoint->z()));
+      GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX);
+      for (; anExp.more(); anExp.next()) {
+        GeomVertexPtr aCurV = anExp.current()->vertex();
+        isInside = !GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertex, aCurV);
+      }
+    }
+  }
+  return isInside;
+}
+
 std::string doubleToString(double theValue)
 {
   std::string aValueStr;
   char aBuf[50];
-  int n = sprintf(aBuf, "%g", theValue);
+  sprintf(aBuf, "%g", theValue);
   aValueStr = std::string(aBuf);
   return aValueStr;
 }