1 // Created on: 2003-09-19
2 // Created by: Alexander SOLOVYOV
3 // Copyright (c) 2003-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #include <MeshVS_VectorPrsBuilder.ixx>
23 #include <MeshVS_DisplayModeFlags.hxx>
25 #include <Graphic3d_ArrayOfPolylines.hxx>
26 #include <Graphic3d_ArrayOfPolygons.hxx>
27 #include <Graphic3d_ArrayOfTriangleFans.hxx>
28 #include <Graphic3d_MaterialAspect.hxx>
29 #include <Graphic3d_AspectLine3d.hxx>
30 #include <Graphic3d_AspectFillArea3d.hxx>
31 #include <Graphic3d_Group.hxx>
33 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
34 #include <TColStd_Array1OfReal.hxx>
35 #include <TColgp_Array1OfPnt.hxx>
36 #include <TColStd_HPackedMapOfInteger.hxx>
38 #include <Precision.hxx>
42 #include <Prs3d_Root.hxx>
44 #include <Aspect_TypeOfLine.hxx>
46 #include <MeshVS_DataSource.hxx>
47 #include <MeshVS_Drawer.hxx>
48 #include <MeshVS_DrawerAttribute.hxx>
49 #include <MeshVS_Mesh.hxx>
50 #include <MeshVS_EntityType.hxx>
51 #include <MeshVS_DataMapIteratorOfDataMapOfIntegerVector.hxx>
52 #include <MeshVS_Buffer.hxx>
54 //================================================================
55 // Function : Constructor MeshVS_VectorPrsBuilder
57 //================================================================
58 MeshVS_VectorPrsBuilder::MeshVS_VectorPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
59 const Standard_Real MaxLength,
60 const Quantity_Color& VectorColor,
61 const MeshVS_DisplayModeFlags& Flags,
62 const Handle (MeshVS_DataSource)& DS,
63 const Standard_Integer Id,
64 const MeshVS_BuilderPriority& Priority,
65 const Standard_Boolean IsSimplePrs )
66 : MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority ),
67 myIsSimplePrs( IsSimplePrs ),
68 mySimpleWidthPrm( 2.5 ),
69 mySimpleStartPrm( 0.85 ),
70 mySimpleEndPrm( 0.95 )
72 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
73 if ( !aDrawer.IsNull() )
75 aDrawer->SetDouble ( MeshVS_DA_VectorMaxLength, MaxLength );
76 aDrawer->SetColor ( MeshVS_DA_VectorColor, VectorColor );
77 aDrawer->SetDouble ( MeshVS_DA_VectorArrowPart, 0.1 );
81 //================================================================
82 // Function : GetVectors
84 //================================================================
85 const MeshVS_DataMapOfIntegerVector& MeshVS_VectorPrsBuilder::GetVectors
86 ( const Standard_Boolean IsElements ) const
89 return myElemVectorMap;
91 return myNodeVectorMap;
94 //================================================================
95 // Function : SetVectors
97 //================================================================
98 void MeshVS_VectorPrsBuilder::SetVectors ( const Standard_Boolean IsElements,
99 const MeshVS_DataMapOfIntegerVector& theMap )
102 myElemVectorMap = theMap;
104 myNodeVectorMap = theMap;
107 //================================================================
108 // Function : HasVectors
110 //================================================================
111 Standard_Boolean MeshVS_VectorPrsBuilder::HasVectors ( const Standard_Boolean IsElement ) const
113 Standard_Boolean aRes = (myNodeVectorMap.Extent()>0);
115 aRes = (myElemVectorMap.Extent()>0);
120 //================================================================
121 // Function : GetVector
123 //================================================================
124 Standard_Boolean MeshVS_VectorPrsBuilder::GetVector ( const Standard_Boolean IsElement,
125 const Standard_Integer ID,
128 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
130 aMap = &myElemVectorMap;
132 Standard_Boolean aRes = aMap->IsBound ( ID );
134 Vect = aMap->Find ( ID );
139 //================================================================
140 // Function : SetVector
142 //================================================================
143 void MeshVS_VectorPrsBuilder::SetVector ( const Standard_Boolean IsElement,
144 const Standard_Integer ID,
147 MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
149 aMap = &myElemVectorMap;
151 Standard_Boolean aRes = aMap->IsBound ( ID );
153 aMap->ChangeFind ( ID ) = Vect;
155 aMap->Bind ( ID, Vect );
158 //================================================================
159 // Function : GetMaxVectorValue
161 //================================================================
162 void MeshVS_VectorPrsBuilder::GetMinMaxVectorValue ( const Standard_Boolean IsElement,
163 Standard_Real& MinValue,
164 Standard_Real& MaxValue ) const
166 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
168 aMap = &myElemVectorMap;
170 MeshVS_DataMapIteratorOfDataMapOfIntegerVector anIt ( *aMap );
172 MinValue = MaxValue = anIt.Value().Magnitude();
174 Standard_Real aCurValue;
176 for ( ; anIt.More(); anIt.Next() )
178 aCurValue = anIt.Value().Magnitude();
179 if ( MinValue > aCurValue )
180 MinValue = aCurValue;
181 if ( MaxValue < aCurValue )
182 MaxValue = aCurValue;
186 //================================================================
189 //================================================================
191 #define NB_VERTICES 2
193 #define NB_TRIANGLES 6
196 void MeshVS_VectorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
197 const TColStd_PackedMapOfInteger& IDs,
198 TColStd_PackedMapOfInteger& IDsToExclude,
199 const Standard_Boolean IsElement,
200 const Standard_Integer theDisplayMode ) const
202 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
203 Handle (MeshVS_DataSource) aSource = GetDataSource();
204 if ( aSource.IsNull() || aDrawer.IsNull() || !HasVectors( IsElement ) ||
205 ( theDisplayMode & GetFlags() )==0 )
208 Standard_Integer aMaxFaceNodes;
209 Standard_Real aMaxLen, anArrowPart = 0.1;
211 if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) ||
212 aMaxFaceNodes <= 0 ||
213 !aDrawer->GetDouble ( MeshVS_DA_VectorMaxLength, aMaxLen ) ||
215 !aDrawer->GetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart ) ||
220 MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real));
221 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*aMaxFaceNodes);
222 Standard_Integer NbNodes;
223 MeshVS_EntityType aType;
225 // DECLARE ARRAYS OF PRIMITIVES
226 const MeshVS_DataMapOfIntegerVector& aMap = GetVectors ( IsElement );
227 Standard_Integer aNbVectors = aMap.Extent();
229 if ( aNbVectors <= 0 )
233 Standard_Integer aNbVertices = aNbVectors * NB_VERTICES;
234 Standard_Integer aNbBounds = aNbVectors * NB_BOUNDS;
237 Standard_Integer aNbTriangleVertices = aNbVectors * (NB_TRIANGLES + 2);
238 Standard_Integer aNbFans = aNbVectors * NB_TRIANGLES;
240 Handle(Graphic3d_ArrayOfPrimitives) aLineArray =
241 new Graphic3d_ArrayOfPolylines(aNbVertices, aNbBounds);
242 Handle(Graphic3d_ArrayOfPrimitives) aArrowLineArray =
243 new Graphic3d_ArrayOfPolylines(aNbVertices, aNbBounds);
245 Handle(Graphic3d_ArrayOfTriangleFans) aTriangleArray =
246 new Graphic3d_ArrayOfTriangleFans(aNbTriangleVertices, aNbFans);
248 TColgp_Array1OfPnt anArrowPnt(1,8);
249 Standard_Real k, b, aMaxValue, aMinValue, aValue, X, Y, Z;
251 Standard_Real aMinLength = calculateArrow( anArrowPnt, aMaxLen, anArrowPart );
252 gp_Vec aVec; gp_Trsf aTrsf;
254 GetMinMaxVectorValue ( IsElement, aMinValue, aMaxValue );
256 if ( aMaxValue - aMinValue > Precision::Confusion() )
258 k = 0.8 * aMaxLen / ( aMaxValue - aMinValue );
259 b = aMaxLen - k * aMaxValue;
267 TColStd_PackedMapOfInteger aCustomElements;
269 // subtract the hidden elements and ids to exclude (to minimise allocated memory)
270 TColStd_PackedMapOfInteger anIDs;
274 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
275 if ( !aHiddenElems.IsNull() )
276 anIDs.Subtract( aHiddenElems->Map() );
278 anIDs.Subtract( IDsToExclude );
280 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
281 for( ; it.More(); it.Next() )
283 Standard_Integer aKey = it.Key();
284 if( GetVector ( IsElement, aKey, aVec ) )
286 aValue = aVec.Magnitude();
288 if ( Abs( aValue ) < Precision::Confusion() )
291 if( aSource->GetGeom ( aKey, IsElement, aCoords, NbNodes, aType ) )
293 if( aType == MeshVS_ET_Node )
299 else if( aType == MeshVS_ET_Link ||
300 aType == MeshVS_ET_Face ||
301 aType == MeshVS_ET_Volume )
303 if( IsElement && IsExcludingOn() )
304 IDsToExclude.Add( aKey );
306 for ( Standard_Integer i=1; i<=NbNodes; i++ )
308 X += aCoords (3*i-2);
309 Y += aCoords (3*i-1);
312 X /= Standard_Real ( NbNodes );
313 Y /= Standard_Real ( NbNodes );
314 Z /= Standard_Real ( NbNodes );
318 aCustomElements.Add( aKey );
322 aTrsf.SetDisplacement ( gp_Ax3 ( gp_Pnt ( 0, 0, 0 ), gp_Dir(0, 0, 1)),
323 gp_Ax3 ( gp_Pnt ( X, Y, Z ), aVec ) );
325 DrawVector ( aTrsf, Max( k * fabs( aValue ) + b, aMinLength), aMaxLen,
326 anArrowPnt, aLineArray, aArrowLineArray, aTriangleArray );
331 Prs3d_Root::NewGroup ( Prs );
332 Handle (Graphic3d_Group) aVGroup = Prs3d_Root::CurrentGroup ( Prs );
334 Quantity_Color aColor;
335 aDrawer->GetColor ( MeshVS_DA_VectorColor, aColor );
337 // Add primitive arrays to group
338 Handle(Graphic3d_AspectLine3d) aLinAspect =
339 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, 1.5 );
341 aVGroup->SetPrimitivesAspect( aLinAspect );
343 aVGroup->BeginPrimitives();
344 aVGroup->AddPrimitiveArray( aLineArray );
345 aVGroup->EndPrimitives();
346 if ( !myIsSimplePrs )
348 Graphic3d_MaterialAspect aMatAspect;
349 aMatAspect.SetAmbient( 1 );
350 aMatAspect.SetDiffuse( 0 );
351 aMatAspect.SetEmissive( 0 );
352 aMatAspect.SetShininess( 1 );
353 aMatAspect.SetSpecular( 0 );
354 Handle(Graphic3d_AspectFillArea3d) aFillAspect =
355 new Graphic3d_AspectFillArea3d (Aspect_IS_HOLLOW, aColor, aColor, Aspect_TOL_SOLID,
356 1., aMatAspect, aMatAspect );
358 aVGroup->SetPrimitivesAspect( aFillAspect );
360 aVGroup->BeginPrimitives();
361 aVGroup->AddPrimitiveArray( aTriangleArray );
362 aVGroup->EndPrimitives();
366 Handle(Graphic3d_AspectLine3d) anArrowLinAspect =
367 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, mySimpleWidthPrm * 1.5 );
369 aVGroup->SetPrimitivesAspect( anArrowLinAspect );
371 aVGroup->BeginPrimitives();
372 aVGroup->AddPrimitiveArray( aArrowLineArray );
373 aVGroup->EndPrimitives();
376 if( !aCustomElements.IsEmpty() )
377 CustomBuild( Prs, aCustomElements, IDsToExclude, theDisplayMode );
380 //=======================================================================
382 // Purpose : Fill arrays of primitives for drawing force
383 //=======================================================================
384 void MeshVS_VectorPrsBuilder::DrawVector ( const gp_Trsf& theTrsf,
385 const Standard_Real Length,
386 const Standard_Real MaxLength,
387 const TColgp_Array1OfPnt& ArrowPoints,
388 const Handle(Graphic3d_ArrayOfPrimitives)& Lines,
389 const Handle(Graphic3d_ArrayOfPrimitives)& ArrowLines,
390 const Handle(Graphic3d_ArrayOfPrimitives)& Triangles) const
392 const int PntNum = 8;
394 const Standard_Real aMinLength = MaxLength * ( 1 - mySimpleStartPrm );
395 const Standard_Real aLocalLength = ( !myIsSimplePrs || Length > aMinLength ? Length : aMinLength );
397 gp_Pnt aLinePnt[ 2 ] = { gp_Pnt( 0, 0, 0 ) , gp_Pnt( 0, 0, aLocalLength ) };
398 theTrsf.Transforms( aLinePnt[ 0 ].ChangeCoord() );
399 theTrsf.Transforms( aLinePnt[ 1 ].ChangeCoord() );
401 Lines->AddBound( 2 );
402 Lines->AddVertex( aLinePnt[ 0 ] );
403 Lines->AddVertex( aLinePnt[ 1 ] );
406 if ( !myIsSimplePrs )
408 Standard_Integer l = ArrowPoints.Lower(),
409 u = ArrowPoints.Upper(),
411 if ( u-l < PntNum-1 )
414 TColgp_Array1OfPnt anArrowPnt( l, u );
415 for ( i = l; i < l+PntNum; i++ )
417 anArrowPnt( i ).ChangeCoord() = ArrowPoints ( i ).Coord() + gp_XYZ( 0, 0, aLocalLength );
418 theTrsf.Transforms( anArrowPnt( i ).ChangeCoord() );
421 Triangles->AddBound(8);
422 for ( i = 0; i < PntNum; i++ )
423 Triangles->AddVertex( anArrowPnt( l+i ) );
427 const Standard_Real aEndPos = aLocalLength - MaxLength * ( 1 - mySimpleEndPrm );
428 const Standard_Real aArrowLength = MaxLength * ( mySimpleEndPrm - mySimpleStartPrm );
429 gp_Pnt aArrowPnt[ 2 ] = { gp_Pnt( 0, 0, aEndPos - aArrowLength ),
430 gp_Pnt( 0, 0, aEndPos ) };
431 theTrsf.Transforms( aArrowPnt[ 0 ].ChangeCoord() );
432 theTrsf.Transforms( aArrowPnt[ 1 ].ChangeCoord() );
434 ArrowLines->AddBound( 2 );
435 ArrowLines->AddVertex( aArrowPnt[ 0 ] );
436 ArrowLines->AddVertex( aArrowPnt[ 1 ] );
440 //=======================================================================
441 // name : calculateArrow
442 // Purpose : Calculate points of arrow ( 8 pnts )
443 //=======================================================================
444 Standard_Real MeshVS_VectorPrsBuilder::calculateArrow ( TColgp_Array1OfPnt& Points,
445 const Standard_Real Length,
446 const Standard_Real ArrowPart )
448 Standard_Real h = Length * ArrowPart;
449 Standard_Real w = h / 5.;
451 Standard_Integer f = Points.Lower();
452 Points( f ) = gp_Pnt( 0, 0, 0 );
453 Points( f+1 ) = gp_Pnt( 0, -w, -h );
454 Points( f+2 ) = gp_Pnt( w * 0.866, -w * 0.5, -h );
455 Points( f+3 ) = gp_Pnt( w * 0.866, w * 0.5, -h );
456 Points( f+4 ) = gp_Pnt( 0 , w, -h );
457 Points( f+5 ) = gp_Pnt( -w * 0.866, w * 0.5, -h );
458 Points( f+6 ) = gp_Pnt( -w * 0.866, -w * 0.5, -h );
459 Points( f+7 ) = gp_Pnt( 0, -w, -h );
464 //=======================================================================
465 // name : SetSimplePrsMode
467 //=======================================================================
468 void MeshVS_VectorPrsBuilder::SetSimplePrsMode( const Standard_Boolean IsSimpleArrow )
470 myIsSimplePrs = IsSimpleArrow;
473 //=======================================================================
474 // name : SetSimplePrsParams
476 //=======================================================================
477 void MeshVS_VectorPrsBuilder::SetSimplePrsParams( const Standard_Real theLineWidthParam,
478 const Standard_Real theStartParam,
479 const Standard_Real theEndParam )
481 mySimpleWidthPrm = theLineWidthParam;
482 mySimpleStartPrm = theStartParam;
483 mySimpleEndPrm = theEndParam;