]> OCCT Git - occt.git/commitdiff
0026072: Visualization - more realistic display of face edges
authordrochalo <diogo.lopes@opencascade.com>
Mon, 11 Mar 2024 09:46:04 +0000 (09:46 +0000)
committerdrochalo <diogo.lopes@opencascade.com>
Fri, 15 Mar 2024 15:27:02 +0000 (15:27 +0000)
Added calculation of normals to boundary edges.
Extended draw harness commands.
Added new test case.

src/AIS/AIS_ColoredShape.cxx
src/Graphic3d/Graphic3d_ArrayOfSegments.hxx
src/Prs3d/Prs3d_Drawer.hxx
src/StdPrs/StdPrs_ShadedShape.cxx
src/ViewerTest/ViewerTest.cxx
src/XDEDRAW/XDEDRAW.cxx
tests/v3d/bugs/bug26072 [new file with mode: 0644]

index ec68acf92574a817da421505604cb67ded27ee7c..516042e75de2830ea93a44033c1bf748b79f26cf 100644 (file)
@@ -636,12 +636,22 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation
         {
           if (Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw, aDrawer->FaceBoundaryUpperContinuity()))
           {
-            if (anEdgesGroup.IsNull())
+            Handle(Graphic3d_AspectLine3d) aLineAspect = aDrawer->FaceBoundaryAspect()->Aspect();
+            if (aDrawer->FaceBoundaryShadingOverride())
             {
+              Quantity_Color aColor = aDrawer->Color();
+              if (aDrawer->HasOwnShadingAspect())
+              {
+                aColor = aDrawer->ShadingAspect()->Color();
+              }
+              aLineAspect->SetColor (aColor);
               anEdgesGroup = thePrs->NewGroup();
             }
-
-            anEdgesGroup->SetPrimitivesAspect (aDrawer->FaceBoundaryAspect()->Aspect());
+            else if (anEdgesGroup.IsNull())
+            {
+              anEdgesGroup = thePrs->NewGroup();
+            }
+            anEdgesGroup->SetGroupPrimitivesAspect (aLineAspect);
             anEdgesGroup->AddPrimitiveArray (aBndSegments);
           }
         }
index 2059c9587a89aff96eae8735caa43b321be551b0..770614011910b353a793cb7975d36089b0cd9c2e 100644 (file)
@@ -54,11 +54,16 @@ public:
   //! @param theMaxVertexs defines the maximum allowed vertex number in the array
   //! @param theMaxEdges   defines the maximum allowed edge   number in the array
   //! @param theHasVColors when TRUE, AddVertex(Point,Color) should be used for specifying vertex color
+  //! @param theHasVNormals when TRUE,  AddVertex(Point,Normal) or AddVertex(Point,Normal,Color) should be used to specify vertex normal;
+  //!                       vertex normals should be specified coherent to the edge's neighbour triangle face's orientation
+  //!                       (defined by order of vertexes within triangle) for proper rendering
   Graphic3d_ArrayOfSegments (Standard_Integer theMaxVertexs,
-                             Standard_Integer theMaxEdges   = 0,
-                             Standard_Boolean theHasVColors = Standard_False)
-  : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_SEGMENTS, theMaxVertexs, 0, theMaxEdges, theHasVColors ? Graphic3d_ArrayFlags_VertexColor : Graphic3d_ArrayFlags_None) {}
-
+                             Standard_Integer theMaxEdges = 0,
+                             Standard_Boolean theHasVColors = Standard_False,
+                             Standard_Boolean theHasVNormals = Standard_False)
+  : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_SEGMENTS, theMaxVertexs, 0, theMaxEdges,
+                                 (theHasVNormals ? Graphic3d_ArrayFlags_VertexNormal : Graphic3d_ArrayFlags_None)
+                               | (theHasVColors  ? Graphic3d_ArrayFlags_VertexColor  : Graphic3d_ArrayFlags_None)) {}
 
 };
 
index 38c85647b93807c4247f1b3fa2febb14d8edee02..83042c96a66be05077ed99821de12a06ae60d49c 100644 (file)
@@ -772,6 +772,17 @@ public:
     myFaceBoundaryDraw = false;
   }
 
+  //! Return flag value for boundary shading edge color override
+  Standard_Boolean FaceBoundaryShadingOverride() const
+  {
+    return myHasOwnFaceBoundaryDraw || myLink.IsNull()
+      ? myFaceBoundaryShadingOverride
+      : myLink->FaceBoundaryShadingOverride();
+  }
+  
+  //! Return flag value for boundary shading edge color override
+  void SetFaceBoundaryShadingOverride (Standard_Boolean theFlag) { myFaceBoundaryShadingOverride = theFlag; }
+
   //! Returns true if the drawer has its own attribute for face boundaries upper edge continuity class that overrides the one in the link.
   Standard_Boolean HasOwnFaceBoundaryUpperContinuity() const { return myFaceBoundaryUpperContinuity != -1; }
 
@@ -1008,6 +1019,7 @@ protected:
   Standard_Integer              myFaceBoundaryUpperContinuity; //!< the most edge continuity class (GeomAbs_Shape) to be included to face boundaries presentation, or -1 if undefined
   Standard_Boolean              myFaceBoundaryDraw;
   Standard_Boolean              myHasOwnFaceBoundaryDraw;
+  Standard_Boolean              myFaceBoundaryShadingOverride;
 
   Handle(Prs3d_DimensionAspect) myDimensionAspect;
   Prs3d_DimensionUnits          myDimensionModelUnits;
index fe2f667dbaa83aeb51e391400e8e172c3a37c4db..ba986bda7fb9a5f212a6c9689713af3cd7dbbddc 100644 (file)
@@ -299,9 +299,7 @@ namespace
     // for computing boundaries presentation
     Standard_Integer aNodeNumber = 0;
     Standard_Integer aNbPolylines = 0;
-
-    TopLoc_Location aTrsf;
-
+    TopLoc_Location aLoc;
     Handle(NCollection_Shared<TColgp_SequenceOfPnt>) aSeqPntsExtra;
     for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
     {
@@ -331,7 +329,7 @@ namespace
 
       // take one of the shared edges and get edge triangulation
       const TopoDS_Face& aFace = TopoDS::Face (anEdgeIter.Value().First());
-      Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aTrsf);
+      Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLoc);
       if (aTriangulation.IsNull())
       {
         continue;
@@ -345,7 +343,7 @@ namespace
         continue;
       }
 
-      Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf);
+      Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aLoc);
       if (!anEdgePoly.IsNull()
         && anEdgePoly->Nodes().Length() >= 2)
       {
@@ -371,7 +369,9 @@ namespace
 
     // create indexed segments array to pack polylines from different edges into single array
     const Standard_Integer aSegmentEdgeNb = (aNodeNumber - aNbPolylines) * 2;
-    Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNodeNumber + aNbExtra, aSegmentEdgeNb + aNbExtra);
+    const Standard_Boolean aToAddNormals = Standard_True;
+    Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNodeNumber + aNbExtra, aSegmentEdgeNb + aNbExtra,
+                                                                                 Standard_False, aToAddNormals);
     for (TopTools_IndexedDataMapOfShapeListOfShape::Iterator anEdgeIter (anEdgesMap); anEdgeIter.More(); anEdgeIter.Next())
     {
       if (anEdgeIter.Value().Extent() == 0)
@@ -379,49 +379,75 @@ namespace
         continue;
       }
 
-      const TopoDS_Face& aFace = TopoDS::Face (anEdgeIter.Value().First());
-      Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aTrsf);
-      if (aTriangulation.IsNull())
-      {
-        continue;
-      }
-
-      const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key());
-      if (theUpperContinuity < GeomAbs_CN
-       && anEdgeIter.Value().Extent() >= 2
-       && BRep_Tool::MaxContinuity (anEdge) > theUpperContinuity)
-      {
-        continue;
-      }
-
-      Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf);
-      if (anEdgePoly.IsNull()
-       || anEdgePoly->Nodes().Length () < 2)
+      Standard_Integer aFaceIndex = 0;
+      const Standard_Integer aFirstNodeInFace = aSegments->VertexNumber() + 1;
+      for (TopTools_ListOfShape::Iterator aFaceIter (anEdgeIter.Value()); aFaceIter.More(); aFaceIter.Next())
       {
-        continue;
-      }
+        const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Value());
+        Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLoc);
+        if (aTriangulation.IsNull())
+        {
+          continue;
+        }
 
-      // get edge nodes indexes from face triangulation
-      const TColStd_Array1OfInteger& anEdgeNodes = anEdgePoly->Nodes();
+        const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key());
+        if (theUpperContinuity < GeomAbs_CN
+         && anEdgeIter.Value().Extent() >= 2
+         && BRep_Tool::MaxContinuity (anEdge) > theUpperContinuity)
+        {
+          continue;
+        }
 
-      // collect the edge nodes
-      Standard_Integer aSegmentEdge = aSegments->VertexNumber() + 1;
-      for (Standard_Integer aNodeIdx = anEdgeNodes.Lower(); aNodeIdx <= anEdgeNodes.Upper(); ++aNodeIdx)
-      {
-        // node index in face triangulation
-        // get node and apply location transformation to the node
-        const Standard_Integer aTriIndex = anEdgeNodes.Value (aNodeIdx);
-        gp_Pnt aTriNode = aTriangulation->Node (aTriIndex);
-        if (!aTrsf.IsIdentity())
+        Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aLoc);
+        if (anEdgePoly.IsNull()
+          || anEdgePoly->Nodes().Length () < 2)
         {
-          aTriNode.Transform (aTrsf);
+          continue;
         }
 
-        aSegments->AddVertex (aTriNode);
-        if (aNodeIdx != anEdgeNodes.Lower())
+        // get edge nodes indexes from face triangulation
+        ++aFaceIndex;
+        const TColStd_Array1OfInteger& anEdgeNodes = anEdgePoly->Nodes();
+        const gp_Trsf& aTrsf = aLoc.Transformation();
+
+        // collect the edge nodes
+        Standard_Integer aSegmentEdge = aFirstNodeInFace;
+        for (Standard_Integer aNodeIdx = anEdgeNodes.Lower(); aNodeIdx <= anEdgeNodes.Upper(); ++aNodeIdx)
         {
-          aSegments->AddEdge (  aSegmentEdge);
-          aSegments->AddEdge (++aSegmentEdge);
+          // node index in face triangulation
+          // get node and apply location transformation to the node
+          const Standard_Integer aTriIndex = anEdgeNodes.Value (aNodeIdx);
+          
+          gp_Pnt aTriNode = aTriangulation->Node (aTriIndex);
+          gp_Dir aNorm = aTriangulation->Normal (aTriIndex);
+          if (aFace.Orientation() == TopAbs_REVERSED)
+          {
+            aNorm.Reverse();
+          }
+          if (!aLoc.IsIdentity())
+          {
+            aTriNode.Transform (aTrsf);
+            aNorm.Transform (aTrsf);
+          }
+          
+          if (aFaceIndex == 1)
+          {
+            aSegments->AddVertex (aTriNode, aNorm);
+            if (aNodeIdx != anEdgeNodes.Lower())
+            {
+              aSegments->AddEdge (aSegmentEdge);
+              aSegments->AddEdge (++aSegmentEdge);
+            }
+          }
+          else
+          {
+            gp_XYZ aNormSum;
+            aSegments->VertexNormal (aSegmentEdge, aNormSum.ChangeCoord (1), aNormSum.ChangeCoord (2), aNormSum.ChangeCoord (3));
+            aNormSum += aNorm.XYZ();
+            aNormSum.Normalize();
+            aSegments->SetVertexNormal (aSegmentEdge, aNormSum.ChangeCoord (1), aNormSum.ChangeCoord (2), aNormSum.ChangeCoord (3));
+            ++aSegmentEdge;
+          }
         }
       }
     }
@@ -588,7 +614,13 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs,
     if (Handle(Graphic3d_ArrayOfSegments) aBndSegments = fillFaceBoundaries (theShape, theDrawer->FaceBoundaryUpperContinuity()))
     {
       Handle(Graphic3d_Group) aPrsGrp = !theGroup.IsNull() ? theGroup : thePrs->NewGroup();
-      aPrsGrp->SetGroupPrimitivesAspect (theDrawer->FaceBoundaryAspect()->Aspect());
+      Handle(Graphic3d_AspectLine3d) aLineAspect = theDrawer->FaceBoundaryAspect()->Aspect();
+      if (theDrawer->FaceBoundaryShadingOverride())
+      {
+        Quantity_Color aColor = theDrawer->ShadingAspect()->Color();
+        aLineAspect->SetColor (aColor);
+      }
+      aPrsGrp->SetGroupPrimitivesAspect (aLineAspect);
       aPrsGrp->AddPrimitiveArray (aBndSegments);
     }
   }
index 43aced25af00d2e8753c32968cafe1ef1b040fad..5824d3a32c90a4f2768a6ba6bc8bf5551813e5b3 100644 (file)
@@ -1713,6 +1713,11 @@ struct ViewerTest_AspectsChangeSet
   Standard_Integer             ToSetTypeOfFaceBoundaryLine;
   Aspect_TypeOfLine            TypeOfFaceBoundaryLine;
 
+  Standard_Integer             ToSetFaceBoundaryShading;
+  Standard_Integer             ToFaceBoundaryEdgeColorOverride;
+  Graphic3d_TypeOfShadingModel FaceBoundaryShading;
+  TCollection_AsciiString      FaceBoundaryShadingModelName;
+
   Standard_Integer             ToSetMaxParamValue;
   Standard_Real                MaxParamValue;
 
@@ -1787,6 +1792,9 @@ struct ViewerTest_AspectsChangeSet
     FaceBoundaryWidth          (1.0f),
     ToSetTypeOfFaceBoundaryLine(0),
     TypeOfFaceBoundaryLine     (Aspect_TOL_SOLID),
+    ToSetFaceBoundaryShading   (0),
+    ToFaceBoundaryEdgeColorOverride (0),
+    FaceBoundaryShading        (Graphic3d_TypeOfShadingModel_DEFAULT),
     //
     ToSetMaxParamValue         (0),
     MaxParamValue              (500000),
@@ -1828,6 +1836,7 @@ struct ViewerTest_AspectsChangeSet
         && ToSetFaceBoundaryUpperContinuity == 0
         && ToSetFaceBoundaryColor == 0
         && ToSetFaceBoundaryWidth == 0
+        && ToSetFaceBoundaryShading == 0
         && ToSetTypeOfFaceBoundaryLine == 0
         && ToSetMaxParamValue     == 0
         && ToSetSensitivity       == 0
@@ -1875,6 +1884,12 @@ struct ViewerTest_AspectsChangeSet
       Message::SendFail() << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")";
       isOk = Standard_False;
     }
+    if (ToSetFaceBoundaryShading == 1
+      && (FaceBoundaryShading < Graphic3d_TypeOfShadingModel_DEFAULT || FaceBoundaryShading > Graphic3d_TypeOfShadingModel_PbrFacet))
+    {
+      Message::SendFail() << "Error: unknown face boundary shading model " << FaceBoundaryShadingModelName << ".";
+      isOk = Standard_False;
+    }
     if (MaxParamValue < 0.0)
     {
       Message::SendFail() << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")";
@@ -2034,6 +2049,16 @@ struct ViewerTest_AspectsChangeSet
         theDrawer->FaceBoundaryAspect()->SetWidth (FaceBoundaryWidth);
       }
     }
+    if (ToSetFaceBoundaryShading != 0)
+    {
+      if (ToSetFaceBoundaryShading != -1
+        || theDrawer->HasOwnFaceBoundaryAspect())
+      {
+        toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
+        theDrawer->FaceBoundaryAspect()->Aspect()->SetShadingModel (FaceBoundaryShading);
+        theDrawer->SetFaceBoundaryShadingOverride (ToFaceBoundaryEdgeColorOverride);
+      }
+    }
     if (ToSetTypeOfFaceBoundaryLine != 0)
     {
       if (ToSetTypeOfFaceBoundaryLine != -1
@@ -2389,6 +2414,17 @@ static Standard_Integer VAspects (Draw_Interpretor& theDI,
     if (aNames.Size() >= 2
      && aNames.Value (2).IsIntegerValue())
     {
+      if (aNames.Size() == 9 && aNames.Value (9).IsIntegerValue())
+      {
+        if (ViewerTest::ParseShadingModel (aNames.Value (8).ToCString(), aChangeSet->FaceBoundaryShading)
+         && (aNames.Value (9).IsIntegerValue() == 0 || aNames.Value (9).IsIntegerValue() == 1))
+        {
+          aChangeSet->ToSetFaceBoundaryShading = 1;
+          aChangeSet->ToFaceBoundaryEdgeColorOverride = aNames.Value (9).IsIntegerValue();
+          aNames.Remove (9);
+          aNames.Remove (8);
+        }
+      }
       if (aNames.Size() == 7)
       {
         if (ViewerTest::ParseLineType (aNames.Value (7).ToCString(), aChangeSet->TypeOfFaceBoundaryLine))
@@ -3148,6 +3184,29 @@ static Standard_Integer VAspects (Draw_Interpretor& theDI,
       aChangeSet->ToSetShadingModel = -1;
       aChangeSet->ShadingModel = Graphic3d_TypeOfShadingModel_DEFAULT;
     }
+    else if (anArg == "-setboundaryshading")
+    {
+      aChangeSet->ToSetFaceBoundaryShading = 1;
+      aChangeSet->FaceBoundaryShadingModelName = theArgVec[++anArgIter];
+      if (!ViewerTest::ParseShadingModel (theArgVec[anArgIter], aChangeSet->FaceBoundaryShading))
+      {
+        Message::SendFail() << "Error: wrong syntax at " << anArg;
+        return 1;
+      }
+      Standard_Integer anOverrideFlag = Draw::Atoi (theArgVec[++anArgIter]);
+      if (!(anOverrideFlag == 0 || anOverrideFlag == 1))
+      {
+        Message::SendFail() << "Error: wrong syntax at " << anArg;
+        return 1;
+      }
+      aChangeSet->ToFaceBoundaryEdgeColorOverride = anOverrideFlag;
+    }
+    else if (anArg == "-unsetboundaryshading")
+    {
+      aChangeSet->ToSetFaceBoundaryShading = -1;
+      aChangeSet->ToFaceBoundaryEdgeColorOverride = 0;
+      aChangeSet->FaceBoundaryShading = Graphic3d_TypeOfShadingModel_Unlit;
+      }
     else if (anArg == "-setinterior"
           || anArg == "-setinteriorstyle"
           || anArg == "-interior"
@@ -3272,6 +3331,8 @@ static Standard_Integer VAspects (Draw_Interpretor& theDI,
       aChangeSet->FaceBoundaryWidth = 1.0f;
       aChangeSet->ToSetTypeOfFaceBoundaryLine = -1;
       aChangeSet->TypeOfFaceBoundaryLine = Aspect_TOL_SOLID;
+      aChangeSet->ToSetFaceBoundaryShading = -1;
+      aChangeSet->FaceBoundaryShading = Graphic3d_TypeOfShadingModel_DEFAULT;
       //
       aChangeSet->ToSetHatch = -1;
       aChangeSet->StdHatchStyle = -1;
@@ -6804,6 +6865,8 @@ vaspects [-noupdate|-update] [name1 [name2 [...]] | -defaults] [-subshapes subna
          [-sensitivity {selection_mode} {value}]
          [-shadingModel {unlit|flat|gouraud|phong|pbr|pbr_facet}]
            [-unsetShadingModel]
+         [-setboundaryshading {unlit|flat|gouraud|phong|pbr|pbr_facet}]
+           [-unsetboundaryshading]
          [-interior {solid|hatch|hidenline|point}] [-setHatch HatchStyle]
            [-unsetInterior]
          [-faceBoundaryDraw {0|1}] [-mostContinuity {c0|g1|c1|g2|c2|c3|cn}]
index 49d6c2685b3db12c14ff33e8606efd7c57d48994..b557a96523a4bc72821fe23ee356637bdd4515d0 100644 (file)
@@ -1197,7 +1197,7 @@ static Standard_Integer XShowFaceBoundary (Draw_Interpretor& di,
                                            Standard_Integer argc,
                                            const char ** argv)
 {
-  if (( argc != 4 && argc < 7 ) || argc > 9)
+  if (( argc != 4 && argc < 7 ) || argc > 11)
   {
     di << "Usage :\n " << argv[0]
        << " Doc Label IsOn [R G B [LineWidth [LineStyle]]]\n"
@@ -1216,7 +1216,11 @@ static Standard_Integer XShowFaceBoundary (Draw_Interpretor& di,
        << "                 1 - dashed \n"
        << "                 2 - dot    \n"
        << "                 3 - dashdot\n"
-       << "                (default is solid)";
+       << "                (default is solid)\n"
+       << "   Shading   - flag indicating if the boundaries\n"
+       << "               should be shaded:"
+       << "                 0 - no override edge color"
+       << "                 1 - override edge color";
 
     return 1;
   }
@@ -1310,6 +1314,17 @@ static Standard_Integer XShowFaceBoundary (Draw_Interpretor& di,
 
   aDrawer->SetFaceBoundaryAspect (aBoundaryAspect);
 
+  // set shading properties for face boundaries
+  if (argc == 11)
+  {
+    Graphic3d_TypeOfShadingModel aShadingModel;
+    if (ViewerTest::ParseShadingModel (argv[9], aShadingModel))
+    {
+      aDrawer->FaceBoundaryAspect()->Aspect()->SetShadingModel (aShadingModel);
+      aDrawer->SetFaceBoundaryShadingOverride (Draw::Atoi (argv[10]) == 1 ? Standard_True : Standard_False);
+    }
+  }
+
   aContext->Redisplay (anInteractive, Standard_True);
   
   return 0;
diff --git a/tests/v3d/bugs/bug26072 b/tests/v3d/bugs/bug26072
new file mode 100644 (file)
index 0000000..171790e
--- /dev/null
@@ -0,0 +1,40 @@
+puts "========"
+puts "0026072: Visualization - more realistic display of face edges"
+puts "========"
+
+pload MODELING VISUALIZATION XDE
+testreadstep [locate_data_file as1-oc-214-mat.stp] s
+vclear 
+vinit
+vdisplay s -dispmode 1
+vfit
+vshowfaceboundary s -setboundaryshading phong 1 -boundarycolor 50 250 50
+vviewparams -scale 4.0 -proj 1.0 1.0 1.0 -up -1.0 -1.0 0.0 -at 20.0 0.0 -20.0
+vdump $::imagedir/${::casename}_shading_1.png
+vviewparams -scale 4.0 -proj 2.0 -1.5 3.0 -up 0.0 1.0 1.0 -at 20.0 130.0 -50.0
+vdump $::imagedir/${::casename}_shading_2.png
+
+vshowfaceboundary s -setboundaryshading phong 0 -boundarycolor 50 250 50
+vviewparams -scale 4.0 -proj 1.0 1.0 1.0 -up -1.0 -1.0 0.0 -at 20.0 0.0 -20.0
+vdump $::imagedir/${::casename}_noshading_1.png
+vviewparams -scale 4.0 -proj 2.0 -1.5 3.0 -up 0.0 1.0 1.0 -at 20.0 130.0 -50.0
+vdump $::imagedir/${::casename}_noshading_2.png
+
+vclear
+vclose
+ReadStep D [locate_data_file as1-oc-214-mat.stp]
+XShow D
+vfit
+vsetdispmode 1
+
+XShowFaceBoundary D 0:1:1:1 1 156 156 156 1 0 phong 1
+vviewparams -scale 4.0 -proj 1.0 1.0 1.0 -up -1.0 -1.0 0.0 -at 20.0 0.0 -20.0
+vdump $::imagedir/${::casename}_xview_shading_1.png
+vviewparams -scale 4.0 -proj 2.0 -1.5 3.0 -up 0.0 1.0 1.0 -at 20.0 130.0 -50.0
+vdump $::imagedir/${::casename}_xview_shading_2.png
+
+XShowFaceBoundary D 0:1:1:1 1 156 156 156 1 0 phong 0
+vviewparams -scale 4.0 -proj 1.0 1.0 1.0 -up -1.0 -1.0 0.0 -at 20.0 0.0 -20.0
+vdump $::imagedir/${::casename}_xview_noshading_1.png
+vviewparams -scale 4.0 -proj 2.0 -1.5 3.0 -up 0.0 1.0 1.0 -at 20.0 130.0 -50.0
+vdump $::imagedir/${::casename}_xview_noshading_2.png