0022777: Visualization - Unsafe way to get attribute values from MeshVS_Drawer
[occt.git] / src / MeshVS / MeshVS_ElementalColorPrsBuilder.cxx
index c246e84..7ceb269 100644 (file)
@@ -179,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 );
@@ -194,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;
 
@@ -213,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,
@@ -227,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
     {
@@ -239,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())
   {
-    Standard_Integer aSize = aColIter.Value().Extent();
-    if ( aSize<=0 )
+    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())
+  {
+    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;
@@ -335,9 +351,6 @@ 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() );
     aFillAspect->SetEdgeOff();
@@ -448,11 +461,11 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
     {
       aGGroup->SetPrimitivesAspect (aFillAspect);
       aGGroup->AddPrimitiveArray (aFaceTriangles);
+      aGGroup->SetClosed (toSupressBackFaces == Standard_True);
       
       if (anEdgeOn)
       {
         aSGroup->AddPrimitiveArray (anEdgeSegments);
-        aSGroup->SetGroupPrimitivesAspect (anEdgeAspect);
       }
     }
     if (IsPolyL)
@@ -466,13 +479,14 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
       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 )
     {
@@ -481,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
     {
@@ -497,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;
@@ -563,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() )
     {
@@ -629,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);
   }
 }