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