0024171: Eliminate CLang compiler warning -Wreorder
[occt.git] / src / MeshVS / MeshVS_MeshPrsBuilder.cxx
CommitLineData
b311480e 1// Created on: 2003-09-16
2// Created by: Alexander SOLOVYOV
3// Copyright (c) 2003-2012 OPEN CASCADE SAS
4//
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.
9//
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.
12//
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.
19
7fd59977 20
21#include <MeshVS_MeshPrsBuilder.ixx>
22
23#include <Prs3d_Root.hxx>
24#include <Prs3d_ShadingAspect.hxx>
25#include <Prs3d_LineAspect.hxx>
26#include <Prs3d_PointAspect.hxx>
27
28#include <Graphic3d_AspectLine3d.hxx>
29#include <Graphic3d_AspectFillArea3d.hxx>
30#include <Graphic3d_AspectMarker3d.hxx>
31#include <Graphic3d_ArrayOfPolygons.hxx>
b8ddfc2f 32#include <Graphic3d_ArrayOfSegments.hxx>
a577aaab 33#include <Graphic3d_ArrayOfPoints.hxx>
7fd59977 34#include <Graphic3d_ArrayOfPolylines.hxx>
7fd59977 35#include <Graphic3d_Group.hxx>
36
37#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
38#include <TColStd_ListIteratorOfListOfReal.hxx>
39#include <TColStd_MapIntegerHasher.hxx>
40#include <TColStd_Array1OfReal.hxx>
41#include <TColStd_Array1OfInteger.hxx>
42#include <TColStd_SequenceOfInteger.hxx>
43#include <TColStd_PackedMapOfInteger.hxx>
44#include <TColStd_HPackedMapOfInteger.hxx>
45
46#include <Quantity_NameOfColor.hxx>
47#include <Aspect_InteriorStyle.hxx>
48#include <Select3D_SensitivePoint.hxx>
49
50#include <MeshVS_DataSource.hxx>
51#include <MeshVS_Drawer.hxx>
52#include <MeshVS_Mesh.hxx>
53#include <MeshVS_Tool.hxx>
54#include <MeshVS_DrawerAttribute.hxx>
55#include <MeshVS_MapOfTwoNodes.hxx>
56#include <MeshVS_Buffer.hxx>
57
58//================================================================
59// Function : Constructor MeshVS_MeshPrsBuilder
60// Purpose :
61//================================================================
62MeshVS_MeshPrsBuilder::MeshVS_MeshPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
63 const Standard_Integer& DisplayModeMask,
64 const Handle (MeshVS_DataSource)& DS,
65 const Standard_Integer Id,
66 const MeshVS_BuilderPriority& Priority )
67: MeshVS_PrsBuilder ( Parent, DisplayModeMask, DS, Id, Priority )
68{
69}
70
71//================================================================
72// Function : Build
73// Purpose :
74//================================================================
75void MeshVS_MeshPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
76 const TColStd_PackedMapOfInteger& IDs,
77 TColStd_PackedMapOfInteger& IDsToExclude,
78 const Standard_Boolean IsElement,
79 const Standard_Integer DisplayMode ) const
80{
81 if ( DisplayMode <= 0 )
82 return;
83
84 Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 );
85 Standard_Integer Extent = IDs.Extent();
86
87 if ( HasHilightFlag && Extent == 1)
88 BuildHilightPrs ( Prs, IDs, IsElement );
89 else if ( IsElement )
90 BuildElements ( Prs, IDs, IDsToExclude, DisplayMode );
91 else
92 BuildNodes ( Prs, IDs, IDsToExclude, DisplayMode );
93}
94
95//================================================================
96// Function : BuildNodes
97// Purpose :
98//================================================================
99void MeshVS_MeshPrsBuilder::BuildNodes ( const Handle(Prs3d_Presentation)& Prs,
100 const TColStd_PackedMapOfInteger& IDs,
101 TColStd_PackedMapOfInteger& IDsToExclude,
102 const Standard_Integer DisplayMode ) const
103{
104 Handle( MeshVS_DataSource ) aSource = GetDataSource();
105 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
106 Handle (Graphic3d_AspectMarker3d) aNodeMark =
107 MeshVS_Tool::CreateAspectMarker3d( GetDrawer() );
108 if ( aSource.IsNull() || aDrawer.IsNull() || aNodeMark.IsNull() )
109 return;
110
111 Standard_Boolean DisplayFreeNodes = Standard_True;
112 aDrawer->GetBoolean( MeshVS_DA_DisplayNodes, DisplayFreeNodes );
113 Standard_Boolean HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 );
114 Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 );
115
116 Standard_Real aCoordsBuf[ 3 ];
117 TColStd_Array1OfReal aCoords( *aCoordsBuf, 1, 3 );
118 Standard_Integer NbNodes;
119 MeshVS_EntityType aType;
120
121 if ( !DisplayFreeNodes )
122 return;
123
124 TColStd_PackedMapOfInteger anIDs;
125 anIDs.Assign( IDs );
126 if ( !HasSelectFlag && !HasHilightFlag )
127 {
128 // subtract the hidden nodes and ids to exclude (to minimise allocated memory)
129 Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = myParentMesh->GetHiddenNodes();
130 if ( !aHiddenNodes.IsNull() )
131 anIDs.Subtract( aHiddenNodes->Map() );
132 }
133 anIDs.Subtract( IDsToExclude );
134
135 Standard_Integer upper = anIDs.Extent();
136 if ( upper<=0 )
137 return;
138
a577aaab 139 Handle(Graphic3d_ArrayOfPoints) aNodePoints = new Graphic3d_ArrayOfPoints (upper);
7fd59977 140 Standard_Integer k=0;
141 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
142 for( ; it.More(); it.Next() )
143 {
144 Standard_Integer aKey = it.Key();
145 if ( aSource->GetGeom ( aKey, Standard_False, aCoords, NbNodes, aType ) )
146 {
147 if ( IsExcludingOn() )
148 IDsToExclude.Add (aKey);
a577aaab 149 k++;
150 aNodePoints->AddVertex (aCoords(1), aCoords(2), aCoords(3));
7fd59977 151 }
152 }
153
154 if ( k>0 )
155 {
156 Prs3d_Root::NewGroup ( Prs );
157 Handle (Graphic3d_Group) aNodeGroup = Prs3d_Root::CurrentGroup ( Prs );
158 aNodeGroup->SetPrimitivesAspect ( aNodeMark );
a577aaab 159 aNodeGroup->AddPrimitiveArray (aNodePoints);
7fd59977 160 }
161}
162
163//================================================================
164// Function : BuildElements
165// Purpose :
166//================================================================
167void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs,
168 const TColStd_PackedMapOfInteger& IDs,
169 TColStd_PackedMapOfInteger& IDsToExclude,
170 const Standard_Integer DisplayMode ) const
171{
172 Standard_Integer maxnodes;
173
174 Handle (MeshVS_DataSource) aSource = GetDataSource();
175 if ( aSource.IsNull() )
176 return;
177
178 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
179 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
180 maxnodes <= 0 )
181 return;
182
183 //----------- extract useful display mode flags ----------
184 Standard_Integer aDispMode = ( DisplayMode & GetFlags() );
185 if ( ( aDispMode & MeshVS_DMF_DeformedMask) != 0 )
186 {
187 aDispMode /= MeshVS_DMF_DeformedPrsWireFrame;
188 // This transformation turns deformed mesh flags to real display modes
189 }
190 aDispMode &= MeshVS_DMF_OCCMask;
191 //--------------------------------------------------------
192
193 Standard_Real aShrinkCoef;
194 aDrawer->GetDouble ( MeshVS_DA_ShrinkCoeff, aShrinkCoef );
195
196 Standard_Boolean IsWireFrame = ( aDispMode==MeshVS_DMF_WireFrame ),
197 IsShading = ( aDispMode==MeshVS_DMF_Shading ),
198 IsShrink = ( aDispMode==MeshVS_DMF_Shrink ),
199 HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 ),
200 HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 ),
201 IsMeshReflect, IsMeshAllowOverlap, IsReflect, IsMeshSmoothShading = Standard_False;
202
203 aDrawer->GetBoolean ( MeshVS_DA_Reflection, IsMeshReflect );
204 aDrawer->GetBoolean ( MeshVS_DA_IsAllowOverlapped, IsMeshAllowOverlap );
205 IsReflect = ( IsMeshReflect && !HasHilightFlag );
206 aDrawer->GetBoolean ( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
207
208 // display mode for hilighted prs of groups
209 IsShrink = ( IsShrink && !HasHilightFlag );
210 IsShading = ( IsShading || HasHilightFlag );
211
212 //---------- Creating AspectFillArea3d and AspectLine3d -------------
213 Graphic3d_MaterialAspect AMat;
214 aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat );
215 if ( !IsReflect )
216 {
217 AMat.SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
218 AMat.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
219 AMat.SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
220 AMat.SetReflectionModeOff(Graphic3d_TOR_EMISSION);
221 }
222 Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat );
223 Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d ( GetDrawer() );
224 //-------------------------------------------------------------------
225
226 Standard_Boolean IsOverlapControl =
227 !IsMeshAllowOverlap && ( IsWireFrame || IsShading ) && !HasSelectFlag;
228
229 Handle (Graphic3d_ArrayOfPolygons) aPolygons, aVolumes;
230 Handle (Graphic3d_ArrayOfPolylines) aPolylines, aLinkPolylines;
231
232 Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0,
233 PolylineVerticesFor3D = 0, PolylineBoundsFor3D = 0,
234 NbNodes;
235
236 // subtract the hidden elements and ids to exclude (to minimise allocated memory)
237 TColStd_PackedMapOfInteger anIDs;
238 anIDs.Assign( IDs );
239 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
240 if ( !aHiddenElems.IsNull() )
241 anIDs.Subtract( aHiddenElems->Map() );
242 anIDs.Subtract( IDsToExclude );
243
244 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
245 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
246 for( ; it.More(); it.Next() )
247 {
248 Standard_Integer aKey = it.Key();
249 if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
250 {
251 if( !HasSelectFlag )
252 HowManyPrimitives( aTopo, Standard_True, HasSelectFlag, NbNodes,
253 PolygonVerticesFor3D, PolygonBoundsFor3D );
254 HowManyPrimitives( aTopo, Standard_False, HasSelectFlag, NbNodes,
255 PolylineVerticesFor3D, PolylineBoundsFor3D );
256 }
257 }
258
259 Standard_Integer Extent = anIDs.Extent();
260
261 if ( IsReflect )
262 {
263 aPolygons = new Graphic3d_ArrayOfPolygons
264 ( maxnodes*Extent, Extent, 0, Standard_True );
265 aVolumes = new Graphic3d_ArrayOfPolygons
266 ( PolygonVerticesFor3D, PolygonBoundsFor3D, 0, Standard_True );
267 }
268 else
269 {
270 aPolygons = new Graphic3d_ArrayOfPolygons( maxnodes*Extent, Extent );
271 aVolumes = new Graphic3d_ArrayOfPolygons ( PolygonVerticesFor3D, PolygonBoundsFor3D );
272 }
273
274 Standard_Integer howMany = 1;
275 if ( IsOverlapControl )
276 howMany = 2;
277
278 Standard_Boolean showEdges = Standard_True;
279 aDrawer->GetBoolean( MeshVS_DA_ShowEdges, showEdges );
280
281 showEdges = IsWireFrame || showEdges;
282 if ( showEdges )
283 {
284 aPolylines = new Graphic3d_ArrayOfPolylines ( ( maxnodes+1 )*Extent + PolylineVerticesFor3D,
285 howMany * Extent + PolylineBoundsFor3D );
286 aLinkPolylines = new Graphic3d_ArrayOfPolylines ( 2*Extent, Extent );
287 }
288
289 MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real));
290 TColStd_Array1OfReal aCoords( aCoordsBuf, 1, 3*maxnodes );
291 MeshVS_EntityType aType;
292
293 TColStd_PackedMapOfInteger aCustomElements;
294
295 Quantity_Color anOldEdgeColor;
296 Aspect_InteriorStyle anIntType;
297 Quantity_Color anIntColor, anEdgeColor;
298 Aspect_TypeOfLine aLine;
299 Standard_Real aWidth;
300
301 MeshVS_TwoNodes aTwoNodes;
302 aFill->Values ( anIntType, anIntColor, anEdgeColor, aLine, aWidth );
303
304 MeshVS_MapOfTwoNodes aLinkNodes;
305 if ( showEdges && IsOverlapControl )
306 // Forbid drawings of edges, which overlap with some links
307 for( it.Reset(); it.More(); it.Next() )
308 {
309 Standard_Integer aKey = it.Key();
310 if ( aSource->GetGeomType ( aKey, Standard_True, aType ) &&
311 aType == MeshVS_ET_Link )
312 {
313 MeshVS_Buffer aNodesBuf (maxnodes * sizeof(Standard_Integer));
314 TColStd_Array1OfInteger aNodes (aNodesBuf, 1, maxnodes);
315 Standard_Integer nbNodes;
316 if ( aSource->GetNodesByElement( aKey, aNodes, nbNodes ) &&
317 nbNodes == 2 )
318 {
319 aTwoNodes.First = aNodes(1);
320 aTwoNodes.Second = aNodes(2);
321 aLinkNodes.Add ( aTwoNodes );
322 }
323 }
324 }
325
326 for( it.Reset(); it.More(); it.Next() )
327 {
328 Standard_Integer aKey = it.Key();
329
330 if ( ! aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) )
331 continue;
332
333 switch ( aType )
334 {
335 case MeshVS_ET_Volume :
336 if( IsExcludingOn() )
337 IDsToExclude.Add (aKey);
338 if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
339 {
340 // !!! TO DO: Overlap control
341 // add wireframe presentation (draw edges for shading mode as well)
342 if ( showEdges )
343 AddVolumePrs ( aTopo, aCoords, NbNodes, aPolylines, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
344
345 // add shading presentation
346 if ( ( IsShading || IsShrink ) && !HasSelectFlag )
347 AddVolumePrs ( aTopo, aCoords, NbNodes, aVolumes, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
7fd59977 348 }
349 break;
350
351 case MeshVS_ET_Link :
352 if( IsExcludingOn() )
353 IDsToExclude.Add (aKey);
354 if ( showEdges )
355 AddLinkPrs ( aCoords, aLinkPolylines, IsShrink || HasSelectFlag, aShrinkCoef );
356 break;
357
358 case MeshVS_ET_Face :
359 if( IsExcludingOn() )
360 IDsToExclude.Add (aKey);
361 if ( showEdges && IsOverlapControl )
362 {
363 MeshVS_Buffer aNodesBuf (NbNodes * sizeof(Standard_Integer));
364 TColStd_Array1OfInteger aNodes (aNodesBuf, 1, NbNodes);
365 if ( !aSource->GetNodesByElement( aKey, aNodes, NbNodes ) )
366 continue;
367
368 Standard_Integer Last = 0;
369 for ( Standard_Integer i=1; i<=NbNodes; i++ )
370 {
371 if ( i==1 )
372 aTwoNodes.First = aNodes(i);
373 else
374 aTwoNodes.First = aTwoNodes.Second;
375
376 aTwoNodes.Second = ( i<NbNodes ? aNodes(i+1) : aNodes(1) );
377 if ( aLinkNodes.Contains ( aTwoNodes ) )
378 {
379 aPolylines->AddBound ( i-Last );
380 for (Standard_Integer j = Last+1; j<=i; j++)
381 aPolylines->AddVertex ( aCoords(3*j-2), aCoords(3*j-1), aCoords(3*j) );
382 Last = i;
383 }
384 }
385 if ( NbNodes-Last > 0 )
386 {
387 aPolylines->AddBound ( NbNodes-Last+1 );
388 for (Standard_Integer j = Last+1; j<=NbNodes; j++)
389 aPolylines->AddVertex ( aCoords(3*j-2), aCoords(3*j-1), aCoords(3*j) );
390
391 aPolylines->AddVertex ( aCoords(1), aCoords(2), aCoords(3) );
392 }
393 }
394
395 if ( !IsOverlapControl || IsShading )
396 {
397 if ( !IsOverlapControl && showEdges )
398 AddFaceWirePrs(aCoords, NbNodes, aPolylines,
399 IsShrink || HasSelectFlag, aShrinkCoef );
400 if ( ( IsShading || IsShrink ) && !HasSelectFlag )
401 AddFaceSolidPrs(aKey, aCoords, NbNodes, maxnodes, aPolygons,
402 IsReflect, IsShrink || HasSelectFlag,
403 aShrinkCoef, IsMeshSmoothShading );
404 }
405 break;
406
407 default:
408 aCustomElements.Add( aKey );
409 break;
410 }
411 }
412
413 if ( IsShrink )
414 {
415 anOldEdgeColor = anEdgeColor;
416 aFill->SetEdgeColor ( Quantity_NOC_BLACK );
417 }
418
419 DrawArrays ( Prs, aPolygons, aPolylines, aLinkPolylines, aVolumes,
420 !showEdges, HasSelectFlag, aFill, aBeam );
421
422 if ( !aCustomElements.IsEmpty() )
423 CustomBuild ( Prs, aCustomElements, IDsToExclude, DisplayMode );
424
425 if( IsShrink )
426 aFill->SetEdgeColor( anOldEdgeColor );
427}
428
429//================================================================
430// Function : BuildHilightPrs
431// Purpose :
432//================================================================
433void MeshVS_MeshPrsBuilder::BuildHilightPrs ( const Handle(Prs3d_Presentation)& Prs,
434 const TColStd_PackedMapOfInteger& IDs,
435 const Standard_Boolean IsElement ) const
436{
437 Standard_Integer maxnodes;
438
439 Handle (MeshVS_DataSource) aSource = GetDataSource();
440 if ( aSource.IsNull() || IDs.IsEmpty() )
441 return;
442
443 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
444 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
445 maxnodes <= 0 )
446 return;
447
448 MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real));
449 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*maxnodes);
450
451 Graphic3d_MaterialAspect AMat;
452 aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat );
453 AMat.SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
454 AMat.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
455 AMat.SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
456 AMat.SetReflectionModeOff(Graphic3d_TOR_EMISSION);
457
458 Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat );
459 Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d( GetDrawer() );
460 Handle( Graphic3d_AspectMarker3d ) aNodeMark = MeshVS_Tool::CreateAspectMarker3d( GetDrawer() );
461
462 // Hilight one element or node
463 TColStd_MapIteratorOfPackedMapOfInteger it (IDs);
464 Standard_Integer ID = it.Key(), NbNodes;
465 MeshVS_EntityType aType;
466
467 if ( !aSource->GetGeom ( ID, IsElement, aCoords, NbNodes, aType ) )
468 return;
469
470 Prs3d_Root::NewGroup ( Prs );
471 Handle (Graphic3d_Group) aHilightGroup = Prs3d_Root::CurrentGroup ( Prs );
472
473 switch ( aType )
474 {
475 case MeshVS_ET_Node :
476 {
a577aaab 477 aHilightGroup->SetPrimitivesAspect (aNodeMark);
478 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
479 anArrayOfPoints->AddVertex (aCoords(1), aCoords(2), aCoords(3));
480 aHilightGroup->AddPrimitiveArray (anArrayOfPoints);
7fd59977 481 }
482 break;
483
484 case MeshVS_ET_Link:
485 {
486 aHilightGroup->SetPrimitivesAspect ( aBeam );
b8ddfc2f 487 Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
488 aPrims->AddVertex(aCoords(1),aCoords(2),aCoords(3));
489 aPrims->AddVertex(aCoords(4),aCoords(5),aCoords(6));
490 aHilightGroup->AddPrimitiveArray(aPrims);
7fd59977 491 }
492 break;
493
494 case MeshVS_ET_Face:
495 if ( NbNodes > 0 )
496 {
7fd59977 497 aHilightGroup->SetPrimitivesAspect ( aFill );
b8ddfc2f 498 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(NbNodes);
7fd59977 499 for ( Standard_Integer k=1; k<=NbNodes; k++)
b8ddfc2f 500 aPrims->AddVertex(aCoords(3*k-2),aCoords(3*k-1),aCoords(3*k));
501 aHilightGroup->AddPrimitiveArray(aPrims);
7fd59977 502 }
503 break;
504
505 case MeshVS_ET_Volume:
506 if( NbNodes > 0 )
507 {
508 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
509
510 aHilightGroup->SetPrimitivesAspect ( aFill );
511
512 if( aSource->Get3DGeom( ID, NbNodes, aTopo ) )
513 {
b8ddfc2f 514 const Standard_Integer up = aTopo->Upper();
515 const Standard_Integer lo = aTopo->Lower();
516 Standard_Integer nbnodes = 0, i, j;
517 for( i=lo; i<=up; i++ )
518 nbnodes += aTopo->Value( i ).Length();
519
520 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(nbnodes,aTopo->Length());
521 for( i=lo; i<=up; i++ )
7fd59977 522 {
523 const TColStd_SequenceOfInteger& aSeq = aTopo->Value( i );
b8ddfc2f 524 const Standard_Integer m = aSeq.Length();
525 aPrims->AddBound(m);
7fd59977 526 for( j=1; j<=m; j++ )
527 {
b8ddfc2f 528 const Standard_Integer ind = 3*aSeq.Value( j );
529 aPrims->AddVertex(aCoords(ind+1),aCoords(ind+2),aCoords(ind+3));
7fd59977 530 }
7fd59977 531 }
b8ddfc2f 532 aHilightGroup->AddPrimitiveArray(aPrims);
7fd59977 533 }
534 }
535 break;
536
537 default:
538 {
539 TColStd_PackedMapOfInteger tmp;
540 CustomBuild ( Prs, IDs, tmp, MeshVS_DMF_HilightPrs );
541 }
542 break;
543 }
544}
545
546//================================================================
547// Function : AddLinkPrs
548// Purpose :
549//================================================================
550void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
551 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
552 const Standard_Boolean IsShrinked,
553 const Standard_Real ShrinkCoef) const
554{
555 Standard_Real x1 = theCoords(1);
556 Standard_Real y1 = theCoords(2);
557 Standard_Real z1 = theCoords(3);
558 Standard_Real x2 = theCoords(4);
559 Standard_Real y2 = theCoords(5);
560 Standard_Real z2 = theCoords(6);
561 Standard_Real xG, yG, zG;
562
563 if ( IsShrinked )
564 {
565 xG = (x1+x2)/2.0;
566 yG = (y1+y2)/2.0;
567 zG = (z1+z2)/2.0;
568 x1 = (x1 - xG) * ShrinkCoef + xG;
569 x2 = 2.0*xG - x1;
570 y1 = (y1 - yG) * ShrinkCoef + yG;
571 y2 = 2.0*yG - y1;
572 z1 = (z1 - zG) * ShrinkCoef + zG;
573 z2 = 2.0*zG - z1;
574 }
575 theLines->AddBound ( 2 );
576 theLines->AddVertex ( x1, y1, z1 );
577 theLines->AddVertex ( x2, y2, z2 );
578}
579
580//================================================================
581// Function : AddFaceWirePrs
582// Purpose :
583//================================================================
584void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal& theCoords,
585 const Standard_Integer NbNodes,
586 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
587 const Standard_Boolean IsShrinked,
588 const Standard_Real ShrinkCoef) const
589{
1d47d8d0 590 Standard_Real xG = 0., yG = 0., zG = 0., X, Y, Z, startX=0., startY=0., startZ=0.;
7fd59977 591 theLines->AddBound ( NbNodes+1 );
592 if ( IsShrinked )
593 CalculateCenter( theCoords, NbNodes, xG, yG, zG );
594
595 for ( Standard_Integer k=1; k<=NbNodes; k++)
596 {
597 X = theCoords(3*k-2);
598 Y = theCoords(3*k-1);
599 Z = theCoords(3*k);
600 if ( IsShrinked )
601 {
602 X = (X - xG) * ShrinkCoef + xG;
603 Y = (Y - yG) * ShrinkCoef + yG;
604 Z = (Z - zG) * ShrinkCoef + zG;
605 }
606 if( k==1 )
607 {
608 startX = X; startY = Y; startZ = Z;
609 }
610 theLines->AddVertex ( X, Y, Z );
611 }
612 theLines->AddVertex( startX, startY, startZ );
613}
614
615//================================================================
616// Function : AddFaceSolidPrs
617// Purpose :
618//================================================================
619void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer ID,
620 const TColStd_Array1OfReal& theCoords,
621 const Standard_Integer NbNodes,
622 const Standard_Integer MaxNodes,
623 const Handle(Graphic3d_ArrayOfPolygons)& thePolygons,
624 const Standard_Boolean IsReflected,
625 const Standard_Boolean IsShrinked,
626 const Standard_Real ShrinkCoef,
627 const Standard_Boolean IsMeshSmoothShading) const
628{
629 Handle( MeshVS_DataSource ) aDS = myParentMesh->GetDataSource();
630 if ( aDS.IsNull() )
631 return;
632
1d47d8d0 633 Standard_Real xG = 0., yG = 0., zG = 0., X, Y, Z, nx = 0., ny = 0., nz = 0.;
7fd59977 634 thePolygons->AddBound ( NbNodes );
635 if ( IsShrinked )
636 CalculateCenter( theCoords, NbNodes, xG, yG, zG );
637
638 Standard_Boolean allNormals = Standard_True;
639 Standard_Integer k;
640
641 if( IsReflected )
642 {
643 if( IsMeshSmoothShading )
644 for( k=1; k<=NbNodes && allNormals; k++ )
645 allNormals = aDS->GetNodeNormal (k, ID, nx, ny, nz);
646 if( !IsMeshSmoothShading || !allNormals )
647 aDS->GetNormal( ID, MaxNodes, nx, ny, nz );
648 }
649
650 for ( k=1; k<=NbNodes; k++)
651 {
652 X = theCoords(3*k-2);
653 Y = theCoords(3*k-1);
654 Z = theCoords(3*k);
655 if ( IsShrinked )
656 {
657 X = (X - xG) * ShrinkCoef + xG;
658 Y = (Y - yG) * ShrinkCoef + yG;
659 Z = (Z - zG) * ShrinkCoef + zG;
660 }
661
662 if ( IsReflected )
663 {
664 if( IsMeshSmoothShading && allNormals )
665 aDS->GetNodeNormal (k, ID, nx, ny, nz);
666 thePolygons->AddVertex ( X, Y, Z, nx, ny, nz );
667 }
668 else
669 thePolygons->AddVertex ( X, Y, Z );
670 }
671}
672
673//================================================================
674// Function : AddVolumePrs
675// Purpose :
676//================================================================
677void MeshVS_MeshPrsBuilder::AddVolumePrs (const Handle( MeshVS_HArray1OfSequenceOfInteger )& Topo,
678 const TColStd_Array1OfReal& Nodes,
679 const Standard_Integer NbNodes,
680 const Handle( Graphic3d_ArrayOfPrimitives )& Array,
681 const Standard_Boolean IsReflected,
682 const Standard_Boolean IsShrinked,
683 const Standard_Boolean IsSelect,
684 const Standard_Real ShrinkCoef)
685{
686 Standard_Real c[3]; c[0] = c[1] = c[2] = 0.0;
687 Standard_Integer low = Nodes.Lower(), n=NbNodes;
688
689 if( Topo.IsNull() || Array.IsNull() )
690 return;
691
692 if( IsShrinked )
693 {
694 for( Standard_Integer i=0; i<3*n; i++ )
695 c[i%3] += Nodes.Value( low + i );
696
697 c[0] /= n;
698 c[1] /= n;
699 c[2] /= n;
700 }
701
702 Standard_Boolean IsPolygons = Array->IsKind( STANDARD_TYPE( Graphic3d_ArrayOfPolygons ) );
703 Standard_Real x[2], y[2], z[2];
704 Standard_Integer ind;
705 gp_Vec norm;
706
707 if( IsPolygons )
708 {
709 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
710 {
711 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
712
713 Standard_Integer m = aSeq.Length();
714 Array->AddBound( m );
715
716 norm.SetCoord( 0, 0, 0 );
717 if( IsReflected )
718 {
719 MeshVS_Buffer PolyNodesBuf (3*m*sizeof(Standard_Real));
720 TColStd_Array1OfReal PolyNodes( PolyNodesBuf, 0, 3*m );
721 PolyNodes.SetValue( 0, m );
722 for( Standard_Integer j=1; j<=m; j++ )
723 {
724 ind = aSeq.Value( j );
725 PolyNodes.SetValue( 3*j-2, Nodes.Value( low+3*ind ) );
726 PolyNodes.SetValue( 3*j-1, Nodes.Value( low+3*ind+1 ) );
727 PolyNodes.SetValue( 3*j, Nodes.Value( low+3*ind+2 ) );
728 }
729
730 // compute normal
731 // if( !MeshVS_Tool::GetNormal( PolyNodes, norm ) )
732 // norm.SetCoord( 0, 0, 0 );
733 MeshVS_Tool::GetAverageNormal( PolyNodes, norm );
734 }
735
736 Standard_Real nx = norm.X(), ny = norm.Y(), nz = norm.Z();
737
738
739 for( Standard_Integer j=1; j<=m; j++ )
740 {
741 ind = aSeq.Value( j );
742 x[0] = Nodes.Value( low + 3*ind );
743 y[0] = Nodes.Value( low + 3*ind+1 );
744 z[0] = Nodes.Value( low + 3*ind+2 );
745
746 if( IsShrinked )
747 {
748 x[0] = c[0] + ShrinkCoef * ( x[0]-c[0] );
749 y[0] = c[1] + ShrinkCoef * ( y[0]-c[1] );
750 z[0] = c[2] + ShrinkCoef * ( z[0]-c[2] );
751 }
752
753 if( IsReflected )
754 Array->AddVertex( x[0], y[0], z[0], nx, ny, nz );
755 else
756 Array->AddVertex( x[0], y[0], z[0] );
757 }
758 }
759 }
760 else if( IsSelect )
761 {
762 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
763 {
764 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
765 Standard_Real pc[3]; pc[0] = pc[1] = pc[2] = 0;
766 Standard_Integer j,m;
767 for( j=1, m=aSeq.Length(); j<=m; j++ )
768 {
769 ind = aSeq.Value( j );
770 for( Standard_Integer k=0; k<3; k++ )
771 pc[k] += Nodes.Value( low + 3*ind+k );
772 }
773 pc[0] /= m;
774 pc[1] /= m;
775 pc[2] /= m;
776
777 Array->AddBound( m+1 );
778 for( j=1, m=aSeq.Length(); j<=m+1; j++ )
779 {
780 ind = aSeq.Value( (j-1)%m + 1 );
781 x[0] = Nodes.Value( low + 3*ind );
782 y[0] = Nodes.Value( low + 3*ind+1 );
783 z[0] = Nodes.Value( low + 3*ind+2 );
784 x[0] = pc[0] + ShrinkCoef * ( x[0]-pc[0] );
785 y[0] = pc[1] + ShrinkCoef * ( y[0]-pc[1] );
786 z[0] = pc[2] + ShrinkCoef * ( z[0]-pc[2] );
787 Array->AddVertex( x[0], y[0], z[0] );
788 }
789 }
790 }
791 else
792 {
793 Standard_Integer F, S=0, k;
794
795 // Find all pairs of nodes (edges) to draw;
796 // map is used to ensure that each edge will be drawn only once
797 TColStd_PackedMapOfInteger aMap;
798 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
799 {
800 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
801 for( Standard_Integer j=1, m=aSeq.Length(); j<=m; j++ )
802 {
803 if( j==1 )
804 F = aSeq.Value( j );
805 else
806 F = S;
807
808 S = j<m ? aSeq.Value( j+1 ) : aSeq.Value( 1 );
809
810 if( F<S )
811 aMap.Add( F + NbNodes * S );
812 else
813 aMap.Add( S + NbNodes * F );
814 }
815 }
816
817 // draw edges
818 TColStd_MapIteratorOfPackedMapOfInteger anIt( aMap );
819 for( ; anIt.More(); anIt.Next() )
820 {
821 F = low + 3*(anIt.Key()%NbNodes);
822 S = low + 3*(anIt.Key()/NbNodes);
823
824 x[0] = Nodes.Value( F );
825 y[0] = Nodes.Value( F+1 );
826 z[0] = Nodes.Value( F+2 );
827 x[1] = Nodes.Value( S );
828 y[1] = Nodes.Value( S+1 );
829 z[1] = Nodes.Value( S+2 );
830
831 if( IsShrinked )
832 for( k=0; k<2; k++ )
833 {
834 x[k] = c[0] + ShrinkCoef * ( x[k]-c[0] );
835 y[k] = c[1] + ShrinkCoef * ( y[k]-c[1] );
836 z[k] = c[2] + ShrinkCoef * ( z[k]-c[2] );
837 }
838
839 Array->AddBound( 2 );
840 Array->AddVertex( x[0], y[0], z[0] );
841 Array->AddVertex( x[1], y[1], z[1] );
842 }
843 }
844}
845
846//================================================================
847// Function : HowManyPrimitives
848// Purpose :
849//================================================================
850void MeshVS_MeshPrsBuilder::HowManyPrimitives (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo,
851 const Standard_Boolean AsPolygons,
852 const Standard_Boolean IsSelect,
853 const Standard_Integer NbNodes,
854 Standard_Integer& Vertices,
855 Standard_Integer& Bounds)
856{
eafb234b 857 if( !Topo.IsNull() ) {
7fd59977 858 if( AsPolygons || IsSelect )
859 {
860 Standard_Integer B = Topo->Upper()-Topo->Lower()+1;
861 Bounds += B;
862 for( Standard_Integer i=Topo->Lower(), n=Topo->Upper(); i<=n; i++ )
863 Vertices += Topo->Value( i ).Length();
864
865 if( IsSelect )
866 Vertices+=B;
867 }
868 else
869 {
870 Standard_Integer F = Topo->Upper()-Topo->Lower()+1,
871 E = NbNodes + F - 2;
872 // number of edges is obtained by Euler's expression for polyhedrons
873
874 Bounds += E;
875 Vertices += 2*E;
876 }
eafb234b 877 }
7fd59977 878}
879
880//================================================================
881// Function : DrawArrays
882// Purpose :
883//================================================================
884void MeshVS_MeshPrsBuilder::DrawArrays( const Handle(Prs3d_Presentation)& Prs,
885 const Handle(Graphic3d_ArrayOfPolygons)& thePolygons,
886 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
887 const Handle(Graphic3d_ArrayOfPolylines)& theLinkLines,
888 const Handle(Graphic3d_ArrayOfPolygons)& theVolumesInShad,
889 const Standard_Boolean IsPolygonsEdgesOff,
890 const Standard_Boolean IsSelected,
891 const Handle(Graphic3d_AspectFillArea3d)& theFillAsp,
892 const Handle(Graphic3d_AspectLine3d)& theLineAsp ) const
893{
894 if ( theFillAsp.IsNull() )
895 return;
896
897 Standard_Boolean IsFacePolygons = ( !thePolygons.IsNull() && thePolygons->ItemNumber() > 0 ),
898 IsVolumePolygons = ( !theVolumesInShad.IsNull() && theVolumesInShad->ItemNumber() > 0 ),
899 IsPolygons = IsFacePolygons || IsVolumePolygons,
900 IsPolylines = ( !theLines.IsNull() && theLines->ItemNumber() > 0 ),
901 IsLinkPolylines = ( !theLinkLines.IsNull() && theLinkLines->ItemNumber() > 0 );
902
903 Aspect_InteriorStyle aStyle;
904 Quantity_Color anIntColor, aBackColor, anEdgeColor;
905 Aspect_TypeOfLine aType;
906 Standard_Real aWidth;
907
908 theFillAsp->Values( aStyle, anIntColor, aBackColor, anEdgeColor, aType, aWidth );
909
910 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()<0.01 )
911 {
912 Prs3d_Root::NewGroup ( Prs );
913 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
914
915 //if ( IsPolygonsEdgesOff )
916 theFillAsp->SetEdgeOff ();
917 //else
918 // theFillAsp->SetEdgeOn ();
919
920 if( anIntColor!=aBackColor )
921 theFillAsp->SetDistinguishOn();
922 else
923 theFillAsp->SetDistinguishOff();
924
925 if( IsFacePolygons )
926 {
927 aGroup->SetPrimitivesAspect ( theFillAsp );
7fd59977 928 aGroup->AddPrimitiveArray ( thePolygons );
7fd59977 929 }
930
931 if( IsVolumePolygons )
932 {
933 Handle( Graphic3d_AspectFillArea3d ) aCullFillAsp =
934 new Graphic3d_AspectFillArea3d( *( theFillAsp.operator->() ) );
935
936 Standard_Boolean isSupressBackFaces = Standard_False;
937 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
938 if (!aDrawer.IsNull())
939 aDrawer->GetBoolean ( MeshVS_DA_SupressBackFaces, isSupressBackFaces );
940
941 if (isSupressBackFaces)
942 aCullFillAsp->SuppressBackFace();
943
944 aGroup->SetPrimitivesAspect ( aCullFillAsp );
7fd59977 945 aGroup->AddPrimitiveArray ( theVolumesInShad );
7fd59977 946 }
947 }
948
949 if ( IsPolylines && !IsPolygonsEdgesOff )
950 {
951 Prs3d_Root::NewGroup ( Prs );
952 Handle (Graphic3d_Group) aLGroup = Prs3d_Root::CurrentGroup ( Prs );
953
954 theFillAsp->SetEdgeOff();
955 if ( IsSelected )
956 aLGroup->SetPrimitivesAspect ( theLineAsp );
957 else
958 {
959 aLGroup->SetPrimitivesAspect ( theFillAsp );
960 aLGroup->SetPrimitivesAspect ( new Graphic3d_AspectLine3d
961 ( anEdgeColor, Aspect_TOL_SOLID, aWidth ) );
962 }
7fd59977 963 aLGroup->AddPrimitiveArray ( theLines );
7fd59977 964 theFillAsp->SetEdgeOn();
965 }
966
967 if ( IsLinkPolylines )
968 {
969 Prs3d_Root::NewGroup ( Prs );
970 Handle (Graphic3d_Group) aBeamGroup = Prs3d_Root::CurrentGroup ( Prs );
971
972 theFillAsp->SetEdgeOff();
973 if ( !IsSelected )
974 aBeamGroup->SetPrimitivesAspect ( theFillAsp );
975 aBeamGroup->SetPrimitivesAspect ( theLineAsp );
7fd59977 976 aBeamGroup->AddPrimitiveArray ( theLinkLines );
7fd59977 977 theFillAsp->SetEdgeOn();
978 }
979
980 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()>=0.01 )
981 {
982 Prs3d_Root::NewGroup ( Prs );
983 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
984
985 //if ( IsPolygonsEdgesOff )
986 theFillAsp->SetEdgeOff ();
987 //else
988 // theFillAsp->SetEdgeOn ();
989
990 if( anIntColor!=aBackColor )
991 theFillAsp->SetDistinguishOn();
992 else
993 theFillAsp->SetDistinguishOff();
994
995 if( IsFacePolygons )
996 {
997 aGroup->SetPrimitivesAspect ( theFillAsp );
7fd59977 998 aGroup->AddPrimitiveArray ( thePolygons );
7fd59977 999 }
1000
1001 if( IsVolumePolygons )
1002 {
1003 Handle( Graphic3d_AspectFillArea3d ) aCullFillAsp =
1004 new Graphic3d_AspectFillArea3d( *( theFillAsp.operator->() ) );
1005
1006 Standard_Boolean isSupressBackFaces = Standard_False;
1007 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
1008 if (!aDrawer.IsNull())
1009 aDrawer->GetBoolean ( MeshVS_DA_SupressBackFaces, isSupressBackFaces );
1010
1011 if (isSupressBackFaces)
1012 aCullFillAsp->SuppressBackFace();
1013
1014 aGroup->SetPrimitivesAspect ( aCullFillAsp );
7fd59977 1015 aGroup->AddPrimitiveArray ( theVolumesInShad );
7fd59977 1016 }
1017 }
1018}
1019
1020//================================================================
1021// Function : CalculateCenter
1022// Purpose :
1023//================================================================
1024void MeshVS_MeshPrsBuilder::CalculateCenter (const TColStd_Array1OfReal& theCoords,
1025 const Standard_Integer NbNodes,
1026 Standard_Real &xG,
1027 Standard_Real &yG,
1028 Standard_Real &zG)
1029{
1030 xG = yG = zG = 0;
1031 if ( NbNodes < 4 )
1032 {
1033 for ( Standard_Integer k=1; k<=NbNodes; k++)
1034 {
1035 xG += theCoords(3*k-2);
1036 yG += theCoords(3*k-1);
1037 zG += theCoords(3*k);
1038 }
1039 xG /= Standard_Real(NbNodes);
1040 yG /= Standard_Real(NbNodes);
1041 zG /= Standard_Real(NbNodes);
1042 }
1043 else
1044 {
1045 Standard_Integer a = 1, b = 3;
1046 xG = ( theCoords( 3*a-2 ) + theCoords( 3*b-2 ) ) / 2.0;
1047 yG = ( theCoords( 3*a-1 ) + theCoords( 3*b-1 ) ) / 2.0;
1048 zG = ( theCoords( 3*a ) + theCoords( 3*b ) ) / 2.0;
1049 }
1050}