1 // Created on: 2003-09-19
2 // Created by: Alexander SOLOVYOV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
17 #include <Graphic3d_ArrayOfSegments.hxx>
18 #include <Graphic3d_AspectLine3d.hxx>
19 #include <MeshVS_Buffer.hxx>
20 #include <MeshVS_DataSource.hxx>
21 #include <MeshVS_Drawer.hxx>
22 #include <MeshVS_DrawerAttribute.hxx>
23 #include <MeshVS_EntityType.hxx>
24 #include <MeshVS_Mesh.hxx>
25 #include <MeshVS_VectorPrsBuilder.hxx>
26 #include <Precision.hxx>
27 #include <Prs3d_Presentation.hxx>
28 #include <Quantity_Color.hxx>
29 #include <Standard_Type.hxx>
30 #include <TColgp_Array1OfPnt.hxx>
31 #include <TColStd_Array1OfReal.hxx>
32 #include <TColStd_HPackedMapOfInteger.hxx>
33 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
35 IMPLEMENT_STANDARD_RTTIEXT(MeshVS_VectorPrsBuilder,MeshVS_PrsBuilder)
37 //================================================================
38 // Function : Constructor MeshVS_VectorPrsBuilder
40 //================================================================
41 MeshVS_VectorPrsBuilder::MeshVS_VectorPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
42 const Standard_Real MaxLength,
43 const Quantity_Color& VectorColor,
44 const MeshVS_DisplayModeFlags& Flags,
45 const Handle (MeshVS_DataSource)& DS,
46 const Standard_Integer Id,
47 const MeshVS_BuilderPriority& Priority,
48 const Standard_Boolean IsSimplePrs )
49 : MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority ),
50 myIsSimplePrs( IsSimplePrs ),
51 mySimpleWidthPrm( 2.5 ),
52 mySimpleStartPrm( 0.85 ),
53 mySimpleEndPrm( 0.95 )
55 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
56 if ( !aDrawer.IsNull() )
58 aDrawer->SetDouble ( MeshVS_DA_VectorMaxLength, MaxLength );
59 aDrawer->SetColor ( MeshVS_DA_VectorColor, VectorColor );
60 aDrawer->SetDouble ( MeshVS_DA_VectorArrowPart, 0.1 );
64 //================================================================
65 // Function : GetVectors
67 //================================================================
68 const MeshVS_DataMapOfIntegerVector& MeshVS_VectorPrsBuilder::GetVectors
69 ( const Standard_Boolean IsElements ) const
72 return myElemVectorMap;
74 return myNodeVectorMap;
77 //================================================================
78 // Function : SetVectors
80 //================================================================
81 void MeshVS_VectorPrsBuilder::SetVectors ( const Standard_Boolean IsElements,
82 const MeshVS_DataMapOfIntegerVector& theMap )
85 myElemVectorMap = theMap;
87 myNodeVectorMap = theMap;
90 //================================================================
91 // Function : HasVectors
93 //================================================================
94 Standard_Boolean MeshVS_VectorPrsBuilder::HasVectors ( const Standard_Boolean IsElement ) const
96 Standard_Boolean aRes = (myNodeVectorMap.Extent()>0);
98 aRes = (myElemVectorMap.Extent()>0);
103 //================================================================
104 // Function : GetVector
106 //================================================================
107 Standard_Boolean MeshVS_VectorPrsBuilder::GetVector ( const Standard_Boolean IsElement,
108 const Standard_Integer ID,
111 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
113 aMap = &myElemVectorMap;
115 Standard_Boolean aRes = aMap->IsBound ( ID );
117 Vect = aMap->Find ( ID );
122 //================================================================
123 // Function : SetVector
125 //================================================================
126 void MeshVS_VectorPrsBuilder::SetVector ( const Standard_Boolean IsElement,
127 const Standard_Integer ID,
130 MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
132 aMap = &myElemVectorMap;
134 Standard_Boolean aRes = aMap->IsBound ( ID );
136 aMap->ChangeFind ( ID ) = Vect;
138 aMap->Bind ( ID, Vect );
141 //================================================================
142 // Function : GetMaxVectorValue
144 //================================================================
145 void MeshVS_VectorPrsBuilder::GetMinMaxVectorValue ( const Standard_Boolean IsElement,
146 Standard_Real& MinValue,
147 Standard_Real& MaxValue ) const
149 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
151 aMap = &myElemVectorMap;
153 MeshVS_DataMapIteratorOfDataMapOfIntegerVector anIt ( *aMap );
155 MinValue = MaxValue = anIt.Value().Magnitude();
157 Standard_Real aCurValue;
159 for ( ; anIt.More(); anIt.Next() )
161 aCurValue = anIt.Value().Magnitude();
162 if ( MinValue > aCurValue )
163 MinValue = aCurValue;
164 if ( MaxValue < aCurValue )
165 MaxValue = aCurValue;
169 //================================================================
172 //================================================================
174 #define NB_VERTICES 2
176 #define NB_TRIANGLES 6
179 void MeshVS_VectorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
180 const TColStd_PackedMapOfInteger& IDs,
181 TColStd_PackedMapOfInteger& IDsToExclude,
182 const Standard_Boolean IsElement,
183 const Standard_Integer theDisplayMode ) const
185 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
186 Handle (MeshVS_DataSource) aSource = GetDataSource();
187 if ( aSource.IsNull() || aDrawer.IsNull() || !HasVectors( IsElement ) ||
188 ( theDisplayMode & GetFlags() )==0 )
191 Standard_Integer aMaxFaceNodes;
192 Standard_Real aMaxLen, anArrowPart = 0.1;
194 if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) ||
195 aMaxFaceNodes <= 0 ||
196 !aDrawer->GetDouble ( MeshVS_DA_VectorMaxLength, aMaxLen ) ||
198 !aDrawer->GetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart ) ||
203 MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real));
204 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*aMaxFaceNodes);
205 Standard_Integer NbNodes;
206 MeshVS_EntityType aType;
208 // DECLARE ARRAYS OF PRIMITIVES
209 const MeshVS_DataMapOfIntegerVector& aMap = GetVectors ( IsElement );
210 Standard_Integer aNbVectors = aMap.Extent();
212 if ( aNbVectors <= 0 )
216 Standard_Integer aNbVertices = aNbVectors * NB_VERTICES;
218 Handle(Graphic3d_ArrayOfPrimitives) aLineArray = new Graphic3d_ArrayOfSegments (aNbVertices);
219 Handle(Graphic3d_ArrayOfPrimitives) aArrowLineArray = new Graphic3d_ArrayOfSegments (aNbVertices);
221 Handle(Graphic3d_ArrayOfPrimitives) aTriangleArray = new Graphic3d_ArrayOfSegments (
222 aNbVectors * 8 /* vertices per arrow */, aNbVectors * 12 /* segments per arrow */ * 2 /* indices per segment */);
224 TColgp_Array1OfPnt anArrowPnt(1,8);
225 Standard_Real k, b, aMaxValue, aMinValue, aValue, X, Y, Z;
227 Standard_Real aMinLength = calculateArrow( anArrowPnt, aMaxLen, anArrowPart );
228 gp_Vec aVec; gp_Trsf aTrsf;
230 GetMinMaxVectorValue ( IsElement, aMinValue, aMaxValue );
232 if ( aMaxValue - aMinValue > Precision::Confusion() )
234 k = 0.8 * aMaxLen / ( aMaxValue - aMinValue );
235 b = aMaxLen - k * aMaxValue;
243 TColStd_PackedMapOfInteger aCustomElements;
245 // subtract the hidden elements and ids to exclude (to minimize allocated memory)
246 TColStd_PackedMapOfInteger anIDs;
250 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
251 if ( !aHiddenElems.IsNull() )
252 anIDs.Subtract( aHiddenElems->Map() );
254 anIDs.Subtract( IDsToExclude );
256 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
257 for( ; it.More(); it.Next() )
259 Standard_Integer aKey = it.Key();
260 if( GetVector ( IsElement, aKey, aVec ) )
262 aValue = aVec.Magnitude();
264 if ( Abs( aValue ) < Precision::Confusion() )
267 if( aSource->GetGeom ( aKey, IsElement, aCoords, NbNodes, aType ) )
269 if( aType == MeshVS_ET_Node )
275 else if( aType == MeshVS_ET_Link ||
276 aType == MeshVS_ET_Face ||
277 aType == MeshVS_ET_Volume )
279 if( IsElement && IsExcludingOn() )
280 IDsToExclude.Add( aKey );
282 for ( Standard_Integer i=1; i<=NbNodes; i++ )
284 X += aCoords (3*i-2);
285 Y += aCoords (3*i-1);
288 X /= Standard_Real ( NbNodes );
289 Y /= Standard_Real ( NbNodes );
290 Z /= Standard_Real ( NbNodes );
294 aCustomElements.Add( aKey );
298 aTrsf.SetDisplacement ( gp_Ax3 ( gp_Pnt ( 0, 0, 0 ), gp_Dir(0, 0, 1)),
299 gp_Ax3 ( gp_Pnt ( X, Y, Z ), aVec ) );
301 DrawVector ( aTrsf, Max( k * fabs( aValue ) + b, aMinLength), aMaxLen,
302 anArrowPnt, aLineArray, aArrowLineArray, aTriangleArray );
307 Handle (Graphic3d_Group) aVGroup = Prs->NewGroup();
309 Quantity_Color aColor;
310 aDrawer->GetColor ( MeshVS_DA_VectorColor, aColor );
312 // Add primitive arrays to group
313 Handle(Graphic3d_AspectLine3d) aLinAspect =
314 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, 1.5 );
316 aVGroup->SetPrimitivesAspect( aLinAspect );
317 aVGroup->AddPrimitiveArray( aLineArray );
319 if ( !myIsSimplePrs )
321 Handle(Graphic3d_AspectLine3d) anArrowLinAspect =
322 new Graphic3d_AspectLine3d (aColor, Aspect_TOL_SOLID, mySimpleWidthPrm);
324 aVGroup->SetPrimitivesAspect( anArrowLinAspect );
325 aVGroup->AddPrimitiveArray( aTriangleArray );
329 Handle(Graphic3d_AspectLine3d) anArrowLinAspect =
330 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, mySimpleWidthPrm * 1.5 );
332 aVGroup->SetPrimitivesAspect( anArrowLinAspect );
333 aVGroup->AddPrimitiveArray( aArrowLineArray );
336 if( !aCustomElements.IsEmpty() )
337 CustomBuild( Prs, aCustomElements, IDsToExclude, theDisplayMode );
340 //=======================================================================
342 // Purpose : Fill arrays of primitives for drawing force
343 //=======================================================================
344 void MeshVS_VectorPrsBuilder::DrawVector ( const gp_Trsf& theTrsf,
345 const Standard_Real theLength,
346 const Standard_Real theMaxLength,
347 const TColgp_Array1OfPnt& theArrowPoints,
348 const Handle(Graphic3d_ArrayOfPrimitives)& theLines,
349 const Handle(Graphic3d_ArrayOfPrimitives)& theArrowLines,
350 const Handle(Graphic3d_ArrayOfPrimitives)& theTriangles) const
352 const int PntNum = 8;
354 const Standard_Real aMinLength = theMaxLength * ( 1 - mySimpleStartPrm );
355 const Standard_Real aLocalLength = ( !myIsSimplePrs || theLength > aMinLength ? theLength : aMinLength );
357 gp_Pnt aLinePnt[ 2 ] = { gp_Pnt( 0, 0, 0 ) , gp_Pnt( 0, 0, aLocalLength ) };
358 theTrsf.Transforms (aLinePnt[0].ChangeCoord());
359 theTrsf.Transforms (aLinePnt[1].ChangeCoord());
361 theLines->AddVertex (aLinePnt[0]);
362 theLines->AddVertex (aLinePnt[1]);
367 Standard_Integer aLower = theArrowPoints.Lower(),
368 aUpper = theArrowPoints.Upper();
370 if (aUpper - aLower < PntNum - 1)
373 TColgp_Array1OfPnt anArrowPnt (aLower, aUpper);
374 for (Standard_Integer aPntIdx = aLower; aPntIdx < aLower + PntNum; ++aPntIdx)
376 anArrowPnt (aPntIdx).ChangeCoord() = theArrowPoints (aPntIdx).Coord() + gp_XYZ (0, 0, aLocalLength);
377 theTrsf.Transforms (anArrowPnt (aPntIdx).ChangeCoord());
380 const Standard_Integer aVrtOffset = theTriangles->VertexNumber() + 1;
382 for (Standard_Integer aPntIdx = 0; aPntIdx < PntNum; ++aPntIdx)
384 theTriangles->AddVertex (anArrowPnt (aLower + aPntIdx));
387 for (Standard_Integer aPntIdx = 1; aPntIdx <= PntNum - 2; ++aPntIdx)
389 theTriangles->AddEdge (aVrtOffset);
390 theTriangles->AddEdge (aVrtOffset + aPntIdx);
392 theTriangles->AddEdge (aVrtOffset + aPntIdx);
393 theTriangles->AddEdge (aVrtOffset + aPntIdx + 1);
398 const Standard_Real aEndPos = aLocalLength - theMaxLength * ( 1 - mySimpleEndPrm );
399 const Standard_Real aArrowLength = theMaxLength * ( mySimpleEndPrm - mySimpleStartPrm );
400 gp_Pnt aArrowPnt[ 2 ] = { gp_Pnt( 0, 0, aEndPos - aArrowLength ),
401 gp_Pnt( 0, 0, aEndPos ) };
402 theTrsf.Transforms (aArrowPnt[0].ChangeCoord());
403 theTrsf.Transforms (aArrowPnt[1].ChangeCoord());
405 theArrowLines->AddVertex (aArrowPnt[0]);
406 theArrowLines->AddVertex (aArrowPnt[1]);
410 //=======================================================================
411 // name : calculateArrow
412 // Purpose : Calculate points of arrow ( 8 pnts )
413 //=======================================================================
414 Standard_Real MeshVS_VectorPrsBuilder::calculateArrow ( TColgp_Array1OfPnt& Points,
415 const Standard_Real Length,
416 const Standard_Real ArrowPart )
418 Standard_Real h = Length * ArrowPart;
419 Standard_Real w = h / 5.;
421 Standard_Integer f = Points.Lower();
422 Points( f ) = gp_Pnt( 0, 0, 0 );
423 Points( f+1 ) = gp_Pnt( 0, -w, -h );
424 Points( f+2 ) = gp_Pnt( w * 0.866, -w * 0.5, -h );
425 Points( f+3 ) = gp_Pnt( w * 0.866, w * 0.5, -h );
426 Points( f+4 ) = gp_Pnt( 0 , w, -h );
427 Points( f+5 ) = gp_Pnt( -w * 0.866, w * 0.5, -h );
428 Points( f+6 ) = gp_Pnt( -w * 0.866, -w * 0.5, -h );
429 Points( f+7 ) = gp_Pnt( 0, -w, -h );
434 //=======================================================================
435 // name : SetSimplePrsMode
437 //=======================================================================
438 void MeshVS_VectorPrsBuilder::SetSimplePrsMode( const Standard_Boolean IsSimpleArrow )
440 myIsSimplePrs = IsSimpleArrow;
443 //=======================================================================
444 // name : SetSimplePrsParams
446 //=======================================================================
447 void MeshVS_VectorPrsBuilder::SetSimplePrsParams( const Standard_Real theLineWidthParam,
448 const Standard_Real theStartParam,
449 const Standard_Real theEndParam )
451 mySimpleWidthPrm = theLineWidthParam;
452 mySimpleStartPrm = theStartParam;
453 mySimpleEndPrm = theEndParam;