1 // Created on: 2003-09-16
2 // Created by: Alexander SOLOVYOV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <MeshVS_MeshPrsBuilder.ixx>
18 #include <Prs3d_Root.hxx>
19 #include <Prs3d_ShadingAspect.hxx>
20 #include <Prs3d_LineAspect.hxx>
21 #include <Prs3d_PointAspect.hxx>
23 #include <Graphic3d_AspectLine3d.hxx>
24 #include <Graphic3d_AspectFillArea3d.hxx>
25 #include <Graphic3d_AspectMarker3d.hxx>
26 #include <Graphic3d_ArrayOfPolygons.hxx>
27 #include <Graphic3d_ArrayOfSegments.hxx>
28 #include <Graphic3d_ArrayOfPoints.hxx>
29 #include <Graphic3d_ArrayOfPolylines.hxx>
30 #include <Graphic3d_Group.hxx>
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>
41 #include <Quantity_NameOfColor.hxx>
42 #include <Aspect_InteriorStyle.hxx>
43 #include <Select3D_SensitivePoint.hxx>
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>
53 //================================================================
54 // Function : Constructor MeshVS_MeshPrsBuilder
56 //================================================================
57 MeshVS_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 )
66 //================================================================
69 //================================================================
70 void 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
76 if ( DisplayMode <= 0 )
79 Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 );
80 Standard_Integer Extent = IDs.Extent();
82 if ( HasHilightFlag && Extent == 1)
83 BuildHilightPrs ( Prs, IDs, IsElement );
85 BuildElements ( Prs, IDs, IDsToExclude, DisplayMode );
87 BuildNodes ( Prs, IDs, IDsToExclude, DisplayMode );
90 //================================================================
91 // Function : BuildNodes
93 //================================================================
94 void MeshVS_MeshPrsBuilder::BuildNodes ( const Handle(Prs3d_Presentation)& Prs,
95 const TColStd_PackedMapOfInteger& IDs,
96 TColStd_PackedMapOfInteger& IDsToExclude,
97 const Standard_Integer DisplayMode ) const
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() )
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 );
111 Standard_Real aCoordsBuf[ 3 ];
112 TColStd_Array1OfReal aCoords( *aCoordsBuf, 1, 3 );
113 Standard_Integer NbNodes;
114 MeshVS_EntityType aType;
116 if ( !DisplayFreeNodes )
119 TColStd_PackedMapOfInteger anIDs;
121 if ( !HasSelectFlag && !HasHilightFlag )
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() );
128 anIDs.Subtract( IDsToExclude );
130 Standard_Integer upper = anIDs.Extent();
134 Handle(Graphic3d_ArrayOfPoints) aNodePoints = new Graphic3d_ArrayOfPoints (upper);
135 Standard_Integer k=0;
136 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
137 for( ; it.More(); it.Next() )
139 Standard_Integer aKey = it.Key();
140 if ( aSource->GetGeom ( aKey, Standard_False, aCoords, NbNodes, aType ) )
142 if ( IsExcludingOn() )
143 IDsToExclude.Add (aKey);
145 aNodePoints->AddVertex (aCoords(1), aCoords(2), aCoords(3));
151 Prs3d_Root::NewGroup ( Prs );
152 Handle (Graphic3d_Group) aNodeGroup = Prs3d_Root::CurrentGroup ( Prs );
153 aNodeGroup->SetPrimitivesAspect ( aNodeMark );
154 aNodeGroup->AddPrimitiveArray (aNodePoints);
158 //================================================================
159 // Function : BuildElements
161 //================================================================
162 void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs,
163 const TColStd_PackedMapOfInteger& IDs,
164 TColStd_PackedMapOfInteger& IDsToExclude,
165 const Standard_Integer DisplayMode ) const
167 Standard_Integer maxnodes;
169 Handle (MeshVS_DataSource) aSource = GetDataSource();
170 if ( aSource.IsNull() )
173 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
174 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
178 //----------- extract useful display mode flags ----------
179 Standard_Integer aDispMode = ( DisplayMode & GetFlags() );
180 if ( ( aDispMode & MeshVS_DMF_DeformedMask) != 0 )
182 aDispMode /= MeshVS_DMF_DeformedPrsWireFrame;
183 // This transformation turns deformed mesh flags to real display modes
185 aDispMode &= MeshVS_DMF_OCCMask;
186 //--------------------------------------------------------
188 Standard_Real aShrinkCoef;
189 aDrawer->GetDouble ( MeshVS_DA_ShrinkCoeff, aShrinkCoef );
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;
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 );
203 // display mode for hilighted prs of groups
204 IsShrink = ( IsShrink && !HasHilightFlag );
205 IsShading = ( IsShading || HasHilightFlag );
207 //---------- Creating AspectFillArea3d and AspectLine3d -------------
208 Graphic3d_MaterialAspect AMat;
209 aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat );
212 AMat.SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
213 AMat.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
214 AMat.SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
215 AMat.SetReflectionModeOff(Graphic3d_TOR_EMISSION);
217 Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat );
218 Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d ( GetDrawer() );
219 //-------------------------------------------------------------------
221 Standard_Boolean IsOverlapControl =
222 !IsMeshAllowOverlap && ( IsWireFrame || IsShading ) && !HasSelectFlag;
224 Handle (Graphic3d_ArrayOfPolygons) aPolygons, aVolumes;
225 Handle (Graphic3d_ArrayOfPolylines) aPolylines, aLinkPolylines;
227 Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0,
228 PolylineVerticesFor3D = 0, PolylineBoundsFor3D = 0,
231 // subtract the hidden elements and ids to exclude (to minimise allocated memory)
232 TColStd_PackedMapOfInteger anIDs;
234 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
235 if ( !aHiddenElems.IsNull() )
236 anIDs.Subtract( aHiddenElems->Map() );
237 anIDs.Subtract( IDsToExclude );
239 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
240 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
241 for( ; it.More(); it.Next() )
243 Standard_Integer aKey = it.Key();
244 if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
247 HowManyPrimitives( aTopo, Standard_True, HasSelectFlag, NbNodes,
248 PolygonVerticesFor3D, PolygonBoundsFor3D );
249 HowManyPrimitives( aTopo, Standard_False, HasSelectFlag, NbNodes,
250 PolylineVerticesFor3D, PolylineBoundsFor3D );
254 Standard_Integer Extent = anIDs.Extent();
258 aPolygons = new Graphic3d_ArrayOfPolygons
259 ( maxnodes*Extent, Extent, 0, Standard_True );
260 aVolumes = new Graphic3d_ArrayOfPolygons
261 ( PolygonVerticesFor3D, PolygonBoundsFor3D, 0, Standard_True );
265 aPolygons = new Graphic3d_ArrayOfPolygons( maxnodes*Extent, Extent );
266 aVolumes = new Graphic3d_ArrayOfPolygons ( PolygonVerticesFor3D, PolygonBoundsFor3D );
269 Standard_Integer howMany = 1;
270 if ( IsOverlapControl )
273 Standard_Boolean showEdges = Standard_True;
274 aDrawer->GetBoolean( MeshVS_DA_ShowEdges, showEdges );
276 showEdges = IsWireFrame || showEdges;
279 aPolylines = new Graphic3d_ArrayOfPolylines ( ( maxnodes+1 )*Extent + PolylineVerticesFor3D,
280 howMany * Extent + PolylineBoundsFor3D );
281 aLinkPolylines = new Graphic3d_ArrayOfPolylines ( 2*Extent, Extent );
284 MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real));
285 TColStd_Array1OfReal aCoords( aCoordsBuf, 1, 3*maxnodes );
286 MeshVS_EntityType aType;
288 TColStd_PackedMapOfInteger aCustomElements;
290 Quantity_Color anOldEdgeColor;
291 Aspect_InteriorStyle anIntType;
292 Quantity_Color anIntColor, anEdgeColor;
293 Aspect_TypeOfLine aLine;
294 Standard_Real aWidth;
296 MeshVS_TwoNodes aTwoNodes;
297 aFill->Values ( anIntType, anIntColor, anEdgeColor, aLine, aWidth );
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() )
304 Standard_Integer aKey = it.Key();
305 if ( aSource->GetGeomType ( aKey, Standard_True, aType ) &&
306 aType == MeshVS_ET_Link )
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 ) &&
314 aTwoNodes.First = aNodes(1);
315 aTwoNodes.Second = aNodes(2);
316 aLinkNodes.Add ( aTwoNodes );
321 for( it.Reset(); it.More(); it.Next() )
323 Standard_Integer aKey = it.Key();
325 if ( ! aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) )
330 case MeshVS_ET_Volume :
331 if( IsExcludingOn() )
332 IDsToExclude.Add (aKey);
333 if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
335 // !!! TO DO: Overlap control
336 // add wireframe presentation (draw edges for shading mode as well)
338 AddVolumePrs ( aTopo, aCoords, NbNodes, aPolylines, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
340 // add shading presentation
341 if ( ( IsShading || IsShrink ) && !HasSelectFlag )
342 AddVolumePrs ( aTopo, aCoords, NbNodes, aVolumes, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
346 case MeshVS_ET_Link :
347 if( IsExcludingOn() )
348 IDsToExclude.Add (aKey);
350 AddLinkPrs ( aCoords, aLinkPolylines, IsShrink || HasSelectFlag, aShrinkCoef );
353 case MeshVS_ET_Face :
354 if( IsExcludingOn() )
355 IDsToExclude.Add (aKey);
356 if ( showEdges && IsOverlapControl )
358 MeshVS_Buffer aNodesBuf (NbNodes * sizeof(Standard_Integer));
359 TColStd_Array1OfInteger aNodes (aNodesBuf, 1, NbNodes);
360 if ( !aSource->GetNodesByElement( aKey, aNodes, NbNodes ) )
363 Standard_Integer Last = 0;
364 for ( Standard_Integer i=1; i<=NbNodes; i++ )
367 aTwoNodes.First = aNodes(i);
369 aTwoNodes.First = aTwoNodes.Second;
371 aTwoNodes.Second = ( i<NbNodes ? aNodes(i+1) : aNodes(1) );
372 if ( aLinkNodes.Contains ( aTwoNodes ) )
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) );
380 if ( NbNodes-Last > 0 )
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) );
386 aPolylines->AddVertex ( aCoords(1), aCoords(2), aCoords(3) );
390 if ( !IsOverlapControl || IsShading )
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 );
403 aCustomElements.Add( aKey );
410 anOldEdgeColor = anEdgeColor;
411 aFill->SetEdgeColor ( Quantity_NOC_BLACK );
414 DrawArrays ( Prs, aPolygons, aPolylines, aLinkPolylines, aVolumes,
415 !showEdges, HasSelectFlag, aFill, aBeam );
417 if ( !aCustomElements.IsEmpty() )
418 CustomBuild ( Prs, aCustomElements, IDsToExclude, DisplayMode );
421 aFill->SetEdgeColor( anOldEdgeColor );
424 //================================================================
425 // Function : BuildHilightPrs
427 //================================================================
428 void MeshVS_MeshPrsBuilder::BuildHilightPrs ( const Handle(Prs3d_Presentation)& Prs,
429 const TColStd_PackedMapOfInteger& IDs,
430 const Standard_Boolean IsElement ) const
432 Standard_Integer maxnodes;
434 Handle (MeshVS_DataSource) aSource = GetDataSource();
435 if ( aSource.IsNull() || IDs.IsEmpty() )
438 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
439 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
443 MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real));
444 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*maxnodes);
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);
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() );
457 // Hilight one element or node
458 TColStd_MapIteratorOfPackedMapOfInteger it (IDs);
459 Standard_Integer ID = it.Key(), NbNodes;
460 MeshVS_EntityType aType;
462 if ( !aSource->GetGeom ( ID, IsElement, aCoords, NbNodes, aType ) )
465 Prs3d_Root::NewGroup ( Prs );
466 Handle (Graphic3d_Group) aHilightGroup = Prs3d_Root::CurrentGroup ( Prs );
470 case MeshVS_ET_Node :
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);
481 aHilightGroup->SetPrimitivesAspect ( aBeam );
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);
492 aHilightGroup->SetPrimitivesAspect ( aFill );
493 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(NbNodes);
494 for ( Standard_Integer k=1; k<=NbNodes; k++)
495 aPrims->AddVertex(aCoords(3*k-2),aCoords(3*k-1),aCoords(3*k));
496 aHilightGroup->AddPrimitiveArray(aPrims);
500 case MeshVS_ET_Volume:
503 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
505 aHilightGroup->SetPrimitivesAspect ( aFill );
507 if( aSource->Get3DGeom( ID, NbNodes, aTopo ) )
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();
515 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(nbnodes,aTopo->Length());
516 for( i=lo; i<=up; i++ )
518 const TColStd_SequenceOfInteger& aSeq = aTopo->Value( i );
519 const Standard_Integer m = aSeq.Length();
521 for( j=1; j<=m; j++ )
523 const Standard_Integer ind = 3*aSeq.Value( j );
524 aPrims->AddVertex(aCoords(ind+1),aCoords(ind+2),aCoords(ind+3));
527 aHilightGroup->AddPrimitiveArray(aPrims);
534 TColStd_PackedMapOfInteger tmp;
535 CustomBuild ( Prs, IDs, tmp, MeshVS_DMF_HilightPrs );
541 //================================================================
542 // Function : AddLinkPrs
544 //================================================================
545 void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
546 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
547 const Standard_Boolean IsShrinked,
548 const Standard_Real ShrinkCoef) const
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;
563 x1 = (x1 - xG) * ShrinkCoef + xG;
565 y1 = (y1 - yG) * ShrinkCoef + yG;
567 z1 = (z1 - zG) * ShrinkCoef + zG;
570 theLines->AddBound ( 2 );
571 theLines->AddVertex ( x1, y1, z1 );
572 theLines->AddVertex ( x2, y2, z2 );
575 //================================================================
576 // Function : AddFaceWirePrs
578 //================================================================
579 void 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
585 Standard_Real xG = 0., yG = 0., zG = 0., X, Y, Z, startX=0., startY=0., startZ=0.;
586 theLines->AddBound ( NbNodes+1 );
588 CalculateCenter( theCoords, NbNodes, xG, yG, zG );
590 for ( Standard_Integer k=1; k<=NbNodes; k++)
592 X = theCoords(3*k-2);
593 Y = theCoords(3*k-1);
597 X = (X - xG) * ShrinkCoef + xG;
598 Y = (Y - yG) * ShrinkCoef + yG;
599 Z = (Z - zG) * ShrinkCoef + zG;
603 startX = X; startY = Y; startZ = Z;
605 theLines->AddVertex ( X, Y, Z );
607 theLines->AddVertex( startX, startY, startZ );
610 //================================================================
611 // Function : AddFaceSolidPrs
613 //================================================================
614 void 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
624 Handle( MeshVS_DataSource ) aDS = myParentMesh->GetDataSource();
628 Standard_Real xG = 0., yG = 0., zG = 0., X, Y, Z, nx = 0., ny = 0., nz = 0.;
629 thePolygons->AddBound ( NbNodes );
631 CalculateCenter( theCoords, NbNodes, xG, yG, zG );
633 Standard_Boolean allNormals = Standard_True;
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 );
645 for ( k=1; k<=NbNodes; k++)
647 X = theCoords(3*k-2);
648 Y = theCoords(3*k-1);
652 X = (X - xG) * ShrinkCoef + xG;
653 Y = (Y - yG) * ShrinkCoef + yG;
654 Z = (Z - zG) * ShrinkCoef + zG;
659 if( IsMeshSmoothShading && allNormals )
660 aDS->GetNodeNormal (k, ID, nx, ny, nz);
661 thePolygons->AddVertex ( X, Y, Z, nx, ny, nz );
664 thePolygons->AddVertex ( X, Y, Z );
668 //================================================================
669 // Function : AddVolumePrs
671 //================================================================
672 void 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)
681 Standard_Real c[3]; c[0] = c[1] = c[2] = 0.0;
682 Standard_Integer low = Nodes.Lower(), n=NbNodes;
684 if( Topo.IsNull() || Array.IsNull() )
689 for( Standard_Integer i=0; i<3*n; i++ )
690 c[i%3] += Nodes.Value( low + i );
697 Standard_Boolean IsPolygons = Array->IsKind( STANDARD_TYPE( Graphic3d_ArrayOfPolygons ) );
698 Standard_Real x[2], y[2], z[2];
699 Standard_Integer ind;
704 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
706 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
708 Standard_Integer m = aSeq.Length();
709 Array->AddBound( m );
711 norm.SetCoord( 0, 0, 0 );
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++ )
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 ) );
726 // if( !MeshVS_Tool::GetNormal( PolyNodes, norm ) )
727 // norm.SetCoord( 0, 0, 0 );
728 MeshVS_Tool::GetAverageNormal( PolyNodes, norm );
731 Standard_Real nx = norm.X(), ny = norm.Y(), nz = norm.Z();
734 for( Standard_Integer j=1; j<=m; j++ )
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 );
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] );
749 Array->AddVertex( x[0], y[0], z[0], nx, ny, nz );
751 Array->AddVertex( x[0], y[0], z[0] );
757 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
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++ )
764 ind = aSeq.Value( j );
765 for( Standard_Integer k=0; k<3; k++ )
766 pc[k] += Nodes.Value( low + 3*ind+k );
772 Array->AddBound( m+1 );
773 for( j=1, m=aSeq.Length(); j<=m+1; j++ )
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] );
788 Standard_Integer F, S=0, k;
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++ )
795 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
796 for( Standard_Integer j=1, m=aSeq.Length(); j<=m; j++ )
803 S = j<m ? aSeq.Value( j+1 ) : aSeq.Value( 1 );
806 aMap.Add( F + NbNodes * S );
808 aMap.Add( S + NbNodes * F );
813 TColStd_MapIteratorOfPackedMapOfInteger anIt( aMap );
814 for( ; anIt.More(); anIt.Next() )
816 F = low + 3*(anIt.Key()%NbNodes);
817 S = low + 3*(anIt.Key()/NbNodes);
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 );
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] );
834 Array->AddBound( 2 );
835 Array->AddVertex( x[0], y[0], z[0] );
836 Array->AddVertex( x[1], y[1], z[1] );
841 //================================================================
842 // Function : HowManyPrimitives
844 //================================================================
845 void 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)
852 if( !Topo.IsNull() ) {
853 if( AsPolygons || IsSelect )
855 Standard_Integer B = Topo->Upper()-Topo->Lower()+1;
857 for( Standard_Integer i=Topo->Lower(), n=Topo->Upper(); i<=n; i++ )
858 Vertices += Topo->Value( i ).Length();
865 Standard_Integer F = Topo->Upper()-Topo->Lower()+1,
867 // number of edges is obtained by Euler's expression for polyhedrons
875 //================================================================
876 // Function : DrawArrays
878 //================================================================
879 void 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
889 if ( theFillAsp.IsNull() )
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 );
898 Aspect_InteriorStyle aStyle;
899 Quantity_Color anIntColor, aBackColor, anEdgeColor;
900 Aspect_TypeOfLine aType;
901 Standard_Real aWidth;
903 theFillAsp->Values( aStyle, anIntColor, aBackColor, anEdgeColor, aType, aWidth );
905 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()<0.01 )
907 Prs3d_Root::NewGroup ( Prs );
908 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
910 //if ( IsPolygonsEdgesOff )
911 theFillAsp->SetEdgeOff ();
913 // theFillAsp->SetEdgeOn ();
915 if( anIntColor!=aBackColor )
916 theFillAsp->SetDistinguishOn();
918 theFillAsp->SetDistinguishOff();
922 aGroup->SetPrimitivesAspect ( theFillAsp );
923 aGroup->AddPrimitiveArray ( thePolygons );
926 if( IsVolumePolygons )
928 Handle( Graphic3d_AspectFillArea3d ) aCullFillAsp =
929 new Graphic3d_AspectFillArea3d( *( theFillAsp.operator->() ) );
931 Standard_Boolean isSupressBackFaces = Standard_False;
932 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
933 if (!aDrawer.IsNull())
934 aDrawer->GetBoolean ( MeshVS_DA_SupressBackFaces, isSupressBackFaces );
936 if (isSupressBackFaces)
937 aCullFillAsp->SuppressBackFace();
939 aGroup->SetPrimitivesAspect ( aCullFillAsp );
940 aGroup->AddPrimitiveArray ( theVolumesInShad );
944 if ( IsPolylines && !IsPolygonsEdgesOff )
946 Prs3d_Root::NewGroup ( Prs );
947 Handle (Graphic3d_Group) aLGroup = Prs3d_Root::CurrentGroup ( Prs );
949 theFillAsp->SetEdgeOff();
951 aLGroup->SetPrimitivesAspect ( theLineAsp );
954 aLGroup->SetPrimitivesAspect ( theFillAsp );
955 aLGroup->SetPrimitivesAspect ( new Graphic3d_AspectLine3d
956 ( anEdgeColor, Aspect_TOL_SOLID, aWidth ) );
958 aLGroup->AddPrimitiveArray ( theLines );
959 theFillAsp->SetEdgeOn();
962 if ( IsLinkPolylines )
964 Prs3d_Root::NewGroup ( Prs );
965 Handle (Graphic3d_Group) aBeamGroup = Prs3d_Root::CurrentGroup ( Prs );
967 theFillAsp->SetEdgeOff();
969 aBeamGroup->SetPrimitivesAspect ( theFillAsp );
970 aBeamGroup->SetPrimitivesAspect ( theLineAsp );
971 aBeamGroup->AddPrimitiveArray ( theLinkLines );
972 theFillAsp->SetEdgeOn();
975 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()>=0.01 )
977 Prs3d_Root::NewGroup ( Prs );
978 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
980 //if ( IsPolygonsEdgesOff )
981 theFillAsp->SetEdgeOff ();
983 // theFillAsp->SetEdgeOn ();
985 if( anIntColor!=aBackColor )
986 theFillAsp->SetDistinguishOn();
988 theFillAsp->SetDistinguishOff();
992 aGroup->SetPrimitivesAspect ( theFillAsp );
993 aGroup->AddPrimitiveArray ( thePolygons );
996 if( IsVolumePolygons )
998 Handle( Graphic3d_AspectFillArea3d ) aCullFillAsp =
999 new Graphic3d_AspectFillArea3d( *( theFillAsp.operator->() ) );
1001 Standard_Boolean isSupressBackFaces = Standard_False;
1002 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
1003 if (!aDrawer.IsNull())
1004 aDrawer->GetBoolean ( MeshVS_DA_SupressBackFaces, isSupressBackFaces );
1006 if (isSupressBackFaces)
1007 aCullFillAsp->SuppressBackFace();
1009 aGroup->SetPrimitivesAspect ( aCullFillAsp );
1010 aGroup->AddPrimitiveArray ( theVolumesInShad );
1015 //================================================================
1016 // Function : CalculateCenter
1018 //================================================================
1019 void MeshVS_MeshPrsBuilder::CalculateCenter (const TColStd_Array1OfReal& theCoords,
1020 const Standard_Integer NbNodes,
1028 for ( Standard_Integer k=1; k<=NbNodes; k++)
1030 xG += theCoords(3*k-2);
1031 yG += theCoords(3*k-1);
1032 zG += theCoords(3*k);
1034 xG /= Standard_Real(NbNodes);
1035 yG /= Standard_Real(NbNodes);
1036 zG /= Standard_Real(NbNodes);
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;