Salome HOME
lot 3 - coloring of section in OCC view see also refs #1838
[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 bool HYDROGUI_Polyline::GetColorOfSubShape(const TopoDS_Shape& SubShape, Quantity_Color& outColor)
66 {
67   for (int i=1; i<=myShapeToColor.Extent();i++)
68   {
69     const TopoDS_Shape& aCurShape = myShapeToColor.FindKey(i);
70     TopTools_IndexedMapOfShape aSubShMap;
71     TopExp::MapShapes(aCurShape, aSubShMap);
72     if (aSubShMap.Contains(SubShape))
73     {
74       outColor = myShapeToColor(i);
75       return true;
76     }
77   }
78   return false;
79 }
80
81 void HYDROGUI_Polyline::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
82                             const Handle(Prs3d_Presentation)& aPrs,
83                             const Standard_Integer aMode)
84 {  
85   //AIS_Shape::Compute(aPresentationManager, aPrs, aMode);
86   // return;
87
88   aPrs->Clear();
89   Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup( aPrs );
90   Quantity_Color aColor;
91   Aspect_TypeOfLine aType;
92   Standard_Real anWidth;
93   Attributes()->LineAspect()->Aspect()->Values( aColor, aType, anWidth );
94   anWidth =2;
95   Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d( aColor, aType, anWidth );
96
97   Bnd_Box BB;
98   BRepBndLib::AddClose(myshape, BB);
99   double xmin, xmax, ymin, ymax, zmin, zmax;
100   double devCoeff = 0.05;
101   if (!BB.IsVoid())
102   {
103     BB.Get(xmin, ymin, zmin, xmax, ymax, zmax); //ignore Z coord
104     double minSide = Min(Abs(xmax - xmin), Abs(ymax - ymin));
105     devCoeff = minSide > 50 ? 0.05 : minSide / 3000;
106   }
107
108   TopExp_Explorer Exp ( myshape, TopAbs_WIRE );
109   for ( ; Exp.More(); Exp.Next() )
110   {
111     TopoDS_Shape W = Exp.Current();
112     TopExp_Explorer Exp1 (W, TopAbs_EDGE );
113     Quantity_Color aWCol = aColor; //from drawer
114     if (myShapeToColor.Contains(W))
115     {
116       Quantity_Color aWCol = myShapeToColor.FindFromKey(W);
117       anAspect = new Graphic3d_AspectLine3d( aWCol, aType, anWidth );
118     }
119     for ( ; Exp1.More(); Exp1.Next() )
120     {
121       TopoDS_Edge anEdge = TopoDS::Edge( Exp1.Current() );
122       Handle( Graphic3d_ArrayOfPolylines ) anArray = BuildEdgePresentation( anEdge, devCoeff);
123       if( !anArray.IsNull() )
124       {
125         aGroup->SetPrimitivesAspect( anAspect );
126         aGroup->AddPrimitiveArray( anArray );
127       }
128     }
129   }
130 }
131
132 QList<Handle(AIS_InteractiveObject)> HYDROGUI_Polyline::createPresentations
133   ( const TopoDS_Shape& theShape, int theType, int theSize )
134 {
135   QList<Handle(AIS_InteractiveObject)> shapes;
136
137   // 1. Main shape
138   Handle(HYDROGUI_Polyline) aMPoly = new HYDROGUI_Polyline( theShape );
139   shapes.append( aMPoly );
140
141   // 2. Shapes for direction arrows on edges
142   TopExp_Explorer Exp ( theShape, TopAbs_EDGE );
143   for ( ; Exp.More(); Exp.Next() )
144   {
145     TopoDS_Edge anEdge = TopoDS::Edge(Exp.Current());
146     if ( !anEdge.IsNull() ) 
147     {
148       Handle(HYDROGUI_Arrow) arrow = new HYDROGUI_Arrow( anEdge, aMPoly );
149       if( theType>=0 )
150         arrow->SetType( (HYDROGUI_Arrow::Type)theType );
151       if( theSize>=0 )
152         arrow->SetSize( theSize );
153       shapes.append( arrow );
154     }
155   }
156
157   return shapes;
158 }
159
160 void HYDROGUI_Polyline::update( const QList<Handle(AIS_InteractiveObject)>& theObjects, int theType, int theSize )
161 {
162   foreach( Handle(AIS_InteractiveObject) obj, theObjects )
163   {
164     Handle(HYDROGUI_Arrow) arrow = Handle(HYDROGUI_Arrow)::DownCast( obj );
165     if( !arrow.IsNull() )
166     {
167       if( theType>=0 )
168         arrow->SetType( (HYDROGUI_Arrow::Type)theType );
169       if( theSize>=0 )
170         arrow->SetSize( theSize );
171     }
172   }
173 }
174
175
176
177
178 IMPLEMENT_STANDARD_RTTIEXT(HYDROGUI_Arrow, AIS_Shape)
179
180
181   HYDROGUI_Arrow::HYDROGUI_Arrow( const TopoDS_Edge& edge, const Handle(HYDROGUI_Polyline)& polyline )
182   : AIS_Shape( edge ), myType( Cone ), mySize( 35 ), myParentPoly (polyline)
183 {
184 }
185
186 HYDROGUI_Arrow::~HYDROGUI_Arrow()
187 {
188 }
189
190 HYDROGUI_Arrow::Type HYDROGUI_Arrow::GetType() const
191 {
192   return myType;
193 }
194
195 void HYDROGUI_Arrow::SetType( HYDROGUI_Arrow::Type theType )
196 {
197   myType = theType;
198 }
199
200 int HYDROGUI_Arrow::GetSize() const
201 {
202   return mySize;
203 }
204
205 void HYDROGUI_Arrow::SetSize( int theSize )
206 {
207   mySize = qMax( theSize, 0 );
208 }
209
210 const Handle(HYDROGUI_Polyline)& HYDROGUI_Arrow::getParentPolyline() const
211 {
212   return myParentPoly;
213 }
214
215 void HYDROGUI_Arrow::BoundingBox (Bnd_Box& theBndBox)
216 {
217   //Nothing to change, we consider arrow as object with empty bounding box
218 }
219
220 void HYDROGUI_Arrow::Compute( const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
221                                                       const Handle(Prs3d_Presentation)& aPrs,
222                                                       const Standard_Integer aMode )
223 {
224   aPrs->Clear();
225   if( myType==None )
226     return;
227   
228   TopoDS_Edge anEdge = TopoDS::Edge( myshape );
229   if( anEdge.IsNull() )
230     return;
231
232   BRepAdaptor_Curve anAdaptor( anEdge );
233   double curveLen = GCPnts_AbscissaPoint::Length( anAdaptor, anAdaptor.FirstParameter(), anAdaptor.LastParameter() );
234   double arrowLen;
235   if( mySize==0 )
236     // if size==0, then the arrow length is proportional to curve length
237     arrowLen = curveLen/10;
238   else
239   {
240     //arrowLen = qMin( curveLen/10, (double)mySize );
241     arrowLen = (double)mySize;
242   }
243
244   double t = ( anAdaptor.FirstParameter() + anAdaptor.LastParameter() ) / 2;
245   gp_Pnt P, P1;
246   gp_Vec V;
247   anAdaptor.D1( t, P, V );
248
249   bool isFixed = mySize>0;
250
251   if( isFixed )
252   {
253     gp_Trsf tr;
254     tr.SetTranslation( -gp_Vec( gp_Pnt(), P ) );
255     aPrs->SetTransformation( new Geom_Transformation( tr ) );
256
257     Handle(Graphic3d_TransformPers) tp = new Graphic3d_TransformPers( Graphic3d_TMF_ZoomPers, P );
258     SetTransformPersistence( tp );
259
260     P1 = gp_Pnt();
261   }
262   else
263   {
264     aPrs->SetTransformation( Handle(Geom_Transformation)() );
265     SetTransformPersistence( Handle(Graphic3d_TransformPers)() );
266     P1 = P;
267   }
268
269   Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup( aPrs );
270   Quantity_Color aColor;
271   Aspect_TypeOfLine aType;
272   Standard_Real anWidth;
273   Attributes()->LineAspect()->Aspect()->Values( aColor, aType, anWidth );
274   anWidth = 1;
275
276   const Handle(HYDROGUI_Polyline)& aParentPoly = getParentPolyline();
277   aParentPoly->GetColorOfSubShape(anEdge, aColor);
278
279   if( myType==Cone )
280   {
281     Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d( aColor, aType, anWidth );
282     aGroup->SetPrimitivesAspect( anAspect );
283
284     Prs3d_Arrow::Draw( aGroup, P1, V, M_PI/180.*12., arrowLen );
285   }
286   else
287   {
288     Graphic3d_MaterialAspect m( Graphic3d_NOM_PLASTIC );
289     Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d
290       ( Aspect_IS_SOLID, aColor, aColor, Aspect_TOL_SOLID, 1, m, m );
291     aGroup->SetPrimitivesAspect( anAspect );
292
293     gp_Vec d = -V.Normalized() * arrowLen;
294     const double k = 5.0;
295     gp_Vec n( -d.Y()/k, d.X()/k, 0 );
296
297     gp_Pnt Pa = P1.Translated( d );
298     gp_Pnt P2 = Pa.Translated( n );
299     gp_Pnt P3 = Pa.Translated( -n );
300
301     Handle(Graphic3d_ArrayOfTriangles) prim = new Graphic3d_ArrayOfTriangles(3);
302     prim->AddVertex( P1 );
303     prim->AddVertex( P2 );
304     prim->AddVertex( P3 );
305
306     aGroup->AddPrimitiveArray( prim );
307   }
308 }