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