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