Salome HOME
Merge remote-tracking branch 'origin/BR_1321_ECW' into BR_DEMO
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Polyline.cxx
index b9a7a2aacb62ab1c041395bc3438460992192639..035e0ca3df1edf80d984c1fc17808bb54fa18186 100644 (file)
 //
 
 #include <HYDROGUI_Polyline.h>
-
-#include <AIS_InteractiveContext.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepBndLib.hxx>
 #include <BRep_Tool.hxx>
 #include <GCPnts_AbscissaPoint.hxx>
-#include <GeomAdaptor_Curve.hxx>
-#include <Graphic3d_AspectLine3d.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Dir.hxx>
+#include <GCPnts_QuasiUniformDeflection.hxx>
+#include <Graphic3d_ArrayOfPolylines.hxx>
 #include <Prs3d_Arrow.hxx>
-#include <TopExp.hxx>
-#include <TopoDS_Shape.hxx>
+#include <Prs3d_LineAspect.hxx>
+#include <Prs3d_Point.hxx>
+#include <Prs3d_Root.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
-#include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
-#include <BRepBndLib.hxx>
-#include <Precision.hxx>
-#include <Graphic3d_ArrayOfPolylines.hxx>
-#include <GCPnts_QuasiUniformDeflection.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <Prs3d_LineAspect.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(HYDROGUI_Polyline, AIS_Shape)
 
@@ -75,6 +67,7 @@ void HYDROGUI_Polyline::Compute(const Handle(PrsMgr_PresentationManager3d)& aPre
                             const Standard_Integer aMode)
 {  
   //AIS_Shape::Compute(aPresentationManager, aPrs, aMode);
+  //return;
 
   aPrs->Clear();
   Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup( aPrs );
@@ -106,79 +99,168 @@ void HYDROGUI_Polyline::Compute(const Handle(PrsMgr_PresentationManager3d)& aPre
       aGroup->AddPrimitiveArray( anArray );
     }
   }
+}
+
+QList<Handle(AIS_InteractiveObject)> HYDROGUI_Polyline::createPresentations
+  ( const TopoDS_Shape& theShape, int theType, int theSize )
+{
+  QList<Handle(AIS_InteractiveObject)> shapes;
+
+  // 1. Main shape
+  shapes.append( new HYDROGUI_Polyline( theShape ) );
 
-   
-  TopExp_Explorer Exp ( myshape, TopAbs_EDGE );
-  for ( ; Exp.More(); Exp.Next() ) {
-    TopoDS_Vertex aV1, aV2;
+  // 2. Shapes for direction arrows on edges
+  TopExp_Explorer Exp ( theShape, TopAbs_EDGE );
+  for ( ; Exp.More(); Exp.Next() )
+  {
     TopoDS_Edge anEdge = TopoDS::Edge(Exp.Current());
-    
-    if ( anEdge.IsNull() ) 
-      continue;
-    TopExp::Vertices(anEdge, aV1, aV2);
-    gp_Pnt aP = BRep_Tool::Pnt(aV1);
-    gp_Vec aDirVec;
-    double aFp, aLp;
-    Handle(Geom_Curve) C = BRep_Tool::Curve(anEdge,aFp,aLp);
-    if ( C.IsNull() ) 
-      continue;
-  
-    Bnd_Box aBB;
-    BRepBndLib::Add(anEdge, aBB);
-    Standard_Real aXmin,aYmin,aZmin,aXmax,aYmax,aZmax;
-    aBB.Get(aXmin,aYmin,aZmin,aXmax,aYmax,aZmax);
-    Standard_Real aLen = Max(Abs(aXmax - aXmin), Max (Abs(aZmax - aZmin), Abs(aYmax - aYmin)));
-  
-    GeomAdaptor_Curve aAdC;
-    aAdC.Load(C, aFp, aLp);
-    double aLenC;
-    double aLenH;
-    int aNbSegments = 20;
-    double aArrLen = aLen / 10.;
-    double anIncr = (aLp-aFp)/aNbSegments;
-    double aMaxRatio = 0;
-    double aMaxRatioStep = 1;
-    for (double t = aFp; t < aLp - anIncr; t += anIncr)
+    if ( !anEdge.IsNull() ) 
     {
-       aLenC  = GCPnts_AbscissaPoint::Length(aAdC, t, t + anIncr);
-       aLenH = C->Value (t).Distance (C->Value (t + anIncr));
-       if ( aLenH / aLenC > aMaxRatio) {
-         aMaxRatio = aLenH / aLenC;
-         aMaxRatioStep = t;
-       }
+      Handle(HYDROGUI_Arrow) arrow = new HYDROGUI_Arrow( anEdge );
+      if( theType>=0 )
+        arrow->SetType( (HYDROGUI_Arrow::Type)theType );
+      if( theSize>=0 )
+        arrow->SetSize( theSize );
+      shapes.append( arrow );
     }
+  }
 
-    bool UseD1 = false;
-    if (Abs(aMaxRatioStep) < Precision::Confusion())
-    {
-      aMaxRatioStep = (aLp - aFp)/2.0;
-      UseD1 = true;
-    }
+  return shapes;
+}
 
-    if (Abs(aLp - aMaxRatioStep) < Precision::Confusion())
-    {
-      aMaxRatioStep =  (aLp - aFp)/2.0;
-      UseD1 = true;
-    }      
-    
-    gp_Pnt aPnt1 = C->Value (aMaxRatioStep);
-    gp_Vec aDir;
-    if (!UseD1) 
+void HYDROGUI_Polyline::update( const QList<Handle(AIS_InteractiveObject)>& theObjects, int theType, int theSize )
+{
+  foreach( Handle(AIS_InteractiveObject) obj, theObjects )
+  {
+    Handle(HYDROGUI_Arrow) arrow = Handle(HYDROGUI_Arrow)::DownCast( obj );
+    if( !arrow.IsNull() )
     {
-      GCPnts_AbscissaPoint aAbsPoint(aAdC, -aArrLen, aMaxRatioStep);
-      double aParam = aAbsPoint.Parameter();      
-      gp_Pnt aPnt2 = C->Value (aParam);
-      gp_XYZ D = aPnt1.XYZ();
-      D.Subtract (aPnt2.XYZ());
-      aDir = D;
+      if( theType>=0 )
+        arrow->SetType( (HYDROGUI_Arrow::Type)theType );
+      if( theSize>=0 )
+        arrow->SetSize( theSize );
     }
+  }
+}
 
-    if (UseD1 || aDir.IsEqual (gp_Vec(0,0,0), Precision::Confusion(), Precision::Angular()))
-      C->D1(aMaxRatioStep, aPnt1, aDir);
-  
-    if ( anEdge.Orientation() == TopAbs_REVERSED )
-      aDir = -aDir;
+
+
+
+IMPLEMENT_STANDARD_RTTIEXT(HYDROGUI_Arrow, AIS_Shape)
+
+
+HYDROGUI_Arrow::HYDROGUI_Arrow( const TopoDS_Edge& edge )
+  : AIS_Shape( edge ), myType( Cone ), mySize( 35 )
+{
+}
+
+HYDROGUI_Arrow::~HYDROGUI_Arrow()
+{
+}
+
+HYDROGUI_Arrow::Type HYDROGUI_Arrow::GetType() const
+{
+  return myType;
+}
+
+void HYDROGUI_Arrow::SetType( HYDROGUI_Arrow::Type theType )
+{
+  myType = theType;
+}
+
+int HYDROGUI_Arrow::GetSize() const
+{
+  return mySize;
+}
+
+void HYDROGUI_Arrow::SetSize( int theSize )
+{
+  mySize = qMax( theSize, 0 );
+}
+
+void HYDROGUI_Arrow::Compute( const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
+                                                     const Handle(Prs3d_Presentation)& aPrs,
+                                                     const Standard_Integer aMode )
+{
+  aPrs->Clear();
+  if( myType==None )
+    return;
   
-    Prs3d_Arrow::Draw(aPrs, aPnt1, aDir, M_PI/180.*12., aArrLen);     
+  TopoDS_Edge anEdge = TopoDS::Edge( myshape );
+  if( anEdge.IsNull() )
+    return;
+
+  BRepAdaptor_Curve anAdaptor( anEdge );
+  double curveLen = GCPnts_AbscissaPoint::Length( anAdaptor, anAdaptor.FirstParameter(), anAdaptor.LastParameter() );
+  double arrowLen;
+  if( mySize==0 )
+    // if size==0, then the arrow length is proportional to curve length
+    arrowLen = curveLen/10;
+  else
+  {
+    //arrowLen = qMin( curveLen/10, (double)mySize );
+    arrowLen = (double)mySize;
+  }
+
+  double t = ( anAdaptor.FirstParameter() + anAdaptor.LastParameter() ) / 2;
+  gp_Pnt P, P1;
+  gp_Vec V;
+  anAdaptor.D1( t, P, V );
+
+  bool isFixed = mySize>0;
+
+  if( isFixed )
+  {
+    gp_Trsf tr;
+    tr.SetTranslation( -gp_Vec( gp_Pnt(), P ) );
+    aPrs->SetTransformation( new Geom_Transformation( tr ) );
+
+    Handle(Graphic3d_TransformPers) tp = new Graphic3d_TransformPers( Graphic3d_TMF_ZoomPers, P );
+    SetTransformPersistence( tp );
+
+    P1 = gp_Pnt();
+  }
+  else
+  {
+    aPrs->SetTransformation( Handle(Geom_Transformation)() );
+    SetTransformPersistence( Handle(Graphic3d_TransformPers)() );
+    P1 = P;
+  }
+
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup( aPrs );
+  Quantity_Color aColor;
+  Aspect_TypeOfLine aType;
+  Standard_Real anWidth;
+  Attributes()->LineAspect()->Aspect()->Values( aColor, aType, anWidth );
+  anWidth = 1;
+
+  if( myType==Cone )
+  {
+    Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d( aColor, aType, anWidth );
+    aGroup->SetPrimitivesAspect( anAspect );
+
+    Prs3d_Arrow::Draw( aGroup, P1, V, M_PI/180.*12., arrowLen );
+  }
+  else
+  {
+    Graphic3d_MaterialAspect m( Graphic3d_NOM_PLASTIC );
+    Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d
+      ( Aspect_IS_SOLID, aColor, aColor, Aspect_TOL_SOLID, 1, m, m );
+    aGroup->SetPrimitivesAspect( anAspect );
+
+    gp_Vec d = -V.Normalized() * arrowLen;
+    const double k = 5.0;
+    gp_Vec n( -d.Y()/k, d.X()/k, 0 );
+
+    gp_Pnt Pa = P1.Translated( d );
+    gp_Pnt P2 = Pa.Translated( n );
+    gp_Pnt P3 = Pa.Translated( -n );
+
+    Handle(Graphic3d_ArrayOfTriangles) prim = new Graphic3d_ArrayOfTriangles(3);
+    prim->AddVertex( P1 );
+    prim->AddVertex( P2 );
+    prim->AddVertex( P3 );
+
+    aGroup->AddPrimitiveArray( prim );
   }
 }