0022777: Visualization - Unsafe way to get attribute values from MeshVS_Drawer
[occt.git] / src / MeshVS / MeshVS_ElementalColorPrsBuilder.cxx
index 28e677a..7ceb269 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <MeshVS_ElementalColorPrsBuilder.ixx>
 
-#include <Graphic3d_AspectFillArea3d.hxx>
-#include <Graphic3d_AspectLine3d.hxx>
 #include <Graphic3d_ArrayOfPolygons.hxx>
 #include <Graphic3d_ArrayOfPolylines.hxx>
 #include <Graphic3d_ArrayOfSegments.hxx>
 #include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Graphic3d_AspectFillArea3d.hxx>
+#include <Graphic3d_AspectLine3d.hxx>
 #include <Graphic3d_Group.hxx>
-
-#include <Prs3d_ShadingAspect.hxx>
-#include <Prs3d_Root.hxx>
-#include <Prs3d_LineAspect.hxx>
-
-#include <TColStd_MapOfInteger.hxx>
-#include <TColStd_PackedMapOfInteger.hxx>
-#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_SequenceOfInteger.hxx>
-#include <TColStd_HArray1OfReal.hxx>
-#include <TColStd_HPackedMapOfInteger.hxx>
-
-#include <MeshVS_DisplayModeFlags.hxx>
-#include <MeshVS_DataSource.hxx>
-#include <MeshVS_Mesh.hxx>
+#include <MeshVS_Buffer.hxx>
+#include <MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger.hxx>
+#include <MeshVS_DataMapIteratorOfDataMapOfIntegerColor.hxx>
+#include <MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors.hxx>
+#include <MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger.hxx>
 #include <MeshVS_DataMapOfColorMapOfInteger.hxx>
 #include <MeshVS_DataMapOfTwoColorsMapOfInteger.hxx>
+#include <MeshVS_DataSource.hxx>
+#include <MeshVS_DisplayModeFlags.hxx>
 #include <MeshVS_Drawer.hxx>
 #include <MeshVS_DrawerAttribute.hxx>
-#include <MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors.hxx>
-#include <MeshVS_DataMapIteratorOfDataMapOfIntegerColor.hxx>
-#include <MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger.hxx>
-#include <MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger.hxx>
-#include <MeshVS_MeshPrsBuilder.hxx>
-#include <MeshVS_Buffer.hxx>
+#include <MeshVS_ElementalColorPrsBuilder.hxx>
 #include <MeshVS_HArray1OfSequenceOfInteger.hxx>
+#include <MeshVS_Mesh.hxx>
+#include <MeshVS_MeshPrsBuilder.hxx>
+#include <Prs3d_LineAspect.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <Prs3d_Root.hxx>
+#include <Prs3d_ShadingAspect.hxx>
+#include <Quantity_Color.hxx>
+#include <Standard_Type.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+#include <TColStd_HPackedMapOfInteger.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_PackedMapOfInteger.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(MeshVS_ElementalColorPrsBuilder,MeshVS_PrsBuilder)
 
 //================================================================
 // Function : Constructor MeshVS_ElementalColorPrsBuilder
@@ -177,12 +179,12 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
   //Now we are ready to draw faces with equal colors
   Aspect_TypeOfLine    anEdgeType = Aspect_TOL_SOLID;
   Aspect_TypeOfLine    aLineType = Aspect_TOL_SOLID;
-  Standard_Integer     anEdgeInt, aLineInt;
-  Standard_Real        anEdgeWidth, aLineWidth;
+  Standard_Real        anEdgeWidth = 1.0, aLineWidth = 1.0;
   Quantity_Color       anInteriorColor;
   Quantity_Color       anEdgeColor, aLineColor;
   Standard_Boolean     anEdgeOn = Standard_True, IsReflect = Standard_False,
                        IsMeshSmoothShading = Standard_False;
+  Standard_Boolean toSupressBackFaces = Standard_False;
 
   aDrawer->GetColor  ( MeshVS_DA_InteriorColor, anInteriorColor );
   aDrawer->GetColor  ( MeshVS_DA_EdgeColor, anEdgeColor );
@@ -192,10 +194,13 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
   aDrawer->GetBoolean( MeshVS_DA_ShowEdges, anEdgeOn );
   aDrawer->GetBoolean( MeshVS_DA_ColorReflection, IsReflect );
   aDrawer->GetBoolean( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
+  aDrawer->GetBoolean (MeshVS_DA_SupressBackFaces, toSupressBackFaces);
 
+  Standard_Integer anEdgeInt = Aspect_TOL_SOLID;
   if ( aDrawer->GetInteger ( MeshVS_DA_EdgeType, anEdgeInt) )
     anEdgeType = (Aspect_TypeOfLine) anEdgeInt;
 
+  Standard_Integer aLineInt = Aspect_TOL_SOLID;
   if ( aDrawer->GetInteger ( MeshVS_DA_BeamType, aLineInt) )
     aLineType = (Aspect_TypeOfLine) aLineInt;
 
@@ -211,13 +216,14 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
             PolygonVerticesFor3D, PolygonBoundsFor3D );
   }
 
-  Graphic3d_MaterialAspect aMaterial[2];
+  Graphic3d_MaterialAspect aMaterial[2] = { Graphic3d_NOM_PLASTIC, Graphic3d_NOM_PLASTIC };
   for (Standard_Integer i = 0; i < 2; i++)
   {
     // OCC20644 "plastic" is most suitable here, as it is "non-physic"
     // so TelUpdateMaterial() from OpenGl_attri.c uses the interior
     // color from AspectFillArea3d to calculate all material colors
-    aMaterial[i] = Graphic3d_MaterialAspect ( Graphic3d_NOM_PLASTIC );
+    aMaterial[i].SetSpecularColor (Quantity_NOC_BLACK);
+    aMaterial[i].SetEmissiveColor (Quantity_NOC_BLACK);
 
     // OCC21720 For single-colored elements turning all material components off is a good idea,
     // as anyhow the normals are not computed and the lighting will be off,
@@ -225,10 +231,8 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
     // and there is no need to spend time on updating material properties 
     if ( !IsReflect )
     {
-      aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
-      aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
-      aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
-      aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_EMISSION);
+      aMaterial[i].SetAmbientColor (Quantity_NOC_BLACK);
+      aMaterial[i].SetDiffuseColor (Quantity_NOC_BLACK);
     }
     else
     {
@@ -237,30 +241,44 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
       // those in the color scale most exactly (the sum of all reflection 
       // coefficients is equal to 1). See also MeshVS_NodalColorPrsBuilder
       // class for more explanations.
-      aMaterial[i].SetAmbient( .5 );
-      aMaterial[i].SetDiffuse( .5 );
-      aMaterial[i].SetSpecular( 0. );
-      aMaterial[i].SetEmissive( 0. );
+      aMaterial[i].SetAmbientColor (Quantity_Color (Graphic3d_Vec3 (0.5f)));
+      aMaterial[i].SetDiffuseColor (Quantity_Color (Graphic3d_Vec3 (0.5f)));
     }
   }
 
   // Draw elements with one color
-  for ( MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger aColIter ( aColorsOfElements ); aColIter.More();
-        aColIter.Next() )
+  Handle(Graphic3d_Group) aGGroup, aGroup2, aLGroup, aSGroup;
+  if (!aTwoColorsOfElements.IsEmpty())
+  {
+    aGroup2 = Prs3d_Root::NewGroup (Prs);
+  }
+  if (!aColorsOfElements.IsEmpty())
+  {
+    Handle(Graphic3d_AspectFillArea3d) aGroupFillAspect = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, anInteriorColor, anEdgeColor,
+                                                                                          anEdgeType, anEdgeWidth, aMaterial[0], aMaterial[1]);
+    aGGroup = Prs3d_Root::NewGroup (Prs);
+    aLGroup = Prs3d_Root::NewGroup (Prs);
+    aGGroup->SetClosed (toSupressBackFaces == Standard_True);
+    aGGroup->SetGroupPrimitivesAspect (aGroupFillAspect);
+  }
+
+  if (anEdgeOn)
+  {
+    Handle(Graphic3d_AspectLine3d) anEdgeAspect = new Graphic3d_AspectLine3d (anEdgeColor, anEdgeType, anEdgeWidth);
+    aSGroup = Prs3d_Root::NewGroup (Prs);
+    aSGroup->SetGroupPrimitivesAspect (anEdgeAspect);
+  }
+
+  for (MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger aColIter (aColorsOfElements);
+       aColIter.More(); aColIter.Next())
   {
-    Standard_Integer aSize = aColIter.Value().Extent();
-    if ( aSize<=0 )
+    if (aColIter.Value().IsEmpty())
+    {
       continue;
+    }
 
     TColStd_PackedMapOfInteger aCustomElements;
 
-    Prs3d_Root::NewGroup ( Prs );
-    Handle ( Graphic3d_Group ) aGGroup = Prs3d_Root::CurrentGroup ( Prs );
-    Prs3d_Root::NewGroup ( Prs );
-    Handle ( Graphic3d_Group ) aLGroup = Prs3d_Root::CurrentGroup ( Prs );
-    Prs3d_Root::NewGroup ( Prs );
-    Handle ( Graphic3d_Group ) aSGroup = Prs3d_Root::CurrentGroup ( Prs );
-
     Standard_Integer aNbFacePrimitives = 0;
     Standard_Integer aNbVolmPrimitives = 0;
     Standard_Integer aNbEdgePrimitives = 0;
@@ -333,15 +351,9 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
     Handle(Graphic3d_AspectLine3d) aLinkAspect =
       new Graphic3d_AspectLine3d ( aColIter.Key(), aLineType, aLineWidth );
 
-    Handle(Graphic3d_AspectLine3d) anEdgeAspect =
-      new Graphic3d_AspectLine3d ( anEdgeColor, anEdgeType, anEdgeWidth );
-
     aFillAspect->SetDistinguishOff ();
     aFillAspect->SetInteriorColor ( aColIter.Key() );
-    if (anEdgeOn)
-      aFillAspect->SetEdgeOn();
-    else
-      aFillAspect->SetEdgeOff();
+    aFillAspect->SetEdgeOff();
 
     for (it.Reset(); it.More(); it.Next())
     {
@@ -447,40 +459,34 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
 
     if (IsPolyG)
     {
-      aFillAspect->SetEdgeOff();
       aGGroup->SetPrimitivesAspect (aFillAspect);
       aGGroup->AddPrimitiveArray (aFaceTriangles);
+      aGGroup->SetClosed (toSupressBackFaces == Standard_True);
       
       if (anEdgeOn)
       {
-        aFillAspect->SetEdgeOff();
         aSGroup->AddPrimitiveArray (anEdgeSegments);
-        aSGroup->SetGroupPrimitivesAspect (anEdgeAspect);
       }
     }
     if (IsPolyL)
     {
-      aFillAspect->SetEdgeOff();
       aLGroup->SetPrimitivesAspect (aFillAspect);
       aLGroup->SetPrimitivesAspect (aLinkAspect);
       aLGroup->AddPrimitiveArray (aLinkSegments);
-      if (anEdgeOn)
-        aFillAspect->SetEdgeOn();
-      else
-        aFillAspect->SetEdgeOff();
     }
 
     if (!aCustomElements.IsEmpty())
       CustomBuild(Prs, aCustomElements, IDsToExclude, DisplayMode);
   }
 
-  Graphic3d_MaterialAspect aMaterial2[2];
+  Graphic3d_MaterialAspect aMaterial2[2] = { Graphic3d_NOM_PLASTIC, Graphic3d_NOM_PLASTIC };
   for (Standard_Integer i = 0; i < 2; i++)
   {
     // OCC20644 "plastic" is most suitable here, as it is "non-physic"
     // so TelUpdateMaterial() from OpenGl_attri.c uses the interior
     // color from AspectFillArea3d to calculate all material colors
-    aMaterial2[i] = Graphic3d_MaterialAspect ( Graphic3d_NOM_PLASTIC );
+    aMaterial2[i].SetSpecularColor (Quantity_NOC_BLACK);
+    aMaterial2[i].SetEmissiveColor (Quantity_NOC_BLACK);
 
     if ( !IsReflect )
     {
@@ -489,14 +495,8 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
       // to have different materials for front and back sides!
       // Instead, trying to make material color "nondirectional" with 
       // only ambient component on.
-      aMaterial2[i].SetReflectionModeOn ( Graphic3d_TOR_AMBIENT );
-      aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_DIFFUSE );
-      aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_SPECULAR );
-      aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_EMISSION );
-      aMaterial2[i].SetAmbient ( 1. );
-      aMaterial2[i].SetDiffuse ( 0. );
-      aMaterial2[i].SetSpecular( 0. );
-      aMaterial2[i].SetEmissive( 0. );
+      aMaterial2[i].SetAmbientColor (Quantity_Color (Graphic3d_Vec3 (1.0f)));
+      aMaterial2[i].SetDiffuseColor (Quantity_NOC_BLACK);
     }
     else
     {
@@ -505,25 +505,26 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
       // those in the color scale most exactly (the sum of all reflection 
       // coefficients is equal to 1). See also MeshVS_NodalColorPrsBuilder
       // class for more explanations.
-      aMaterial2[i].SetAmbient( .5 );
-      aMaterial2[i].SetDiffuse( .5 );
-      aMaterial2[i].SetSpecular( 0. );
-      aMaterial2[i].SetEmissive( 0. );
+      aMaterial2[i].SetAmbientColor (Quantity_Color (Graphic3d_Vec3 (0.5f)));
+      aMaterial2[i].SetDiffuseColor (Quantity_Color (Graphic3d_Vec3 (0.5f)));
     }
   }
 
   // Draw faces with two color
+  if (!aTwoColorsOfElements.IsEmpty())
+  {
+    Handle(Graphic3d_AspectFillArea3d) aGroupFillAspect2 = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, anInteriorColor, anEdgeColor,
+                                                                                          anEdgeType, anEdgeWidth, aMaterial2[0], aMaterial2[1]);
+    aGroup2->SetClosed (Standard_False); // ignore toSupressBackFaces
+    aGroup2->SetGroupPrimitivesAspect (aGroupFillAspect2);
+  }
   for ( MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger aColIter2 ( aTwoColorsOfElements );
         aColIter2.More(); aColIter2.Next() )
   {
-    Prs3d_Root::NewGroup ( Prs );
-    Handle ( Graphic3d_Group ) aGroup2 = Prs3d_Root::CurrentGroup ( Prs );
-    Prs3d_Root::NewGroup ( Prs );
-    Handle ( Graphic3d_Group ) aGroup3 = Prs3d_Root::CurrentGroup ( Prs );
-
-    Standard_Integer aSize = aColIter2.Value().Extent();
-    if ( aSize<=0 )
+    if (aColIter2.Value().IsEmpty())
+    {
       continue;
+    }
 
     Standard_Integer aNbFacePrimitives = 0;
     Standard_Integer aNbEdgePrimitives = 0;
@@ -571,9 +572,7 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
       anAsp->SetEdgeOn();
     else
       anAsp->SetEdgeOff();*/
-
-    Handle(Graphic3d_AspectLine3d) anEdgeAspect =
-      new Graphic3d_AspectLine3d (anEdgeColor, anEdgeType, anEdgeWidth);
+    aGroup2->SetPrimitivesAspect (anAsp);
 
     for( it.Reset(); it.More(); it.Next() )
     {
@@ -637,9 +636,7 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
     }
 
     aGroup2->AddPrimitiveArray (aFaceTriangles);
-    aGroup2->SetGroupPrimitivesAspect (anAsp);
-    aGroup3->AddPrimitiveArray (anEdgeSegments);
-    aGroup3->SetGroupPrimitivesAspect (anEdgeAspect);
+    aSGroup->AddPrimitiveArray (anEdgeSegments);
   }
 }