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