Salome HOME
refs #1330: basic implementation of the not zoomable polyline arrows
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Polyline.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include <HYDROGUI_Polyline.h>
20 #include <BRepAdaptor_Curve.hxx>
21 #include <BRepBndLib.hxx>
22 #include <BRep_Tool.hxx>
23 #include <GCPnts_AbscissaPoint.hxx>
24 #include <GCPnts_QuasiUniformDeflection.hxx>
25 #include <Graphic3d_ArrayOfPolylines.hxx>
26 #include <Prs3d_Arrow.hxx>
27 #include <Prs3d_LineAspect.hxx>
28 #include <Prs3d_Point.hxx>
29 #include <Prs3d_Root.hxx>
30 #include <TopExp.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopoDS.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Vertex.hxx>
35
36 IMPLEMENT_STANDARD_RTTIEXT(HYDROGUI_Polyline, AIS_Shape)
37
38
39 HYDROGUI_Polyline::HYDROGUI_Polyline(const TopoDS_Shape& shape)
40   : AIS_Shape(shape)
41
42 }
43
44 HYDROGUI_Polyline::~HYDROGUI_Polyline()
45 {
46 }
47
48 Handle( Graphic3d_ArrayOfPolylines ) BuildEdgePresentation( const TopoDS_Edge& theEdge, double theDeviation )
49 {
50   BRepAdaptor_Curve aCurveAdaptor( theEdge );
51   GCPnts_QuasiUniformDeflection aPnts( aCurveAdaptor, theDeviation );
52
53   Handle( Graphic3d_ArrayOfPolylines ) anArray;
54   if( !aPnts.IsDone() )
55     return anArray;
56
57   int n = aPnts.NbPoints();
58   anArray = new Graphic3d_ArrayOfPolylines( n );
59   for( int i=1; i<=n; i++ )
60     anArray->AddVertex( aPnts.Value( i ) );
61
62   return anArray;
63 }
64
65 void HYDROGUI_Polyline::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
66                             const Handle(Prs3d_Presentation)& aPrs,
67                             const Standard_Integer aMode)
68 {  
69   //AIS_Shape::Compute(aPresentationManager, aPrs, aMode);
70   //return;
71
72   aPrs->Clear();
73   Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup( aPrs );
74   Quantity_Color aColor;
75   Aspect_TypeOfLine aType;
76   Standard_Real anWidth;
77   Attributes()->LineAspect()->Aspect()->Values( aColor, aType, anWidth );
78   anWidth =2;
79   Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d( aColor, aType, anWidth );
80
81   TopExp_Explorer Exp1 ( myshape, TopAbs_EDGE );
82   Bnd_Box BB;
83   BRepBndLib::AddClose(myshape, BB);
84   double xmin, xmax, ymin, ymax, zmin, zmax;
85   double devCoeff = 0.05;
86   if (!BB.IsVoid())
87   {
88     BB.Get(xmin, ymin, zmin, xmax, ymax, zmax); //ignore Z coord
89     double minSide = Min(Abs(xmax - xmin), Abs(ymax - ymin));
90     devCoeff = minSide > 50 ? 0.05 : minSide / 3000;
91   }
92   for ( ; Exp1.More(); Exp1.Next() )
93   {
94     TopoDS_Edge anEdge = TopoDS::Edge( Exp1.Current() );
95     Handle( Graphic3d_ArrayOfPolylines ) anArray = BuildEdgePresentation( anEdge, devCoeff );
96     if( !anArray.IsNull() )
97     {
98       aGroup->SetPrimitivesAspect( anAspect );
99       aGroup->AddPrimitiveArray( anArray );
100     }
101   }
102 }
103
104 QList<Handle(AIS_InteractiveObject)> HYDROGUI_Polyline::createPresentations( const TopoDS_Shape& shape )
105 {
106   QList<Handle(AIS_InteractiveObject)> shapes;
107
108   // 1. Main shape
109   shapes.append( new HYDROGUI_Polyline( shape ) );
110
111   // 2. Shapes for direction arrows on edges
112   TopExp_Explorer Exp ( shape, TopAbs_EDGE );
113   for ( ; Exp.More(); Exp.Next() )
114   {
115     TopoDS_Edge anEdge = TopoDS::Edge(Exp.Current());
116     if ( !anEdge.IsNull() ) 
117       shapes.append( new HYDROGUI_Arrow( anEdge ) );
118   }
119
120   return shapes;
121 }
122
123
124
125
126
127 IMPLEMENT_STANDARD_RTTIEXT(HYDROGUI_Arrow, AIS_Shape)
128
129
130 HYDROGUI_Arrow::HYDROGUI_Arrow( const TopoDS_Edge& edge )
131   : AIS_Shape( edge )
132 {
133 }
134
135 HYDROGUI_Arrow::~HYDROGUI_Arrow()
136 {
137 }
138
139 void HYDROGUI_Arrow::Compute( const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
140                                                       const Handle(Prs3d_Presentation)& aPrs,
141                                                       const Standard_Integer aMode )
142 {
143   aPrs->Clear();
144
145   TopoDS_Edge anEdge = TopoDS::Edge( myshape );
146   if( anEdge.IsNull() )
147     return;
148
149   BRepAdaptor_Curve anAdaptor( anEdge );
150   double curveLen = GCPnts_AbscissaPoint::Length( anAdaptor, anAdaptor.FirstParameter(), anAdaptor.LastParameter() );
151   double arrowLen = qMin( curveLen/10, 35.0 );
152
153   double t = ( anAdaptor.FirstParameter() + anAdaptor.LastParameter() ) / 2;
154   gp_Pnt P;
155   gp_Vec V;
156   anAdaptor.D1( t, P, V );
157
158   gp_Trsf tr;
159   tr.SetTranslation( -gp_Vec( gp_Pnt(), P ) );
160   aPrs->SetTransformation( new Geom_Transformation( tr ) );
161
162   Handle(Graphic3d_TransformPers) tp = new Graphic3d_TransformPers( Graphic3d_TMF_ZoomPers, P );
163   SetTransformPersistence( tp );
164
165   Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup( aPrs );
166   Quantity_Color aColor;
167   Aspect_TypeOfLine aType;
168   Standard_Real anWidth;
169   Attributes()->LineAspect()->Aspect()->Values( aColor, aType, anWidth );
170   anWidth = 1;
171   Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d( aColor, aType, anWidth );
172   aGroup->SetPrimitivesAspect( anAspect );
173   Prs3d_Arrow::Draw( aGroup, gp_Pnt(), V, M_PI/180.*12., arrowLen );
174 }