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