1 // File: MeshVS_VectorPrsBuilder.cxx
2 // Created: Fri Sep 19 2003
3 // Author: Alexander SOLOVYOV
4 // Copyright: Open CASCADE 2003
6 #include <MeshVS_VectorPrsBuilder.ixx>
8 #include <MeshVS_DisplayModeFlags.hxx>
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>
18 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
19 #include <TColStd_Array1OfReal.hxx>
20 #include <TColgp_Array1OfPnt.hxx>
21 #include <TColStd_HPackedMapOfInteger.hxx>
23 #include <Precision.hxx>
27 #include <Prs3d_Root.hxx>
29 #include <Aspect_TypeOfLine.hxx>
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>
39 //================================================================
40 // Function : Constructor MeshVS_VectorPrsBuilder
42 //================================================================
43 MeshVS_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 ),
52 myIsSimplePrs( IsSimplePrs ),
53 mySimpleWidthPrm( 2.5 ),
54 mySimpleStartPrm( 0.85 ),
55 mySimpleEndPrm( 0.95 )
57 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
58 if ( !aDrawer.IsNull() )
60 aDrawer->SetDouble ( MeshVS_DA_VectorMaxLength, MaxLength );
61 aDrawer->SetColor ( MeshVS_DA_VectorColor, VectorColor );
62 aDrawer->SetDouble ( MeshVS_DA_VectorArrowPart, 0.1 );
66 //================================================================
67 // Function : GetVectors
69 //================================================================
70 const MeshVS_DataMapOfIntegerVector& MeshVS_VectorPrsBuilder::GetVectors
71 ( const Standard_Boolean IsElements ) const
74 return myElemVectorMap;
76 return myNodeVectorMap;
79 //================================================================
80 // Function : SetVectors
82 //================================================================
83 void MeshVS_VectorPrsBuilder::SetVectors ( const Standard_Boolean IsElements,
84 const MeshVS_DataMapOfIntegerVector& theMap )
87 myElemVectorMap = theMap;
89 myNodeVectorMap = theMap;
92 //================================================================
93 // Function : HasVectors
95 //================================================================
96 Standard_Boolean MeshVS_VectorPrsBuilder::HasVectors ( const Standard_Boolean IsElement ) const
98 Standard_Boolean aRes = (myNodeVectorMap.Extent()>0);
100 aRes = (myElemVectorMap.Extent()>0);
105 //================================================================
106 // Function : GetVector
108 //================================================================
109 Standard_Boolean MeshVS_VectorPrsBuilder::GetVector ( const Standard_Boolean IsElement,
110 const Standard_Integer ID,
113 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
115 aMap = &myElemVectorMap;
117 Standard_Boolean aRes = aMap->IsBound ( ID );
119 Vect = aMap->Find ( ID );
124 //================================================================
125 // Function : SetVector
127 //================================================================
128 void MeshVS_VectorPrsBuilder::SetVector ( const Standard_Boolean IsElement,
129 const Standard_Integer ID,
132 MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
134 aMap = &myElemVectorMap;
136 Standard_Boolean aRes = aMap->IsBound ( ID );
138 aMap->ChangeFind ( ID ) = Vect;
140 aMap->Bind ( ID, Vect );
143 //================================================================
144 // Function : GetMaxVectorValue
146 //================================================================
147 void MeshVS_VectorPrsBuilder::GetMinMaxVectorValue ( const Standard_Boolean IsElement,
148 Standard_Real& MinValue,
149 Standard_Real& MaxValue ) const
151 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
153 aMap = &myElemVectorMap;
155 MeshVS_DataMapIteratorOfDataMapOfIntegerVector anIt ( *aMap );
157 MinValue = MaxValue = anIt.Value().Magnitude();
159 Standard_Real aCurValue;
161 for ( ; anIt.More(); anIt.Next() )
163 aCurValue = anIt.Value().Magnitude();
164 if ( MinValue > aCurValue )
165 MinValue = aCurValue;
166 if ( MaxValue < aCurValue )
167 MaxValue = aCurValue;
171 //================================================================
174 //================================================================
176 #define NB_VERTICES 2
178 #define NB_TRIANGLES 6
181 void 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
187 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
188 Handle (MeshVS_DataSource) aSource = GetDataSource();
189 if ( aSource.IsNull() || aDrawer.IsNull() || !HasVectors( IsElement ) ||
190 ( theDisplayMode & GetFlags() )==0 )
193 Standard_Integer aMaxFaceNodes;
194 Standard_Real aMaxLen, anArrowPart = 0.1;
196 if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) ||
197 aMaxFaceNodes <= 0 ||
198 !aDrawer->GetDouble ( MeshVS_DA_VectorMaxLength, aMaxLen ) ||
200 !aDrawer->GetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart ) ||
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;
210 // DECLARE ARRAYS OF PRIMITIVES
211 const MeshVS_DataMapOfIntegerVector& aMap = GetVectors ( IsElement );
212 Standard_Integer aNbVectors = aMap.Extent();
214 if ( aNbVectors <= 0 )
218 Standard_Integer aNbVertices = aNbVectors * NB_VERTICES;
219 Standard_Integer aNbBounds = aNbVectors * NB_BOUNDS;
222 Standard_Integer aNbTriangleVertices = aNbVectors * (NB_TRIANGLES + 2);
223 Standard_Integer aNbFans = aNbVectors * NB_TRIANGLES;
225 Handle(Graphic3d_ArrayOfPrimitives) aLineArray =
226 new Graphic3d_ArrayOfPolylines(aNbVertices, aNbBounds);
227 Handle(Graphic3d_ArrayOfPrimitives) aArrowLineArray =
228 new Graphic3d_ArrayOfPolylines(aNbVertices, aNbBounds);
230 Handle(Graphic3d_ArrayOfTriangleFans) aTriangleArray =
231 new Graphic3d_ArrayOfTriangleFans(aNbTriangleVertices, aNbFans);
233 TColgp_Array1OfPnt anArrowPnt(1,8);
234 Standard_Real k, b, aMaxValue, aMinValue, aValue, X, Y, Z;
236 Standard_Real aMinLength = calculateArrow( anArrowPnt, aMaxLen, anArrowPart );
237 gp_Vec aVec; gp_Trsf aTrsf;
239 GetMinMaxVectorValue ( IsElement, aMinValue, aMaxValue );
241 if ( aMaxValue - aMinValue > Precision::Confusion() )
243 k = 0.8 * aMaxLen / ( aMaxValue - aMinValue );
244 b = aMaxLen - k * aMaxValue;
252 TColStd_PackedMapOfInteger aCustomElements;
254 // subtract the hidden elements and ids to exclude (to minimise allocated memory)
255 TColStd_PackedMapOfInteger anIDs;
259 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
260 if ( !aHiddenElems.IsNull() )
261 anIDs.Subtract( aHiddenElems->Map() );
263 anIDs.Subtract( IDsToExclude );
265 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
266 for( ; it.More(); it.Next() )
268 Standard_Integer aKey = it.Key();
269 if( GetVector ( IsElement, aKey, aVec ) )
271 aValue = aVec.Magnitude();
273 if ( Abs( aValue ) < Precision::Confusion() )
276 if( aSource->GetGeom ( aKey, IsElement, aCoords, NbNodes, aType ) )
278 if( aType == MeshVS_ET_Node )
284 else if( aType == MeshVS_ET_Link ||
285 aType == MeshVS_ET_Face ||
286 aType == MeshVS_ET_Volume )
288 if( IsElement && IsExcludingOn() )
289 IDsToExclude.Add( aKey );
291 for ( Standard_Integer i=1; i<=NbNodes; i++ )
293 X += aCoords (3*i-2);
294 Y += aCoords (3*i-1);
297 X /= Standard_Real ( NbNodes );
298 Y /= Standard_Real ( NbNodes );
299 Z /= Standard_Real ( NbNodes );
303 aCustomElements.Add( aKey );
307 aTrsf.SetDisplacement ( gp_Ax3 ( gp_Pnt ( 0, 0, 0 ), gp_Dir(0, 0, 1)),
308 gp_Ax3 ( gp_Pnt ( X, Y, Z ), aVec ) );
310 DrawVector ( aTrsf, Max( k * fabs( aValue ) + b, aMinLength), aMaxLen,
311 anArrowPnt, aLineArray, aArrowLineArray, aTriangleArray );
316 Prs3d_Root::NewGroup ( Prs );
317 Handle (Graphic3d_Group) aVGroup = Prs3d_Root::CurrentGroup ( Prs );
319 Quantity_Color aColor;
320 aDrawer->GetColor ( MeshVS_DA_VectorColor, aColor );
322 // Add primitive arrays to group
323 Handle(Graphic3d_AspectLine3d) aLinAspect =
324 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, 1.5 );
326 aVGroup->SetPrimitivesAspect( aLinAspect );
328 aVGroup->BeginPrimitives();
329 aVGroup->AddPrimitiveArray( aLineArray );
330 aVGroup->EndPrimitives();
331 if ( !myIsSimplePrs )
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 );
343 aVGroup->SetPrimitivesAspect( aFillAspect );
345 aVGroup->BeginPrimitives();
346 aVGroup->AddPrimitiveArray( aTriangleArray );
347 aVGroup->EndPrimitives();
351 Handle(Graphic3d_AspectLine3d) anArrowLinAspect =
352 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, mySimpleWidthPrm * 1.5 );
354 aVGroup->SetPrimitivesAspect( anArrowLinAspect );
356 aVGroup->BeginPrimitives();
357 aVGroup->AddPrimitiveArray( aArrowLineArray );
358 aVGroup->EndPrimitives();
361 if( !aCustomElements.IsEmpty() )
362 CustomBuild( Prs, aCustomElements, IDsToExclude, theDisplayMode );
365 //=======================================================================
367 // Purpose : Fill arrays of primitives for drawing force
368 //=======================================================================
369 void 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
377 const int PntNum = 8;
379 const Standard_Real aMinLength = MaxLength * ( 1 - mySimpleStartPrm );
380 const Standard_Real aLocalLength = ( !myIsSimplePrs || Length > aMinLength ? Length : aMinLength );
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() );
386 Lines->AddBound( 2 );
387 Lines->AddVertex( aLinePnt[ 0 ] );
388 Lines->AddVertex( aLinePnt[ 1 ] );
391 if ( !myIsSimplePrs )
393 Standard_Integer l = ArrowPoints.Lower(),
394 u = ArrowPoints.Upper(),
396 if ( u-l < PntNum-1 )
399 TColgp_Array1OfPnt anArrowPnt( l, u );
400 for ( i = l; i < l+PntNum; i++ )
402 anArrowPnt( i ).ChangeCoord() = ArrowPoints ( i ).Coord() + gp_XYZ( 0, 0, aLocalLength );
403 theTrsf.Transforms( anArrowPnt( i ).ChangeCoord() );
406 Triangles->AddBound(8);
407 for ( i = 0; i < PntNum; i++ )
408 Triangles->AddVertex( anArrowPnt( l+i ) );
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() );
419 ArrowLines->AddBound( 2 );
420 ArrowLines->AddVertex( aArrowPnt[ 0 ] );
421 ArrowLines->AddVertex( aArrowPnt[ 1 ] );
425 //=======================================================================
426 // name : calculateArrow
427 // Purpose : Calculate points of arrow ( 8 pnts )
428 //=======================================================================
429 Standard_Real MeshVS_VectorPrsBuilder::calculateArrow ( TColgp_Array1OfPnt& Points,
430 const Standard_Real Length,
431 const Standard_Real ArrowPart )
433 Standard_Real h = Length * ArrowPart;
434 Standard_Real w = h / 5.;
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 );
449 //=======================================================================
450 // name : SetSimplePrsMode
452 //=======================================================================
453 void MeshVS_VectorPrsBuilder::SetSimplePrsMode( const Standard_Boolean IsSimpleArrow )
455 myIsSimplePrs = IsSimpleArrow;
458 //=======================================================================
459 // name : SetSimplePrsParams
461 //=======================================================================
462 void MeshVS_VectorPrsBuilder::SetSimplePrsParams( const Standard_Real theLineWidthParam,
463 const Standard_Real theStartParam,
464 const Standard_Real theEndParam )
466 mySimpleWidthPrm = theLineWidthParam;
467 mySimpleStartPrm = theStartParam;
468 mySimpleEndPrm = theEndParam;