Salome HOME
Improve GEOM_AISShape::computeMassCenter() on edges and faces
[modules/geom.git] / src / OBJECT / GEOM_AISShape.cxx
index 341018e89a170f23c23aee29d33c3055e1f9aa89..4734bf77e11f57d358c04d6bdcb19c1b3ebec113 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-//  GEOM OBJECT : interactive object for Geometry entities visualization
-//  File   : GEOM_AISShape.cxx
-//  Author : Nicolas REJNERI
-//  Module : GEOM
-
 /*!
   \class GEOM_AISShape GEOM_AISShape.hxx
   \brief ....
 */
 
-#include "GEOM_AISShape.ixx"
-#include "SALOME_InteractiveObject.hxx"
+#include "GEOM_AISShape.hxx"
 #include "GEOM_AISVector.hxx"
 
+#include <GEOMUtils.hxx>
+
 #include <Basics_OCCTVersion.hxx>
 
 // Open CASCADE Includes
-#include <AIS_Drawer.hxx>
 #include <AIS_InteractiveContext.hxx>
-
+#include <BRepAdaptor_Surface.hxx>
 #include <BRep_Tool.hxx>
-
 #include <GCPnts_AbscissaPoint.hxx>
 #include <GeomAdaptor_Curve.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Vec.hxx>
+#include <Graphic3d_ArrayOfPoints.hxx>
 #include <Graphic3d_AspectFillArea3d.hxx>
 #include <Graphic3d_AspectLine3d.hxx>
 #include <Graphic3d_AspectMarker3d.hxx>
 #include <Graphic3d_AspectText3d.hxx>
-
-#include <Prs3d_ShadingAspect.hxx>
 #include <Prs3d_Arrow.hxx>
 #include <Prs3d_IsoAspect.hxx>
-#if OCC_VERSION_LARGE > 0x06070200
-#include <Prs3d_VertexDrawMode.hxx>
-#endif
-
+#include <Prs3d_ShadingAspect.hxx>
 #include <SelectBasics_SensitiveEntity.hxx>
 #include <SelectMgr_EntityOwner.hxx>
-#include <StdSelect_BRepOwner.hxx>
 #include <SelectMgr_IndexedMapOfOwner.hxx>
 #include <SelectMgr_Selection.hxx>
-#include <StdSelect_DisplayMode.hxx>
 #include <StdPrs_ShadedShape.hxx>
-#include <StdPrs_WFDeflectionShape.hxx>
-
+#include <StdSelect_BRepOwner.hxx>
+#include <StdSelect_DisplayMode.hxx>
 #include <TColStd_IndexedMapOfInteger.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <TColStd_ListOfInteger.hxx>
 #include <TopExp.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
-#include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
+#include <V3d_View.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
 
-#include <TColStd_SequenceOfInteger.hxx>
+#if OCC_VERSION_LARGE > 0x06070200
+#include <Prs3d_VertexDrawMode.hxx>
+#endif
 
-#include <V3d_View.hxx>
+#if OCC_VERSION_MAJOR < 7
+  #include <StdPrs_WFDeflectionShape.hxx>
+#else
+  #include <StdPrs_WFShape.hxx>
+#endif
 
 #include <SalomeApp_Tools.h>
-
 #include <SUIT_Session.h>
 #include <SUIT_ResourceMgr.h>
 
+OCCT_IMPLEMENT_STANDARD_RTTIEXT(GEOM_AISShape, SALOME_AISShape)
+
 GEOM_AISShape::TopLevelDispMode GEOM_AISShape::myTopLevelDm = GEOM_AISShape::TopKeepCurrent;
 Quantity_Color GEOM_AISShape::myTopLevelColor;
 
@@ -113,10 +107,17 @@ static void getEntityOwners( const Handle(AIS_InteractiveObject)& theObj,
     Handle(SelectMgr_Selection) sel = theObj->Selection( m );
 
     for ( sel->Init(); sel->More(); sel->Next() ) {
+#if OCC_VERSION_LARGE > 0x06080100
+      const Handle(SelectMgr_SensitiveEntity) aHSenEntity = sel->Sensitive();
+      if( aHSenEntity.IsNull() )
+        continue;
+
+      Handle(SelectBasics_SensitiveEntity) entity = aHSenEntity->BaseSensitive();
+#else
       Handle(SelectBasics_SensitiveEntity) entity = sel->Sensitive();
+#endif
       if ( entity.IsNull() )
         continue;
-
       Handle(SelectMgr_EntityOwner) owner =
         Handle(SelectMgr_EntityOwner)::DownCast(entity->OwnerId());
       if ( !owner.IsNull() )
@@ -181,6 +182,10 @@ GEOM_AISShape::GEOM_AISShape(const TopoDS_Shape& shape,
   }
 }
 
+GEOM_AISShape::~GEOM_AISShape()
+{
+}
+
 void GEOM_AISShape::setIO(const Handle(SALOME_InteractiveObject)& io){
   SetOwner( io );
 }
@@ -216,6 +221,10 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent
   if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //pas de prise en compte lors du FITALL
 
   Handle(AIS_InteractiveContext) anIC = GetContext();
+  // AKL: use old behavior to avoid keeping object's wireframe
+  //      if to change shape properties (for example: 'Clear Top Level State','Color', 'Isos') 
+  //      calling popup menu over(!) the shape in OCC viewer.
+  anIC->SetToHilightSelected( false );
 
   bool anIsField = !myFieldStepData.isEmpty();
   bool anIsColorField = anIsField && myFieldDataType != GEOM::FDT_String;
@@ -229,7 +238,7 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent
   //   StdSelect_DisplayMode d = (StdSelect_DisplayMode) aMode;
   bool isTopLev = isTopLevel() && switchTopLevel();
   switch (aMode) {
-    case 0://StdSelect_DM_Wireframe: 
+    case Wireframe:
     case CustomHighlight:
     {
       if(isTopLev) {
@@ -241,30 +250,35 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent
       if( !isTopLev && anIsColorField && myFieldDimension == 1 )
         drawField( aPrs, false, aMode == CustomHighlight );
       else
+#if OCC_VERSION_MAJOR < 7
         StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);      
+#else
+        StdPrs_WFShape::Add(aPrs,myshape,myDrawer);
+#endif
       break;
     }
-    case 1://StdSelect_DM_Shading:
+    case Shading:
     {
       shadingMode(aPresentationManager, aPrs, aMode);
       break;
     }
-    case 2: { //ShadingWithEdges
-      //Shaded faces
-      shadingMode(aPresentationManager, aPrs, AIS_Shaded);
+    case ShadingWithEdges:
+    {
       myDrawer->SetFaceBoundaryDraw( Standard_True );
-      Handle(Prs3d_LineAspect) aBoundaryAspect =
-        new Prs3d_LineAspect ( myEdgesInShadingColor, Aspect_TOL_SOLID, myOwnWidth );
-      myDrawer->SetFaceBoundaryAspect (aBoundaryAspect);
+      shadingMode(aPresentationManager, aPrs, Shading);
+      if( anIsColorField && myFieldDimension == 1 ) {
+        myDrawer->SetFaceBoundaryDraw( Standard_False );
+        drawField( aPrs );
+      }
       break;
     }
-    case 3: //StdSelect_DM_HLR:
+    case TexturedShape:
     {
-      if(!isTopLev)
-              AIS_TexturedShape::Compute(aPresentationManager, aPrs, aMode);
-      else 
-              shadingMode(aPresentationManager, aPrs, AIS_Shaded);
-      break;
+#ifdef USE_TEXTURED_SHAPE
+        AIS_TexturedShape::Compute(aPresentationManager, aPrs, aMode);
+#else
+        AIS_Shape::Compute(aPresentationManager, aPrs, aMode);
+#endif
     }
   }
   if (isShowVectors())
@@ -321,6 +335,9 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent
   if( anIsTextField )
     drawField( aPrs, true );
 
+  if( isShowName() )
+    drawName( aPrs );
+
   //  aPrs->ReCompute(); // for hidden line recomputation if necessary...
 }
 
@@ -334,6 +351,10 @@ void GEOM_AISShape::SetEdgesInShadingColor(const Quantity_Color &aCol)
   myEdgesInShadingColor = aCol;
 }
 
+void GEOM_AISShape::SetLabelColor(const Quantity_Color &aCol) {
+  myLabelColor = aCol;
+}
+
 void GEOM_AISShape::highlightSubShapes(const TColStd_IndexedMapOfInteger& aIndexMap, 
                                        const Standard_Boolean aHighlight )
 {
@@ -375,6 +396,11 @@ void GEOM_AISShape::SetDisplayVertices(bool isDisplayed)
   myDisplayVertices = isDisplayed;
 }
 
+void GEOM_AISShape::SetDisplayName(bool isDisplayed)
+{
+  myDisplayName = isDisplayed;
+}
+
 void GEOM_AISShape::shadingMode(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
                                 const Handle(Prs3d_Presentation)& aPrs,
                                 const Standard_Integer aMode)
@@ -406,7 +432,11 @@ void GEOM_AISShape::shadingMode(const Handle(PrsMgr_PresentationManager3d)& aPre
   {
     // PAL12113: AIS_Shape::Compute() works correctly with shapes containing no faces
     //StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer);
+#ifdef USE_TEXTURED_SHAPE
+    AIS_TexturedShape::Compute(aPresentationManager, aPrs, aMode);
+#else
     AIS_Shape::Compute(aPresentationManager, aPrs, aMode);
+#endif
   }
 }
 
@@ -420,10 +450,10 @@ void GEOM_AISShape::setTopLevel(Standard_Boolean f) {
       myPrevDisplayMode = DisplayMode();
     Standard_Integer dm;
     switch(topLevelDisplayMode()) {
-      case TopKeepCurrent : dm = myPrevDisplayMode; break;
-      case TopWireFrame : dm = AIS_WireFrame; break;     
-      case TopShadingWithEdges : dm = ShadingWithEdges; break;
-      default : dm = AIS_Shaded; break;
+      case TopWireFrame :        dm = Wireframe;         break;
+      case TopShading :          dm = Shading;           break;
+      case TopShadingWithEdges : dm = ShadingWithEdges;  break;
+      default :                  dm = myPrevDisplayMode; break;
     }
     SetDisplayMode(dm);
   } else {
@@ -453,11 +483,11 @@ void GEOM_AISShape::setTopLevelDisplayMode(const GEOM_AISShape::TopLevelDispMode
 }
 
 Standard_Boolean GEOM_AISShape::switchTopLevel() {
-        return myTopLevelDm != TopShowAdditionalWActor;
+  return myTopLevelDm != TopShowAdditionalWActor;
 }
 
 Standard_Boolean GEOM_AISShape::toActivate() {
-        return Standard_True;
+  return ( myTopLevel && myTopLevelDm == TopShowAdditionalWActor ) ? false : true;
 }
 
 void GEOM_AISShape::setFieldStepInfo( const GEOM::field_data_type theFieldDataType,
@@ -550,6 +580,7 @@ void GEOM_AISShape::drawField( const Handle(Prs3d_Presentation)& thePrs,
 
           Handle(Graphic3d_AspectText3d) anAspectText3d = new Graphic3d_AspectText3d();
           anAspectText3d->SetStyle( Aspect_TOST_ANNOTATION );
+          anAspectText3d->SetColor( myLabelColor );
           aGroup->SetPrimitivesAspect( anAspectText3d );
 
           aGroup->Text( aString.toLatin1().constData(), aVertex, 14 );
@@ -584,7 +615,11 @@ void GEOM_AISShape::drawField( const Handle(Prs3d_Presentation)& thePrs,
             myDrawer->WireAspect()->SetWidth( myOwnWidth );
           else
             myDrawer->WireAspect()->SetWidth( myOwnWidth + 4 );
+#if OCC_VERSION_MAJOR < 7
           StdPrs_WFDeflectionShape::Add( thePrs, aSubShape, myDrawer );
+#else
+          StdPrs_WFShape::Add( thePrs, aSubShape, myDrawer );
+#endif
         }
         else if( myFieldDimension == 2 ||
                  myFieldDimension == 3 ||
@@ -598,31 +633,65 @@ void GEOM_AISShape::drawField( const Handle(Prs3d_Presentation)& thePrs,
   }
 }
 
+void GEOM_AISShape::drawName( const Handle(Prs3d_Presentation)& thePrs )
+{
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup( thePrs );
+
+  gp_Ax3 anAx3 = GEOMUtils::GetPosition(myshape);
+  gp_Pnt aCenter = anAx3.Location();
+
+  Graphic3d_Vertex aVertex( aCenter.X(), aCenter.Y(), aCenter.Z() );
+
+  Handle(Graphic3d_AspectText3d) anAspectText3d = new Graphic3d_AspectText3d();
+  anAspectText3d->SetStyle( Aspect_TOST_ANNOTATION );
+  anAspectText3d->SetColor( myLabelColor );
+  aGroup->SetPrimitivesAspect( anAspectText3d );
+
+  const char* aName = getIO()->getName();
+  aGroup->Text( TCollection_ExtendedString( aName ), aVertex, 16 );
+}
+
 Standard_Boolean GEOM_AISShape::computeMassCenter( const TopoDS_Shape& theShape,
-                                                   gp_Pnt& theCenter )
+                                                   gp_Pnt&             theCenter )
 {
-  Standard_Real aX = 0, aY = 0, aZ = 0;
+  theCenter.SetCoord( 0,0,0 );
   Standard_Integer aNbPoints = 0;
 
-  TopExp_Explorer anExp;
-  for( anExp.Init( theShape, TopAbs_VERTEX ); anExp.More(); anExp.Next() )
+  if ( theShape.ShapeType() == TopAbs_EDGE )
   {
-    TopoDS_Vertex aVertex = TopoDS::Vertex( anExp.Current() );
-    if( !aVertex.IsNull() )
+    double f,l;
+    Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( theShape ), f, l );
+    if ( !curve.IsNull() )
     {
-      gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
-      aX += aPnt.X();
-      aY += aPnt.Y();
-      aZ += aPnt.Z();
-      aNbPoints++;
+      theCenter = curve->Value( 0.5 * ( f + l ));
+      aNbPoints = 1;
+    }
+  }
+  else if ( theShape.ShapeType() == TopAbs_FACE )
+  {
+    BRepAdaptor_Surface surface( TopoDS::Face( theShape ));
+    theCenter = surface.Value( 0.5 * ( surface.FirstUParameter() + surface.LastUParameter() ),
+                               0.5 * ( surface.FirstVParameter() + surface.LastVParameter() ));
+    aNbPoints = 1;
+  }
+
+  if ( aNbPoints == 0 )
+  {
+    TopExp_Explorer anExp;
+    for( anExp.Init( theShape, TopAbs_VERTEX ); anExp.More(); anExp.Next() )
+    {
+      TopoDS_Vertex aVertex = TopoDS::Vertex( anExp.Current() );
+      if( !aVertex.IsNull() )
+      {
+        gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
+        theCenter.ChangeCoord() += aPnt.XYZ();
+        aNbPoints++;
+      }
     }
   }
 
-  if( aNbPoints == 0 )
-    return Standard_False;
+  if ( aNbPoints > 0 )
+    theCenter.ChangeCoord() /= (Standard_Real) aNbPoints;
 
-  theCenter.SetCoord( aX / (Standard_Real)aNbPoints,
-                      aY / (Standard_Real)aNbPoints,
-                      aZ / (Standard_Real)aNbPoints );
-  return Standard_True;
+  return aNbPoints;
 }