]> OCCT Git - occt.git/commitdiff
0025845: VIS - Surface normals to be associated with polygonal source
authorkgv <kgv@opencascade.com>
Tue, 30 Mar 2021 18:26:45 +0000 (21:26 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 2 Apr 2021 17:01:33 +0000 (20:01 +0300)
IVtk_IShapeData::InsertCoordinate() has been replaced by IVtk_IShapeData::InsertPoint()
defining vertex position with surface normal.
IVtkVTK_ShapeData now allocates normals array within vtkPolyData.
IVtkOCC_ShapeMesher now fills in vertex positions with surfcae normals.
IVtkTools_SubPolyDataFilter has been corrected to optionally copy normals.

ivtksetboundingdraw command has been merged into "ivtksetdispmode -faceBoundaryDraw".

12 files changed:
src/IVtk/IVtk_IShapeData.hxx
src/IVtkDraw/IVtkDraw.cxx
src/IVtkOCC/IVtkOCC_ShapeMesher.cxx
src/IVtkOCC/IVtkOCC_ShapeMesher.hxx
src/IVtkTools/IVtkTools_DisplayModeFilter.cxx
src/IVtkTools/IVtkTools_DisplayModeFilter.hxx
src/IVtkTools/IVtkTools_SubPolyDataFilter.cxx
src/IVtkTools/IVtkTools_SubPolyDataFilter.hxx
src/IVtkVTK/IVtkVTK_ShapeData.cxx
src/IVtkVTK/IVtkVTK_ShapeData.hxx
tests/vtk/ivtk/boundary_draw
tests/vtk/ivtk/seam_edges

index f6e7c6be193e36113ed1eda90f7436eaaf67c626..aed7ddebc2a38ba23116420f77288b6029df4a2e 100644 (file)
 #ifndef __IVTK_ISHAPEDATA_H__
 #define __IVTK_ISHAPEDATA_H__
 
+#include <gp_Pnt.hxx>
 #include <IVtk_Interface.hxx>
 #include <IVtk_Types.hxx>
+#include <NCollection_Vec3.hxx>
 
-class IVtk_IShapeData;
 DEFINE_STANDARD_HANDLE( IVtk_IShapeData, IVtk_Interface )
 
 //! @class IVtk_IShapeData
@@ -34,11 +35,11 @@ public:
   DEFINE_STANDARD_RTTIEXT(IVtk_IShapeData,IVtk_Interface)
 
   //! Insert a coordinate
-  //! @param [in] theX X coordinate
-  //! @param [in] theY Y coordinate
-  //! @param [in] theZ Z coordinate
+  //! @param [in] thePnt  point position
+  //! @param [in] theNorm point normal
   //! @return id of added point
-  virtual IVtk_PointId InsertCoordinate (double theX, double theY, double theZ) = 0;
+  virtual IVtk_PointId InsertPoint (const gp_Pnt& thePnt,
+                                    const NCollection_Vec3<float>& theNorm) = 0;
 
   //! Insert a vertex.
   //! @param [in] theShapeID id of the sub-shape to which the vertex belongs.
@@ -77,6 +78,27 @@ public:
                                const IVtk_PointId  thePointId2,
                                const IVtk_PointId  thePointId3,
                                const IVtk_MeshType theMeshType = MT_Undefined) = 0;
+
+public:
+
+  //! Insert a coordinate
+  //! @param [in] theX X coordinate
+  //! @param [in] theY Y coordinate
+  //! @param [in] theZ Z coordinate
+  //! @return id of added point
+  virtual IVtk_PointId InsertCoordinate (double theX, double theY, double theZ)
+  {
+    return InsertCoordinate (gp_Pnt (theX, theY, theZ));
+  }
+
+  //! Insert a coordinate
+  //! @param [in] thePnt point position
+  //! @return id of added point
+  IVtk_PointId InsertCoordinate (const gp_Pnt& thePnt)
+  {
+    return InsertPoint (thePnt, NCollection_Vec3<float>(0.0f, 0.0f, 1.0f));
+  }
+
 };
 
 #endif // __IVTK_ISHAPEDATA_H__
index b459f0c4abc2750979624e4bd4192f4558dbf9bc..e71826b5ef2d5614d3f5cb0b453b9f4061b3b42b 100644 (file)
@@ -514,6 +514,7 @@ vtkActor* CreateActor (const Standard_Integer theId,
   Handle(PipelinePtr) aPL = new PipelinePtr (theShape, theId, GetDefaultDrawer());
   GetPipelines()->Bind (theId, aPL);
 
+  aPL->Actor()->GetProperty()->SetInterpolationToPhong();
   return aPL->Actor();
 }
 
@@ -828,158 +829,159 @@ static Standard_Integer VtkRemove (Draw_Interpretor& ,
 
 //================================================================
 // Function  : VtkSetDisplayMode
-// Purpose   : 
-// Draw args : ivtksetdispmode [name] mode(0,1)
+// Purpose   :
 //================================================================
-static Standard_Integer VtkSetDisplayMode (Draw_Interpretor& ,
+static Standard_Integer VtkSetDisplayMode (Draw_Interpretor& theDI,
                                            Standard_Integer theArgNum,
                                            const char** theArgs)
 {
   if (!GetInteractor()
    || !GetInteractor()->IsEnabled())
   {
-    Message::SendFail() << "Error: call ivtkinit before";
-    return 1;
-  }
-  else if (theArgNum != 2 && theArgNum != 3)
-  {
-    Message::SendFail() << "Syntax error: expects 1 or 2 arguments";
+    theDI << "Error: call ivtkinit before";
     return 1;
   }
 
-  if (theArgNum == 2)
+  Standard_Integer aDispMode = -1;
+  Standard_Integer isFaceBoundaryDraw = -1, isSmoothShading = -1;
+  Graphic3d_TypeOfShadingModel aShadingModel = Graphic3d_TOSM_DEFAULT;
+  NCollection_Sequence< vtkSmartPointer<vtkActor> > anActors;
+  for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
   {
-    // Set disp mode for all objects
-    Standard_Integer aMode =  Draw::Atoi (theArgs[1]); // Get mode
-    DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors());
-    while (anIter.More())
+    TCollection_AsciiString anArgCase (theArgs[anArgIter]);
+    anArgCase.LowerCase();
+    if (anArgCase == "-faceboundarydraw"
+     || anArgCase == "-drawfaceboundary"
+     || anArgCase == "-faceboundary")
     {
-      vtkSmartPointer<vtkActor> anActor = anIter.Key1();
-      IVtkTools_ShapeDataSource* aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
-      if (aSrc)
+      bool toDraw = Draw::ParseOnOffNoIterator (theArgNum, theArgs, anArgIter);
+      isFaceBoundaryDraw = toDraw ? 1 : 0;
+    }
+    else if (anArgCase == "-smoothshading"
+          || anArgCase == "-smooth")
+    {
+      bool toEnable = Draw::ParseOnOffNoIterator (theArgNum, theArgs, anArgIter);
+      isSmoothShading = toEnable ? 1 : 0;
+    }
+    else if (anArgIter + 1 < theArgNum
+          && (anArgCase == "-shadingmodel"))
+    {
+      TCollection_AsciiString aModelName (theArgs[++anArgIter]);
+      aModelName.LowerCase();
+      if (aModelName == "fragment"
+       || aModelName == "frag"
+       || aModelName == "phong")
       {
-        IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
-        if (!anOccShape.IsNull())
-        {
-          IVtkTools_DisplayModeFilter* aFilter = GetPipeline ( anOccShape->GetId() )->GetDisplayModeFilter();
-          aFilter->SetDisplayMode((IVtk_DisplayMode)aMode);
-          aFilter->Modified();
-          aFilter->Update();
-        }
+        aShadingModel = Graphic3d_TOSM_FRAGMENT;
+      }
+      else if (aModelName == "vertex"
+            || aModelName == "vert"
+            || aModelName == "gouraud")
+      {
+        aShadingModel = Graphic3d_TOSM_VERTEX;
+      }
+      else if (aModelName == "facet"
+            || aModelName == "flat")
+      {
+        aShadingModel = Graphic3d_TOSM_FACET;
+      }
+      else
+      {
+        theDI << "Syntax error: unknown shading model '" << theArgs[anArgIter] << "'";
+        return 1;
       }
-      anIter.Next();
     }
-  }
-  // Set disp mode for named object
-  else 
-  {
-    TCollection_AsciiString aName = theArgs[1];
-    vtkSmartPointer<vtkActor> anActor;
-    if (!GetMapOfActors().Find2 (aName, anActor))
+    else if (aDispMode == -1
+          && (anArgCase == "0"
+           || anArgCase == "1"))
     {
-      Message::SendFail() << "Syntax error: object '" << aName << "' not found";
-      return 1;
+      aDispMode = Draw::Atoi (theArgs[anArgIter]);
     }
-
-    Standard_Integer aMode = atoi(theArgs[2]);
-    vtkSmartPointer<IVtkTools_ShapeDataSource> aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
-    if (aSrc)
+    else if (aDispMode == -1
+          && (anArgCase == "-shaded"
+           || anArgCase == "-shading"))
+    {
+      aDispMode = DM_Shading;
+    }
+    else if (aDispMode == -1
+          && anArgCase == "-wireframe")
     {
-      IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
-      if (!anOccShape.IsNull())
+      aDispMode = DM_Wireframe;
+    }
+    else
+    {
+      TCollection_AsciiString aName = theArgs[anArgIter];
+      vtkSmartPointer<vtkActor> anActor;
+      if (!GetMapOfActors().Find2 (aName, anActor))
       {
-        IVtkTools_DisplayModeFilter* aFilter = GetPipeline (anOccShape->GetId())->GetDisplayModeFilter();
-        aFilter->SetDisplayMode ((IVtk_DisplayMode)aMode);
-        aFilter->Modified();
-        aFilter->Update();
+        theDI << "Syntax error: object '" << aName << "' not found";
+        return 1;
       }
+      anActors.Append (anActor);
     }
   }
-
-  // Redraw window
-  GetInteractor()->Render();
-  return 0;
-}
-
-//================================================================
-// Function  : VtkSetBoundaryDraw
-// Purpose   :
-//================================================================
-static Standard_Integer VtkSetBoundaryDraw (Draw_Interpretor& ,
-                                            Standard_Integer theArgNum,
-                                            const char** theArgs)
-{
-  if (!GetInteractor()
-   || !GetInteractor()->IsEnabled())
+  if (aDispMode == -1)
   {
-    Message::SendFail() << "Error: call ivtkinit before";
-    return 1;
-  }
-  else if (theArgNum != 2 && theArgNum != 3)
-  {
-    Message::SendFail() << "Syntax error: expects 1 or 2 arguments";
+    theDI << "Syntax error: wrong number of arguments";
     return 1;
   }
 
-  if (theArgNum == 2)
+  if (anActors.IsEmpty())
   {
-    // Set disp mode for all objects
-    Standard_Boolean toDraw = true;
-    Draw::ParseOnOff (theArgs[1], toDraw);
-    DoubleMapOfActorsAndNames::Iterator anIter(GetMapOfActors());
-    while (anIter.More())
+    // update all objects
+    for (DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors()); anIter.More(); anIter.Next())
     {
-      vtkSmartPointer<vtkActor> anActor = anIter.Key1();
-      // Set Red color for boundary edges
-      vtkLookupTable* aTable = (vtkLookupTable*)anActor->GetMapper()->GetLookupTable();
-      IVtkTools::SetLookupTableColor(aTable, MT_SharedEdge, 1., 0., 0., 1.);
-
-      IVtkTools_ShapeDataSource* aSrc = IVtkTools_ShapeObject::GetShapeSource(anActor);
-      if (aSrc)
-      {
-        IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
-        if (!anOccShape.IsNull())
-        {
-          IVtkTools_DisplayModeFilter* aFilter = GetPipeline(anOccShape->GetId())->GetDisplayModeFilter();
-          aFilter->SetDisplayMode(DM_Shading);
-          aFilter->SetFaceBoundaryDraw(toDraw != 0);
-          aFilter->Modified();
-          aFilter->Update();
-        }
-      }
-      anIter.Next();
+      anActors.Append (anIter.Key1());
     }
   }
-  else
+
+  for (NCollection_Sequence< vtkSmartPointer<vtkActor> >::Iterator anActorIter (anActors); anActorIter.More(); anActorIter.Next())
   {
-    // Set disp mode for named object
-    TCollection_AsciiString aName = theArgs[1];
-    vtkSmartPointer<vtkActor> anActor;
-    if (!GetMapOfActors().Find2 (aName, anActor))
+    vtkSmartPointer<vtkActor> anActor = anActorIter.Value();
+    IVtkTools_ShapeDataSource* aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
+    if (aSrc == NULL)
     {
-      Message::SendFail() << "Syntax error: object '" << aName << "' not found";
-      return 1;
+      continue;
     }
 
-    Standard_Boolean toDraw = true;
-    Draw::ParseOnOff (theArgs[2], toDraw);
-
-    // Set Red color for boundary edges
-    vtkLookupTable* aTable = (vtkLookupTable*)anActor->GetMapper()->GetLookupTable();
-    IVtkTools::SetLookupTableColor (aTable, MT_SharedEdge, 1., 0., 0., 1.);
-
-    vtkSmartPointer<IVtkTools_ShapeDataSource> aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
-    if (aSrc)
+    IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
+    if (!anOccShape.IsNull())
     {
-      IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
-      if (!anOccShape.IsNull())
+      IVtkTools_DisplayModeFilter* aFilter = GetPipeline ( anOccShape->GetId() )->GetDisplayModeFilter();
+      aFilter->SetDisplayMode ((IVtk_DisplayMode)aDispMode);
+      if (isFaceBoundaryDraw != -1)
+      {
+        // Set Red color for boundary edges
+        vtkLookupTable* aTable = (vtkLookupTable*)anActor->GetMapper()->GetLookupTable();
+        IVtkTools::SetLookupTableColor (aTable, MT_SharedEdge, 1., 0., 0., 1.);
+        aFilter->SetFaceBoundaryDraw (isFaceBoundaryDraw == 1);
+      }
+      if (isSmoothShading != -1)
       {
-        IVtkTools_DisplayModeFilter* aFilter = GetPipeline (anOccShape->GetId())->GetDisplayModeFilter();
-        aFilter->SetDisplayMode (DM_Shading);
-        aFilter->SetFaceBoundaryDraw (toDraw != 0);
-        aFilter->Modified();
-        aFilter->Update();
+        aFilter->SetSmoothShading (isSmoothShading == 1);
       }
+      switch (aShadingModel)
+      {
+        case Graphic3d_TOSM_FACET:
+        {
+          anActor->GetProperty()->SetInterpolationToFlat();
+          break;
+        }
+        case Graphic3d_TOSM_VERTEX:
+        {
+          anActor->GetProperty()->SetInterpolationToGouraud();
+          break;
+        }
+        case Graphic3d_TOSM_FRAGMENT:
+        {
+          anActor->GetProperty()->SetInterpolationToPhong();
+          break;
+        }
+        default: break;
+      }
+
+      aFilter->Modified();
+      aFilter->Update();
     }
   }
 
@@ -1655,16 +1657,14 @@ void IVtkDraw::Commands (Draw_Interpretor& theCommands)
     __FILE__, VtkRemove, group);
 
   theCommands.Add("ivtksetdispmode",
-              "ivtksetdispmode [name] mode={0|1}"
-      "\n\t\t: Sets or unsets display mode 'mode' to the object with name 'name' or to all objects.",
+              "ivtksetdispmode [name] mode={0|1} [-faceBoundaryDraw {0|1}] [-smoothShading {0|1}]"
+      "\n\t\t:                                   [-shadingModel {phong|gouraud|flat}]"
+      "\n\t\t: Sets or unsets display mode to the object with the given name or to all objects."
+      "\n\t\t:   -faceBoundaryDraw show/hide boundaries within shading display mode"
+      "\n\t\t:   -smoothShading    enable/disable vertex normals for smooth shading"
+      "\n\t\t:   -shadingModel     sets specified shading model",
     __FILE__, VtkSetDisplayMode, group);
 
-  theCommands.Add("ivtksetboundingdraw",
-              "ivtksetboundingdraw [name] {on|off}"
-      "\n\t\t: Sets or unsets boundaries drawing for shading display mode"
-      "\n\t\t: to the object with name 'name' or to all objects.",
-    __FILE__, VtkSetBoundaryDraw, group);
-
   theCommands.Add("ivtksetselmode",
               "ivtksetselmode [name] mode {on|off}"
       "\n\t\t: Sets or unsets selection mode 'mode' to the object with name 'name'"
index f0caffdcf6d73d2c54e02e744b589c94f06bf37c..9e341e8d3c6ad48d1da56a6cf3a2c4cfd713aaec 100644 (file)
@@ -71,6 +71,15 @@ void IVtkOCC_ShapeMesher::internalBuild()
     StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (anOcctShape, anOcctDrawer, true);
     StdPrs_ToolTriangulatedShape::Tessellate (anOcctShape, anOcctDrawer);
   }
+  for (TopExp_Explorer aFaceIter (anOcctShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
+  {
+    const TopoDS_Face& anOcctFace = TopoDS::Face (aFaceIter.Current());
+    TopLoc_Location aLoc;
+    if (const Handle(Poly_Triangulation)& anOcctTriangulation = BRep_Tool::Triangulation (anOcctFace, aLoc))
+    {
+      StdPrs_ToolTriangulatedShape::ComputeNormals (anOcctFace, anOcctTriangulation);
+    }
+  }
 
   // Free vertices and free edges should always be shown.
   // Shared edges are needed in WF representation only.
@@ -232,49 +241,11 @@ void IVtkOCC_ShapeMesher::addVertex (const TopoDS_Vertex& theVertex,
 
   gp_Pnt aPnt3d = BRep_Tool::Pnt (theVertex);
 
-  IVtk_PointId anId = myShapeData->InsertCoordinate (aPnt3d.X(), aPnt3d.Y(), aPnt3d.Z());
+  IVtk_PointId anId = myShapeData->InsertCoordinate (aPnt3d);
   myShapeData->InsertVertex (theShapeId, anId, theMeshType);
 
 }
 
-//================================================================
-// Function : processPolyline
-// Purpose  :
-//================================================================
-void IVtkOCC_ShapeMesher::processPolyline (Standard_Integer          theNbNodes,
-                                      const TColgp_Array1OfPnt&      thePoints,
-                                      const TColStd_Array1OfInteger& thePointIds,
-                                      const IVtk_IdType              theOcctId,
-                                      bool                           theNoTransform,
-                                      gp_Trsf                        theTransformation,
-                                      const IVtk_MeshType            theMeshType)
-{
-  if (theNbNodes < 2)
-  {
-    return;
-  }
-
-  IVtk_PointIdList aPolyPointIds;
-
-  IVtk_PointId anId;
-  for (Standard_Integer aJ = 0; aJ < theNbNodes; aJ++)
-  {
-    Standard_Integer aPntId = thePointIds (aJ + 1);
-    gp_Pnt point = thePoints (aPntId);
-
-    if (!theNoTransform)
-    {
-      // Apply the transformation to points
-      point.Transform (theTransformation);
-    }
-
-    anId = myShapeData->InsertCoordinate (point.X(), point.Y(), point.Z());
-    aPolyPointIds.Append (anId);
-  }
-
-  myShapeData->InsertLine (theOcctId, &aPolyPointIds, theMeshType);
-}
-
 //================================================================
 // Function : addEdge
 // Purpose  :
@@ -288,73 +259,60 @@ void IVtkOCC_ShapeMesher::addEdge (const TopoDS_Edge&  theEdge,
     return;
   }
 
-  // Two discrete representations of an OCCT edge are possible:
-  // 1. Polygon on triangulation - holds Ids of points
-  // contained in Poly_Triangulation object
   Handle(Poly_PolygonOnTriangulation) aPolyOnTriangulation;
   Handle(Poly_Triangulation) aTriangulation;
-  TopLoc_Location aLocation;
-  BRep_Tool::PolygonOnTriangulation (theEdge,
-                                     aPolyOnTriangulation,
-                                     aTriangulation,
-                                     aLocation,
-                                     1);
-
-  // 2. 3D polygon - holds 3D points
-  Handle(Poly_Polygon3D) aPoly3d;
-  if (aPolyOnTriangulation.IsNull())
+  TopLoc_Location aLoc;
+  BRep_Tool::PolygonOnTriangulation (theEdge, aPolyOnTriangulation, aTriangulation, aLoc, 1);
+  if (!aPolyOnTriangulation.IsNull()
+    && aPolyOnTriangulation->NbNodes() >= 2)
   {
-    aPoly3d = BRep_Tool::Polygon3D (theEdge, aLocation);
-  }
+    // prefer polygon on triangulation when defined
+    const gp_Trsf aTrsf = aLoc.Transformation();
+    const bool hasTransform = !aLoc.IsIdentity();
 
-  if (aPoly3d.IsNull() && aPolyOnTriangulation.IsNull())
-  {
+    IVtk_PointIdList aPolyPointIds;
+    const Standard_Integer aNbNodes = aPolyOnTriangulation->NbNodes();
+    for (Standard_Integer aJ = 0; aJ < aNbNodes; aJ++)
+    {
+      const Standard_Integer aPntId = aPolyOnTriangulation->Node (aJ + 1);
+      gp_Pnt aPoint = aTriangulation->Node (aPntId);
+      gp_Dir aNorm  = aTriangulation->HasNormals() ? aTriangulation->Normal (aPntId) : gp::DZ();
+      if (hasTransform)
+      {
+        aPoint.Transform (aTrsf);
+        aNorm .Transform (aTrsf);
+      }
+
+      IVtk_PointId anId = myShapeData->InsertPoint (aPoint, Graphic3d_Vec3 ((float )aNorm.X(), (float )aNorm.Y(), (float )aNorm.Z()));
+      aPolyPointIds.Append (anId);
+    }
+    myShapeData->InsertLine (theShapeId, &aPolyPointIds, theMeshType);
     return;
   }
 
-  // Handle a non-identity transformation applied to the edge
-  gp_Trsf anEdgeTransf;
-  bool noTransform = true;
-  if (!aLocation.IsIdentity())
+  // try polygon 3d
+  Handle(Poly_Polygon3D) aPoly3d = BRep_Tool::Polygon3D (theEdge, aLoc);
+  if (aPoly3d.IsNull()
+   || aPoly3d->NbNodes() < 2)
   {
-    noTransform = false;
-    anEdgeTransf = aLocation.Transformation();
+    return;
   }
 
-  if (!aPoly3d.IsNull())
+  const gp_Trsf anEdgeTransf = aLoc.Transformation();
+  const bool     noTransform = aLoc.IsIdentity();
+  IVtk_PointIdList aPolyPointIds;
+  for (Standard_Integer aNodeIter = 1; aNodeIter <= aPoly3d->NbNodes(); ++aNodeIter)
   {
-    Standard_Integer aNbNodes = aPoly3d->NbNodes();
-    const TColgp_Array1OfPnt& aPoints = aPoly3d->Nodes();
-    TColStd_Array1OfInteger aPointIds (1, aNbNodes);
-
-    for (Standard_Integer anI = 1; anI <= aNbNodes; anI++)
+    gp_Pnt aPnt = aPoly3d->Nodes().Value (aNodeIter);
+    if (!noTransform)
     {
-      aPointIds.SetValue (anI, anI);
+      aPnt.Transform (anEdgeTransf);
     }
 
-    processPolyline (aNbNodes,
-                     aPoints,
-                     aPointIds,
-                     theShapeId,
-                     noTransform,
-                     anEdgeTransf,
-                     theMeshType);
-  }
-  else if (aPolyOnTriangulation->NbNodes() >= 2)
-  {
-    IVtk_PointIdList aPolyPointIds;
-    const Standard_Integer aNbNodes = aPolyOnTriangulation->NbNodes();
-    for (Standard_Integer aJ = 0; aJ < aNbNodes; aJ++)
-    {
-      const Standard_Integer aPntId = aPolyOnTriangulation->Node (aJ + 1);
-      gp_Pnt aPoint = aTriangulation->Node (aPntId);
-      if (!noTransform) { aPoint.Transform (anEdgeTransf); }
-
-      IVtk_PointId anId = myShapeData->InsertCoordinate (aPoint.X(), aPoint.Y(), aPoint.Z());
-      aPolyPointIds.Append (anId);
-    }
-    myShapeData->InsertLine (theShapeId, &aPolyPointIds, theMeshType);
+    const IVtk_PointId anId = myShapeData->InsertCoordinate (aPnt);
+    aPolyPointIds.Append (anId);
   }
+  myShapeData->InsertLine (theShapeId, &aPolyPointIds, theMeshType);
 }
 
 //================================================================
@@ -373,12 +331,6 @@ void IVtkOCC_ShapeMesher::addWFFace (const TopoDS_Face&  theFace,
   TopoDS_Face aFaceToMesh = theFace;
   aFaceToMesh.Orientation (TopAbs_FORWARD);
 
-  // The code that builds wireframe representation for a TopoDS_Face
-  // has been adapted from some OCCT 6.5.1 methods:
-  // - Prs3d_WFShape::Add()
-  // - StdPrs_WFDeflectionRestrictedFace::Add()
-  // - StdPrs_DeflectionCurve::Add()
-
   // Add face's edges here but with the face ID
   for (TopExp_Explorer anEdgeIter (aFaceToMesh, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
   {
@@ -408,7 +360,7 @@ void IVtkOCC_ShapeMesher::addWFFace (const TopoDS_Face&  theFace,
     for (TColgp_HSequenceOfPnt::Iterator aNodeIter (*aPoints); aNodeIter.More(); aNodeIter.Next())
     {
       const gp_Pnt& aPnt = aNodeIter.Value();
-      const IVtk_PointId anId = myShapeData->InsertCoordinate (aPnt.X(), aPnt.Y(), aPnt.Z());
+      const IVtk_PointId anId = myShapeData->InsertCoordinate (aPnt);
       aPolyPointIds.Append (anId);
     }
 
@@ -428,7 +380,6 @@ void IVtkOCC_ShapeMesher::addShadedFace (const TopoDS_Face& theFace,
     return;
   }
 
-  // Build triangulation of the face.
   TopLoc_Location aLoc;
   const Handle(Poly_Triangulation)& anOcctTriangulation = BRep_Tool::Triangulation (theFace, aLoc);
   if (anOcctTriangulation.IsNull())
@@ -436,13 +387,10 @@ void IVtkOCC_ShapeMesher::addShadedFace (const TopoDS_Face& theFace,
     return;
   }
 
-  gp_Trsf aPntTransform;
-  Standard_Boolean noTransform = Standard_True;
-  if (!aLoc.IsIdentity())
-  {
-    noTransform = Standard_False;
-    aPntTransform = aLoc.Transformation();
-  }
+  // Determinant of transform matrix less then 0 means that mirror transform applied
+  const gp_Trsf aTrsf = aLoc.Transformation();
+  const bool hasTransform = !aLoc.IsIdentity();
+  const bool isMirrored   = aTrsf.VectorialPart().Determinant() < 0;
 
   // Get triangulation points.
   Standard_Integer aNbPoints = anOcctTriangulation->NbNodes();
@@ -453,14 +401,19 @@ void IVtkOCC_ShapeMesher::addShadedFace (const TopoDS_Face& theFace,
   for (Standard_Integer anI = 1; anI <= aNbPoints; anI++)
   {
     gp_Pnt aPoint = anOcctTriangulation->Node (anI);
-
-    if (!noTransform)
+    gp_Dir aNorm  = anOcctTriangulation->HasNormals() ? anOcctTriangulation->Normal (anI) : gp::DZ();
+    if ((theFace.Orientation() == TopAbs_REVERSED) ^ isMirrored)
     {
-      aPoint.Transform (aPntTransform);
+      aNorm.Reverse();
+    }
+    if (hasTransform)
+    {
+      aPoint.Transform (aTrsf);
+      aNorm .Transform (aTrsf);
     }
 
     // Add a point into output shape data and keep its id in the array.
-    anId = myShapeData->InsertCoordinate (aPoint.X(), aPoint.Y(), aPoint.Z());
+    anId = myShapeData->InsertPoint (aPoint, Graphic3d_Vec3 ((float )aNorm.X(), (float )aNorm.Y(), (float )aNorm.Z()));
     aPointIds.SetValue (anI, anId);
   }
 
@@ -469,9 +422,16 @@ void IVtkOCC_ShapeMesher::addShadedFace (const TopoDS_Face& theFace,
   Standard_Integer aN1, aN2, aN3;
   for (Standard_Integer anI = 1; anI <= aNbTriangles; anI++)
   {
-    anOcctTriangulation->Triangle (anI).Get (aN1, aN2, aN3); // get indexes of triangle's points
+    if (theFace.Orientation() == TopAbs_REVERSED)
+    {
+      anOcctTriangulation->Triangle (anI).Get (aN1, aN3, aN2);
+    }
+    else
+    {
+      anOcctTriangulation->Triangle (anI).Get (aN1, aN2, aN3);
+    }
+
     // Insert new triangle on these points into output shape data.
-    myShapeData->InsertTriangle (
-      theShapeId, aPointIds(aN1), aPointIds(aN2), aPointIds(aN3), MT_ShadedFace);
+    myShapeData->InsertTriangle (theShapeId, aPointIds(aN1), aPointIds(aN2), aPointIds(aN3), MT_ShadedFace);
   }
 }
index d369c2d5ae9aa28ecda0f3122454fcf9d62dfde8..591fe72cb94d5180fd84a4a7aa7c8a64e7895f9c 100644 (file)
@@ -122,19 +122,6 @@ private:
   void addShadedFace (const TopoDS_Face&  theFace,
                       const IVtk_IdType   theShapeId);
 
-  //! Internal helper method that unpacks the input arrays of points and 
-  //! connectivity and creates the polyline using IPolyData interface.
-  //! Optionally, the transformation specified through the last argument
-  //! can be applied to each point's coordinates (noTransform == true).
-  //! The polyline is associated with the given sub-shape ID.
-  void processPolyline (Standard_Integer               theNbNodes,
-                        const TColgp_Array1OfPnt&      thePoints,
-                        const TColStd_Array1OfInteger& thePointIds, 
-                        const IVtk_IdType              theOcctId,
-                        bool                           theNoTransform,
-                        gp_Trsf                        theTransformation,
-                        const IVtk_MeshType            theMeshType);
-
   //! Get the IShape as OCC implementation
   const IVtkOCC_Shape::Handle GetShapeObj() const;
 
index e80a2104f02bb174d8a73c46c070ad449654413f..d478fc146040b1ff63417cfac6bfada0779e7c6a 100644 (file)
@@ -34,9 +34,10 @@ vtkStandardNewMacro(IVtkTools_DisplayModeFilter)
 // Purpose:
 //============================================================================
 IVtkTools_DisplayModeFilter::IVtkTools_DisplayModeFilter()
-  : myDisplayMode (DM_Wireframe),
-    myDoDisplaySharedVertices (false),
-  myDrawFaceBoundaries( false )
+: myDisplayMode (DM_Wireframe),
+  myDoDisplaySharedVertices (false),
+  myDrawFaceBoundaries (false),
+  myIsSmoothShading (true)
 {
   // Filter according to values in subshapes types array.
   myIdsArrayName = IVtkVTK_ShapeData::ARRNAME_MESH_TYPES();
@@ -78,6 +79,7 @@ int IVtkTools_DisplayModeFilter::RequestData (vtkInformation        *theRequest,
                                               vtkInformationVector  *theOutputVector)
 {
   SetData (myModesDefinition[myDisplayMode]);
+  myToCopyNormals = myIsSmoothShading && (myDisplayMode == DM_Shading);
   return Superclass::RequestData (theRequest, theInputVector, theOutputVector);
 }
 
@@ -184,3 +186,16 @@ void IVtkTools_DisplayModeFilter::SetFaceBoundaryDraw(bool theToDraw)
   }
   Modified();
 }
+
+//============================================================================
+// Method: SetSmoothShading
+// Purpose:
+//============================================================================
+void IVtkTools_DisplayModeFilter::SetSmoothShading (bool theIsSmooth)
+{
+  if (myIsSmoothShading != theIsSmooth)
+  {
+    myIsSmoothShading = theIsSmooth;
+    Modified();
+  }
+}
index a81e331e45db02af304e06b3d982d4e06fa16f49..72ee21188ac0691f7fa54af1df28eb13d1758947 100644 (file)
@@ -58,6 +58,12 @@ public:
   //! Returns True if drawing Boundary of faces for shading mode is defined.
   bool FaceBoundaryDraw() const { return myDrawFaceBoundaries; }
 
+  //! Returns TRUE if vertex normals should be included for smooth shading within DM_Shading mode or not.
+  bool IsSmoothShading() const { return myIsSmoothShading; }
+
+  //! Set if vertex normals should be included for smooth shading or not.
+  void SetSmoothShading (bool theIsSmooth);
+
 protected:
   //! Filter cells according to the given set of ids.
   virtual int RequestData (vtkInformation *, vtkInformationVector **, vtkInformationVector *) Standard_OVERRIDE;
@@ -66,13 +72,12 @@ protected:
   virtual ~IVtkTools_DisplayModeFilter();
 
 protected:
-  //! Display mode defining mesh types to pass through this filter.
-  IVtk_DisplayMode      myDisplayMode;
+  IVtk_DisplayMode      myDisplayMode;             //!< Display mode defining mesh types to pass through this filter
   IVtk_IdTypeMap        myModesDefinition[2];
   bool                  myDoDisplaySharedVertices;
 
-  //! Draw Face boundaries flag is applicable only for shading display mode.
-  bool                  myDrawFaceBoundaries;
+  bool                  myDrawFaceBoundaries;      //!< Draw Face boundaries within shading display mode
+  bool                  myIsSmoothShading;         //!< include vertex normals for smooth shading or not
 };
 
 #ifdef _MSC_VER
index 26ded68af52fbf75f829989baf26223d14b6e668..31163f602874cf0b79937eb89c2494e93fed06db 100644 (file)
 #pragma warning(push)
 #endif
 #include <vtkCellData.h>
+#include <vtkFloatArray.h>
+#include <vtkGenericCell.h>
 #include <vtkIdList.h>
 #include <vtkIdTypeArray.h>
 #include <vtkInformation.h>
 #include <vtkInformationVector.h>
 #include <vtkObjectFactory.h>
+#include <vtkPointData.h>
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
+namespace
+{
+  //! Modified version of vtkPolyData::CopyCells() that includes copying of normals.
+  //! How to ask vtkPolyData::CopyCells() to do that automatically?
+  static void copyCells (vtkPolyData* theDst,
+                         vtkPolyData* theSrc,
+                         vtkIdList* theIdList)
+  {
+    //theDst->CopyCells (theSrc, theIdList);
+
+    const vtkIdType aNbPts = theSrc->GetNumberOfPoints();
+    vtkDataArray* anOldNormals = theSrc->GetPointData()->GetNormals();
+
+    if (theDst->GetPoints() == NULL)
+    {
+      theDst->SetPoints (vtkSmartPointer<vtkPoints>::New());
+    }
+
+    vtkSmartPointer<vtkIdList> aNewCellPts = vtkSmartPointer<vtkIdList>::New();
+    vtkSmartPointer<vtkGenericCell> aCell  = vtkSmartPointer<vtkGenericCell>::New();
+    NCollection_Vec3<double> anXYZ;
+    vtkPointData* aNewPntData  = theDst->GetPointData();
+    vtkCellData*  aNewCellData = theDst->GetCellData();
+    vtkPoints*    aNewPoints   = theDst->GetPoints();
+    vtkSmartPointer<vtkFloatArray> aNewNormals;
+    if (anOldNormals != NULL)
+    {
+      aNewNormals = vtkSmartPointer<vtkFloatArray>::New();
+      aNewNormals->SetName ("Normals");
+      aNewNormals->SetNumberOfComponents (3);
+      theDst->GetPointData()->SetNormals (aNewNormals);
+    }
+
+    vtkSmartPointer<vtkIdList> aPntMap = vtkSmartPointer<vtkIdList>::New(); // maps old pt ids into new
+    aPntMap->SetNumberOfIds (aNbPts);
+    for (vtkIdType i = 0; i < aNbPts; ++i)
+    {
+      aPntMap->SetId (i, -1);
+    }
+
+    // Filter the cells
+    for (vtkIdType aCellIter = 0; aCellIter < theIdList->GetNumberOfIds(); ++aCellIter)
+    {
+      theSrc->GetCell (theIdList->GetId (aCellIter), aCell);
+      vtkIdList* aCellPts = aCell->GetPointIds();
+      const vtkIdType aNbCellPts = aCell->GetNumberOfPoints();
+      for (vtkIdType i = 0; i < aNbCellPts; ++i)
+      {
+        const vtkIdType aPtId = aCellPts->GetId (i);
+        vtkIdType aNewId = aPntMap->GetId (aPtId);
+        if (aNewId < 0)
+        {
+          theSrc->GetPoint (aPtId, anXYZ.ChangeData());
+
+          aNewId = aNewPoints->InsertNextPoint (anXYZ.GetData());
+          aPntMap->SetId (aPtId, aNewId);
+          aNewPntData->CopyData (theSrc->GetPointData(), aPtId, aNewId);
+
+          if (anOldNormals != NULL)
+          {
+            anOldNormals->GetTuple (aPtId, anXYZ.ChangeData());
+            aNewNormals->InsertNextTuple (anXYZ.GetData());
+          }
+        }
+        aNewCellPts->InsertId (i, aNewId);
+      }
+
+      const vtkIdType aNewCellId = theDst->InsertNextCell (aCell->GetCellType(), aNewCellPts);
+      aNewCellData->CopyData (theSrc->GetCellData(), theIdList->GetId (aCellIter), aNewCellId);
+      aNewCellPts->Reset();
+    }
+  }
+}
+
 vtkStandardNewMacro(IVtkTools_SubPolyDataFilter)
 
 //================================================================
 // Function : Constructor
-// Purpose  : 
+// Purpose  :
 //================================================================
 IVtkTools_SubPolyDataFilter::IVtkTools_SubPolyDataFilter()
+: myIdsArrayName (IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS()),
+  myDoFiltering (true),
+  myToCopyNormals (true)
 {
-  myIdsArrayName = IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS();
-  myDoFiltering = true;
+  //
 }
 
 //================================================================
 // Function : Destructor
-// Purpose  : 
+// Purpose  :
 //================================================================
 IVtkTools_SubPolyDataFilter::~IVtkTools_SubPolyDataFilter() { }
 
@@ -70,18 +149,17 @@ int IVtkTools_SubPolyDataFilter::RequestData (vtkInformation *vtkNotUsed(theRequ
 
   if (myDoFiltering)
   {
-    vtkSmartPointer<vtkCellData> aCellData = anInput->GetCellData();
-    vtkIdType aSize = 0;
-    vtkSmartPointer<vtkIdTypeArray> aDataArray =
-      vtkIdTypeArray::SafeDownCast (aCellData->GetArray (myIdsArrayName));
+    vtkSmartPointer<vtkCellData> anInputCellData  = anInput->GetCellData();
+    vtkSmartPointer<vtkCellData> anOutputCellData = anOutput->GetCellData();
+    vtkSmartPointer<vtkIdTypeArray> aDataArray = vtkIdTypeArray::SafeDownCast (anInputCellData->GetArray (myIdsArrayName));
 
     // List of cell ids to be passed
     vtkSmartPointer<vtkIdList> anIdList = vtkSmartPointer<vtkIdList>::New();
-    anIdList->Allocate(myIdsSet.Extent());  // Allocate the list of ids
+    anIdList->Allocate (myIdsSet.Extent());  // Allocate the list of ids
 
-    if (aDataArray.GetPointer() != NULL)
+    const vtkIdType aSize = aDataArray.GetPointer() != NULL ? aDataArray->GetNumberOfTuples() : 0;
+    if (aSize != 0)
     {
-      aSize = aDataArray->GetNumberOfTuples();
       anIdList->Allocate (aSize);  // Allocate the list of ids
     }
 
@@ -100,39 +178,41 @@ int IVtkTools_SubPolyDataFilter::RequestData (vtkInformation *vtkNotUsed(theRequ
     }
 
     // Copy cells with their points according to the prepared list of cell ids.
-    anOutput->GetCellData()->AllocateArrays(anInput->GetCellData()->GetNumberOfArrays());
-    anOutput->Allocate(anInput, anIdList->GetNumberOfIds());  // Allocate output cells
+    anOutputCellData->AllocateArrays (anInputCellData->GetNumberOfArrays());
+    anOutput->Allocate (anInput, anIdList->GetNumberOfIds());  // Allocate output cells
+
     // Pass data arrays.
     // Create new arrays for output data 
-    vtkSmartPointer<vtkCellData> anInData = anInput->GetCellData();
-    vtkSmartPointer<vtkCellData> anOutData = anOutput->GetCellData();
-    vtkSmartPointer<vtkDataArray> anInArr, anOutArr;
-
-    for (Standard_Integer anI = 0; anI < anInData->GetNumberOfArrays(); anI++)
+    for (Standard_Integer anI = 0; anI < anInputCellData->GetNumberOfArrays(); anI++)
     {
-      anInArr = anInData->GetArray (anI);
-      anOutArr = vtkSmartPointer<vtkDataArray>::Take(
-        vtkDataArray::CreateDataArray(anInArr->GetDataType()));
-      anOutArr->SetName(anInArr->GetName());
-      anOutArr->Allocate(anIdList->GetNumberOfIds() * anInArr->GetNumberOfComponents());
+      vtkSmartPointer<vtkDataArray> anInArr  = anInputCellData->GetArray (anI);
+      vtkSmartPointer<vtkDataArray> anOutArr = vtkSmartPointer<vtkDataArray>::Take (vtkDataArray::CreateDataArray(anInArr->GetDataType()));
+
+      anOutArr->SetName (anInArr->GetName());
+      anOutArr->Allocate (anIdList->GetNumberOfIds() * anInArr->GetNumberOfComponents());
       anOutArr->SetNumberOfTuples (anIdList->GetNumberOfIds());
       anOutArr->SetNumberOfComponents (anInArr->GetNumberOfComponents());
-      anOutData->AddArray(anOutArr);
+      anOutputCellData->AddArray (anOutArr);
     }
 
     // Copy cells with ids from our list.
-    anOutput->CopyCells (anInput, anIdList);
+    if (myToCopyNormals)
+    {
+      copyCells (anOutput, anInput, anIdList);
+    }
+    else
+    {
+      anOutput->CopyCells (anInput, anIdList);
+    }
 
     // Copy filtered arrays data
-    vtkIdType anOutId, anInId;
-
-    for (Standard_Integer anI = 0; anI < anInData->GetNumberOfArrays(); anI++)
+    for (Standard_Integer anI = 0; anI < anInputCellData->GetNumberOfArrays(); anI++)
     {
-      anInArr = anInData->GetArray (anI);
-      anOutArr = anOutData->GetArray(anI);
-      for (anOutId = 0; anOutId < anIdList->GetNumberOfIds(); anOutId++)
+      vtkSmartPointer<vtkDataArray> anInArr  = anInputCellData ->GetArray (anI);
+      vtkSmartPointer<vtkDataArray> anOutArr = anOutputCellData->GetArray (anI);
+      for (vtkIdType anOutId = 0; anOutId < anIdList->GetNumberOfIds(); anOutId++)
       {
-        anInId = anIdList->GetId (anOutId);
+        const vtkIdType anInId = anIdList->GetId (anOutId);
         anOutArr->SetTuple (anOutId, anInId, anInArr);
       }
     }
@@ -148,7 +228,7 @@ int IVtkTools_SubPolyDataFilter::RequestData (vtkInformation *vtkNotUsed(theRequ
 
 //================================================================
 // Function : SetDoFiltering
-// Purpose  : 
+// Purpose  :
 //================================================================
 void IVtkTools_SubPolyDataFilter::SetDoFiltering (const bool theDoFiltering)
 {
@@ -169,12 +249,12 @@ void IVtkTools_SubPolyDataFilter::PrintSelf (std::ostream& theOs, vtkIndent theI
   IVtk_IdTypeMap::Iterator anIter(myIdsSet);
   while (anIter.More())
   {
-      theOs << " " << anIter.Value();
-      anIter.Next();
-      if (anIter.More())
-      {
-          theOs << "; ";
-      }
+    theOs << " " << anIter.Value();
+    anIter.Next();
+    if (anIter.More())
+    {
+      theOs << "; ";
+    }
   }
   theOs << "}" << "\n";
 }
@@ -203,8 +283,7 @@ void IVtkTools_SubPolyDataFilter::SetData (const IVtk_IdTypeMap theSet)
 //================================================================
 void IVtkTools_SubPolyDataFilter::AddData (const IVtk_IdTypeMap theSet)
 {
-  IVtk_IdTypeMap::Iterator anIt (theSet);
-  for (; anIt.More(); anIt.Next())
+  for (IVtk_IdTypeMap::Iterator anIt (theSet); anIt.More(); anIt.Next())
   {
     if (!myIdsSet.Contains (anIt.Value()))
     {
@@ -229,8 +308,7 @@ void IVtkTools_SubPolyDataFilter::SetData (const IVtk_ShapeIdList theIdList)
 //================================================================
 void IVtkTools_SubPolyDataFilter::AddData (const IVtk_ShapeIdList theIdList)
 {
-  IVtk_ShapeIdList::Iterator anIt (theIdList);
-  for (; anIt.More(); anIt.Next())
+  for (IVtk_ShapeIdList::Iterator anIt (theIdList); anIt.More(); anIt.Next())
   {
     if (!myIdsSet.Contains (anIt.Value()))
     {
@@ -239,10 +317,9 @@ void IVtkTools_SubPolyDataFilter::AddData (const IVtk_ShapeIdList theIdList)
   }
 }
 
-//! Set ids to be passed through this filter.
 //================================================================
 // Function : SetIdsArrayName
-// Purpose  : 
+// Purpose  :
 //================================================================
 void IVtkTools_SubPolyDataFilter::SetIdsArrayName (const char* theArrayName)
 {
index 1ea839c5ad1dbe50637e8c99825a2b65ecdf2e1e..709f08823df6870f8af80f53d7c6359b30914c46 100644 (file)
@@ -70,6 +70,7 @@ protected:
   IVtk_IdTypeMap myIdsSet;
   const char*    myIdsArrayName;
   bool           myDoFiltering;
+  bool           myToCopyNormals;
 };
 
 #ifdef _MSC_VER
index e647fd8df8a7f4f67f130bd5a2036cfcd4adbbcf..90387972f2579e9ff72667ffeca1a23de4674a39 100644 (file)
@@ -19,7 +19,9 @@
 #include <Standard_WarningsDisable.hxx>
 #include <vtkCellData.h>
 #include <vtkDoubleArray.h>
+#include <vtkFloatArray.h>
 #include <vtkIdList.h>
+#include <vtkPointData.h>
 #include <vtkPoints.h>
 #include <vtkPolyData.h>
 #include <Standard_WarningsRestore.hxx>
@@ -28,7 +30,7 @@ IMPLEMENT_STANDARD_RTTIEXT(IVtkVTK_ShapeData,IVtk_IShapeData)
 
 //================================================================
 // Function : Constructor
-// Purpose  : 
+// Purpose  :
 //================================================================
 IVtkVTK_ShapeData::IVtkVTK_ShapeData()
 {
@@ -36,6 +38,11 @@ IVtkVTK_ShapeData::IVtkVTK_ShapeData()
   myPolyData->Allocate();
   myPolyData->SetPoints (vtkSmartPointer<vtkPoints>::New());
 
+  myNormals = vtkSmartPointer<vtkFloatArray>::New();
+  myNormals->SetName ("Normals");
+  myNormals->SetNumberOfComponents (3);
+  myPolyData->GetPointData()->SetNormals (myNormals);
+
   mySubShapeIDs = vtkSmartPointer<vtkIdTypeArray>::New();
   mySubShapeIDs->SetName (IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS());
   mySubShapeIDs->SetNumberOfComponents (1);
@@ -49,25 +56,29 @@ IVtkVTK_ShapeData::IVtkVTK_ShapeData()
 
 //================================================================
 // Function : Destructor
-// Purpose  : 
+// Purpose  :
 //================================================================
 IVtkVTK_ShapeData::~IVtkVTK_ShapeData()
 { }
 
 //================================================================
-// Function : InsertCoordinate
-// Purpose  : 
+// Function : InsertPoint
+// Purpose  :
 //================================================================
-IVtk_PointId IVtkVTK_ShapeData::InsertCoordinate (double theX,
-                                                  double theY,
-                                                  double theZ)
+IVtk_PointId IVtkVTK_ShapeData::InsertPoint (const gp_Pnt& thePnt,
+                                             const NCollection_Vec3<float>& theNorm)
 {
-  return myPolyData->GetPoints()->InsertNextPoint (theX, theY, theZ);
+  IVtk_PointId aPointId = myPolyData->GetPoints()->InsertNextPoint (thePnt.X(), thePnt.Y(), thePnt.Z());
+  if (myNormals.GetPointer() != NULL)
+  {
+    myNormals->InsertNextTuple (theNorm.GetData());
+  }
+  return aPointId;
 }
 
 //================================================================
 // Function : InsertVertex
-// Purpose  : 
+// Purpose  :
 //================================================================
 void IVtkVTK_ShapeData::InsertVertex (const IVtk_IdType theShapeID,
                                       const IVtk_PointId thePointId,
@@ -80,7 +91,7 @@ void IVtkVTK_ShapeData::InsertVertex (const IVtk_IdType theShapeID,
 
 //================================================================
 // Function : InsertLine
-// Purpose  : 
+// Purpose  :
 //================================================================
 void IVtkVTK_ShapeData::InsertLine (const IVtk_IdType   theShapeID,
                                     const IVtk_PointId  thePointId1,
@@ -94,7 +105,7 @@ void IVtkVTK_ShapeData::InsertLine (const IVtk_IdType   theShapeID,
 
 //================================================================
 // Function : InsertLine
-// Purpose  : 
+// Purpose  :
 //================================================================
 void IVtkVTK_ShapeData::InsertLine (const IVtk_IdType       theShapeID,
                                     const IVtk_PointIdList* thePointIds,
@@ -119,7 +130,7 @@ void IVtkVTK_ShapeData::InsertLine (const IVtk_IdType       theShapeID,
 
 //================================================================
 // Function : InsertTriangle
-// Purpose  : 
+// Purpose  :
 //================================================================
 void IVtkVTK_ShapeData::InsertTriangle (const IVtk_IdType   theShapeID,
                                         const IVtk_PointId  thePointId1,
index 0fda1748ab206fc600cedd931ea18f2cf476caa1..a12d24588561cdf145ba5bb3b785514ffc5c7c13 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef __IVTKVTK_SHAPEDATA_H__
 #define __IVTKVTK_SHAPEDATA_H__
 
+#include <gp_Dir.hxx>
+#include <gp_Pnt.hxx>
 #include <IVtk_IShapeData.hxx>
 
 // prevent disabling some MSVC warning messages by VTK headers 
@@ -26,6 +28,7 @@
 #include <Standard_WarningsRestore.hxx>
 
 class vtkIdTypeArray;
+class vtkFloatArray;
 
 class IVtkVTK_ShapeData;
 DEFINE_STANDARD_HANDLE( IVtkVTK_ShapeData, IVtk_IShapeData )
@@ -51,11 +54,11 @@ public:
   DEFINE_STANDARD_RTTIEXT(IVtkVTK_ShapeData,IVtk_IShapeData)
 
   //! Insert a coordinate
-  //! @param [in] theX X coordinate
-  //! @param [in] theY Y coordinate
-  //! @param [in] theZ Z coordinate
+  //! @param [in] thePnt  point position
+  //! @param [in] theNorm point normal
   //! @return id of added point
-  Standard_EXPORT virtual IVtk_PointId InsertCoordinate (double theX, double theY, double theZ) Standard_OVERRIDE;
+  Standard_EXPORT virtual IVtk_PointId InsertPoint (const gp_Pnt& thePnt,
+                                                    const NCollection_Vec3<float>& theNorm) Standard_OVERRIDE;
 
   //! Insert a vertex.
   //! @param [in] theShapeID id of the subshape to which the vertex belongs.
@@ -121,6 +124,7 @@ private:
 
 private:
   vtkSmartPointer< vtkPolyData >    myPolyData;    //!< Shape geometry as vtkPolyData
+  vtkSmartPointer< vtkFloatArray >  myNormals;     //!< vertex normals
   vtkSmartPointer< vtkIdTypeArray > mySubShapeIDs; //!< Array of sub-shapes ids
   vtkSmartPointer< vtkIdTypeArray > myMeshTypes;   //!< Array of type codes of mesh parts
 };
index 986bae04f15c2c14d02ab56dda0edf4ca7f79149..a4cf453dd28c3dac9db411270105c37b8e7b32fd 100644 (file)
@@ -7,9 +7,8 @@ pload MODELING VIS
 box b 1 1 1
 ivtkinit
 ivtkdisplay b
-ivtksetdispmode 1
-ivtksetboundingdraw 1
-ivtkdump $imagedir/${casename}_1.png
-
-ivtksetboundingdraw 0
+ivtksetdispmode 1 -faceBoundaryDraw 0 -smoothShading 1
 ivtkdump $imagedir/${casename}_2.png
+
+ivtksetdispmode 1 -faceBoundaryDraw 1 -smoothShading 0
+ivtkdump $imagedir/${casename}_1.png
index dd6c9034aaf70234931a77fdfe77b8bc77ac6290..607a57a14788a68c84e7b75e5b1c371f0058240e 100644 (file)
@@ -7,7 +7,8 @@ pload MODELING VIS
 psphere s 10 15 80
 ivtkinit
 ivtkdisplay s
-ivtksetdispmode 1
-ivtksetboundingdraw 1
-
+ivtksetdispmode 1 -faceBoundaryDraw 1 -smoothShading 0
 ivtkdump $imagedir/${casename}.png
+
+ivtksetdispmode 1 -faceBoundaryDraw 1 -smoothShading 1
+ivtkdump $imagedir/${casename}_smooth.png