Salome HOME
Issue #1477 Build Vertex - wrong selection in viewer
[modules/shaper.git] / src / ModuleBase / ModuleBase_ViewerFilters.cpp
index 6406ccca612aca59840aa253b243fbecf8c65f55..f92e3895e9ab363cdb63cb29d0a6b0b6f0f13fb9 100644 (file)
 #include <ModelAPI_Document.h>
 #include <ModelAPI_ResultConstruction.h>
 
+#include <GeomAPI_Edge.h>
+
 #include <AIS_InteractiveObject.hxx>
 #include <AIS_Shape.hxx>
+#include <AIS_Axis.hxx>
+#include <AIS_Point.hxx>
+#include <AIS_Plane.hxx>
+#include <Geom_Point.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Plane.hxx>
 
 #include <StdSelect_BRepOwner.hxx>
 
@@ -74,29 +82,22 @@ Standard_Boolean ModuleBase_ShapeInPlaneFilter::IsOk(const Handle(SelectMgr_Enti
   if (myPlane.get()) {
     aValid = Standard_False;
     if (theOwner->HasSelectable()) {
+      gp_Pln aPlane = myPlane->impl<gp_Pln>();
       Handle(StdSelect_BRepOwner) aShapeOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner);
-      if (!aShapeOwner.IsNull()) {
+      if (!aShapeOwner.IsNull() && aShapeOwner->HasShape()) {
         TopoDS_Shape aShape = aShapeOwner->Shape();
         TopAbs_ShapeEnum aType = aShape.ShapeType();
-        gp_Pln aPlane = myPlane->impl<gp_Pln>();
         switch (aType) {
         case TopAbs_VERTEX:
           {
             gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
-            return aPlane.Distance(aPnt) < Precision::Confusion();
+            return aPlane.SquareDistance(aPnt) < Precision::SquareConfusion();
           }
         case TopAbs_EDGE:
           {
-            TopoDS_Edge aEdge = TopoDS::Edge(aShape);
-            Standard_Real aFirst, aLast;
-            Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aFirst, aLast);
-            gp_Pnt aFirstPnt = aCurve->Value(aFirst);
-            gp_Pnt aMidPnt = aCurve->Value((aFirst + aLast) / 2.);
-            gp_Pnt aLastPnt = aCurve->Value(aLast);
-            bool aD1 = aPlane.Distance(aFirstPnt) < Precision::Confusion();
-            bool aD2 = aPlane.Distance(aMidPnt) < Precision::Confusion();
-            bool aD3 = aPlane.Distance(aLastPnt) < Precision::Confusion();
-            return aD1 && aD2 && aD3;
+            std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge);
+            anEdge->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
+            return anEdge->isInPlane(myPlane);
           }
         default:
           // The object can be selected in Object browser and contain, for example, compound.
@@ -105,6 +106,23 @@ Standard_Boolean ModuleBase_ShapeInPlaneFilter::IsOk(const Handle(SelectMgr_Enti
         break;
         }
       } else {
+        // Check Trihedron sub-objects
+        Handle(SelectMgr_SelectableObject) aSelObj = theOwner->Selectable();
+        Handle(Standard_Type) aType = aSelObj->DynamicType();
+        if (aType == STANDARD_TYPE(AIS_Axis)) {
+          Handle(AIS_Axis) aAxis = Handle(AIS_Axis)::DownCast(aSelObj);
+          gp_Lin aLine = aAxis->Component()->Lin();
+          return aPlane.Contains(aLine, Precision::Confusion(), Precision::Angular());
+
+        } else if (aType == STANDARD_TYPE(AIS_Point)) {
+          Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(aSelObj);
+          return aPlane.Distance(aPoint->Component()->Pnt()) < Precision::Confusion();
+
+        } else if (aType == STANDARD_TYPE(AIS_Plane)) {
+          Handle(AIS_Plane) aAisPlane = Handle(AIS_Plane)::DownCast(aSelObj);
+          gp_Pln aPln = aAisPlane->Component()->Pln();
+          return aPlane.Distance(aPln) < Precision::Confusion();
+        }
         // This is not object controlled by the filter
         aValid = Standard_True;
       }