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 <Aspect_TypeOfLine.hxx>
19 #include <gp_Trsf.hxx>
21 #include <Graphic3d_ArrayOfPolygons.hxx>
22 #include <Graphic3d_ArrayOfPolylines.hxx>
23 #include <Graphic3d_ArrayOfPrimitives.hxx>
24 #include <Graphic3d_ArrayOfSegments.hxx>
25 #include <Graphic3d_ArrayOfTriangleFans.hxx>
26 #include <Graphic3d_ArrayOfTriangles.hxx>
27 #include <Graphic3d_AspectFillArea3d.hxx>
28 #include <Graphic3d_AspectLine3d.hxx>
29 #include <Graphic3d_Group.hxx>
30 #include <Graphic3d_MaterialAspect.hxx>
31 #include <MeshVS_Buffer.hxx>
32 #include <MeshVS_DataMapIteratorOfDataMapOfIntegerVector.hxx>
33 #include <MeshVS_DataSource.hxx>
34 #include <MeshVS_DisplayModeFlags.hxx>
35 #include <MeshVS_Drawer.hxx>
36 #include <MeshVS_DrawerAttribute.hxx>
37 #include <MeshVS_EntityType.hxx>
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>
50 IMPLEMENT_STANDARD_RTTIEXT(MeshVS_VectorPrsBuilder,MeshVS_PrsBuilder)
52 //================================================================
53 // Function : Constructor MeshVS_VectorPrsBuilder
55 //================================================================
56 MeshVS_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 ),
65 myIsSimplePrs( IsSimplePrs ),
66 mySimpleWidthPrm( 2.5 ),
67 mySimpleStartPrm( 0.85 ),
68 mySimpleEndPrm( 0.95 )
70 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
71 if ( !aDrawer.IsNull() )
73 aDrawer->SetDouble ( MeshVS_DA_VectorMaxLength, MaxLength );
74 aDrawer->SetColor ( MeshVS_DA_VectorColor, VectorColor );
75 aDrawer->SetDouble ( MeshVS_DA_VectorArrowPart, 0.1 );
79 //================================================================
80 // Function : GetVectors
82 //================================================================
83 const MeshVS_DataMapOfIntegerVector& MeshVS_VectorPrsBuilder::GetVectors
84 ( const Standard_Boolean IsElements ) const
87 return myElemVectorMap;
89 return myNodeVectorMap;
92 //================================================================
93 // Function : SetVectors
95 //================================================================
96 void MeshVS_VectorPrsBuilder::SetVectors ( const Standard_Boolean IsElements,
97 const MeshVS_DataMapOfIntegerVector& theMap )
100 myElemVectorMap = theMap;
102 myNodeVectorMap = theMap;
105 //================================================================
106 // Function : HasVectors
108 //================================================================
109 Standard_Boolean MeshVS_VectorPrsBuilder::HasVectors ( const Standard_Boolean IsElement ) const
111 Standard_Boolean aRes = (myNodeVectorMap.Extent()>0);
113 aRes = (myElemVectorMap.Extent()>0);
118 //================================================================
119 // Function : GetVector
121 //================================================================
122 Standard_Boolean MeshVS_VectorPrsBuilder::GetVector ( const Standard_Boolean IsElement,
123 const Standard_Integer ID,
126 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
128 aMap = &myElemVectorMap;
130 Standard_Boolean aRes = aMap->IsBound ( ID );
132 Vect = aMap->Find ( ID );
137 //================================================================
138 // Function : SetVector
140 //================================================================
141 void MeshVS_VectorPrsBuilder::SetVector ( const Standard_Boolean IsElement,
142 const Standard_Integer ID,
145 MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
147 aMap = &myElemVectorMap;
149 Standard_Boolean aRes = aMap->IsBound ( ID );
151 aMap->ChangeFind ( ID ) = Vect;
153 aMap->Bind ( ID, Vect );
156 //================================================================
157 // Function : GetMaxVectorValue
159 //================================================================
160 void MeshVS_VectorPrsBuilder::GetMinMaxVectorValue ( const Standard_Boolean IsElement,
161 Standard_Real& MinValue,
162 Standard_Real& MaxValue ) const
164 const MeshVS_DataMapOfIntegerVector* aMap = &myNodeVectorMap;
166 aMap = &myElemVectorMap;
168 MeshVS_DataMapIteratorOfDataMapOfIntegerVector anIt ( *aMap );
170 MinValue = MaxValue = anIt.Value().Magnitude();
172 Standard_Real aCurValue;
174 for ( ; anIt.More(); anIt.Next() )
176 aCurValue = anIt.Value().Magnitude();
177 if ( MinValue > aCurValue )
178 MinValue = aCurValue;
179 if ( MaxValue < aCurValue )
180 MaxValue = aCurValue;
184 //================================================================
187 //================================================================
189 #define NB_VERTICES 2
191 #define NB_TRIANGLES 6
194 void 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
200 Handle ( MeshVS_Drawer ) aDrawer = GetDrawer();
201 Handle (MeshVS_DataSource) aSource = GetDataSource();
202 if ( aSource.IsNull() || aDrawer.IsNull() || !HasVectors( IsElement ) ||
203 ( theDisplayMode & GetFlags() )==0 )
206 Standard_Integer aMaxFaceNodes;
207 Standard_Real aMaxLen, anArrowPart = 0.1;
209 if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) ||
210 aMaxFaceNodes <= 0 ||
211 !aDrawer->GetDouble ( MeshVS_DA_VectorMaxLength, aMaxLen ) ||
213 !aDrawer->GetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart ) ||
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;
223 // DECLARE ARRAYS OF PRIMITIVES
224 const MeshVS_DataMapOfIntegerVector& aMap = GetVectors ( IsElement );
225 Standard_Integer aNbVectors = aMap.Extent();
227 if ( aNbVectors <= 0 )
231 Standard_Integer aNbVertices = aNbVectors * NB_VERTICES;
233 Handle(Graphic3d_ArrayOfPrimitives) aLineArray = new Graphic3d_ArrayOfSegments (aNbVertices);
234 Handle(Graphic3d_ArrayOfPrimitives) aArrowLineArray = new Graphic3d_ArrayOfSegments (aNbVertices);
236 Handle(Graphic3d_ArrayOfPrimitives) aTriangleArray = new Graphic3d_ArrayOfSegments (
237 aNbVectors * 8 /* vertices per arrow */, aNbVectors * 12 /* segments per arrow */ * 2 /* indices per segment */);
239 TColgp_Array1OfPnt anArrowPnt(1,8);
240 Standard_Real k, b, aMaxValue, aMinValue, aValue, X, Y, Z;
242 Standard_Real aMinLength = calculateArrow( anArrowPnt, aMaxLen, anArrowPart );
243 gp_Vec aVec; gp_Trsf aTrsf;
245 GetMinMaxVectorValue ( IsElement, aMinValue, aMaxValue );
247 if ( aMaxValue - aMinValue > Precision::Confusion() )
249 k = 0.8 * aMaxLen / ( aMaxValue - aMinValue );
250 b = aMaxLen - k * aMaxValue;
258 TColStd_PackedMapOfInteger aCustomElements;
260 // subtract the hidden elements and ids to exclude (to minimize allocated memory)
261 TColStd_PackedMapOfInteger anIDs;
265 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
266 if ( !aHiddenElems.IsNull() )
267 anIDs.Subtract( aHiddenElems->Map() );
269 anIDs.Subtract( IDsToExclude );
271 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
272 for( ; it.More(); it.Next() )
274 Standard_Integer aKey = it.Key();
275 if( GetVector ( IsElement, aKey, aVec ) )
277 aValue = aVec.Magnitude();
279 if ( Abs( aValue ) < Precision::Confusion() )
282 if( aSource->GetGeom ( aKey, IsElement, aCoords, NbNodes, aType ) )
284 if( aType == MeshVS_ET_Node )
290 else if( aType == MeshVS_ET_Link ||
291 aType == MeshVS_ET_Face ||
292 aType == MeshVS_ET_Volume )
294 if( IsElement && IsExcludingOn() )
295 IDsToExclude.Add( aKey );
297 for ( Standard_Integer i=1; i<=NbNodes; i++ )
299 X += aCoords (3*i-2);
300 Y += aCoords (3*i-1);
303 X /= Standard_Real ( NbNodes );
304 Y /= Standard_Real ( NbNodes );
305 Z /= Standard_Real ( NbNodes );
309 aCustomElements.Add( aKey );
313 aTrsf.SetDisplacement ( gp_Ax3 ( gp_Pnt ( 0, 0, 0 ), gp_Dir(0, 0, 1)),
314 gp_Ax3 ( gp_Pnt ( X, Y, Z ), aVec ) );
316 DrawVector ( aTrsf, Max( k * fabs( aValue ) + b, aMinLength), aMaxLen,
317 anArrowPnt, aLineArray, aArrowLineArray, aTriangleArray );
322 Prs3d_Root::NewGroup ( Prs );
323 Handle (Graphic3d_Group) aVGroup = Prs3d_Root::CurrentGroup ( Prs );
325 Quantity_Color aColor;
326 aDrawer->GetColor ( MeshVS_DA_VectorColor, aColor );
328 // Add primitive arrays to group
329 Handle(Graphic3d_AspectLine3d) aLinAspect =
330 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, 1.5 );
332 aVGroup->SetPrimitivesAspect( aLinAspect );
333 aVGroup->AddPrimitiveArray( aLineArray );
335 if ( !myIsSimplePrs )
337 Handle(Graphic3d_AspectLine3d) anArrowLinAspect =
338 new Graphic3d_AspectLine3d (aColor, Aspect_TOL_SOLID, mySimpleWidthPrm);
340 aVGroup->SetPrimitivesAspect( anArrowLinAspect );
341 aVGroup->AddPrimitiveArray( aTriangleArray );
345 Handle(Graphic3d_AspectLine3d) anArrowLinAspect =
346 new Graphic3d_AspectLine3d ( aColor, Aspect_TOL_SOLID, mySimpleWidthPrm * 1.5 );
348 aVGroup->SetPrimitivesAspect( anArrowLinAspect );
349 aVGroup->AddPrimitiveArray( aArrowLineArray );
352 if( !aCustomElements.IsEmpty() )
353 CustomBuild( Prs, aCustomElements, IDsToExclude, theDisplayMode );
356 //=======================================================================
358 // Purpose : Fill arrays of primitives for drawing force
359 //=======================================================================
360 void MeshVS_VectorPrsBuilder::DrawVector ( const gp_Trsf& theTrsf,
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
368 const int PntNum = 8;
370 const Standard_Real aMinLength = theMaxLength * ( 1 - mySimpleStartPrm );
371 const Standard_Real aLocalLength = ( !myIsSimplePrs || theLength > aMinLength ? theLength : aMinLength );
373 gp_Pnt aLinePnt[ 2 ] = { gp_Pnt( 0, 0, 0 ) , gp_Pnt( 0, 0, aLocalLength ) };
374 theTrsf.Transforms (aLinePnt[0].ChangeCoord());
375 theTrsf.Transforms (aLinePnt[1].ChangeCoord());
377 theLines->AddVertex (aLinePnt[0]);
378 theLines->AddVertex (aLinePnt[1]);
383 Standard_Integer aLower = theArrowPoints.Lower(),
384 aUpper = theArrowPoints.Upper();
386 if (aUpper - aLower < PntNum - 1)
389 TColgp_Array1OfPnt anArrowPnt (aLower, aUpper);
390 for (Standard_Integer aPntIdx = aLower; aPntIdx < aLower + PntNum; ++aPntIdx)
392 anArrowPnt (aPntIdx).ChangeCoord() = theArrowPoints (aPntIdx).Coord() + gp_XYZ (0, 0, aLocalLength);
393 theTrsf.Transforms (anArrowPnt (aPntIdx).ChangeCoord());
396 const Standard_Integer aVrtOffset = theTriangles->VertexNumber() + 1;
398 for (Standard_Integer aPntIdx = 0; aPntIdx < PntNum; ++aPntIdx)
400 theTriangles->AddVertex (anArrowPnt (aLower + aPntIdx));
403 for (Standard_Integer aPntIdx = 1; aPntIdx <= PntNum - 2; ++aPntIdx)
405 theTriangles->AddEdge (aVrtOffset);
406 theTriangles->AddEdge (aVrtOffset + aPntIdx);
408 theTriangles->AddEdge (aVrtOffset + aPntIdx);
409 theTriangles->AddEdge (aVrtOffset + aPntIdx + 1);
414 const Standard_Real aEndPos = aLocalLength - theMaxLength * ( 1 - mySimpleEndPrm );
415 const Standard_Real aArrowLength = theMaxLength * ( mySimpleEndPrm - mySimpleStartPrm );
416 gp_Pnt aArrowPnt[ 2 ] = { gp_Pnt( 0, 0, aEndPos - aArrowLength ),
417 gp_Pnt( 0, 0, aEndPos ) };
418 theTrsf.Transforms (aArrowPnt[0].ChangeCoord());
419 theTrsf.Transforms (aArrowPnt[1].ChangeCoord());
421 theArrowLines->AddVertex (aArrowPnt[0]);
422 theArrowLines->AddVertex (aArrowPnt[1]);
426 //=======================================================================
427 // name : calculateArrow
428 // Purpose : Calculate points of arrow ( 8 pnts )
429 //=======================================================================
430 Standard_Real MeshVS_VectorPrsBuilder::calculateArrow ( TColgp_Array1OfPnt& Points,
431 const Standard_Real Length,
432 const Standard_Real ArrowPart )
434 Standard_Real h = Length * ArrowPart;
435 Standard_Real w = h / 5.;
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 );
450 //=======================================================================
451 // name : SetSimplePrsMode
453 //=======================================================================
454 void MeshVS_VectorPrsBuilder::SetSimplePrsMode( const Standard_Boolean IsSimpleArrow )
456 myIsSimplePrs = IsSimpleArrow;
459 //=======================================================================
460 // name : SetSimplePrsParams
462 //=======================================================================
463 void MeshVS_VectorPrsBuilder::SetSimplePrsParams( const Standard_Real theLineWidthParam,
464 const Standard_Real theStartParam,
465 const Standard_Real theEndParam )
467 mySimpleWidthPrm = theLineWidthParam;
468 mySimpleStartPrm = theStartParam;
469 mySimpleEndPrm = theEndParam;