0023634: Eliminate Polyline and Polygon usage in drawers
[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>
7fd59977 33#include <Graphic3d_ArrayOfPolylines.hxx>
34#include <Graphic3d_Array1OfVertex.hxx>
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
139 Graphic3d_Array1OfVertex aNodePoints ( 1, upper );
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);
149 k++;
150 aNodePoints.SetValue ( k, Graphic3d_Vertex ( aCoords(1), aCoords(2), aCoords(3) ) );
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 );
7fd59977 159 aNodeGroup->MarkerSet ( 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 {
477 aHilightGroup->SetPrimitivesAspect ( aNodeMark );
478 aHilightGroup->Marker ( Graphic3d_Vertex ( aCoords(1), aCoords(2), aCoords(3) ) );
479 }
480 break;
481
482 case MeshVS_ET_Link:
483 {
484 aHilightGroup->SetPrimitivesAspect ( aBeam );
b8ddfc2f 485 Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
486 aPrims->AddVertex(aCoords(1),aCoords(2),aCoords(3));
487 aPrims->AddVertex(aCoords(4),aCoords(5),aCoords(6));
488 aHilightGroup->AddPrimitiveArray(aPrims);
7fd59977 489 }
490 break;
491
492 case MeshVS_ET_Face:
493 if ( NbNodes > 0 )
494 {
7fd59977 495 aHilightGroup->SetPrimitivesAspect ( aFill );
b8ddfc2f 496 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(NbNodes);
7fd59977 497 for ( Standard_Integer k=1; k<=NbNodes; k++)
b8ddfc2f 498 aPrims->AddVertex(aCoords(3*k-2),aCoords(3*k-1),aCoords(3*k));
499 aHilightGroup->AddPrimitiveArray(aPrims);
7fd59977 500 }
501 break;
502
503 case MeshVS_ET_Volume:
504 if( NbNodes > 0 )
505 {
506 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
507
508 aHilightGroup->SetPrimitivesAspect ( aFill );
509
510 if( aSource->Get3DGeom( ID, NbNodes, aTopo ) )
511 {
b8ddfc2f 512 const Standard_Integer up = aTopo->Upper();
513 const Standard_Integer lo = aTopo->Lower();
514 Standard_Integer nbnodes = 0, i, j;
515 for( i=lo; i<=up; i++ )
516 nbnodes += aTopo->Value( i ).Length();
517
518 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(nbnodes,aTopo->Length());
519 for( i=lo; i<=up; i++ )
7fd59977 520 {
521 const TColStd_SequenceOfInteger& aSeq = aTopo->Value( i );
b8ddfc2f 522 const Standard_Integer m = aSeq.Length();
523 aPrims->AddBound(m);
7fd59977 524 for( j=1; j<=m; j++ )
525 {
b8ddfc2f 526 const Standard_Integer ind = 3*aSeq.Value( j );
527 aPrims->AddVertex(aCoords(ind+1),aCoords(ind+2),aCoords(ind+3));
7fd59977 528 }
7fd59977 529 }
b8ddfc2f 530 aHilightGroup->AddPrimitiveArray(aPrims);
7fd59977 531 }
532 }
533 break;
534
535 default:
536 {
537 TColStd_PackedMapOfInteger tmp;
538 CustomBuild ( Prs, IDs, tmp, MeshVS_DMF_HilightPrs );
539 }
540 break;
541 }
542}
543
544//================================================================
545// Function : AddLinkPrs
546// Purpose :
547//================================================================
548void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
549 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
550 const Standard_Boolean IsShrinked,
551 const Standard_Real ShrinkCoef) const
552{
553 Standard_Real x1 = theCoords(1);
554 Standard_Real y1 = theCoords(2);
555 Standard_Real z1 = theCoords(3);
556 Standard_Real x2 = theCoords(4);
557 Standard_Real y2 = theCoords(5);
558 Standard_Real z2 = theCoords(6);
559 Standard_Real xG, yG, zG;
560
561 if ( IsShrinked )
562 {
563 xG = (x1+x2)/2.0;
564 yG = (y1+y2)/2.0;
565 zG = (z1+z2)/2.0;
566 x1 = (x1 - xG) * ShrinkCoef + xG;
567 x2 = 2.0*xG - x1;
568 y1 = (y1 - yG) * ShrinkCoef + yG;
569 y2 = 2.0*yG - y1;
570 z1 = (z1 - zG) * ShrinkCoef + zG;
571 z2 = 2.0*zG - z1;
572 }
573 theLines->AddBound ( 2 );
574 theLines->AddVertex ( x1, y1, z1 );
575 theLines->AddVertex ( x2, y2, z2 );
576}
577
578//================================================================
579// Function : AddFaceWirePrs
580// Purpose :
581//================================================================
582void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal& theCoords,
583 const Standard_Integer NbNodes,
584 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
585 const Standard_Boolean IsShrinked,
586 const Standard_Real ShrinkCoef) const
587{
588 Standard_Real xG, yG, zG, X, Y, Z, startX=0., startY=0., startZ=0.;
589 theLines->AddBound ( NbNodes+1 );
590 if ( IsShrinked )
591 CalculateCenter( theCoords, NbNodes, xG, yG, zG );
592
593 for ( Standard_Integer k=1; k<=NbNodes; k++)
594 {
595 X = theCoords(3*k-2);
596 Y = theCoords(3*k-1);
597 Z = theCoords(3*k);
598 if ( IsShrinked )
599 {
600 X = (X - xG) * ShrinkCoef + xG;
601 Y = (Y - yG) * ShrinkCoef + yG;
602 Z = (Z - zG) * ShrinkCoef + zG;
603 }
604 if( k==1 )
605 {
606 startX = X; startY = Y; startZ = Z;
607 }
608 theLines->AddVertex ( X, Y, Z );
609 }
610 theLines->AddVertex( startX, startY, startZ );
611}
612
613//================================================================
614// Function : AddFaceSolidPrs
615// Purpose :
616//================================================================
617void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer ID,
618 const TColStd_Array1OfReal& theCoords,
619 const Standard_Integer NbNodes,
620 const Standard_Integer MaxNodes,
621 const Handle(Graphic3d_ArrayOfPolygons)& thePolygons,
622 const Standard_Boolean IsReflected,
623 const Standard_Boolean IsShrinked,
624 const Standard_Real ShrinkCoef,
625 const Standard_Boolean IsMeshSmoothShading) const
626{
627 Handle( MeshVS_DataSource ) aDS = myParentMesh->GetDataSource();
628 if ( aDS.IsNull() )
629 return;
630
631 Standard_Real xG, yG, zG, X, Y, Z, nx, ny, nz;
632 thePolygons->AddBound ( NbNodes );
633 if ( IsShrinked )
634 CalculateCenter( theCoords, NbNodes, xG, yG, zG );
635
636 Standard_Boolean allNormals = Standard_True;
637 Standard_Integer k;
638
639 if( IsReflected )
640 {
641 if( IsMeshSmoothShading )
642 for( k=1; k<=NbNodes && allNormals; k++ )
643 allNormals = aDS->GetNodeNormal (k, ID, nx, ny, nz);
644 if( !IsMeshSmoothShading || !allNormals )
645 aDS->GetNormal( ID, MaxNodes, nx, ny, nz );
646 }
647
648 for ( k=1; k<=NbNodes; k++)
649 {
650 X = theCoords(3*k-2);
651 Y = theCoords(3*k-1);
652 Z = theCoords(3*k);
653 if ( IsShrinked )
654 {
655 X = (X - xG) * ShrinkCoef + xG;
656 Y = (Y - yG) * ShrinkCoef + yG;
657 Z = (Z - zG) * ShrinkCoef + zG;
658 }
659
660 if ( IsReflected )
661 {
662 if( IsMeshSmoothShading && allNormals )
663 aDS->GetNodeNormal (k, ID, nx, ny, nz);
664 thePolygons->AddVertex ( X, Y, Z, nx, ny, nz );
665 }
666 else
667 thePolygons->AddVertex ( X, Y, Z );
668 }
669}
670
671//================================================================
672// Function : AddVolumePrs
673// Purpose :
674//================================================================
675void MeshVS_MeshPrsBuilder::AddVolumePrs (const Handle( MeshVS_HArray1OfSequenceOfInteger )& Topo,
676 const TColStd_Array1OfReal& Nodes,
677 const Standard_Integer NbNodes,
678 const Handle( Graphic3d_ArrayOfPrimitives )& Array,
679 const Standard_Boolean IsReflected,
680 const Standard_Boolean IsShrinked,
681 const Standard_Boolean IsSelect,
682 const Standard_Real ShrinkCoef)
683{
684 Standard_Real c[3]; c[0] = c[1] = c[2] = 0.0;
685 Standard_Integer low = Nodes.Lower(), n=NbNodes;
686
687 if( Topo.IsNull() || Array.IsNull() )
688 return;
689
690 if( IsShrinked )
691 {
692 for( Standard_Integer i=0; i<3*n; i++ )
693 c[i%3] += Nodes.Value( low + i );
694
695 c[0] /= n;
696 c[1] /= n;
697 c[2] /= n;
698 }
699
700 Standard_Boolean IsPolygons = Array->IsKind( STANDARD_TYPE( Graphic3d_ArrayOfPolygons ) );
701 Standard_Real x[2], y[2], z[2];
702 Standard_Integer ind;
703 gp_Vec norm;
704
705 if( IsPolygons )
706 {
707 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
708 {
709 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
710
711 Standard_Integer m = aSeq.Length();
712 Array->AddBound( m );
713
714 norm.SetCoord( 0, 0, 0 );
715 if( IsReflected )
716 {
717 MeshVS_Buffer PolyNodesBuf (3*m*sizeof(Standard_Real));
718 TColStd_Array1OfReal PolyNodes( PolyNodesBuf, 0, 3*m );
719 PolyNodes.SetValue( 0, m );
720 for( Standard_Integer j=1; j<=m; j++ )
721 {
722 ind = aSeq.Value( j );
723 PolyNodes.SetValue( 3*j-2, Nodes.Value( low+3*ind ) );
724 PolyNodes.SetValue( 3*j-1, Nodes.Value( low+3*ind+1 ) );
725 PolyNodes.SetValue( 3*j, Nodes.Value( low+3*ind+2 ) );
726 }
727
728 // compute normal
729 // if( !MeshVS_Tool::GetNormal( PolyNodes, norm ) )
730 // norm.SetCoord( 0, 0, 0 );
731 MeshVS_Tool::GetAverageNormal( PolyNodes, norm );
732 }
733
734 Standard_Real nx = norm.X(), ny = norm.Y(), nz = norm.Z();
735
736
737 for( Standard_Integer j=1; j<=m; j++ )
738 {
739 ind = aSeq.Value( j );
740 x[0] = Nodes.Value( low + 3*ind );
741 y[0] = Nodes.Value( low + 3*ind+1 );
742 z[0] = Nodes.Value( low + 3*ind+2 );
743
744 if( IsShrinked )
745 {
746 x[0] = c[0] + ShrinkCoef * ( x[0]-c[0] );
747 y[0] = c[1] + ShrinkCoef * ( y[0]-c[1] );
748 z[0] = c[2] + ShrinkCoef * ( z[0]-c[2] );
749 }
750
751 if( IsReflected )
752 Array->AddVertex( x[0], y[0], z[0], nx, ny, nz );
753 else
754 Array->AddVertex( x[0], y[0], z[0] );
755 }
756 }
757 }
758 else if( IsSelect )
759 {
760 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
761 {
762 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
763 Standard_Real pc[3]; pc[0] = pc[1] = pc[2] = 0;
764 Standard_Integer j,m;
765 for( j=1, m=aSeq.Length(); j<=m; j++ )
766 {
767 ind = aSeq.Value( j );
768 for( Standard_Integer k=0; k<3; k++ )
769 pc[k] += Nodes.Value( low + 3*ind+k );
770 }
771 pc[0] /= m;
772 pc[1] /= m;
773 pc[2] /= m;
774
775 Array->AddBound( m+1 );
776 for( j=1, m=aSeq.Length(); j<=m+1; j++ )
777 {
778 ind = aSeq.Value( (j-1)%m + 1 );
779 x[0] = Nodes.Value( low + 3*ind );
780 y[0] = Nodes.Value( low + 3*ind+1 );
781 z[0] = Nodes.Value( low + 3*ind+2 );
782 x[0] = pc[0] + ShrinkCoef * ( x[0]-pc[0] );
783 y[0] = pc[1] + ShrinkCoef * ( y[0]-pc[1] );
784 z[0] = pc[2] + ShrinkCoef * ( z[0]-pc[2] );
785 Array->AddVertex( x[0], y[0], z[0] );
786 }
787 }
788 }
789 else
790 {
791 Standard_Integer F, S=0, k;
792
793 // Find all pairs of nodes (edges) to draw;
794 // map is used to ensure that each edge will be drawn only once
795 TColStd_PackedMapOfInteger aMap;
796 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
797 {
798 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
799 for( Standard_Integer j=1, m=aSeq.Length(); j<=m; j++ )
800 {
801 if( j==1 )
802 F = aSeq.Value( j );
803 else
804 F = S;
805
806 S = j<m ? aSeq.Value( j+1 ) : aSeq.Value( 1 );
807
808 if( F<S )
809 aMap.Add( F + NbNodes * S );
810 else
811 aMap.Add( S + NbNodes * F );
812 }
813 }
814
815 // draw edges
816 TColStd_MapIteratorOfPackedMapOfInteger anIt( aMap );
817 for( ; anIt.More(); anIt.Next() )
818 {
819 F = low + 3*(anIt.Key()%NbNodes);
820 S = low + 3*(anIt.Key()/NbNodes);
821
822 x[0] = Nodes.Value( F );
823 y[0] = Nodes.Value( F+1 );
824 z[0] = Nodes.Value( F+2 );
825 x[1] = Nodes.Value( S );
826 y[1] = Nodes.Value( S+1 );
827 z[1] = Nodes.Value( S+2 );
828
829 if( IsShrinked )
830 for( k=0; k<2; k++ )
831 {
832 x[k] = c[0] + ShrinkCoef * ( x[k]-c[0] );
833 y[k] = c[1] + ShrinkCoef * ( y[k]-c[1] );
834 z[k] = c[2] + ShrinkCoef * ( z[k]-c[2] );
835 }
836
837 Array->AddBound( 2 );
838 Array->AddVertex( x[0], y[0], z[0] );
839 Array->AddVertex( x[1], y[1], z[1] );
840 }
841 }
842}
843
844//================================================================
845// Function : HowManyPrimitives
846// Purpose :
847//================================================================
848void MeshVS_MeshPrsBuilder::HowManyPrimitives (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo,
849 const Standard_Boolean AsPolygons,
850 const Standard_Boolean IsSelect,
851 const Standard_Integer NbNodes,
852 Standard_Integer& Vertices,
853 Standard_Integer& Bounds)
854{
855 if( !Topo.IsNull() )
856 if( AsPolygons || IsSelect )
857 {
858 Standard_Integer B = Topo->Upper()-Topo->Lower()+1;
859 Bounds += B;
860 for( Standard_Integer i=Topo->Lower(), n=Topo->Upper(); i<=n; i++ )
861 Vertices += Topo->Value( i ).Length();
862
863 if( IsSelect )
864 Vertices+=B;
865 }
866 else
867 {
868 Standard_Integer F = Topo->Upper()-Topo->Lower()+1,
869 E = NbNodes + F - 2;
870 // number of edges is obtained by Euler's expression for polyhedrons
871
872 Bounds += E;
873 Vertices += 2*E;
874 }
875}
876
877//================================================================
878// Function : DrawArrays
879// Purpose :
880//================================================================
881void MeshVS_MeshPrsBuilder::DrawArrays( const Handle(Prs3d_Presentation)& Prs,
882 const Handle(Graphic3d_ArrayOfPolygons)& thePolygons,
883 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
884 const Handle(Graphic3d_ArrayOfPolylines)& theLinkLines,
885 const Handle(Graphic3d_ArrayOfPolygons)& theVolumesInShad,
886 const Standard_Boolean IsPolygonsEdgesOff,
887 const Standard_Boolean IsSelected,
888 const Handle(Graphic3d_AspectFillArea3d)& theFillAsp,
889 const Handle(Graphic3d_AspectLine3d)& theLineAsp ) const
890{
891 if ( theFillAsp.IsNull() )
892 return;
893
894 Standard_Boolean IsFacePolygons = ( !thePolygons.IsNull() && thePolygons->ItemNumber() > 0 ),
895 IsVolumePolygons = ( !theVolumesInShad.IsNull() && theVolumesInShad->ItemNumber() > 0 ),
896 IsPolygons = IsFacePolygons || IsVolumePolygons,
897 IsPolylines = ( !theLines.IsNull() && theLines->ItemNumber() > 0 ),
898 IsLinkPolylines = ( !theLinkLines.IsNull() && theLinkLines->ItemNumber() > 0 );
899
900 Aspect_InteriorStyle aStyle;
901 Quantity_Color anIntColor, aBackColor, anEdgeColor;
902 Aspect_TypeOfLine aType;
903 Standard_Real aWidth;
904
905 theFillAsp->Values( aStyle, anIntColor, aBackColor, anEdgeColor, aType, aWidth );
906
907 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()<0.01 )
908 {
909 Prs3d_Root::NewGroup ( Prs );
910 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
911
912 //if ( IsPolygonsEdgesOff )
913 theFillAsp->SetEdgeOff ();
914 //else
915 // theFillAsp->SetEdgeOn ();
916
917 if( anIntColor!=aBackColor )
918 theFillAsp->SetDistinguishOn();
919 else
920 theFillAsp->SetDistinguishOff();
921
922 if( IsFacePolygons )
923 {
924 aGroup->SetPrimitivesAspect ( theFillAsp );
7fd59977 925 aGroup->AddPrimitiveArray ( thePolygons );
7fd59977 926 }
927
928 if( IsVolumePolygons )
929 {
930 Handle( Graphic3d_AspectFillArea3d ) aCullFillAsp =
931 new Graphic3d_AspectFillArea3d( *( theFillAsp.operator->() ) );
932
933 Standard_Boolean isSupressBackFaces = Standard_False;
934 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
935 if (!aDrawer.IsNull())
936 aDrawer->GetBoolean ( MeshVS_DA_SupressBackFaces, isSupressBackFaces );
937
938 if (isSupressBackFaces)
939 aCullFillAsp->SuppressBackFace();
940
941 aGroup->SetPrimitivesAspect ( aCullFillAsp );
7fd59977 942 aGroup->AddPrimitiveArray ( theVolumesInShad );
7fd59977 943 }
944 }
945
946 if ( IsPolylines && !IsPolygonsEdgesOff )
947 {
948 Prs3d_Root::NewGroup ( Prs );
949 Handle (Graphic3d_Group) aLGroup = Prs3d_Root::CurrentGroup ( Prs );
950
951 theFillAsp->SetEdgeOff();
952 if ( IsSelected )
953 aLGroup->SetPrimitivesAspect ( theLineAsp );
954 else
955 {
956 aLGroup->SetPrimitivesAspect ( theFillAsp );
957 aLGroup->SetPrimitivesAspect ( new Graphic3d_AspectLine3d
958 ( anEdgeColor, Aspect_TOL_SOLID, aWidth ) );
959 }
7fd59977 960 aLGroup->AddPrimitiveArray ( theLines );
7fd59977 961 theFillAsp->SetEdgeOn();
962 }
963
964 if ( IsLinkPolylines )
965 {
966 Prs3d_Root::NewGroup ( Prs );
967 Handle (Graphic3d_Group) aBeamGroup = Prs3d_Root::CurrentGroup ( Prs );
968
969 theFillAsp->SetEdgeOff();
970 if ( !IsSelected )
971 aBeamGroup->SetPrimitivesAspect ( theFillAsp );
972 aBeamGroup->SetPrimitivesAspect ( theLineAsp );
7fd59977 973 aBeamGroup->AddPrimitiveArray ( theLinkLines );
7fd59977 974 theFillAsp->SetEdgeOn();
975 }
976
977 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()>=0.01 )
978 {
979 Prs3d_Root::NewGroup ( Prs );
980 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
981
982 //if ( IsPolygonsEdgesOff )
983 theFillAsp->SetEdgeOff ();
984 //else
985 // theFillAsp->SetEdgeOn ();
986
987 if( anIntColor!=aBackColor )
988 theFillAsp->SetDistinguishOn();
989 else
990 theFillAsp->SetDistinguishOff();
991
992 if( IsFacePolygons )
993 {
994 aGroup->SetPrimitivesAspect ( theFillAsp );
7fd59977 995 aGroup->AddPrimitiveArray ( thePolygons );
7fd59977 996 }
997
998 if( IsVolumePolygons )
999 {
1000 Handle( Graphic3d_AspectFillArea3d ) aCullFillAsp =
1001 new Graphic3d_AspectFillArea3d( *( theFillAsp.operator->() ) );
1002
1003 Standard_Boolean isSupressBackFaces = Standard_False;
1004 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
1005 if (!aDrawer.IsNull())
1006 aDrawer->GetBoolean ( MeshVS_DA_SupressBackFaces, isSupressBackFaces );
1007
1008 if (isSupressBackFaces)
1009 aCullFillAsp->SuppressBackFace();
1010
1011 aGroup->SetPrimitivesAspect ( aCullFillAsp );
7fd59977 1012 aGroup->AddPrimitiveArray ( theVolumesInShad );
7fd59977 1013 }
1014 }
1015}
1016
1017//================================================================
1018// Function : CalculateCenter
1019// Purpose :
1020//================================================================
1021void MeshVS_MeshPrsBuilder::CalculateCenter (const TColStd_Array1OfReal& theCoords,
1022 const Standard_Integer NbNodes,
1023 Standard_Real &xG,
1024 Standard_Real &yG,
1025 Standard_Real &zG)
1026{
1027 xG = yG = zG = 0;
1028 if ( NbNodes < 4 )
1029 {
1030 for ( Standard_Integer k=1; k<=NbNodes; k++)
1031 {
1032 xG += theCoords(3*k-2);
1033 yG += theCoords(3*k-1);
1034 zG += theCoords(3*k);
1035 }
1036 xG /= Standard_Real(NbNodes);
1037 yG /= Standard_Real(NbNodes);
1038 zG /= Standard_Real(NbNodes);
1039 }
1040 else
1041 {
1042 Standard_Integer a = 1, b = 3;
1043 xG = ( theCoords( 3*a-2 ) + theCoords( 3*b-2 ) ) / 2.0;
1044 yG = ( theCoords( 3*a-1 ) + theCoords( 3*b-1 ) ) / 2.0;
1045 zG = ( theCoords( 3*a ) + theCoords( 3*b ) ) / 2.0;
1046 }
1047}