Integration of OCCT 6.5.0 from SVN
[occt.git] / src / MeshVS / MeshVS_VectorPrsBuilder.cxx
CommitLineData
7fd59977 1// File: MeshVS_VectorPrsBuilder.cxx
2// Created: Fri Sep 19 2003
3// Author: Alexander SOLOVYOV
4// Copyright: Open CASCADE 2003
5
6#include <MeshVS_VectorPrsBuilder.ixx>
7
8#include <MeshVS_DisplayModeFlags.hxx>
9
10#include <Graphic3d_ArrayOfPolylines.hxx>
11#include <Graphic3d_ArrayOfPolygons.hxx>
12#include <Graphic3d_ArrayOfTriangleFans.hxx>
13#include <Graphic3d_MaterialAspect.hxx>
14#include <Graphic3d_AspectLine3d.hxx>
15#include <Graphic3d_AspectFillArea3d.hxx>
16#include <Graphic3d_Group.hxx>
17
18#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
19#include <TColStd_Array1OfReal.hxx>
20#include <TColgp_Array1OfPnt.hxx>
21#include <TColStd_HPackedMapOfInteger.hxx>
22
23#include <Precision.hxx>
24
25#include <gp_Ax3.hxx>
26
27#include <Prs3d_Root.hxx>
28
29#include <Aspect_TypeOfLine.hxx>
30
31#include <MeshVS_DataSource.hxx>
32#include <MeshVS_Drawer.hxx>
33#include <MeshVS_DrawerAttribute.hxx>
34#include <MeshVS_Mesh.hxx>
35#include <MeshVS_EntityType.hxx>
36#include <MeshVS_DataMapIteratorOfDataMapOfIntegerVector.hxx>
37#include <MeshVS_Buffer.hxx>
38
39//================================================================
40// Function : Constructor MeshVS_VectorPrsBuilder
41// Purpose :
42//================================================================
43MeshVS_VectorPrsBuilder::MeshVS_VectorPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
44 const Standard_Real MaxLength,
45 const Quantity_Color& VectorColor,
46 const MeshVS_DisplayModeFlags& Flags,
47 const Handle (MeshVS_DataSource)& DS,
48 const Standard_Integer Id,
49 const MeshVS_BuilderPriority& Priority,
50 const Standard_Boolean IsSimplePrs )
51: MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority ),
52myIsSimplePrs( IsSimplePrs ),
53mySimpleWidthPrm( 2.5 ),
54mySimpleStartPrm( 0.85 ),
55mySimpleEndPrm( 0.95 )
56{
57 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
58 if ( !aDrawer.IsNull() )
59 {
60 aDrawer->SetDouble ( MeshVS_DA_VectorMaxLength, MaxLength );
61 aDrawer->SetColor ( MeshVS_DA_VectorColor, VectorColor );
62 aDrawer->SetDouble ( MeshVS_DA_VectorArrowPart, 0.1 );
63 }
64}
65
66//================================================================
67// Function : GetVectors
68// Purpose :
69//================================================================
70const MeshVS_DataMapOfIntegerVector& MeshVS_VectorPrsBuilder::GetVectors
71 ( const Standard_Boolean IsElements ) const
72{
73 if ( IsElements )
74 return myElemVectorMap;
75 else
76 return myNodeVectorMap;
77}
78
79//================================================================
80// Function : SetVectors
81// Purpose :
82//================================================================
83void MeshVS_VectorPrsBuilder::SetVectors ( const Standard_Boolean IsElements,
84 const MeshVS_DataMapOfIntegerVector& theMap )
85{
86 if ( IsElements )
87 myElemVectorMap = theMap;
88 else
89 myNodeVectorMap = theMap;
90}
91
92//================================================================
93// Function : HasVectors
94// Purpose :
95//================================================================
96Standard_Boolean MeshVS_VectorPrsBuilder::HasVectors ( const Standard_Boolean IsElement ) const
97{
98 Standard_Boolean aRes = (myNodeVectorMap.Extent()>0);
99 if ( IsElement )
100 aRes = (myElemVectorMap.Extent()>0);
101 return aRes;
102
103}
104
105//================================================================
106// Function : GetVector
107// Purpose :
108//================================================================
109Standard_Boolean MeshVS_VectorPrsBuilder::GetVector ( const Standard_Boolean IsElement,
110 const Standard_Integer ID,
111 gp_Vec& Vect ) const
112{
113 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
114 if ( IsElement )
115 aMap = &myElemVectorMap;
116
117 Standard_Boolean aRes = aMap->IsBound ( ID );
118 if ( aRes )
119 Vect = aMap->Find ( ID );
120
121 return aRes;
122}
123
124//================================================================
125// Function : SetVector
126// Purpose :
127//================================================================
128void MeshVS_VectorPrsBuilder::SetVector ( const Standard_Boolean IsElement,
129 const Standard_Integer ID,
130 const gp_Vec& Vect )
131{
132 MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
133 if ( IsElement )
134 aMap = &myElemVectorMap;
135
136 Standard_Boolean aRes = aMap->IsBound ( ID );
137 if ( aRes )
138 aMap->ChangeFind ( ID ) = Vect;
139 else
140 aMap->Bind ( ID, Vect );
141}
142
143//================================================================
144// Function : GetMaxVectorValue
145// Purpose :
146//================================================================
147void MeshVS_VectorPrsBuilder::GetMinMaxVectorValue ( const Standard_Boolean IsElement,
148 Standard_Real& MinValue,
149 Standard_Real& MaxValue ) const
150{
151 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
152 if ( IsElement )
153 aMap = &myElemVectorMap;
154
155 MeshVS_DataMapIteratorOfDataMapOfIntegerVector anIt ( *aMap );
156 if ( anIt.More() )
157 MinValue = MaxValue = anIt.Value().Magnitude();
158
159 Standard_Real aCurValue;
160
161 for ( ; anIt.More(); anIt.Next() )
162 {
163 aCurValue = anIt.Value().Magnitude();
164 if ( MinValue > aCurValue )
165 MinValue = aCurValue;
166 if ( MaxValue < aCurValue )
167 MaxValue = aCurValue;
168 }
169}
170
171//================================================================
172// Function : Build
173// Purpose :
174//================================================================
175
176#define NB_VERTICES 2
177#define NB_BOUNDS 1
178#define NB_TRIANGLES 6
179#define NB_FANS 1
180
181void MeshVS_VectorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
182 const TColStd_PackedMapOfInteger& IDs,
183 TColStd_PackedMapOfInteger& IDsToExclude,
184 const Standard_Boolean IsElement,
185 const Standard_Integer theDisplayMode ) const
186{
187 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
188 Handle (MeshVS_DataSource) aSource = GetDataSource();
189 if ( aSource.IsNull() || aDrawer.IsNull() || !HasVectors( IsElement ) ||
190 ( theDisplayMode & GetFlags() )==0 )
191 return;
192
193 Standard_Integer aMaxFaceNodes;
194 Standard_Real aMaxLen, anArrowPart = 0.1;
195
196 if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) ||
197 aMaxFaceNodes <= 0 ||
198 !aDrawer->GetDouble ( MeshVS_DA_VectorMaxLength, aMaxLen ) ||
199 aMaxLen <= 0 ||
200 !aDrawer->GetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart ) ||
201 anArrowPart <= 0
202 )
203 return;
204
205 MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real));
206 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*aMaxFaceNodes);
207 Standard_Integer NbNodes;
208 MeshVS_EntityType aType;
209
210 // DECLARE ARRAYS OF PRIMITIVES
211 const MeshVS_DataMapOfIntegerVector& aMap = GetVectors ( IsElement );
212 Standard_Integer aNbVectors = aMap.Extent();
213
214 if ( aNbVectors <= 0 )
215 return;
216
217 // polylines
218 Standard_Integer aNbVertices = aNbVectors * NB_VERTICES;
219 Standard_Integer aNbBounds = aNbVectors * NB_BOUNDS;
220
221 // fans
222 Standard_Integer aNbTriangleVertices = aNbVectors * (NB_TRIANGLES + 2);
223 Standard_Integer aNbFans = aNbVectors * NB_TRIANGLES;
224
225 Handle(Graphic3d_ArrayOfPrimitives) aLineArray =
226 new Graphic3d_ArrayOfPolylines(aNbVertices, aNbBounds);
227 Handle(Graphic3d_ArrayOfPrimitives) aArrowLineArray =
228 new Graphic3d_ArrayOfPolylines(aNbVertices, aNbBounds);
229
230 Handle(Graphic3d_ArrayOfTriangleFans) aTriangleArray =
231 new Graphic3d_ArrayOfTriangleFans(aNbTriangleVertices, aNbFans);
232
233 TColgp_Array1OfPnt anArrowPnt(1,8);
234 Standard_Real k, b, aMaxValue, aMinValue, aValue, X, Y, Z;
235
236 Standard_Real aMinLength = calculateArrow( anArrowPnt, aMaxLen, anArrowPart );
237 gp_Vec aVec; gp_Trsf aTrsf;
238
239 GetMinMaxVectorValue ( IsElement, aMinValue, aMaxValue );
240
241 if ( aMaxValue - aMinValue > Precision::Confusion() )
242 {
243 k = 0.8 * aMaxLen / ( aMaxValue - aMinValue );
244 b = aMaxLen - k * aMaxValue;
245 }
246 else
247 {
248 k = 0;
249 b = aMaxLen;
250 }
251
252 TColStd_PackedMapOfInteger aCustomElements;
253
254 // subtract the hidden elements and ids to exclude (to minimise allocated memory)
255 TColStd_PackedMapOfInteger anIDs;
256 anIDs.Assign( IDs );
257 if ( IsElement )
258 {
259 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
260 if ( !aHiddenElems.IsNull() )
261 anIDs.Subtract( aHiddenElems->Map() );
262 }
263 anIDs.Subtract( IDsToExclude );
264
265 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
266 for( ; it.More(); it.Next() )
267 {
268 Standard_Integer aKey = it.Key();
269 if( GetVector ( IsElement, aKey, aVec ) )
270 {
271 aValue = aVec.Magnitude();
272
273 if ( Abs( aValue ) < Precision::Confusion() )
274 continue;
275
276 if( aSource->GetGeom ( aKey, IsElement, aCoords, NbNodes, aType ) )
277 {
278 if( aType == MeshVS_ET_Node )
279 {
280 X = aCoords(1);
281 Y = aCoords(2);
282 Z = aCoords(3);
283 }
284 else if( aType == MeshVS_ET_Link ||
285 aType == MeshVS_ET_Face ||
286 aType == MeshVS_ET_Volume )
287 {
288 if( IsElement && IsExcludingOn() )
289 IDsToExclude.Add( aKey );
290 X = Y = Z = 0;
291 for ( Standard_Integer i=1; i<=NbNodes; i++ )
292 {
293 X += aCoords (3*i-2);
294 Y += aCoords (3*i-1);
295 Z += aCoords (3*i);
296 }
297 X /= Standard_Real ( NbNodes );
298 Y /= Standard_Real ( NbNodes );
299 Z /= Standard_Real ( NbNodes );
300 }
301 else
302 {
303 aCustomElements.Add( aKey );
304 continue;
305 }
306
307 aTrsf.SetDisplacement ( gp_Ax3 ( gp_Pnt ( 0, 0, 0 ), gp_Dir(0, 0, 1)),
308 gp_Ax3 ( gp_Pnt ( X, Y, Z ), aVec ) );
309
310 DrawVector ( aTrsf, Max( k * fabs( aValue ) + b, aMinLength), aMaxLen,
311 anArrowPnt, aLineArray, aArrowLineArray, aTriangleArray );
312 }
313 }
314 }
315
316 Prs3d_Root::NewGroup ( Prs );
317 Handle (Graphic3d_Group) aVGroup = Prs3d_Root::CurrentGroup ( Prs );
318
319 Quantity_Color aColor;
320 aDrawer->GetColor ( MeshVS_DA_VectorColor, aColor );
321
322 // Add primitive arrays to group
323 Handle(Graphic3d_AspectLine3d) aLinAspect =
324 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, 1.5 );
325
326 aVGroup->SetPrimitivesAspect( aLinAspect );
327
328 aVGroup->BeginPrimitives();
329 aVGroup->AddPrimitiveArray( aLineArray );
330 aVGroup->EndPrimitives();
331 if ( !myIsSimplePrs )
332 {
333 Graphic3d_MaterialAspect aMatAspect;
334 aMatAspect.SetAmbient( 1 );
335 aMatAspect.SetDiffuse( 0 );
336 aMatAspect.SetEmissive( 0 );
337 aMatAspect.SetShininess( 1 );
338 aMatAspect.SetSpecular( 0 );
339 Handle(Graphic3d_AspectFillArea3d) aFillAspect =
340 new Graphic3d_AspectFillArea3d (Aspect_IS_HOLLOW, aColor, aColor, Aspect_TOL_SOLID,
341 1., aMatAspect, aMatAspect );
342
343 aVGroup->SetPrimitivesAspect( aFillAspect );
344
345 aVGroup->BeginPrimitives();
346 aVGroup->AddPrimitiveArray( aTriangleArray );
347 aVGroup->EndPrimitives();
348 }
349 else
350 {
351 Handle(Graphic3d_AspectLine3d) anArrowLinAspect =
352 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, mySimpleWidthPrm * 1.5 );
353
354 aVGroup->SetPrimitivesAspect( anArrowLinAspect );
355
356 aVGroup->BeginPrimitives();
357 aVGroup->AddPrimitiveArray( aArrowLineArray );
358 aVGroup->EndPrimitives();
359 }
360
361 if( !aCustomElements.IsEmpty() )
362 CustomBuild( Prs, aCustomElements, IDsToExclude, theDisplayMode );
363}
364
365//=======================================================================
366// name : DrawVector
367// Purpose : Fill arrays of primitives for drawing force
368//=======================================================================
369void MeshVS_VectorPrsBuilder::DrawVector ( const gp_Trsf& theTrsf,
370 const Standard_Real Length,
371 const Standard_Real MaxLength,
372 const TColgp_Array1OfPnt& ArrowPoints,
373 const Handle(Graphic3d_ArrayOfPrimitives)& Lines,
374 const Handle(Graphic3d_ArrayOfPrimitives)& ArrowLines,
375 const Handle(Graphic3d_ArrayOfPrimitives)& Triangles) const
376{
377 const int PntNum = 8;
378
379 const Standard_Real aMinLength = MaxLength * ( 1 - mySimpleStartPrm );
380 const Standard_Real aLocalLength = ( !myIsSimplePrs || Length > aMinLength ? Length : aMinLength );
381 // draw line
382 gp_Pnt aLinePnt[ 2 ] = { gp_Pnt( 0, 0, 0 ) , gp_Pnt( 0, 0, aLocalLength ) };
383 theTrsf.Transforms( aLinePnt[ 0 ].ChangeCoord() );
384 theTrsf.Transforms( aLinePnt[ 1 ].ChangeCoord() );
385
386 Lines->AddBound( 2 );
387 Lines->AddVertex( aLinePnt[ 0 ] );
388 Lines->AddVertex( aLinePnt[ 1 ] );
389
390 // draw arrow
391 if ( !myIsSimplePrs )
392 {
393 Standard_Integer l = ArrowPoints.Lower(),
394 u = ArrowPoints.Upper(),
395 i;
396 if ( u-l < PntNum-1 )
397 return;
398
399 TColgp_Array1OfPnt anArrowPnt( l, u );
400 for ( i = l; i < l+PntNum; i++ )
401 {
402 anArrowPnt( i ).ChangeCoord() = ArrowPoints ( i ).Coord() + gp_XYZ( 0, 0, aLocalLength );
403 theTrsf.Transforms( anArrowPnt( i ).ChangeCoord() );
404 }
405
406 Triangles->AddBound(8);
407 for ( i = 0; i < PntNum; i++ )
408 Triangles->AddVertex( anArrowPnt( l+i ) );
409 }
410 else
411 {
412 const Standard_Real aEndPos = aLocalLength - MaxLength * ( 1 - mySimpleEndPrm );
413 const Standard_Real aArrowLength = MaxLength * ( mySimpleEndPrm - mySimpleStartPrm );
414 gp_Pnt aArrowPnt[ 2 ] = { gp_Pnt( 0, 0, aEndPos - aArrowLength ),
415 gp_Pnt( 0, 0, aEndPos ) };
416 theTrsf.Transforms( aArrowPnt[ 0 ].ChangeCoord() );
417 theTrsf.Transforms( aArrowPnt[ 1 ].ChangeCoord() );
418
419 ArrowLines->AddBound( 2 );
420 ArrowLines->AddVertex( aArrowPnt[ 0 ] );
421 ArrowLines->AddVertex( aArrowPnt[ 1 ] );
422 }
423}
424
425//=======================================================================
426// name : calculateArrow
427// Purpose : Calculate points of arrow ( 8 pnts )
428//=======================================================================
429Standard_Real MeshVS_VectorPrsBuilder::calculateArrow ( TColgp_Array1OfPnt& Points,
430 const Standard_Real Length,
431 const Standard_Real ArrowPart )
432{
433 Standard_Real h = Length * ArrowPart;
434 Standard_Real w = h / 5.;
435
436 Standard_Integer f = Points.Lower();
437 Points( f ) = gp_Pnt( 0, 0, 0 );
438 Points( f+1 ) = gp_Pnt( 0, -w, -h );
439 Points( f+2 ) = gp_Pnt( w * 0.866, -w * 0.5, -h );
440 Points( f+3 ) = gp_Pnt( w * 0.866, w * 0.5, -h );
441 Points( f+4 ) = gp_Pnt( 0 , w, -h );
442 Points( f+5 ) = gp_Pnt( -w * 0.866, w * 0.5, -h );
443 Points( f+6 ) = gp_Pnt( -w * 0.866, -w * 0.5, -h );
444 Points( f+7 ) = gp_Pnt( 0, -w, -h );
445
446 return h;
447}
448
449//=======================================================================
450// name : SetSimplePrsMode
451// Purpose :
452//=======================================================================
453void MeshVS_VectorPrsBuilder::SetSimplePrsMode( const Standard_Boolean IsSimpleArrow )
454{
455 myIsSimplePrs = IsSimpleArrow;
456}
457
458//=======================================================================
459// name : SetSimplePrsParams
460// Purpose :
461//=======================================================================
462void MeshVS_VectorPrsBuilder::SetSimplePrsParams( const Standard_Real theLineWidthParam,
463 const Standard_Real theStartParam,
464 const Standard_Real theEndParam )
465{
466 mySimpleWidthPrm = theLineWidthParam;
467 mySimpleStartPrm = theStartParam;
468 mySimpleEndPrm = theEndParam;
469}