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 under
8 // the terms of the GNU Lesser General Public License 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.
17 #include <Aspect_InteriorStyle.hxx>
18 #include <Graphic3d_ArrayOfPoints.hxx>
19 #include <Graphic3d_ArrayOfPolygons.hxx>
20 #include <Graphic3d_ArrayOfPolylines.hxx>
21 #include <Graphic3d_ArrayOfPrimitives.hxx>
22 #include <Graphic3d_ArrayOfSegments.hxx>
23 #include <Graphic3d_ArrayOfTriangles.hxx>
24 #include <Graphic3d_AspectFillArea3d.hxx>
25 #include <Graphic3d_AspectLine3d.hxx>
26 #include <Graphic3d_AspectMarker3d.hxx>
27 #include <Graphic3d_Group.hxx>
28 #include <MeshVS_Buffer.hxx>
29 #include <MeshVS_DataSource.hxx>
30 #include <MeshVS_Drawer.hxx>
31 #include <MeshVS_DrawerAttribute.hxx>
32 #include <MeshVS_MapOfTwoNodes.hxx>
33 #include <MeshVS_Mesh.hxx>
34 #include <MeshVS_MeshPrsBuilder.hxx>
35 #include <MeshVS_SymmetricPairHasher.hxx>
36 #include <MeshVS_Tool.hxx>
37 #include <NCollection_Map.hxx>
38 #include <NCollection_Vector.hxx>
39 #include <Prs3d_LineAspect.hxx>
40 #include <Prs3d_PointAspect.hxx>
41 #include <Prs3d_Presentation.hxx>
42 #include <Prs3d_Root.hxx>
43 #include <Prs3d_ShadingAspect.hxx>
44 #include <Quantity_NameOfColor.hxx>
45 #include <Select3D_SensitivePoint.hxx>
46 #include <Standard_Type.hxx>
47 #include <TColStd_Array1OfInteger.hxx>
48 #include <TColStd_Array1OfReal.hxx>
49 #include <TColStd_HPackedMapOfInteger.hxx>
50 #include <TColStd_ListIteratorOfListOfReal.hxx>
51 #include <TColStd_MapIntegerHasher.hxx>
52 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
53 #include <TColStd_MapOfInteger.hxx>
54 #include <TColStd_PackedMapOfInteger.hxx>
55 #include <TColStd_SequenceOfInteger.hxx>
58 #include <malloc.h> // for alloca()
61 IMPLEMENT_STANDARD_RTTIEXT(MeshVS_MeshPrsBuilder,MeshVS_PrsBuilder)
63 //================================================================
64 // Function : Constructor MeshVS_MeshPrsBuilder
66 //================================================================
67 MeshVS_MeshPrsBuilder::MeshVS_MeshPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
68 const Standard_Integer& DisplayModeMask,
69 const Handle (MeshVS_DataSource)& DS,
70 const Standard_Integer Id,
71 const MeshVS_BuilderPriority& Priority )
72 : MeshVS_PrsBuilder ( Parent, DisplayModeMask, DS, Id, Priority )
76 //================================================================
79 //================================================================
80 void MeshVS_MeshPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
81 const TColStd_PackedMapOfInteger& IDs,
82 TColStd_PackedMapOfInteger& IDsToExclude,
83 const Standard_Boolean IsElement,
84 const Standard_Integer DisplayMode ) const
86 if ( DisplayMode <= 0 )
89 Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 );
90 Standard_Integer Extent = IDs.Extent();
92 if ( HasHilightFlag && Extent == 1)
93 BuildHilightPrs ( Prs, IDs, IsElement );
95 BuildElements ( Prs, IDs, IDsToExclude, DisplayMode );
97 BuildNodes ( Prs, IDs, IDsToExclude, DisplayMode );
100 //================================================================
101 // Function : BuildNodes
103 //================================================================
104 void MeshVS_MeshPrsBuilder::BuildNodes ( const Handle(Prs3d_Presentation)& Prs,
105 const TColStd_PackedMapOfInteger& IDs,
106 TColStd_PackedMapOfInteger& IDsToExclude,
107 const Standard_Integer DisplayMode ) const
109 Handle( MeshVS_DataSource ) aSource = GetDataSource();
110 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
111 Handle (Graphic3d_AspectMarker3d) aNodeMark =
112 MeshVS_Tool::CreateAspectMarker3d( GetDrawer() );
113 if ( aSource.IsNull() || aDrawer.IsNull() || aNodeMark.IsNull() )
116 Standard_Boolean DisplayFreeNodes = Standard_True;
117 aDrawer->GetBoolean( MeshVS_DA_DisplayNodes, DisplayFreeNodes );
118 Standard_Boolean HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 );
119 Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 );
121 Standard_Real aCoordsBuf[ 3 ];
122 TColStd_Array1OfReal aCoords( *aCoordsBuf, 1, 3 );
123 Standard_Integer NbNodes;
124 MeshVS_EntityType aType;
126 if ( !DisplayFreeNodes )
129 TColStd_PackedMapOfInteger anIDs;
131 if ( !HasSelectFlag && !HasHilightFlag )
133 // subtract the hidden nodes and ids to exclude (to minimize allocated memory)
134 Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = myParentMesh->GetHiddenNodes();
135 if ( !aHiddenNodes.IsNull() )
136 anIDs.Subtract( aHiddenNodes->Map() );
138 anIDs.Subtract( IDsToExclude );
140 Standard_Integer upper = anIDs.Extent();
144 Handle(Graphic3d_ArrayOfPoints) aNodePoints = new Graphic3d_ArrayOfPoints (upper);
145 Standard_Integer k=0;
146 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
147 for( ; it.More(); it.Next() )
149 Standard_Integer aKey = it.Key();
150 if ( aSource->GetGeom ( aKey, Standard_False, aCoords, NbNodes, aType ) )
152 if ( IsExcludingOn() )
153 IDsToExclude.Add (aKey);
155 aNodePoints->AddVertex (aCoords(1), aCoords(2), aCoords(3));
161 Prs3d_Root::NewGroup ( Prs );
162 Handle (Graphic3d_Group) aNodeGroup = Prs3d_Root::CurrentGroup ( Prs );
163 aNodeGroup->SetPrimitivesAspect ( aNodeMark );
164 aNodeGroup->AddPrimitiveArray (aNodePoints);
168 //================================================================
169 // Function : BuildElements
171 //================================================================
172 void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs,
173 const TColStd_PackedMapOfInteger& IDs,
174 TColStd_PackedMapOfInteger& IDsToExclude,
175 const Standard_Integer DisplayMode ) const
177 Standard_Integer maxnodes;
179 Handle(MeshVS_DataSource) aSource = GetDataSource();
180 if ( aSource.IsNull() )
183 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
184 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
188 //----------- extract useful display mode flags ----------
189 Standard_Integer aDispMode = ( DisplayMode & GetFlags() );
190 if ( ( aDispMode & MeshVS_DMF_DeformedMask) != 0 )
192 aDispMode /= MeshVS_DMF_DeformedPrsWireFrame;
193 // This transformation turns deformed mesh flags to real display modes
195 aDispMode &= MeshVS_DMF_OCCMask;
196 //--------------------------------------------------------
198 Standard_Real aShrinkCoef;
199 aDrawer->GetDouble ( MeshVS_DA_ShrinkCoeff, aShrinkCoef );
201 Standard_Boolean IsWireFrame = ( aDispMode==MeshVS_DMF_WireFrame ),
202 IsShading = ( aDispMode==MeshVS_DMF_Shading ),
203 IsShrink = ( aDispMode==MeshVS_DMF_Shrink ),
204 HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 ),
205 HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 ),
206 IsMeshReflect, IsMeshAllowOverlap, IsReflect, IsMeshSmoothShading = Standard_False;
208 aDrawer->GetBoolean ( MeshVS_DA_Reflection, IsMeshReflect );
209 aDrawer->GetBoolean ( MeshVS_DA_IsAllowOverlapped, IsMeshAllowOverlap );
210 IsReflect = ( IsMeshReflect && !HasHilightFlag );
211 aDrawer->GetBoolean ( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
213 // display mode for highlighted prs of groups
214 IsShrink = ( IsShrink && !HasHilightFlag );
215 IsShading = ( IsShading || HasHilightFlag );
217 //---------- Creating AspectFillArea3d and AspectLine3d -------------
218 Graphic3d_MaterialAspect AMat;
219 aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat );
222 AMat.SetAmbientColor (Quantity_NOC_BLACK);
223 AMat.SetDiffuseColor (Quantity_NOC_BLACK);
224 AMat.SetSpecularColor(Quantity_NOC_BLACK);
225 AMat.SetEmissiveColor(Quantity_NOC_BLACK);
227 Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat );
228 Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d ( GetDrawer() );
229 //-------------------------------------------------------------------
231 Standard_Boolean IsOverlapControl =
232 !IsMeshAllowOverlap && ( IsWireFrame || IsShading ) && !HasSelectFlag;
234 // subtract the hidden elements and ids to exclude (to minimize allocated memory)
235 TColStd_PackedMapOfInteger anIDs;
237 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
238 if ( !aHiddenElems.IsNull() )
239 anIDs.Subtract( aHiddenElems->Map() );
240 anIDs.Subtract( IDsToExclude );
242 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
243 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
245 Standard_Boolean showEdges = Standard_True;
246 aDrawer->GetBoolean( MeshVS_DA_ShowEdges, showEdges );
248 showEdges = IsWireFrame || showEdges;
250 Standard_Integer* aNodesBuf = (Standard_Integer*) alloca (maxnodes * sizeof (Standard_Integer));
251 Standard_Real* aCoordsBuf = (Standard_Real*) alloca (3 * maxnodes * sizeof (Standard_Real));
253 TColStd_Array1OfInteger aNodes (*aNodesBuf, 1, maxnodes);
254 TColStd_Array1OfReal aCoords (*aCoordsBuf, 1, 3 * maxnodes);
256 Standard_Integer aNbFacePrimitives = 0;
257 Standard_Integer aNbVolmPrimitives = 0;
258 Standard_Integer aNbEdgePrimitives = 0;
259 Standard_Integer aNbLinkPrimitives = 0;
261 MeshVS_EntityType aType;
263 for (it.Reset(); it.More(); it.Next())
265 Standard_Integer aNbNodes = 0;
267 if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
270 if (aType == MeshVS_ET_Volume)
272 if (aSource->Get3DGeom (it.Key(), aNbNodes, aTopo))
274 for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx)
276 const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value (aFaceIdx);
278 if (showEdges) // add edge segments
280 aNbEdgePrimitives += aFaceNodes.Length();
283 if (IsShading || IsShrink) // add volumetric cell triangles
286 aNbVolmPrimitives += aFaceNodes.Length() - 2;
291 else if (aType == MeshVS_ET_Link)
295 aNbLinkPrimitives += 1; // add link segment
298 else if (aType == MeshVS_ET_Face)
302 aNbEdgePrimitives += aNbNodes; // add edge segments
305 if (!IsOverlapControl || IsShading)
307 if ((IsShading || IsShrink) && !HasSelectFlag)
309 aNbFacePrimitives += aNbNodes - 2; // add face triangles
315 // Here we do not use indices arrays because they are not effective for some mesh
316 // drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
317 // cell rendering (normal interpolation is not always applicable - flat shading),
318 // elemental coloring (color interpolation is impossible)
319 Handle (Graphic3d_ArrayOfTriangles) aVolmTriangles =
320 new Graphic3d_ArrayOfTriangles (aNbVolmPrimitives * 3, 0, IsReflect);
321 Handle (Graphic3d_ArrayOfTriangles) aFaceTriangles =
322 new Graphic3d_ArrayOfTriangles (aNbFacePrimitives * 3, 0, IsReflect);
324 Handle (Graphic3d_ArrayOfSegments) aLinkSegments;
325 Handle (Graphic3d_ArrayOfSegments) aEdgeSegments;
329 aLinkSegments = new Graphic3d_ArrayOfSegments (aNbLinkPrimitives * 2);
330 aEdgeSegments = new Graphic3d_ArrayOfSegments (aNbEdgePrimitives * 2);
333 TColStd_PackedMapOfInteger aCustomElements;
335 Quantity_Color anOldEdgeColor;
336 Quantity_Color anEdgeColor = aFill->EdgeColor();
337 MeshVS_MapOfTwoNodes aLinkNodes;
339 // Forbid drawings of edges which overlap with some links
340 if (showEdges && IsOverlapControl)
342 for (it.Reset(); it.More(); it.Next())
344 if (aSource->GetGeomType (it.Key(), Standard_True, aType) && aType == MeshVS_ET_Link)
346 Standard_Integer aNbNodes;
348 if (aSource->GetNodesByElement (it.Key(), aNodes, aNbNodes) && aNbNodes == 2)
350 aLinkNodes.Add (MeshVS_TwoNodes (aNodes(1), aNodes(2)));
356 NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aSegmentMap;
358 for (it.Reset(); it.More(); it.Next())
360 const Standard_Integer aKey = it.Key();
362 Standard_Integer NbNodes;
363 if (!aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
366 if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes))
371 case MeshVS_ET_Volume:
374 IDsToExclude.Add (aKey);
376 if (aSource->Get3DGeom (aKey, NbNodes, aTopo))
378 // Add wire-frame presentation (draw edges for shading mode as well)
381 AddVolumePrs (aTopo, aCoords, NbNodes,
382 aEdgeSegments, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef);
385 // Add shading presentation
386 if ((IsShading || IsShrink) && !HasSelectFlag)
388 AddVolumePrs (aTopo, aCoords, NbNodes,
389 aVolmTriangles, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef);
398 IDsToExclude.Add (aKey);
402 AddLinkPrs (aCoords, aLinkSegments, IsShrink || HasSelectFlag, aShrinkCoef);
410 IDsToExclude.Add (aKey);
412 if (showEdges && IsOverlapControl)
414 Standard_Integer Last = 0;
416 MeshVS_TwoNodes aTwoNodes (aNodes (1));
418 for (Standard_Integer i = 1; i <= NbNodes; ++i)
421 aTwoNodes.First = aTwoNodes.Second;
423 aTwoNodes.Second = (i < NbNodes) ? aNodes (i+1) : aNodes (1);
425 if (aLinkNodes.Contains (aTwoNodes))
427 for (Standard_Integer aNodeIdx = Last + 1; aNodeIdx < i; ++aNodeIdx)
429 const Standard_Integer aNextIdx = aNodeIdx + 1;
431 aEdgeSegments->AddVertex (
432 aCoords (3 * aNodeIdx - 2), aCoords (3 * aNodeIdx - 1), aCoords (3 * aNodeIdx));
433 aEdgeSegments->AddVertex (
434 aCoords (3 * aNextIdx - 2), aCoords (3 * aNextIdx - 1), aCoords (3 * aNextIdx));
441 if (NbNodes - Last > 0)
443 for (Standard_Integer aNodeIdx = Last; aNodeIdx < NbNodes; ++aNodeIdx)
445 const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
447 const MeshVS_NodePair aSegment (aNodes (aNodeIdx + 1),
448 aNodes (aNextIdx + 1));
450 if (!aSegmentMap.Contains (aSegment))
452 aEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
453 aCoords (3 * aNodeIdx + 2),
454 aCoords (3 * aNodeIdx + 3));
456 aEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
457 aCoords (3 * aNextIdx + 2),
458 aCoords (3 * aNextIdx + 3));
460 aSegmentMap.Add (aSegment);
466 if (!IsOverlapControl || IsShading)
468 if (!IsOverlapControl && showEdges)
470 AddFaceWirePrs (aCoords, NbNodes,
471 aEdgeSegments, IsShrink || HasSelectFlag, aShrinkCoef);
474 if ((IsShading || IsShrink) && !HasSelectFlag)
476 AddFaceSolidPrs (aKey, aCoords, NbNodes, maxnodes, aFaceTriangles, IsReflect,
477 IsShrink || HasSelectFlag, aShrinkCoef, IsMeshSmoothShading);
485 aCustomElements.Add (aKey);
492 anOldEdgeColor = anEdgeColor;
493 aFill->SetEdgeColor (Quantity_NOC_BLACK);
496 //std::cout << "Actual extents: " << std::endl
497 // << "Face tris: " << aFaceTriangles->ItemNumber() << " from " << aNbFacePrimitives << std::endl
498 // << "Volm tris: " << aVolmTriangles->ItemNumber() << " from " << aNbVolmPrimitives << std::endl
499 // << "Face segs: " << aEdgeSegments->ItemNumber() << " from " << aNbEdgePrimitives << std::endl
500 // << "Link segs: " << aLinkSegments->ItemNumber() << " from " << aNbLinkPrimitives << std::endl;
502 DrawArrays ( Prs, aFaceTriangles, aEdgeSegments, aLinkSegments, aVolmTriangles,
503 !showEdges, HasSelectFlag, aFill, aBeam );
505 if ( !aCustomElements.IsEmpty() )
506 CustomBuild ( Prs, aCustomElements, IDsToExclude, DisplayMode );
509 aFill->SetEdgeColor( anOldEdgeColor );
512 //================================================================
513 // Function : BuildHilightPrs
515 //================================================================
516 void MeshVS_MeshPrsBuilder::BuildHilightPrs ( const Handle(Prs3d_Presentation)& Prs,
517 const TColStd_PackedMapOfInteger& IDs,
518 const Standard_Boolean IsElement ) const
520 Standard_Integer maxnodes;
522 Handle (MeshVS_DataSource) aSource = GetDataSource();
523 if ( aSource.IsNull() || IDs.IsEmpty() )
526 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
527 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
531 MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real));
532 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*maxnodes);
534 Graphic3d_MaterialAspect AMat;
535 aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat );
536 AMat.SetAmbientColor (Quantity_NOC_BLACK);
537 AMat.SetDiffuseColor (Quantity_NOC_BLACK);
538 AMat.SetSpecularColor(Quantity_NOC_BLACK);
539 AMat.SetEmissiveColor(Quantity_NOC_BLACK);
541 Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat );
542 Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d( GetDrawer() );
543 Handle( Graphic3d_AspectMarker3d ) aNodeMark = MeshVS_Tool::CreateAspectMarker3d( GetDrawer() );
545 // Hilight one element or node
546 TColStd_MapIteratorOfPackedMapOfInteger it (IDs);
547 Standard_Integer ID = it.Key(), NbNodes;
548 MeshVS_EntityType aType;
550 if ( !aSource->GetGeom ( ID, IsElement, aCoords, NbNodes, aType ) )
553 Prs3d_Root::NewGroup ( Prs );
554 Handle (Graphic3d_Group) aHilightGroup = Prs3d_Root::CurrentGroup ( Prs );
558 case MeshVS_ET_Node :
560 aHilightGroup->SetPrimitivesAspect (aNodeMark);
561 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
562 anArrayOfPoints->AddVertex (aCoords(1), aCoords(2), aCoords(3));
563 aHilightGroup->AddPrimitiveArray (anArrayOfPoints);
569 aHilightGroup->SetPrimitivesAspect ( aBeam );
570 Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
571 aPrims->AddVertex(aCoords(1),aCoords(2),aCoords(3));
572 aPrims->AddVertex(aCoords(4),aCoords(5),aCoords(6));
573 aHilightGroup->AddPrimitiveArray(aPrims);
580 aHilightGroup->SetPrimitivesAspect ( aFill );
581 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(NbNodes);
582 for ( Standard_Integer k=1; k<=NbNodes; k++)
583 aPrims->AddVertex(aCoords(3*k-2),aCoords(3*k-1),aCoords(3*k));
584 aHilightGroup->AddPrimitiveArray(aPrims);
588 case MeshVS_ET_Volume:
591 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
593 aHilightGroup->SetPrimitivesAspect ( aFill );
595 if( aSource->Get3DGeom( ID, NbNodes, aTopo ) )
597 const Standard_Integer up = aTopo->Upper();
598 const Standard_Integer lo = aTopo->Lower();
599 Standard_Integer nbnodes = 0, i, j;
600 for( i=lo; i<=up; i++ )
601 nbnodes += aTopo->Value( i ).Length();
603 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(nbnodes,aTopo->Length());
604 for( i=lo; i<=up; i++ )
606 const TColStd_SequenceOfInteger& aSeq = aTopo->Value( i );
607 const Standard_Integer m = aSeq.Length();
609 for( j=1; j<=m; j++ )
611 const Standard_Integer ind = 3*aSeq.Value( j );
612 aPrims->AddVertex(aCoords(ind+1),aCoords(ind+2),aCoords(ind+3));
615 aHilightGroup->AddPrimitiveArray(aPrims);
622 TColStd_PackedMapOfInteger tmp;
623 CustomBuild ( Prs, IDs, tmp, MeshVS_DMF_HilightPrs );
629 //================================================================
630 // Function : AddLinkPrs
632 //================================================================
633 void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
634 const Handle(Graphic3d_ArrayOfSegments)& theSegments,
635 const Standard_Boolean theIsShrinked,
636 const Standard_Real theShrinkCoef) const
638 Standard_Real aX1 = theCoords (1);
639 Standard_Real aY1 = theCoords (2);
640 Standard_Real aZ1 = theCoords (3);
641 Standard_Real aX2 = theCoords (4);
642 Standard_Real aY2 = theCoords (5);
643 Standard_Real aZ2 = theCoords (6);
647 const Standard_Real xG = (aX1 + aX2) * 0.5;
648 const Standard_Real yG = (aY1 + aY2) * 0.5;
649 const Standard_Real zG = (aZ1 + aZ2) * 0.5;
651 aX1 = (aX1 - xG) * theShrinkCoef + xG;
652 aY1 = (aY1 - yG) * theShrinkCoef + yG;
653 aZ1 = (aZ1 - zG) * theShrinkCoef + zG;
655 aX2 = 2.0 * xG - aX1;
656 aY2 = 2.0 * yG - aY1;
657 aZ2 = 2.0 * zG - aZ1;
660 theSegments->AddVertex (aX1, aY1, aZ1);
661 theSegments->AddVertex (aX2, aY2, aZ2);
664 //================================================================
665 // Function : AddFaceWirePrs
667 //================================================================
668 void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal& theCoords,
669 const Standard_Integer theNbNodes,
670 const Handle(Graphic3d_ArrayOfSegments)& theSegments,
671 const Standard_Boolean theIsShrinked,
672 const Standard_Real theShrinkingCoef) const
674 Standard_Real aCenterX = 0.0;
675 Standard_Real aCenterY = 0.0;
676 Standard_Real aCenterZ = 0.0;
680 CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ);
683 NCollection_Vector<gp_XYZ> aNodes (theNbNodes);
685 for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
687 gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1),
688 theCoords (3 * aNodeIdx + 2),
689 theCoords (3 * aNodeIdx + 3));
693 aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX);
694 aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY);
695 aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ);
698 aNodes.Append (aPnt);
701 for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
703 theSegments->AddVertex (aNodes.Value (aNodeIdx).X(),
704 aNodes.Value (aNodeIdx).Y(),
705 aNodes.Value (aNodeIdx).Z());
707 const Standard_Integer aNextIdx = (aNodeIdx + 1) % theNbNodes;
709 theSegments->AddVertex (aNodes.Value (aNextIdx).X(),
710 aNodes.Value (aNextIdx).Y(),
711 aNodes.Value (aNextIdx).Z());
715 //================================================================
716 // Function : AddFaceSolidPrs
718 //================================================================
719 void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer theID,
720 const TColStd_Array1OfReal& theCoords,
721 const Standard_Integer theNbNodes,
722 const Standard_Integer theMaxNodes,
723 const Handle(Graphic3d_ArrayOfTriangles)& theTriangles,
724 const Standard_Boolean theIsShaded,
725 const Standard_Boolean theIsShrinked,
726 const Standard_Real theShrinkingCoef,
727 const Standard_Boolean theIsSmoothShading) const
729 Handle(MeshVS_DataSource) aDataSource = myParentMesh->GetDataSource();
731 if (aDataSource.IsNull())
734 Standard_Real aCenterX = 0.0;
735 Standard_Real aCenterY = 0.0;
736 Standard_Real aCenterZ = 0.0;
737 Standard_Real aNormalX = 0.0;
738 Standard_Real aNormalY = 0.0;
739 Standard_Real aNormalZ = 0.0;
743 CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ);
746 NCollection_Vector<gp_XYZ> aVertexNormals (theMaxNodes);
750 if (theIsSmoothShading)
752 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= theNbNodes; ++aNodeIdx)
754 if (!aDataSource->GetNodeNormal (aNodeIdx, theID, aNormalX, aNormalY, aNormalZ))
757 aVertexNormals.Append (gp_XYZ (aNormalX, aNormalY, aNormalZ));
761 if (!theIsSmoothShading || aVertexNormals.Size() != theNbNodes)
763 aDataSource->GetNormal (theID, theMaxNodes, aNormalX, aNormalY, aNormalZ);
767 NCollection_Vector<gp_XYZ> aNodes (theMaxNodes);
769 for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
771 gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1),
772 theCoords (3 * aNodeIdx + 2),
773 theCoords (3 * aNodeIdx + 3));
777 aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX);
778 aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY);
779 aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ);
782 aNodes.Append (aPnt);
785 // Triangulate polygon
786 for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes - 2; ++aNodeIdx)
788 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx)
792 if (theIsSmoothShading && aVertexNormals.Size() == theNbNodes)
794 aNormalX = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X();
795 aNormalY = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y();
796 aNormalZ = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z();
799 theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(),
800 aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(),
801 aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z(),
808 theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(),
809 aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(),
810 aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z());
816 //================================================================
817 // Function : AddVolumePrs
819 //================================================================
820 void MeshVS_MeshPrsBuilder::AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo,
821 const TColStd_Array1OfReal& theNodes,
822 const Standard_Integer theNbNodes,
823 const Handle(Graphic3d_ArrayOfPrimitives)& theArray,
824 const Standard_Boolean theIsShaded,
825 const Standard_Boolean theIsShrinked,
826 const Standard_Boolean theIsSelected,
827 const Standard_Real theShrinkCoef)
829 Standard_Real aCenter[] = { 0.0, 0.0, 0.0 };
831 Standard_Integer aLow = theNodes.Lower();
833 if (theTopo.IsNull() || theArray.IsNull())
838 for (Standard_Integer aNodeIdx = 0; aNodeIdx < 3 * theNbNodes; ++aNodeIdx)
840 aCenter[aNodeIdx % 3] += theNodes.Value (aLow + aNodeIdx);
843 aCenter[0] /= theNbNodes;
844 aCenter[1] /= theNbNodes;
845 aCenter[2] /= theNbNodes;
848 Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles));
852 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
854 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
855 const Standard_Integer aNbPolyNodes = aFaceNodes.Length();
857 Standard_Real* aPolyNodesBuf = (Standard_Real*) alloca ((3 * aNbPolyNodes + 1) * sizeof (Standard_Real));
858 TColStd_Array1OfReal aPolyNodes (*aPolyNodesBuf, 0, 3 * aNbPolyNodes);
860 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes; ++aNodeIdx)
862 Standard_Integer anIdx = aFaceNodes.Value (aNodeIdx + 1);
864 Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0);
865 Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1);
866 Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2);
870 aX = aCenter[0] + theShrinkCoef * (aX - aCenter[0]);
871 aY = aCenter[1] + theShrinkCoef * (aY - aCenter[1]);
872 aZ = aCenter[2] + theShrinkCoef * (aZ - aCenter[2]);
875 aPolyNodes.SetValue (3 * aNodeIdx + 1, aX);
876 aPolyNodes.SetValue (3 * aNodeIdx + 2, aY);
877 aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ);
884 aPolyNodes.SetValue (0, aNbPolyNodes);
886 if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm))
888 aNorm.SetCoord (0.0, 0.0, 1.0);
892 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes - 2; ++aNodeIdx) // triangulate polygon
894 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
898 theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
899 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
900 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3),
907 theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
908 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
909 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
915 else if (theIsSelected)
917 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
919 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
921 Standard_Real aFaceCenter[] = { 0.0, 0.0, 0.0 };
923 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aFaceNodes.Length(); ++aNodeIdx)
925 for (Standard_Integer aAxisIdx = 0; aAxisIdx < 3; ++aAxisIdx)
927 aFaceCenter[aAxisIdx] += theNodes.Value (aLow + 3 * aFaceNodes.Value (aNodeIdx) + aAxisIdx);
931 aFaceCenter[0] /= aFaceNodes.Length();
932 aFaceCenter[1] /= aFaceNodes.Length();
933 aFaceCenter[2] /= aFaceNodes.Length();
935 for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
937 for (Standard_Integer aSubIdx = 0; aSubIdx < 2; ++aSubIdx) // add segment
939 Standard_Integer anIdx = aFaceNodes.Value ((aNodeIdx + aSubIdx) % aNbNodes + 1);
941 Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0);
942 Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1);
943 Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2);
945 theArray->AddVertex (aFaceCenter[0] + theShrinkCoef * (aX - aFaceCenter[0]),
946 aFaceCenter[1] + theShrinkCoef * (aY - aFaceCenter[1]),
947 aFaceCenter[2] + theShrinkCoef * (aZ - aFaceCenter[2]));
954 // Find all pairs of nodes (edges) to draw (will be drawn only once)
955 NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aEdgeMap;
957 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
959 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
961 for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
963 const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes;
965 aEdgeMap.Add (MeshVS_NodePair (aFaceNodes.Value (aNodeIdx + 1),
966 aFaceNodes.Value (aNextIdx + 1)));
971 for(NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher>::Iterator anIt (aEdgeMap); anIt.More(); anIt.Next())
973 const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first;
974 const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second;
976 Standard_Real aX[] = { theNodes.Value (anIdx1 + 0), theNodes.Value (anIdx2 + 0) };
977 Standard_Real aY[] = { theNodes.Value (anIdx1 + 1), theNodes.Value (anIdx2 + 1) };
978 Standard_Real aZ[] = { theNodes.Value (anIdx1 + 2), theNodes.Value (anIdx2 + 2) };
982 for (Standard_Integer anAxisIdx = 0; anAxisIdx < 2; ++anAxisIdx)
984 aX[anAxisIdx] = aCenter[0] + theShrinkCoef * (aX[anAxisIdx] - aCenter[0]);
985 aY[anAxisIdx] = aCenter[1] + theShrinkCoef * (aY[anAxisIdx] - aCenter[1]);
986 aZ[anAxisIdx] = aCenter[2] + theShrinkCoef * (aZ[anAxisIdx] - aCenter[2]);
990 theArray->AddVertex (aX[0], aY[0], aZ[0]);
991 theArray->AddVertex (aX[1], aY[1], aZ[1]);
996 //================================================================
997 // Function : HowManyPrimitives
999 //================================================================
1000 void MeshVS_MeshPrsBuilder::HowManyPrimitives (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo,
1001 const Standard_Boolean AsPolygons,
1002 const Standard_Boolean IsSelect,
1003 const Standard_Integer NbNodes,
1004 Standard_Integer& Vertices,
1005 Standard_Integer& Bounds)
1007 if( !Topo.IsNull() ) {
1008 if( AsPolygons || IsSelect )
1010 Standard_Integer B = Topo->Upper()-Topo->Lower()+1;
1012 for( Standard_Integer i=Topo->Lower(), n=Topo->Upper(); i<=n; i++ )
1013 Vertices += Topo->Value( i ).Length();
1020 Standard_Integer F = Topo->Upper()-Topo->Lower()+1,
1021 E = NbNodes + F - 2;
1022 // number of edges is obtained by Euler's expression for polyhedrons
1030 //================================================================
1031 // Function : DrawArrays
1033 //================================================================
1034 void MeshVS_MeshPrsBuilder::DrawArrays( const Handle(Prs3d_Presentation)& Prs,
1035 const Handle(Graphic3d_ArrayOfPrimitives)& thePolygons,
1036 const Handle(Graphic3d_ArrayOfPrimitives)& theLines,
1037 const Handle(Graphic3d_ArrayOfPrimitives)& theLinkLines,
1038 const Handle(Graphic3d_ArrayOfPrimitives)& theVolumesInShad,
1039 const Standard_Boolean IsPolygonsEdgesOff,
1040 const Standard_Boolean IsSelected,
1041 const Handle(Graphic3d_AspectFillArea3d)& theFillAsp,
1042 const Handle(Graphic3d_AspectLine3d)& theLineAsp ) const
1044 if ( theFillAsp.IsNull() )
1047 Standard_Boolean IsFacePolygons = ( !thePolygons.IsNull() && thePolygons->ItemNumber() > 0 ),
1048 IsVolumePolygons = ( !theVolumesInShad.IsNull() && theVolumesInShad->ItemNumber() > 0 ),
1049 IsPolygons = IsFacePolygons || IsVolumePolygons,
1050 IsPolylines = ( !theLines.IsNull() && theLines->ItemNumber() > 0 ),
1051 IsLinkPolylines = ( !theLinkLines.IsNull() && theLinkLines->ItemNumber() > 0 );
1053 Quantity_Color anIntColor = theFillAsp->InteriorColor();
1054 Quantity_Color aBackColor = theFillAsp->BackInteriorColor();
1055 Quantity_Color anEdgeColor = theFillAsp->EdgeColor();
1056 Standard_Real aWidth = theFillAsp->EdgeWidth();
1058 Standard_Boolean isSupressBackFaces = Standard_False;
1059 Handle(MeshVS_Drawer) aDrawer = GetDrawer();
1060 if (!aDrawer.IsNull())
1062 aDrawer->GetBoolean (MeshVS_DA_SupressBackFaces, isSupressBackFaces);
1065 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()<0.01 )
1067 Prs3d_Root::NewGroup ( Prs );
1068 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
1069 aGroup->SetClosed (isSupressBackFaces == Standard_True);
1070 Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*theFillAsp);
1071 //if ( IsPolygonsEdgesOff )
1072 aFillAsp->SetEdgeOff ();
1074 // aFillAsp->SetEdgeOn ();
1076 if( anIntColor!=aBackColor )
1077 aFillAsp->SetDistinguishOn();
1079 aFillAsp->SetDistinguishOff();
1081 aGroup->SetPrimitivesAspect (aFillAsp);
1083 if( IsFacePolygons )
1085 aGroup->AddPrimitiveArray ( thePolygons );
1088 if( IsVolumePolygons )
1090 aGroup->AddPrimitiveArray ( theVolumesInShad );
1094 if ( IsPolylines && !IsPolygonsEdgesOff )
1096 Prs3d_Root::NewGroup ( Prs );
1097 Handle (Graphic3d_Group) aLGroup = Prs3d_Root::CurrentGroup ( Prs );
1100 aLGroup->SetPrimitivesAspect ( theLineAsp );
1103 aLGroup->SetPrimitivesAspect ( theFillAsp );
1104 aLGroup->SetPrimitivesAspect ( new Graphic3d_AspectLine3d
1105 ( anEdgeColor, Aspect_TOL_SOLID, aWidth ) );
1107 aLGroup->AddPrimitiveArray ( theLines );
1110 if ( IsLinkPolylines )
1112 Prs3d_Root::NewGroup ( Prs );
1113 Handle (Graphic3d_Group) aBeamGroup = Prs3d_Root::CurrentGroup ( Prs );
1115 aBeamGroup->SetPrimitivesAspect ( theFillAsp );
1116 aBeamGroup->SetPrimitivesAspect ( theLineAsp );
1117 aBeamGroup->AddPrimitiveArray ( theLinkLines );
1120 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()>=0.01 )
1122 Prs3d_Root::NewGroup ( Prs );
1123 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
1124 aGroup->SetClosed (isSupressBackFaces == Standard_True);
1125 Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*theFillAsp);
1126 //if ( IsPolygonsEdgesOff )
1127 aFillAsp->SetEdgeOff ();
1129 // aFillAsp->SetEdgeOn ();
1131 if( anIntColor!=aBackColor )
1132 aFillAsp->SetDistinguishOn();
1134 aFillAsp->SetDistinguishOff();
1136 aGroup->SetPrimitivesAspect (aFillAsp);
1138 if( IsFacePolygons )
1140 aGroup->AddPrimitiveArray ( thePolygons );
1143 if( IsVolumePolygons )
1145 aGroup->AddPrimitiveArray ( theVolumesInShad );
1150 //================================================================
1151 // Function : CalculateCenter
1153 //================================================================
1154 void MeshVS_MeshPrsBuilder::CalculateCenter (const TColStd_Array1OfReal& theCoords,
1155 const Standard_Integer NbNodes,
1163 for ( Standard_Integer k=1; k<=NbNodes; k++)
1165 xG += theCoords(3*k-2);
1166 yG += theCoords(3*k-1);
1167 zG += theCoords(3*k);
1169 xG /= Standard_Real(NbNodes);
1170 yG /= Standard_Real(NbNodes);
1171 zG /= Standard_Real(NbNodes);
1175 Standard_Integer a = 1, b = 3;
1176 xG = ( theCoords( 3*a-2 ) + theCoords( 3*b-2 ) ) / 2.0;
1177 yG = ( theCoords( 3*a-1 ) + theCoords( 3*b-1 ) ) / 2.0;
1178 zG = ( theCoords( 3*a ) + theCoords( 3*b ) ) / 2.0;