]> OCCT Git - occt-copy.git/commitdiff
Draft implementation of LOD API in OCCT:
authorvpa <vpa@opencascade.com>
Tue, 8 Dec 2015 06:11:46 +0000 (09:11 +0300)
committervpa <vpa@opencascade.com>
Fri, 8 Apr 2016 17:19:59 +0000 (20:19 +0300)
- implemented interfaces for LOD at OpenGl, Graphic3d and MeshVS levels;
- added LOD managers at Graphic3d and OpenGl levels;
- simple mechanism of LOD switching is implemented in LOD manager;
- distance to COG metric is temporarily used;
- the metric could be redefined using custom LOD selectors;
- LODs are added to MeshVS_Mesh in Compute method and are listed as its data sources;
- added commands meshgenlod and meshlod to generate LODs for mesh and its topological representation
  and bind them to its OpenGl structures.

32 files changed:
src/Graphic3d/FILES
src/Graphic3d/Graphic3d_CStructure.hxx
src/Graphic3d/Graphic3d_LOD.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_LOD.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_LODDistanceSelector.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_LODDistanceSelector.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_LODManager.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_LODManager.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_LODSelector.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_Structure.cxx
src/Graphic3d/Graphic3d_Structure.hxx
src/MeshVS/FILES
src/MeshVS/MeshVS_DataSource.hxx
src/MeshVS/MeshVS_LODBuilder.cxx [new file with mode: 0644]
src/MeshVS/MeshVS_LODBuilder.hxx [new file with mode: 0644]
src/MeshVS/MeshVS_LODDataSource.cxx [new file with mode: 0644]
src/MeshVS/MeshVS_LODDataSource.hxx [new file with mode: 0644]
src/MeshVS/MeshVS_Mesh.cxx
src/MeshVS/MeshVS_Mesh.hxx
src/MeshVS/MeshVS_MeshPrsBuilder.cxx
src/MeshVS/MeshVS_MeshPrsBuilder.hxx
src/OpenGl/FILES
src/OpenGl/OpenGl_LOD.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_LOD.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_LODManager.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_LODManager.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_Structure.cxx
src/OpenGl/OpenGl_Structure.hxx
src/Prs3d/Prs3d_Root.hxx
src/TKMeshVS/EXTERNLIB
src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx
tests/bugs/vis/bug26812 [new file with mode: 0644]

index 770c6f9ea77affbadc8e3dcc01af4c9d7a4b244e..b6b77fda1f840089a743e2fa1390d5908cdb522b 100755 (executable)
@@ -77,6 +77,13 @@ Graphic3d_InitialisationError.hxx
 Graphic3d_LevelOfTextureAnisotropy.hxx
 Graphic3d_ListIteratorOfListOfShortReal.hxx
 Graphic3d_ListOfShortReal.hxx
+Graphic3d_LOD.hxx
+Graphic3d_LOD.cxx
+Graphic3d_LODSelector.hxx
+Graphic3d_LODDistanceSelector.hxx
+Graphic3d_LODDistanceSelector.cxx
+Graphic3d_LODManager.hxx
+Graphic3d_LODManager.cxx
 Graphic3d_MapIteratorOfMapOfStructure.hxx
 Graphic3d_MapOfObject.hxx
 Graphic3d_MapOfStructure.hxx
index cc2bee362525a8c6b35cb2b2b1e80c0cf727a3c6..963f326fdf75db44ca34e9bca60faa429a24f5ad 100644 (file)
@@ -28,6 +28,8 @@
 
 class Graphic3d_GraphicDriver;
 class Graphic3d_StructureManager;
+class Graphic3d_LOD;
+class Graphic3d_LODManager;
 
 //! Low-level graphic structure interface
 class Graphic3d_CStructure : public Standard_Transient
@@ -112,9 +114,16 @@ public:
   //! Create new group within this structure
   virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& theStruct) = 0;
 
+  //! Create new LOD within this structure
+  virtual Handle(Graphic3d_LOD) NewLOD (const Handle(Graphic3d_Structure)& theStruct) = 0;
+
   //! Remove group from this structure
   virtual void RemoveGroup (const Handle(Graphic3d_Group)& theGroup) = 0;
 
+  virtual Standard_Integer NbDetailLevels() const = 0;
+
+  virtual void SetDetailLevelRange (const Standard_Integer theIdOfLOD, const Standard_Real theFrom, const Standard_Real theTo) = 0;
+
 public:
 
   int                      Id;
@@ -157,6 +166,7 @@ protected:
   Graphic3d_SequenceOfGroup       myGroups;
   Graphic3d_BndBox4f              myBndBox;
   Graphic3d_SequenceOfHClipPlane  myClipPlanes;
+  Handle(Graphic3d_LODManager)    myLODManager;
 
 public:
 
diff --git a/src/Graphic3d/Graphic3d_LOD.cxx b/src/Graphic3d/Graphic3d_LOD.cxx
new file mode 100644 (file)
index 0000000..badb32b
--- /dev/null
@@ -0,0 +1,39 @@
+// Created on: 2015-10-29
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Graphic3d_LOD.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (Graphic3d_LOD, Standard_Transient)
+
+//=======================================================================
+// function : Destructor
+// purpose  :
+//=======================================================================
+Graphic3d_LOD::~Graphic3d_LOD()
+{
+  myGroups.Clear();
+}
+
+//=======================================================================
+// function : SetRange
+// purpose  :
+//=======================================================================
+void Graphic3d_LOD::SetRange (const Standard_Real theFrom, const Standard_Real theTo)
+{
+    Standard_ASSERT_RAISE (theFrom < theTo,
+    "The upper boundary of the interval must be greater than lower one!");
+
+  myRange = Graphic3d_RangeOfLOD (theFrom, theTo);
+}
diff --git a/src/Graphic3d/Graphic3d_LOD.hxx b/src/Graphic3d/Graphic3d_LOD.hxx
new file mode 100644 (file)
index 0000000..d86bf8d
--- /dev/null
@@ -0,0 +1,96 @@
+// Created on: 2015-10-29
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_LOD_Header
+#define _Graphic3d_LOD_Header
+
+#include <Graphic3d_Camera.hxx>
+#include <Graphic3d_SequenceOfGroup.hxx>
+#include <Graphic3d_Structure.hxx>
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_Transient.hxx>
+
+struct Graphic3d_RangeOfLOD
+{
+public:
+  Graphic3d_RangeOfLOD (const Standard_Real theFrom, const Standard_Real theTo)
+    : myTo (theTo),
+      myFrom (theFrom)
+  {
+    Standard_ASSERT_RAISE (theFrom < theTo,
+      "The upper boundary of the interval must be greater than lower one!");
+  }
+
+  Standard_Boolean IsIn (const Standard_Real theVal) const
+  {
+    return (myFrom < theVal) && (theVal < myTo);
+  }
+
+  Standard_Boolean IsLess (const Standard_Real theVal) const
+  {
+    return theVal < myFrom;
+  }
+
+  Standard_Boolean IsGreater (const Standard_Real theVal) const
+  {
+    return myTo < theVal;
+  }
+
+  bool operator < (const Graphic3d_RangeOfLOD& theOther) const
+  {
+    return myFrom < theOther.myFrom;
+  }
+
+private:
+  Standard_Real myFrom;
+  Standard_Real myTo;
+};
+
+class Graphic3d_LOD : public Standard_Transient
+{
+public:
+  Standard_EXPORT virtual ~Graphic3d_LOD();
+
+  Standard_EXPORT void SetRange (const Standard_Real theFrom, const Standard_Real theTo);
+
+  Standard_EXPORT const Graphic3d_RangeOfLOD& GetRange() const
+  {
+    return myRange;
+  }
+
+  Standard_EXPORT virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& /*theParentStruct*/)
+  {
+    return NULL;
+  };
+
+  const Graphic3d_SequenceOfGroup& GetDrawGroups() const
+  {
+    return myGroups;
+  }
+
+  DEFINE_STANDARD_RTTIEXT (Graphic3d_LOD, Standard_Transient)
+
+protected:
+  Standard_EXPORT Graphic3d_LOD() : myRange (-DBL_MAX, DBL_MAX) {};
+
+protected:
+  Graphic3d_SequenceOfGroup myGroups;
+  Graphic3d_RangeOfLOD      myRange;
+};
+
+DEFINE_STANDARD_HANDLE (Graphic3d_LOD, Standard_Transient)
+
+#endif // _Graphic3d_LOD_Header
diff --git a/src/Graphic3d/Graphic3d_LODDistanceSelector.cxx b/src/Graphic3d/Graphic3d_LODDistanceSelector.cxx
new file mode 100644 (file)
index 0000000..44f7cc5
--- /dev/null
@@ -0,0 +1,34 @@
+// Created on: 2015-11-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Graphic3d_BndBox4f.hxx>
+#include <Graphic3d_Camera.hxx>
+#include <Graphic3d_CStructure.hxx>
+#include <Graphic3d_LODDistanceSelector.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (Graphic3d_LODDistanceSelector, Graphic3d_LODSelector)
+
+//=======================================================================
+// function : ComputeMetric
+// purpose  :
+//=======================================================================
+Standard_Real Graphic3d_LODDistanceSelector::ComputeMetric (const Handle(Graphic3d_CStructure)& theParentStructure,
+                                                            const Handle(Graphic3d_Camera)& theCamera)
+{
+  const Graphic3d_BndBox4f& aBndBox = theParentStructure->BoundingBox();
+  const Graphic3d_Vec4 aCenter = aBndBox.Center();
+  const gp_Pnt aGpCenter = gp_Pnt (aCenter.x(), aCenter.y(), aCenter.z());
+  return (theCamera->Eye().Distance (aGpCenter)) / theCamera->Scale();
+}
diff --git a/src/Graphic3d/Graphic3d_LODDistanceSelector.hxx b/src/Graphic3d/Graphic3d_LODDistanceSelector.hxx
new file mode 100644 (file)
index 0000000..5567769
--- /dev/null
@@ -0,0 +1,38 @@
+// Created on: 2015-11-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_LODDistanceSelector_Header
+#define _Graphic3d_LODDistanceSelector_Header
+
+#include <Graphic3d_LODSelector.hxx>
+
+class Graphic3d_CStructure;
+class Graphic3d_Camera;
+
+class Graphic3d_LODDistanceSelector : public Graphic3d_LODSelector
+{
+public:
+  Standard_EXPORT Graphic3d_LODDistanceSelector() {};
+  Standard_EXPORT virtual ~Graphic3d_LODDistanceSelector() {};
+
+  Standard_EXPORT virtual Standard_Real ComputeMetric (const Handle(Graphic3d_CStructure)& theParentStructure,
+                                                       const Handle(Graphic3d_Camera)& theCamera) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT (Graphic3d_LODDistanceSelector, Graphic3d_LODSelector)
+};
+
+DEFINE_STANDARD_HANDLE (Graphic3d_LODDistanceSelector, Graphic3d_LODSelector)
+
+#endif // _Graphic3d_LODDistanceSelector_Header
diff --git a/src/Graphic3d/Graphic3d_LODManager.cxx b/src/Graphic3d/Graphic3d_LODManager.cxx
new file mode 100644 (file)
index 0000000..1bdc02b
--- /dev/null
@@ -0,0 +1,85 @@
+// Created on: 2015-11-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Graphic3d_LOD.hxx>
+#include <Graphic3d_LODManager.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (Graphic3d_LODManager, Standard_Transient)
+
+//=======================================================================
+// function : Creation
+// purpose  :
+//=======================================================================
+Graphic3d_LODManager::Graphic3d_LODManager (const Handle(Graphic3d_Structure)& theParentStructure)
+  : myCurrentLODIdx (-1),
+    mySelector (new Graphic3d_LODDistanceSelector())
+{
+  myStructure = theParentStructure.operator->();
+}
+
+//=======================================================================
+// function : GetCurrentLODIdx
+// purpose  :
+//=======================================================================
+Standard_Integer Graphic3d_LODManager::GetCurrentLODIdx (const Handle(Graphic3d_Camera)& theCamera)
+{
+  if (theCamera->WorldViewProjState() == myPrevCameraState && myCurrentLODIdx != -1)
+    return myCurrentLODIdx;
+
+  myPrevCameraState = theCamera->WorldViewProjState();
+  const Standard_Real aMetric = mySelector->ComputeMetric (myStructure->CStructure(), theCamera);
+  if (myLODs.Value (0)->GetRange().IsLess (aMetric))
+  {
+    myCurrentLODIdx = -1;
+  }
+  else if (myLODs.Value (myLODs.Size() - 1)->GetRange().IsGreater (aMetric))
+  {
+    myCurrentLODIdx = myLODs.Size() - 1;
+  }
+  else
+  {
+    for (Standard_Integer aLodIdx = 0; aLodIdx < myLODs.Size(); ++aLodIdx)
+    {
+      if (myLODs.Value (aLodIdx)->GetRange().IsIn (aMetric))
+      {
+        myCurrentLODIdx = aLodIdx;
+        break;
+      }
+    }
+  }
+
+  return myCurrentLODIdx;
+}
+
+//=======================================================================
+// function : SetRange
+// purpose  :
+//=======================================================================
+void Graphic3d_LODManager::SetRange (const Standard_Integer theLodIdx,
+                                     const Standard_Real theFrom,
+                                     const Standard_Real theTo)
+{
+  myLODs.ChangeValue (theLodIdx)->SetRange (theFrom, theTo);
+  sortLODs();
+}
+
+//=======================================================================
+// function : GetCurrentGroups
+// purpose  :
+//=======================================================================
+ const Graphic3d_SequenceOfGroup& Graphic3d_LODManager::GetCurrentGroups() const
+ {
+   return myLODs.Value (myCurrentLODIdx)->GetDrawGroups();
+ }
diff --git a/src/Graphic3d/Graphic3d_LODManager.hxx b/src/Graphic3d/Graphic3d_LODManager.hxx
new file mode 100644 (file)
index 0000000..7efbb09
--- /dev/null
@@ -0,0 +1,75 @@
+// Created on: 2015-11-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_LODManager_Header
+#define _Graphic3d_LODManager_Header
+
+#include <Graphic3d_CStructure.hxx>
+#include <Graphic3d_Camera.hxx>
+#include <Graphic3d_LOD.hxx>
+#include <Graphic3d_LODSelector.hxx>
+#include <Graphic3d_LODDistanceSelector.hxx>
+#include <Graphic3d_SequenceOfGroup.hxx>
+#include <Graphic3d_StructurePtr.hxx>
+#include <NCollection_Vector.hxx>
+#include <Standard.hxx>
+#include <Standard_Handle.hxx>
+
+class Graphic3d_LODManager : public Standard_Transient
+{
+public:
+
+  Standard_EXPORT virtual ~Graphic3d_LODManager() {};
+
+  Standard_EXPORT void SetSelector (const Handle(Graphic3d_LODSelector)& theSelector)
+  {
+    mySelector = theSelector;
+  }
+
+  Standard_EXPORT inline Standard_Integer NbOfDetailLevels() const
+  {
+    return myLODs.Size();
+  }
+
+  Standard_EXPORT void SetRange (const Standard_Integer theLodIdx,
+                                 const Standard_Real theFrom,
+                                 const Standard_Real theTo);
+
+  Standard_EXPORT Standard_Integer GetCurrentLODIdx (const Handle(Graphic3d_Camera)& theCamera);
+
+  Standard_EXPORT const Graphic3d_SequenceOfGroup& GetCurrentGroups() const;
+
+  Standard_EXPORT virtual Handle(Graphic3d_LOD) AddNewLOD() = 0;
+
+  DEFINE_STANDARD_RTTIEXT (Graphic3d_LODManager, Standard_Transient)
+
+protected:
+  Standard_EXPORT Graphic3d_LODManager (const Handle(Graphic3d_Structure)& theParentStructure);
+
+  Standard_EXPORT virtual void sortLODs() {};
+
+protected:
+  NCollection_Vector<Handle(Graphic3d_LOD)> myLODs;
+
+private:
+  Standard_Integer              myCurrentLODIdx;
+  Handle(Graphic3d_LODSelector) mySelector;
+  Graphic3d_StructurePtr        myStructure;
+  Graphic3d_WorldViewProjState  myPrevCameraState;
+};
+
+DEFINE_STANDARD_HANDLE (Graphic3d_LODManager, Standard_Transient)
+
+#endif //_Graphic3d_LODManager_Header
diff --git a/src/Graphic3d/Graphic3d_LODSelector.hxx b/src/Graphic3d/Graphic3d_LODSelector.hxx
new file mode 100644 (file)
index 0000000..000fe1f
--- /dev/null
@@ -0,0 +1,38 @@
+// Created on: 2015-11-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_LODSelector_Header
+#define _Graphic3d_LODSelector_Header
+
+#include <Standard.hxx>
+#include <Standard_Handle.hxx>
+#include <Standard_Transient.hxx>
+
+class Graphic3d_CStructure;
+class Graphic3d_Camera;
+
+class Graphic3d_LODSelector : public Standard_Transient
+{
+public:
+
+  virtual Standard_Real ComputeMetric (const Handle(Graphic3d_CStructure)& theParentStructure,
+                                       const Handle(Graphic3d_Camera)& theCamera) = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE (Graphic3d_LODSelector, Standard_Transient)
+};
+
+DEFINE_STANDARD_HANDLE (Graphic3d_LODSelector, Standard_Transient)
+
+#endif // _Graphic3d_LODSelector_Header
index 0ecb12de8d73bcdde0166f246208079f6764c1d2..40117bba469bf2f39707cd8ec6e5f7592b6b76e2 100644 (file)
@@ -1709,6 +1709,33 @@ Handle(Graphic3d_Group) Graphic3d_Structure::NewGroup()
   return myCStructure->NewGroup (this);
 }
 
+//=============================================================================
+//function : NewLOD
+//purpose  :
+//=============================================================================
+Handle(Graphic3d_LOD) Graphic3d_Structure::NewLOD()
+{
+  return myCStructure->NewLOD (this);
+}
+
+//=============================================================================
+//function : NbDetailLevels
+//purpose  :
+//=============================================================================
+Standard_Integer Graphic3d_Structure::NbDetailLevels() const
+{
+  return myCStructure->NbDetailLevels();
+}
+
+//=============================================================================
+//function : SetDetailLevelRange
+//purpose  :
+//=============================================================================
+void Graphic3d_Structure::SetDetailLevelRange (const Standard_Integer theIdOfLOD, const Standard_Real theFrom, const Standard_Real theTo)
+{
+  myCStructure->SetDetailLevelRange (theIdOfLOD, theFrom, theTo);
+}
+
 //=============================================================================
 //function : Remove
 //purpose  :
index 6e0b80eac32d3068ea4f8e94e97bc665c5e5d127..3686531ec63eeb4df716d5f3d29c04d67cf87d2a 100644 (file)
@@ -33,6 +33,7 @@
 #include <Graphic3d_ZLayerId.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
 #include <Standard_Real.hxx>
+#include <TColStd_Array1OfReal.hxx>
 #include <TColStd_Array2OfReal.hxx>
 #include <Graphic3d_SequenceOfGroup.hxx>
 #include <Graphic3d_TypeOfConnection.hxx>
@@ -54,6 +55,7 @@ class Graphic3d_AspectFillArea3d;
 class Graphic3d_AspectText3d;
 class Graphic3d_AspectMarker3d;
 class Graphic3d_DataStructureManager;
+class Graphic3d_LOD;
 class Bnd_Box;
 class gp_Pnt;
 class Graphic3d_Vector;
@@ -254,6 +256,9 @@ public:
   
   //! Append new group to this structure.
   Standard_EXPORT Handle(Graphic3d_Group) NewGroup();
+
+  //! Append new LOD to this structure.
+  Standard_EXPORT Handle(Graphic3d_LOD) NewLOD();
   
   //! Returns the highlight color for the Highlight method
   //! with the highlight method TOHM_COLOR or TOHM_BOUNDBOX.
@@ -479,6 +484,10 @@ public:
   //! Returns the low-level structure
     const Handle(Graphic3d_CStructure)& CStructure() const;
 
+  Standard_EXPORT Standard_Integer NbDetailLevels() const;
+
+  Standard_EXPORT void SetDetailLevelRange (const Standard_Integer theIdOfLOD, const Standard_Real theFrom, const Standard_Real theTo);
+
 friend class Graphic3d_Group;
 
 
index 40672f91fb3eda405c13d0af3269c9977577e94a..16402915146b402cc7c17811c9cb96d9e2f1870a 100755 (executable)
@@ -43,6 +43,10 @@ MeshVS_ElementalColorPrsBuilder.cxx
 MeshVS_ElementalColorPrsBuilder.hxx
 MeshVS_EntityType.hxx
 MeshVS_HArray1OfSequenceOfInteger.hxx
+MeshVS_LODBuilder.hxx
+MeshVS_LODBuilder.cxx
+MeshVS_LODDataSource.hxx
+MeshVS_LODDataSource.cxx
 MeshVS_MapIteratorOfMapOfTwoNodes.hxx
 MeshVS_MapOfTwoNodes.hxx
 MeshVS_Mesh.cxx
index c02e0782a84d5d913e15eaab9e81708674fa5cc2..38687251aaa668c595fa24641d9e6c6b4642cf19 100644 (file)
@@ -56,7 +56,7 @@ class MeshVS_DataSource : public MMgt_TShared
 
 public:
 
-  
+
   //! Returns geometry information about node or element
   //! ID is the numerical identificator of node or element
   //! IsElement indicates this ID describe node ( if Standard_False ) or element ( if Standard_True )
@@ -67,33 +67,44 @@ public:
   //! NbNodes is number of nodes. It is recommended this parameter to be set to 1 for node.
   //! Type is type of node or element (from enumeration). It is recommended this parameter to be set to
   //! MeshVS_ET_Node for node.
-  Standard_EXPORT virtual Standard_Boolean GetGeom (const Standard_Integer ID, const Standard_Boolean IsElement, TColStd_Array1OfReal& Coords, Standard_Integer& NbNodes, MeshVS_EntityType& Type) const = 0;
-  
+  Standard_EXPORT virtual Standard_Boolean GetGeom (const Standard_Integer ID,
+                                                    const Standard_Boolean IsElement,
+                                                    TColStd_Array1OfReal& Coords,
+                                                    Standard_Integer& NbNodes,
+                                                    MeshVS_EntityType& Type) const = 0;
+
   //! This method is similar to GetGeom, but returns only element or node type.
-  Standard_EXPORT virtual Standard_Boolean GetGeomType (const Standard_Integer ID, const Standard_Boolean IsElement, MeshVS_EntityType& Type) const = 0;
-  
+  Standard_EXPORT virtual Standard_Boolean GetGeomType (const Standard_Integer ID,
+                                                        const Standard_Boolean IsElement,
+                                                        MeshVS_EntityType& Type) const = 0;
+
   //! This method returns topology information about 3D-element
   //! Returns false if element with ID isn't 3D or because other troubles
-  Standard_EXPORT virtual Standard_Boolean Get3DGeom (const Standard_Integer ID, Standard_Integer& NbNodes, Handle(MeshVS_HArray1OfSequenceOfInteger)& Data) const;
-  
+  Standard_EXPORT virtual Standard_Boolean Get3DGeom (const Standard_Integer ID,
+                                                      Standard_Integer& NbNodes,
+                                                      Handle(MeshVS_HArray1OfSequenceOfInteger)& Data) const;
+
   //! This method returns pointer which represents element or node data structure.
   //! This address will be saved in MeshVS_MeshEntityOwner, so that you can access to data structure fast
   //! by the method Owner(). In the redefined method you can return NULL.
   //! ID is the numerical identificator of node or element
   //! IsElement indicates this ID describe node ( if Standard_False ) or element ( if Standard_True )
-  Standard_EXPORT virtual Standard_Address GetAddr (const Standard_Integer ID, const Standard_Boolean IsElement) const = 0;
-  
+  Standard_EXPORT virtual Standard_Address GetAddr (const Standard_Integer ID,
+                                                    const Standard_Boolean IsElement) const = 0;
+
   //! This method returns information about nodes this element consist of.
   //! ID is the numerical identificator of element.
   //! NodeIDs is the output array of nodes IDs in correct order,
   //! the same as coordinates returned by GetGeom().
   //! NbNodes is number of nodes (number of items set in NodeIDs).
   //! Returns False if element does not exist
-  Standard_EXPORT virtual Standard_Boolean GetNodesByElement (const Standard_Integer ID, TColStd_Array1OfInteger& NodeIDs, Standard_Integer& NbNodes) const = 0;
-  
+  Standard_EXPORT virtual Standard_Boolean GetNodesByElement (const Standard_Integer ID,
+                                                              TColStd_Array1OfInteger& NodeIDs,
+                                                              Standard_Integer& NbNodes) const = 0;
+
   //! This method returns map of all nodes the object consist of.
   Standard_EXPORT virtual const TColStd_PackedMapOfInteger& GetAllNodes() const = 0;
-  
+
   //! This method returns map of all elements the object consist of.
   Standard_EXPORT virtual const TColStd_PackedMapOfInteger& GetAllElements() const = 0;
   
@@ -105,13 +116,21 @@ public:
   //! In the redefined method you can return normal with length more then 1, but in this case
   //! the appearance of element will be more bright than usual. For ordinary brightness you must return
   //! normal with length 1
-  Standard_EXPORT virtual Standard_Boolean GetNormal (const Standard_Integer Id, const Standard_Integer Max, Standard_Real& nx, Standard_Real& ny, Standard_Real& nz) const;
-  
+  Standard_EXPORT virtual Standard_Boolean GetNormal (const Standard_Integer Id,
+                                                      const Standard_Integer Max,
+                                                      Standard_Real& nx,
+                                                      Standard_Real& ny,
+                                                      Standard_Real& nz) const;
+
   //! This method return normal of node ranknode of face Id,
   //! which is using for smooth shading presentation.
   //! Returns false if normal isn't defined.
-  Standard_EXPORT virtual Standard_Boolean GetNodeNormal (const Standard_Integer ranknode, const Standard_Integer ElementId, Standard_Real& nx, Standard_Real& ny, Standard_Real& nz) const;
-  
+  Standard_EXPORT virtual Standard_Boolean GetNodeNormal (const Standard_Integer ranknode,
+                                                          const Standard_Integer ElementId,
+                                                          Standard_Real& nx,
+                                                          Standard_Real& ny,
+                                                          Standard_Real& nz) const;
+
   //! This method puts components of normal vectors at each node of a mesh face (at each face of a mesh volume)
   //! into the output array.
   //! Returns false if some problem was detected during calculation of normals.
@@ -123,13 +142,18 @@ public:
   //! volume: normals to all faces of the volume are computed (not for each node!).
   //! MaxNodes is maximal number of nodes an element can consist of.
   //! Normals contains the result.
-  Standard_EXPORT virtual Standard_Boolean GetNormalsByElement (const Standard_Integer Id, const Standard_Boolean IsNodal, const Standard_Integer MaxNodes, Handle(TColStd_HArray1OfReal)& Normals) const;
-  
+  Standard_EXPORT virtual Standard_Boolean GetNormalsByElement (const Standard_Integer Id,
+                                                                const Standard_Boolean IsNodal,
+                                                                const Standard_Integer MaxNodes,
+                                                                Handle(TColStd_HArray1OfReal)& Normals) const;
+
   //! This method returns map of all groups the object contains.
   Standard_EXPORT virtual void GetAllGroups (TColStd_PackedMapOfInteger& Ids) const;
-  
+
   //! This method returns map of all group elements.
-  Standard_EXPORT virtual Standard_Boolean GetGroup (const Standard_Integer Id, MeshVS_EntityType& Type, TColStd_PackedMapOfInteger& Ids) const;
+  Standard_EXPORT virtual Standard_Boolean GetGroup (const Standard_Integer Id,
+                                                     MeshVS_EntityType& Type,
+                                                     TColStd_PackedMapOfInteger& Ids) const;
   
   //! This method returns pointer which represents group data structure.
   //! This address will be saved in MeshVS_MeshOwner, so that you can access to data structure fast
@@ -156,7 +180,13 @@ public:
   //! Returns True if something is detected.
   //! It should be redefined if the advanced mesh selection is
   //! activated. Default implementation returns False.
-  Standard_EXPORT virtual Standard_Boolean GetDetectedEntities (const Handle(MeshVS_Mesh)& Prs, const Standard_Real X, const Standard_Real Y, const Standard_Real aTol, Handle(TColStd_HPackedMapOfInteger)& Nodes, Handle(TColStd_HPackedMapOfInteger)& Elements, Standard_Real& DMin);
+  Standard_EXPORT virtual Standard_Boolean GetDetectedEntities (const Handle(MeshVS_Mesh)& Prs,
+                                                                const Standard_Real X,
+                                                                const Standard_Real Y,
+                                                                const Standard_Real aTol,
+                                                                Handle(TColStd_HPackedMapOfInteger)& Nodes,
+                                                                Handle(TColStd_HPackedMapOfInteger)& Elements,
+                                                                Standard_Real& DMin);
   
   //! Returns maps of entities (nodes and elements) detected
   //! by mouse selection with rectangular box (XMin, YMin, XMax, YMax)
@@ -164,45 +194,39 @@ public:
   //! Returns True if something is detected.
   //! It should be redefined if the advanced mesh selection is
   //! activated. Default implementation returns False.
-  Standard_EXPORT virtual Standard_Boolean GetDetectedEntities (const Handle(MeshVS_Mesh)& Prs, const Standard_Real XMin, const Standard_Real YMin, const Standard_Real XMax, const Standard_Real YMax, const Standard_Real aTol, Handle(TColStd_HPackedMapOfInteger)& Nodes, Handle(TColStd_HPackedMapOfInteger)& Elements);
-  
+  Standard_EXPORT virtual Standard_Boolean GetDetectedEntities (const Handle(MeshVS_Mesh)& Prs,
+                                                                const Standard_Real XMin,
+                                                                const Standard_Real YMin,
+                                                                const Standard_Real XMax,
+                                                                const Standard_Real YMax,
+                                                                const Standard_Real aTol,
+                                                                Handle(TColStd_HPackedMapOfInteger)& Nodes,
+                                                                Handle(TColStd_HPackedMapOfInteger)& Elements);
+
   //! Returns maps of entities (nodes and elements) detected
   //! by mouse selection with the polyline <Polyline>
   //! on the current veiw plane, with the tolerance aTol.
   //! Returns True if something is detected.
   //! It should be redefined if the advanced mesh selection is
   //! activated. Default implementation returns False.
-  Standard_EXPORT virtual Standard_Boolean GetDetectedEntities (const Handle(MeshVS_Mesh)& Prs, const TColgp_Array1OfPnt2d& Polyline, const Bnd_Box2d& aBox, const Standard_Real aTol, Handle(TColStd_HPackedMapOfInteger)& Nodes, Handle(TColStd_HPackedMapOfInteger)& Elements);
-  
+  Standard_EXPORT virtual Standard_Boolean GetDetectedEntities (const Handle(MeshVS_Mesh)& Prs,
+                                                                const TColgp_Array1OfPnt2d& Polyline,
+                                                                const Bnd_Box2d& aBox,
+                                                                const Standard_Real aTol,
+                                                                Handle(TColStd_HPackedMapOfInteger)& Nodes,
+                                                                Handle(TColStd_HPackedMapOfInteger)& Elements);
+
   //! Filter out the maps of mesh entities so as to keep
   //! only the entities that are allowed to be selected
   //! according to the current context.
   //! Returns True if any of the maps has been changed.
   //! It should be redefined if the advanced mesh selection is
   //! activated. Default implementation returns False.
-  Standard_EXPORT virtual Standard_Boolean GetDetectedEntities (const Handle(MeshVS_Mesh)& Prs, Handle(TColStd_HPackedMapOfInteger)& Nodes, Handle(TColStd_HPackedMapOfInteger)& Elements);
-
-
-
+  Standard_EXPORT virtual Standard_Boolean GetDetectedEntities (const Handle(MeshVS_Mesh)& Prs,
+                                                                Handle(TColStd_HPackedMapOfInteger)& Nodes,
+                                                                Handle(TColStd_HPackedMapOfInteger)& Elements);
 
   DEFINE_STANDARD_RTTIEXT(MeshVS_DataSource,MMgt_TShared)
-
-protected:
-
-
-
-
-private:
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _MeshVS_DataSource_HeaderFile
diff --git a/src/MeshVS/MeshVS_LODBuilder.cxx b/src/MeshVS/MeshVS_LODBuilder.cxx
new file mode 100644 (file)
index 0000000..4bce494
--- /dev/null
@@ -0,0 +1,546 @@
+// Created on: 2015-11-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Graphic3d_ArrayOfSegments.hxx>
+#include <Graphic3d_LOD.hxx>
+#include <MeshVS_Drawer.hxx>
+#include <MeshVS_DrawerAttribute.hxx>
+#include <MeshVS_LODBuilder.hxx>
+#include <MeshVS_MapOfTwoNodes.hxx>
+#include <MeshVS_MeshPrsBuilder.hxx>
+#include <MeshVS_SymmetricPairHasher.hxx>
+#include <MeshVS_Tool.hxx>
+#include <TColStd_HPackedMapOfInteger.hxx>
+#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (MeshVS_LODBuilder, MeshVS_PrsBuilder)
+
+//=======================================================================
+// function : Creation
+// purpose  :
+//=======================================================================
+MeshVS_LODBuilder::MeshVS_LODBuilder (const Handle(MeshVS_Mesh)& theParentMesh,
+                                      const MeshVS_DisplayModeFlags& theFlags,
+                                      const Handle(MeshVS_LODDataSource)& theDataSource,
+                                      const Standard_Integer theId,
+                                      const MeshVS_BuilderPriority& thePriority)
+  : MeshVS_PrsBuilder (theParentMesh, theFlags, theDataSource, theId, thePriority)
+{}
+
+//=======================================================================
+// function : Build
+// purpose  :
+//=======================================================================
+void MeshVS_LODBuilder::Build (const Handle(Prs3d_Presentation)& theBasePrs,
+                               const TColStd_PackedMapOfInteger& theIDs,
+                               TColStd_PackedMapOfInteger& /*theIDsToExclude*/,
+                               const Standard_Boolean theIsElement,
+                               const Standard_Integer theDisplayMode) const
+{
+  if (myParentMesh == NULL)
+    return;
+
+  //if (!theIsElement)
+  //{
+  //  Standard_Boolean hasSelectFlag = ((aDispMode & MeshVS_DMF_SelectionPrs) != 0);
+  //  Standard_Boolean hasHilightFlag = ((aDispMode & MeshVS_DMF_HilightPrs) != 0);
+
+  //  Standard_Real aCoordsBuf[3];
+  //  TColStd_Array1OfReal aCoords (*aCoordsBuf, 1, 3);
+  //  Standard_Integer aNodesNb;
+  //  MeshVS_EntityType aType;
+
+  //  TColStd_PackedMapOfInteger anIDs;
+  //  anIDs.Assign (myNodeIdxs);
+  //  if (!hasSelectFlag && !hasHilightFlag)
+  //  {
+  //    // subtract the hidden nodes and ids to exclude (to minimize allocated memory)
+  //    Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = aMesh->GetHiddenNodes();
+  //    if (!aHiddenNodes.IsNull())
+  //      anIDs.Subtract (aHiddenNodes->Map());
+  //  }
+
+  //  Standard_Integer aSize = anIDs.Extent();
+  //  if (aSize > 0)
+  //  {
+  //    Handle(Graphic3d_ArrayOfPoints) aNodePoints = new Graphic3d_ArrayOfPoints (aSize);
+  //    Standard_Integer aPntsNb = 0;
+  //    for (TColStd_MapIteratorOfPackedMapOfInteger aNodeIdxsIter (myNodeIdxs); aNodeIdxsIter.More(); aNodeIdxsIter.Next())
+  //    {
+  //      const Standard_Integer aKey = aNodeIdxsIter.Key();
+  //      if (GetGeom (aKey, Standard_False, aCoords, aNodesNb, aType))
+  //      {
+  //        aPntsNb++;
+  //        aNodePoints->AddVertex (aCoords(1), aCoords(2), aCoords(3));
+  //      }
+  //    }
+
+  //    if (aPntsNb > 0)
+  //    {
+  //      Handle(Graphic3d_LOD) aNewLod = Prs3d_Root::NewLOD (aMainPrs);
+  //      Handle(Graphic3d_Group) aLODGroup = aNewLod->NewGroup();
+  //      aLODGroup->AddPrimitiveArray (aNodePoints);
+  //    }
+  //    return;
+  //  }
+  //}
+  if (theIsElement)
+  {
+    Standard_Integer aMaxNodesNb;
+
+    Handle(MeshVS_MeshPrsBuilder) aBuilder = Handle(MeshVS_MeshPrsBuilder)::DownCast (myParentMesh->GetBuilder (1));
+    if (aBuilder.IsNull())
+      return;
+    Handle(MeshVS_Drawer) aDrawer = aBuilder->GetDrawer();
+    if (aDrawer.IsNull() ||
+        !aDrawer->GetInteger (MeshVS_DA_MaxFaceNodes, aMaxNodesNb) ||
+        aMaxNodesNb <= 0)
+      return;
+
+    //----------- extract useful display mode flags ----------
+    Standard_Integer aDispStatus = (theDisplayMode & aBuilder->GetFlags());
+    if ((aDispStatus & MeshVS_DMF_DeformedMask) != 0)
+    {
+      aDispStatus /= MeshVS_DMF_DeformedPrsWireFrame;
+      // This transformation turns deformed mesh flags to real display modes
+    }
+    aDispStatus &= MeshVS_DMF_OCCMask;
+    //--------------------------------------------------------
+
+    Standard_Real aShrinkCoef;
+    aDrawer->GetDouble (MeshVS_DA_ShrinkCoeff, aShrinkCoef);
+
+    const Standard_Boolean isWireframe = theDisplayMode == MeshVS_DMF_WireFrame;
+    Standard_Boolean isShading = theDisplayMode == MeshVS_DMF_Shading;
+    Standard_Boolean isShrink = theDisplayMode == MeshVS_DMF_Shrink;
+    const Standard_Boolean hasHilightFlag = (aDispStatus & MeshVS_DMF_HilightPrs) != 0;
+    const Standard_Boolean hasSelFlag =(aDispStatus & MeshVS_DMF_SelectionPrs) != 0;
+    Standard_Boolean isMeshSmoothShading = Standard_False;
+    Standard_Boolean isMeshReflect, isMeshAllowOverlap, isReflect;
+
+    aDrawer->GetBoolean (MeshVS_DA_Reflection, isMeshReflect);
+    aDrawer->GetBoolean (MeshVS_DA_IsAllowOverlapped, isMeshAllowOverlap);
+    isReflect = isMeshReflect && !hasHilightFlag;
+    aDrawer->GetBoolean (MeshVS_DA_SmoothShading, isMeshSmoothShading);
+
+    // display mode for highlighted prs of groups
+    isShrink = isShrink && !hasHilightFlag;
+    isShading = isShading || hasHilightFlag;
+
+        Graphic3d_MaterialAspect aMatAspect;
+    aDrawer->GetMaterial (MeshVS_DA_FrontMaterial, aMatAspect);
+    if (!isReflect)
+    {
+      aMatAspect.SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
+      aMatAspect.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
+      aMatAspect.SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
+      aMatAspect.SetReflectionModeOff(Graphic3d_TOR_EMISSION);
+    }
+    Handle(Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d (aDrawer, aMatAspect);
+    Handle(Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d (aDrawer);
+
+    const Standard_Boolean isOverlapControl =
+      !isMeshAllowOverlap && (isWireframe || isShading) && !hasSelFlag;
+
+    // subtract the hidden elements and ids to exclude (to minimize allocated memory)
+    TColStd_PackedMapOfInteger anIDs;
+    anIDs.Assign (theIDs);
+    Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
+    if (!aHiddenElems.IsNull())
+      anIDs.Subtract (aHiddenElems->Map());
+
+    Handle(MeshVS_HArray1OfSequenceOfInteger) aTopo;
+
+    Standard_Boolean toShowEdges = Standard_True;
+    aDrawer->GetBoolean (MeshVS_DA_ShowEdges, toShowEdges);
+
+    toShowEdges = isWireframe || toShowEdges;
+
+    Standard_Integer* aNodesBuf = (Standard_Integer*)alloca (aMaxNodesNb * sizeof (Standard_Integer));
+    Standard_Real*    aCoordsBuf = (Standard_Real*)alloca (3 * aMaxNodesNb * sizeof (Standard_Real));
+
+    TColStd_Array1OfInteger aNodes (*aNodesBuf, 1, aMaxNodesNb);
+    TColStd_Array1OfReal    aCoords (*aCoordsBuf, 1, 3 * aMaxNodesNb);
+
+    Standard_Integer aNbFacePrimitives = 0;
+    Standard_Integer aNbVolmPrimitives = 0;
+    Standard_Integer aNbEdgePrimitives = 0;
+    Standard_Integer aNbLinkPrimitives = 0;
+
+    MeshVS_EntityType aType;
+
+    TColStd_MapIteratorOfPackedMapOfInteger anIdxIter (anIDs);
+    for (anIdxIter.Reset(); anIdxIter.More(); anIdxIter.Next())
+    {
+      Standard_Integer aNbNodes = 0;
+
+      if (!DataSource()->GetGeom (anIdxIter.Key(), Standard_True, aCoords, aNbNodes, aType))
+        continue;
+
+      if (aType == MeshVS_ET_Volume)
+      {
+        if (DataSource()->Get3DGeom (anIdxIter.Key(), aNbNodes, aTopo))
+        {
+          for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx)
+          {
+            const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value(aFaceIdx);
+
+            if (toShowEdges) // add edge segments
+            {
+              aNbEdgePrimitives += aFaceNodes.Length();
+            }
+
+            if (isShading || isShrink) // add volumetric cell triangles
+            {
+              if (!hasSelFlag)
+                aNbVolmPrimitives += aFaceNodes.Length() - 2;
+            }
+          }
+        }
+      }
+      else if (aType == MeshVS_ET_Link)
+      {
+        if (toShowEdges)
+        {
+          aNbLinkPrimitives += 1; // add link segment
+        }
+      }
+      else if (aType == MeshVS_ET_Face)
+      {
+        if (toShowEdges)
+        {
+          aNbEdgePrimitives += aNbNodes; // add edge segments
+        }
+
+        if (!isOverlapControl || isShading)
+        {
+          if ((isShading || isShrink) && !hasSelFlag)
+          {
+            aNbFacePrimitives += aNbNodes - 2; // add face triangles
+          }
+        }
+      }
+    }
+
+    // Here we do not use indices arrays because they are not effective for some mesh
+    // drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
+    // cell rendering (normal interpolation is not always applicable - flat shading),
+    // elemental coloring (color interpolation is impossible)
+    Handle(Graphic3d_ArrayOfTriangles) aVolmTriangles =
+      new Graphic3d_ArrayOfTriangles (aNbVolmPrimitives * 3, 0, isReflect);
+    Handle(Graphic3d_ArrayOfTriangles) aFaceTriangles =
+      new Graphic3d_ArrayOfTriangles (aNbFacePrimitives * 3, 0, isReflect);
+
+    Handle(Graphic3d_ArrayOfSegments) aLinkSegments;
+    Handle(Graphic3d_ArrayOfSegments) aEdgeSegments;
+
+    if (toShowEdges)
+    {
+      aLinkSegments = new Graphic3d_ArrayOfSegments (aNbLinkPrimitives * 2);
+      aEdgeSegments = new Graphic3d_ArrayOfSegments (aNbEdgePrimitives * 2);
+    }
+
+    TColStd_PackedMapOfInteger aCustomElements;
+
+    MeshVS_MapOfTwoNodes aLinkNodes;
+
+    Quantity_Color       anOldEdgeColor;
+    Quantity_Color       anEdgeColor;
+    Quantity_Color       anIntColor;
+    Aspect_InteriorStyle anIntType;
+    Aspect_TypeOfLine    aLine;
+    Standard_Real        aWidth;
+
+    aFill->Values (anIntType, anIntColor, anEdgeColor, aLine, aWidth);
+
+    // Forbid drawings of edges which overlap with some links
+    if (toShowEdges && isOverlapControl)
+    {
+      for (anIdxIter.Reset(); anIdxIter.More(); anIdxIter.Next())
+      {
+        if (DataSource()->GetGeomType (anIdxIter.Key(), Standard_True, aType) && aType == MeshVS_ET_Link)
+        {
+          Standard_Integer aNbNodes;
+
+          if (DataSource()->GetNodesByElement (anIdxIter.Key(), aNodes, aNbNodes) && aNbNodes == 2)
+          {
+            aLinkNodes.Add (MeshVS_TwoNodes (aNodes(1), aNodes(2)));
+          }
+        }
+      }
+    }
+
+    NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aSegmentMap;
+
+    for (anIdxIter.Reset(); anIdxIter.More(); anIdxIter.Next())
+    {
+      const Standard_Integer aKey = anIdxIter.Key();
+
+      Standard_Integer NbNodes;
+      if (!DataSource()->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
+        continue;
+
+      if (!DataSource()->GetNodesByElement (aKey, aNodes, NbNodes))
+        continue;
+
+      switch (aType)
+      {
+      case MeshVS_ET_Volume:
+      {
+        if (DataSource()->Get3DGeom (aKey, NbNodes, aTopo))
+        {
+          // Add wire-frame presentation (draw edges for shading mode as well)
+          if (toShowEdges)
+          {
+            aBuilder->AddVolumePrs (aTopo, aCoords, NbNodes,
+                                    aEdgeSegments, isReflect,
+                                    isShrink, hasSelFlag,
+                                    aShrinkCoef);
+          }
+
+          // Add shading presentation
+          if ((isShading || isShrink) && !hasSelFlag)
+          {
+            aBuilder->AddVolumePrs (aTopo, aCoords, NbNodes,
+                                    aVolmTriangles, isReflect,
+                                    isShrink, hasSelFlag,
+                                    aShrinkCoef);
+          }
+        }
+      }
+      break;
+
+      case MeshVS_ET_Link:
+      {
+        if (toShowEdges)
+        {
+          aBuilder->AddLinkPrs (aCoords, aLinkSegments, isShrink || hasSelFlag, aShrinkCoef);
+        }
+      }
+      break;
+
+      case MeshVS_ET_Face:
+      {
+        if (toShowEdges && isOverlapControl)
+        {
+          Standard_Integer Last = 0;
+
+          MeshVS_TwoNodes aTwoNodes (aNodes(1));
+
+          for (Standard_Integer i = 1; i <= NbNodes; ++i)
+          {
+            if (i > 1)
+              aTwoNodes.First = aTwoNodes.Second;
+
+            aTwoNodes.Second = (i < NbNodes) ? aNodes (i + 1) : aNodes (1);
+
+            if (aLinkNodes.Contains (aTwoNodes))
+            {
+              for (Standard_Integer aNodeIdx = Last + 1; aNodeIdx < i; ++aNodeIdx)
+              {
+                const Standard_Integer aNextIdx = aNodeIdx + 1;
+
+                aEdgeSegments->AddVertex (
+                  aCoords (3 * aNodeIdx - 2), aCoords (3 * aNodeIdx - 1), aCoords (3 * aNodeIdx));
+                aEdgeSegments->AddVertex(
+                  aCoords (3 * aNextIdx - 2), aCoords (3 * aNextIdx - 1), aCoords (3 * aNextIdx));
+              }
+
+              Last = i;
+            }
+          }
+
+          if (NbNodes - Last > 0)
+          {
+            for (Standard_Integer aNodeIdx = Last; aNodeIdx < NbNodes; ++aNodeIdx)
+            {
+              const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
+
+              const MeshVS_NodePair aSegment (aNodes (aNodeIdx + 1), aNodes (aNextIdx + 1));
+
+              if (!aSegmentMap.Contains (aSegment))
+              {
+                aEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
+                                          aCoords (3 * aNodeIdx + 2),
+                                          aCoords (3 * aNodeIdx + 3));
+
+                aEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
+                                          aCoords (3 * aNextIdx + 2),
+                                          aCoords (3 * aNextIdx + 3));
+
+                aSegmentMap.Add (aSegment);
+              }
+            }
+          }
+        }
+
+        if (!isOverlapControl || isShading)
+        {
+          if (!isOverlapControl && toShowEdges)
+          {
+            aBuilder->AddFaceWirePrs (aCoords, NbNodes, aEdgeSegments, isShrink || hasSelFlag, aShrinkCoef);
+          }
+
+          if ((isShading || isShrink) && !hasSelFlag)
+          {
+            aBuilder->AddFaceSolidPrs (DataSource(), aKey, aCoords, NbNodes, aMaxNodesNb, aFaceTriangles, isReflect,
+              isShrink || hasSelFlag, aShrinkCoef, isMeshSmoothShading);
+          }
+        }
+      }
+      break;
+
+      default:
+        aCustomElements.Add (aKey);
+      }
+    }
+
+    if (isShrink)
+    {
+      anOldEdgeColor = anEdgeColor;
+      aFill->SetEdgeColor (Quantity_NOC_BLACK);
+    }
+
+    Standard_Boolean isSupressBackFaces = Standard_False;
+    if (!aDrawer.IsNull())
+    {
+      aDrawer->GetBoolean (MeshVS_DA_SupressBackFaces, isSupressBackFaces);
+    }
+    drawArrays (theBasePrs, aFaceTriangles, aEdgeSegments, aLinkSegments, aVolmTriangles,
+      !toShowEdges, hasSelFlag, isSupressBackFaces, aFill, aBeam);
+  }
+}
+
+//================================================================
+// Function : drawArrays
+// Purpose  :
+//================================================================
+void MeshVS_LODBuilder::drawArrays (const Handle(Prs3d_Presentation)& theBasePrs,
+                                    const Handle(Graphic3d_ArrayOfPrimitives)& thePolygons,
+                                    const Handle(Graphic3d_ArrayOfPrimitives)& theLines,
+                                    const Handle(Graphic3d_ArrayOfPrimitives)& theLinkLines,
+                                    const Handle(Graphic3d_ArrayOfPrimitives)& theVolumesInShad,
+                                    const Standard_Boolean theIsPolygonsEdgesOff,
+                                    const Standard_Boolean theIsSelected,
+                                    const Standard_Boolean theIsSupressBackFaces,
+                                    const Handle(Graphic3d_AspectFillArea3d)& theFillAsp,
+                                    const Handle(Graphic3d_AspectLine3d)& theLineAsp) const
+{
+  if (theFillAsp.IsNull())
+    return;
+
+  Standard_Boolean isFacePolygons   = (!thePolygons.IsNull() && thePolygons->ItemNumber() > 0),
+                   isVolumePolygons = (!theVolumesInShad.IsNull() && theVolumesInShad->ItemNumber() > 0),
+                   isPolygons       = isFacePolygons || isVolumePolygons,
+                   isPolylines      = (!theLines.IsNull() && theLines->ItemNumber() > 0),
+                   isLinkPolylines  = (!theLinkLines.IsNull() && theLinkLines->ItemNumber() > 0);
+
+  Aspect_InteriorStyle aStyle;
+  Quantity_Color anIntColor, aBackColor, anEdgeColor;
+  Aspect_TypeOfLine aType;
+  Standard_Real aWidth;
+
+  Handle(Graphic3d_LOD) aNewLod = theBasePrs->NewLOD();
+  theFillAsp->Values (aStyle, anIntColor, aBackColor, anEdgeColor, aType, aWidth);
+
+  if (isPolygons && theFillAsp->FrontMaterial().Transparency() < 0.01)
+  {
+    Handle (Graphic3d_Group) aGroup = aNewLod->NewGroup (theBasePrs);
+
+    theFillAsp->SetEdgeOff();
+
+    if (anIntColor != aBackColor)
+      theFillAsp->SetDistinguishOn();
+    else
+      theFillAsp->SetDistinguishOff();
+
+    aGroup->SetClosed (theIsSupressBackFaces);
+    Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*(theFillAsp.operator->()));
+    if (theIsSupressBackFaces)
+    {
+      aFillAsp->SuppressBackFace();
+    }
+    aGroup->SetPrimitivesAspect (aFillAsp);
+
+    if (isFacePolygons)
+    {
+      aGroup->AddPrimitiveArray (thePolygons);
+    }
+
+    if (isVolumePolygons)
+    {
+      aGroup->AddPrimitiveArray (theVolumesInShad);
+    }
+  }
+
+  if (isPolylines && !theIsPolygonsEdgesOff)
+  {
+    Handle (Graphic3d_Group) aLGroup = aNewLod->NewGroup (theBasePrs);
+
+    theFillAsp->SetEdgeOff();
+    if (theIsSelected)
+      aLGroup->SetPrimitivesAspect (theLineAsp);
+    else
+    {
+      aLGroup->SetPrimitivesAspect (theFillAsp);
+      aLGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (anEdgeColor, Aspect_TOL_SOLID, aWidth));
+    }
+    aLGroup->AddPrimitiveArray (theLines);
+    theFillAsp->SetEdgeOn();
+  }
+
+  if (isLinkPolylines)
+  {
+    Handle (Graphic3d_Group) aBeamGroup = aNewLod->NewGroup (theBasePrs);
+
+    theFillAsp->SetEdgeOff();
+    if (!theIsSelected)
+      aBeamGroup->SetPrimitivesAspect (theFillAsp);
+    aBeamGroup->SetPrimitivesAspect (theLineAsp);
+    aBeamGroup->AddPrimitiveArray (theLinkLines);
+    theFillAsp->SetEdgeOn();
+  }
+
+  if (isPolygons && theFillAsp->FrontMaterial().Transparency() >= 0.01)
+  {
+    Handle (Graphic3d_Group) aGroup = aNewLod->NewGroup (theBasePrs);
+
+    theFillAsp->SetEdgeOff();
+
+    if (anIntColor != aBackColor)
+      theFillAsp->SetDistinguishOn();
+    else
+      theFillAsp->SetDistinguishOff();
+
+    aGroup->SetClosed (theIsSupressBackFaces);
+    Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*(theFillAsp.operator->()));
+    if (theIsSupressBackFaces)
+    {
+      aFillAsp->SuppressBackFace();
+    }
+    aGroup->SetPrimitivesAspect (aFillAsp);
+
+    if (isFacePolygons)
+    {
+      aGroup->AddPrimitiveArray (thePolygons);
+    }
+
+    if (isVolumePolygons)
+    {
+      aGroup->AddPrimitiveArray (theVolumesInShad);
+    }
+  }
+}
diff --git a/src/MeshVS/MeshVS_LODBuilder.hxx b/src/MeshVS/MeshVS_LODBuilder.hxx
new file mode 100644 (file)
index 0000000..4639b1b
--- /dev/null
@@ -0,0 +1,66 @@
+// Created on: 2015-11-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _MeshVS_LODBuilder_Header
+#define _MeshVS_LODBuilder_Header
+
+#include <MeshVS_Mesh.hxx>
+#include <MeshVS_PrsBuilder.hxx>
+#include <MeshVS_LODDataSource.hxx>
+
+class MeshVS_LODBuilder : public MeshVS_PrsBuilder
+{
+public:
+  
+  //! Creates builder with certain display mode flags, data source, ID and priority
+  Standard_EXPORT MeshVS_LODBuilder (const Handle(MeshVS_Mesh)& theParentMesh,
+                                     const MeshVS_DisplayModeFlags& theFlags = MeshVS_DMF_OCCMask,
+                                     const Handle(MeshVS_LODDataSource)& theDataSource = NULL,
+                                     const Standard_Integer theId = -1,
+                                     const MeshVS_BuilderPriority& thePriority = MeshVS_BP_Mesh);
+
+  Standard_EXPORT virtual ~MeshVS_LODBuilder() {};
+
+  //! Builds presentation of certain type of data.
+  //! Prs is presentation object which this method constructs.
+  //! IDs is set of numeric identificators forming object appearance.
+  //! IDsToExclude is set of IDs to exclude from processing. If some entity
+  //! has been excluded, it is not processed by other builders.
+  //! IsElement indicates, IDs is identificators of nodes or elements.
+  //! DisplayMode is numeric constant describing display mode (see MeshVS_DisplayModeFlags.hxx)
+  Standard_EXPORT virtual void Build (const Handle(Prs3d_Presentation)& theBasePrs,
+                                      const TColStd_PackedMapOfInteger& theIDs,
+                                      TColStd_PackedMapOfInteger& theIDsToExclude,
+                                      const Standard_Boolean theIsElement,
+                                      const Standard_Integer theDisplayMode) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT (MeshVS_LODBuilder, MeshVS_PrsBuilder)
+
+protected:
+  void drawArrays (const Handle(Prs3d_Presentation)& theBasePrs,
+                   const Handle(Graphic3d_ArrayOfPrimitives)& thePolygons,
+                   const Handle(Graphic3d_ArrayOfPrimitives)& theLines,
+                   const Handle(Graphic3d_ArrayOfPrimitives)& theLinkLines,
+                   const Handle(Graphic3d_ArrayOfPrimitives)& theVolumesInShad,
+                   const Standard_Boolean theIsPolygonsEdgesOff,
+                   const Standard_Boolean theIsSelected,
+                   const Standard_Boolean theIsSupressBackFaces,
+                   const Handle(Graphic3d_AspectFillArea3d)& theFillAsp,
+                   const Handle(Graphic3d_AspectLine3d)& theLineAsp) const;
+};
+
+DEFINE_STANDARD_HANDLE (MeshVS_LODBuilder, MeshVS_PrsBuilder)
+
+#endif // _MeshVS_LODBuilder_Header
diff --git a/src/MeshVS/MeshVS_LODDataSource.cxx b/src/MeshVS/MeshVS_LODDataSource.cxx
new file mode 100644 (file)
index 0000000..46ddb08
--- /dev/null
@@ -0,0 +1,179 @@
+// Created on: 2015-10-23
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <MeshVS_LODDataSource.hxx>
+
+#include <Graphic3d_ArrayOfPoints.hxx>
+#include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Graphic3d_ArrayOfSegments.hxx>
+#include <Graphic3d_LOD.hxx>
+#include <MeshVS_Drawer.hxx>
+#include <MeshVS_DrawerAttribute.hxx>
+#include <MeshVS_Mesh.hxx>
+#include <MeshVS_MapOfTwoNodes.hxx>
+#include <MeshVS_MeshPrsBuilder.hxx>
+#include <MeshVS_SymmetricPairHasher.hxx>
+#include <MeshVS_Tool.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <Prs3d_Root.hxx>
+#include <TColStd_HPackedMapOfInteger.hxx>
+#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
+#include <TColgp_SequenceOfXYZ.hxx>
+#include <StlMesh_SequenceOfMeshTriangle.hxx>
+#include <StlMesh_MeshTriangle.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (MeshVS_LODDataSource, MeshVS_DataSource)
+
+//=======================================================================
+// function : MeshVS_LODDataSource
+// purpose  :
+//=======================================================================
+MeshVS_LODDataSource::MeshVS_LODDataSource (const Handle(StlMesh_Mesh)& theMesh)
+  : myTriangles (1, theMesh->Triangles().Length()),
+    myNodes     (1, theMesh->Vertices().Length())
+{
+  if (theMesh.IsNull())
+    return;
+
+  const TColgp_SequenceOfXYZ& aVerts = theMesh->Vertices();
+  for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aVerts.Length(); ++aNodeIdx)
+  {
+    myNodeIdxs.Add (aNodeIdx);
+    myNodes.ChangeValue (aNodeIdx) = aVerts (aNodeIdx);
+  }
+
+  const StlMesh_SequenceOfMeshTriangle& aTriangles = theMesh->Triangles();
+  for (Standard_Integer aTrgIdx = 1; aTrgIdx <= aTriangles.Length(); ++aTrgIdx)
+  {
+    myTriangleIdxs.Add (aTrgIdx);
+    const Handle(StlMesh_MeshTriangle)& aTriangle = aTriangles.Value (aTrgIdx);
+    Standard_Integer aNodeIdxs[3];
+    Standard_Real aNormalX, aNormalY, aNormalZ;
+    aTriangle->GetVertexAndOrientation (aNodeIdxs[0], aNodeIdxs[1], aNodeIdxs[2], aNormalX, aNormalY, aNormalZ);
+    myTriangles.ChangeValue (aTrgIdx) = Poly_Triangle (aNodeIdxs[0], aNodeIdxs[1], aNodeIdxs[2]);
+  }
+}
+
+//=======================================================================
+// function : GetGeom
+// purpose  : Returns full info about the entity according to the index and type of element given
+//=======================================================================
+Standard_Boolean MeshVS_LODDataSource::GetGeom (const Standard_Integer theId,
+                                                const Standard_Boolean theIsElement,
+                                                TColStd_Array1OfReal&  theCoords,
+                                                Standard_Integer&      theNodesNb,
+                                                MeshVS_EntityType&     theEntityType) const
+{
+  if (theId < 1)
+    return Standard_False;
+
+  if (theIsElement)
+  {
+    if (theId > myTriangleIdxs.Extent() || theCoords.Length() < 9)
+      return Standard_False;
+
+    Standard_Integer aNode1, aNode2, aNode3;
+    myTriangles.Value (theId).Get (aNode1, aNode2, aNode3);
+    gp_Pnt aPnts[3] = { myNodes.Value (aNode1),
+                        myNodes.Value (aNode2),
+                        myNodes.Value (aNode3) };
+    for (Standard_Integer aPntIdx = 0, anIdx = 1; aPntIdx < 3; ++aPntIdx)
+    {
+      for (Standard_Integer aCoordIdx = 0; aCoordIdx < 3; aCoordIdx++)
+      {
+        theCoords (anIdx++) = aPnts[aPntIdx].XYZ().GetData()[aCoordIdx];
+      }
+    }
+
+    theNodesNb = 3;
+    theEntityType = MeshVS_ET_Face;
+
+    return Standard_True;
+  }
+  else
+  {
+    if (theId > myNodeIdxs.Extent() || theCoords.Length() < 3)
+      return Standard_False;
+
+    const gp_Pnt& aNode = myNodes.Value (theId);
+    theCoords (1) = aNode.X();
+    theCoords (2) = aNode.Y();
+    theCoords (3) = aNode.Z();
+
+    theNodesNb = 1;
+    theEntityType = MeshVS_ET_Node;
+
+    return Standard_True;
+  }
+}
+
+//=======================================================================
+// function : GetGeomType
+// purpose  : Returns type of geometry according to the index and type of element given
+//=======================================================================
+Standard_Boolean MeshVS_LODDataSource::GetGeomType (const Standard_Integer /*theId*/,
+                                                    const Standard_Boolean theIsElement,
+                                                    MeshVS_EntityType&     theEntityType) const
+{
+  theEntityType = theIsElement ? MeshVS_ET_Face : MeshVS_ET_Node;
+  return Standard_True;
+}
+
+//=======================================================================
+// function : GetAddr
+// purpose  :
+//=======================================================================
+Standard_Address MeshVS_LODDataSource::GetAddr (const Standard_Integer /*theId*/,
+                                                const Standard_Boolean /*theIsElement*/) const
+{
+  return NULL;
+}
+
+//=======================================================================
+// function : GetNodesByElement
+// purpose  : Returns nodes forming a triangle with id theId
+//=======================================================================
+Standard_Boolean MeshVS_LODDataSource::GetNodesByElement (const Standard_Integer   theId,
+                                                          TColStd_Array1OfInteger& theNodeIds,
+                                                          Standard_Integer&        theNodesNb) const
+{
+  if (theId < 1 || theId > myTriangleIdxs.Extent() || theNodeIds.Length() < 3)
+    return Standard_False;
+
+  const Standard_Integer aLowerIdx = theNodeIds.Lower();
+  myTriangles.Value (theId).Get (theNodeIds.ChangeValue (aLowerIdx),
+                                 theNodeIds.ChangeValue (aLowerIdx + 1),
+                                 theNodeIds.ChangeValue (aLowerIdx + 2));
+  theNodesNb = 3;
+  return Standard_True;
+}
+
+//=======================================================================
+// function : GetAllNodes
+// purpose  : This method makes storing usless map excusable
+//=======================================================================
+const TColStd_PackedMapOfInteger& MeshVS_LODDataSource::GetAllNodes() const
+{
+  return myNodeIdxs;
+}
+
+//=======================================================================
+// function : GetAllElements
+// purpose  : This method makes storing usless map excusable
+//=======================================================================
+const TColStd_PackedMapOfInteger& MeshVS_LODDataSource::GetAllElements() const
+{
+  return myTriangleIdxs;
+}
diff --git a/src/MeshVS/MeshVS_LODDataSource.hxx b/src/MeshVS/MeshVS_LODDataSource.hxx
new file mode 100644 (file)
index 0000000..a3deb79
--- /dev/null
@@ -0,0 +1,93 @@
+// Created on: 2015-10-23
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _MeshVS_LODDataSource_Header
+#define _MeshVS_LODDataSource_Header
+
+#include <AIS_InteractiveObject.hxx>
+#include <MeshVS_DataSource.hxx>
+#include <Poly_Array1OfTriangle.hxx>
+#include <Poly_Triangle.hxx>
+#include <StlMesh_Mesh.hxx>
+
+//! TODO: VPA: think how to avoid copying mesh data. Now it is done for returning useless maps
+//!            in GetAllElements() and GetAllNodes() because they must return const links. Moreover,
+//!            copying data allows to avoid cases when indexation in Poly_Triangluation inner
+//!            arrays starts from arbitrary numbers (if it is really possible).
+class MeshVS_LODDataSource : public MeshVS_DataSource
+{
+public:
+
+  Standard_EXPORT MeshVS_LODDataSource (const Handle(StlMesh_Mesh)& theMesh);
+
+  Standard_EXPORT virtual ~MeshVS_LODDataSource() {};
+
+  //! Returns geometry information about node or element
+  //! ID is the numerical identificator of node or element
+  //! IsElement indicates this ID describe node ( if Standard_False ) or element ( if Standard_True )
+  //! Coords is an array of co-ordinates of node(s).
+  //! For node it is only 3 numbers: X, Y, Z in the strict order
+  //! For element it is 3*n numbers, where n is number of this element vertices
+  //! The order is strict also: X1, Y1, Z1, X2,...., where Xi, Yi, Zi are co-ordinates of vertices
+  //! NbNodes is number of nodes. It is recommended this parameter to be set to 1 for node.
+  //! Type is type of node or element (from enumeration). It is recommended this parameter to be set to
+  //! MeshVS_ET_Node for node.
+  Standard_EXPORT virtual Standard_Boolean GetGeom (const Standard_Integer theId,
+                                                    const Standard_Boolean theIsElement,
+                                                    TColStd_Array1OfReal&  theCoords,
+                                                    Standard_Integer&      theNodesNb,
+                                                    MeshVS_EntityType&     theEntityType) const Standard_OVERRIDE;
+
+  //! This method is similar to GetGeom, but returns only element or node type.
+  Standard_EXPORT virtual Standard_Boolean GetGeomType (const Standard_Integer theId,
+                                                        const Standard_Boolean theIsElement,
+                                                        MeshVS_EntityType&     theEntityType) const Standard_OVERRIDE;
+
+  //! This method returns pointer which represents element or node data structure.
+  //! This address will be saved in MeshVS_MeshEntityOwner, so that you can access to data structure fast
+  //! by the method Owner(). In the redefined method you can return NULL.
+  //! ID is the numerical identificator of node or element
+  //! IsElement indicates this ID describe node ( if Standard_False ) or element ( if Standard_True )
+  Standard_EXPORT virtual Standard_Address GetAddr (const Standard_Integer theId,
+                                                    const Standard_Boolean theIsElement) const Standard_OVERRIDE;
+
+  //! This method returns information about nodes this element consist of.
+  //! ID is the numerical identificator of element.
+  //! NodeIDs is the output array of nodes IDs in correct order,
+  //! the same as coordinates returned by GetGeom().
+  //! NbNodes is number of nodes (number of items set in NodeIDs).
+  //! Returns False if element does not exist
+  Standard_EXPORT virtual Standard_Boolean GetNodesByElement (const Standard_Integer   theId,
+                                                              TColStd_Array1OfInteger& theNodeIds,
+                                                              Standard_Integer&        theNodesNb) const Standard_OVERRIDE;
+
+  //! This method returns map of all nodes the object consist of.
+  Standard_EXPORT virtual const TColStd_PackedMapOfInteger& GetAllNodes() const Standard_OVERRIDE;
+
+  //! This method returns map of all elements the object consist of.
+  Standard_EXPORT virtual const TColStd_PackedMapOfInteger& GetAllElements() const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT (MeshVS_LODDataSource, MeshVS_DataSource)
+
+private:
+  TColStd_PackedMapOfInteger myNodeIdxs;
+  TColStd_PackedMapOfInteger myTriangleIdxs;
+  TColgp_Array1OfPnt         myNodes;
+  Poly_Array1OfTriangle      myTriangles;
+};
+
+DEFINE_STANDARD_HANDLE (MeshVS_LODDataSource, MeshVS_DataSource)
+
+#endif // _MeshVS_LODDataSource_Header
index e8fb5be73387fc9f6b85735bce4e3fa98fe50117..a66b9482525b4573cb11d26024c6faf8eddf2d47 100644 (file)
@@ -28,6 +28,7 @@
 #include <MeshVS_Drawer.hxx>
 #include <MeshVS_DrawerAttribute.hxx>
 #include <MeshVS_DummySensitiveEntity.hxx>
+#include <MeshVS_LODBuilder.hxx>
 #include <MeshVS_Mesh.hxx>
 #include <MeshVS_MeshEntityOwner.hxx>
 #include <MeshVS_MeshOwner.hxx>
@@ -174,6 +175,10 @@ void MeshVS_Mesh::Compute ( const Handle(PrsMgr_PresentationManager3d)& thePrsMg
     for ( Standard_Integer i=1; i<=len; i++ )
     {
       Handle (MeshVS_PrsBuilder) aCurrent = myBuilders.Value ( i );
+      if (!Handle(MeshVS_LODBuilder)::DownCast (aCurrent).IsNull())
+      {
+        continue;
+      }
       if ( !aCurrent.IsNull() && aCurrent->TestFlags ( theMode ) )
       {
         aCurrent->SetPresentationManager( thePrsMgr );
@@ -184,6 +189,22 @@ void MeshVS_Mesh::Compute ( const Handle(PrsMgr_PresentationManager3d)& thePrsMg
       }
     }
 
+  if (myLODDataSources.Size() > 0)
+  {
+    for (Standard_Integer aLodBldrIdx = 1; aLodBldrIdx <= myBuilders.Length(); ++aLodBldrIdx)
+    {
+      const Handle(MeshVS_LODBuilder) aLodBldr = Handle(MeshVS_LODBuilder)::DownCast (myBuilders.Value (aLodBldrIdx));
+      if (aLodBldr.IsNull() || !aLodBldr->TestFlags (theMode))
+        continue;
+
+      const TColStd_PackedMapOfInteger aVertIdxs = aLodBldr->GetDataSource()->GetAllNodes();
+      const TColStd_PackedMapOfInteger aTrgIdxs = aLodBldr->GetDataSource()->GetAllElements();
+      if (HasNodes)
+        aLodBldr->Build (thePresentation, aVertIdxs, aNodesToExclude, Standard_False, theMode);
+      if (HasElements)
+        aLodBldr->Build (thePresentation, aTrgIdxs, aElemsToExclude, Standard_True,  theMode);
+    }
+  }
 
   if ( ShowComputeTime )
   {
@@ -909,6 +930,15 @@ void MeshVS_Mesh::SetDataSource( const Handle(MeshVS_DataSource)& theDataSource
   myDataSource = theDataSource;
 }
 
+//================================================================
+// Function : AddDataSource
+// Purpose  :
+//================================================================
+void MeshVS_Mesh::AddDataSource (const Handle(MeshVS_DataSource)& theDataSource)
+{
+  myLODDataSources.Append (theDataSource);
+}
+
 //================================================================
 // Function : HilightSelected
 // Purpose  :
index d15c562833b0db726526aeb61493c1f383f62851..dabba4cc415c701de36c5fc981150ca4668b53f8 100644 (file)
@@ -121,7 +121,10 @@ public:
   
   //! Sets default builders' data source
   Standard_EXPORT void SetDataSource (const Handle(MeshVS_DataSource)& aDataSource);
-  
+
+  //! Adds data source to define LOD
+  Standard_EXPORT void AddDataSource (const Handle(MeshVS_DataSource)& theDataSource);
+
   //! Returns default builders' drawer
   Standard_EXPORT Handle(MeshVS_Drawer) GetDrawer() const;
   
@@ -209,10 +212,8 @@ protected:
   Handle(MeshVS_Drawer) myHilightDrawer;
   Handle(SelectMgr_EntityOwner) myWholeMeshOwner;
 
-
 private:
 
-
   MeshVS_SequenceOfPrsBuilder myBuilders;
   Handle(MeshVS_PrsBuilder) myHilighter;
   Handle(TColStd_HPackedMapOfInteger) myHiddenElements;
@@ -220,14 +221,7 @@ private:
   Handle(TColStd_HPackedMapOfInteger) mySelectableNodes;
   Handle(MeshVS_DataSource) myDataSource;
   MeshVS_MeshSelectionMethod mySelectionMethod;
-
-
+  NCollection_Vector<Handle(MeshVS_DataSource)> myLODDataSources;
 };
 
-
-
-
-
-
-
 #endif // _MeshVS_Mesh_HeaderFile
index 1253884018a5f2ce903e1455d406ddae298b0d8d..4322a46693b1cc3d99578711cfb6cd8e0453548b 100644 (file)
@@ -723,7 +723,8 @@ void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal&
 // Function : AddFaceSolidPrs
 // Purpose  :
 //================================================================
-void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer                    theID,
+void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Handle(MeshVS_DataSource)&          theDataSource,
+                                             const Standard_Integer                    theID,
                                              const TColStd_Array1OfReal&               theCoords,
                                              const Standard_Integer                    theNbNodes,
                                              const Standard_Integer                    theMaxNodes,
@@ -733,9 +734,7 @@ void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer
                                              const Standard_Real                       theShrinkingCoef,
                                              const Standard_Boolean                    theIsSmoothShading) const
 {
-  Handle(MeshVS_DataSource) aDataSource = myParentMesh->GetDataSource();
-
-  if (aDataSource.IsNull())
+  if (theDataSource.IsNull())
     return;
 
   Standard_Real aCenterX = 0.0;
@@ -758,7 +757,7 @@ void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer
     {
       for (Standard_Integer aNodeIdx = 1; aNodeIdx <= theNbNodes; ++aNodeIdx)
       {
-        if (!aDataSource->GetNodeNormal (aNodeIdx, theID, aNormalX, aNormalY, aNormalZ))
+        if (!theDataSource->GetNodeNormal (aNodeIdx, theID, aNormalX, aNormalY, aNormalZ))
           break;
 
         aVertexNormals.Append (gp_XYZ (aNormalX, aNormalY, aNormalZ));
@@ -767,7 +766,7 @@ void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer
 
     if (!theIsSmoothShading || aVertexNormals.Size() != theNbNodes)
     {
-      aDataSource->GetNormal (theID, theMaxNodes, aNormalX, aNormalY, aNormalZ);
+      theDataSource->GetNormal (theID, theMaxNodes, aNormalX, aNormalY, aNormalZ);
     }
   }
 
@@ -820,6 +819,26 @@ void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer
   }
 }
 
+//================================================================
+// Function : AddFaceSolidPrs
+// Purpose  :
+//================================================================
+void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer                    theID,
+                                             const TColStd_Array1OfReal&               theCoords,
+                                             const Standard_Integer                    theNbNodes,
+                                             const Standard_Integer                    theMaxNodes,
+                                             const Handle(Graphic3d_ArrayOfTriangles)& theTriangles,
+                                             const Standard_Boolean                    theIsShaded,
+                                             const Standard_Boolean                    theIsShrinked,
+                                             const Standard_Real                       theShrinkingCoef,
+                                             const Standard_Boolean                    theIsSmoothShading) const
+{
+  Handle(MeshVS_DataSource) aDataSource = myParentMesh->GetDataSource();
+  AddFaceSolidPrs (aDataSource, theID, theCoords, theNbNodes, theMaxNodes, theTriangles,
+    theIsShaded, theIsShrinked, theShrinkingCoef, theIsSmoothShading);
+}
+
+
 //================================================================
 // Function : AddVolumePrs
 // Purpose  :
index acdd26d717ac2b927acc6c17a6ef7639ee9f9d4b..8bcb372f9a9d02742841407e28c5fdd6cfde0089 100644 (file)
@@ -44,64 +44,117 @@ DEFINE_STANDARD_HANDLE(MeshVS_MeshPrsBuilder, MeshVS_PrsBuilder)
 //! This class provides methods to compute base mesh presentation
 class MeshVS_MeshPrsBuilder : public MeshVS_PrsBuilder
 {
-
 public:
 
-  
   //! Creates builder with certain display mode flags, data source, ID and priority
-  Standard_EXPORT MeshVS_MeshPrsBuilder(const Handle(MeshVS_Mesh)& Parent, const MeshVS_DisplayModeFlags& Flags = MeshVS_DMF_OCCMask, const Handle(MeshVS_DataSource)& DS = 0, const Standard_Integer Id = -1, const MeshVS_BuilderPriority& Priority = MeshVS_BP_Mesh);
-  
+  Standard_EXPORT MeshVS_MeshPrsBuilder(const Handle(MeshVS_Mesh)& Parent,
+                                        const MeshVS_DisplayModeFlags& Flags = MeshVS_DMF_OCCMask,
+                                        const Handle(MeshVS_DataSource)& DS = 0,
+                                        const Standard_Integer Id = -1,
+                                        const MeshVS_BuilderPriority& Priority = MeshVS_BP_Mesh);
+
   //! Builds base mesh presentation by calling the methods below
-  Standard_EXPORT virtual void Build (const Handle(Prs3d_Presentation)& Prs, const TColStd_PackedMapOfInteger& IDs, TColStd_PackedMapOfInteger& IDsToExclude, const Standard_Boolean IsElement, const Standard_Integer DisplayMode) const Standard_OVERRIDE;
-  
+  Standard_EXPORT virtual void Build (const Handle(Prs3d_Presentation)& Prs,
+                                      const TColStd_PackedMapOfInteger& IDs,
+                                      TColStd_PackedMapOfInteger& IDsToExclude,
+                                      const Standard_Boolean IsElement,
+                                      const Standard_Integer DisplayMode) const Standard_OVERRIDE;
+
   //! Builds nodes presentation
-  Standard_EXPORT virtual void BuildNodes (const Handle(Prs3d_Presentation)& Prs, const TColStd_PackedMapOfInteger& IDs, TColStd_PackedMapOfInteger& IDsToExclude, const Standard_Integer DisplayMode) const;
-  
+  Standard_EXPORT virtual void BuildNodes (const Handle(Prs3d_Presentation)& Prs,
+                                           const TColStd_PackedMapOfInteger& IDs,
+                                           TColStd_PackedMapOfInteger& IDsToExclude,
+                                           const Standard_Integer DisplayMode) const;
+
   //! Builds elements presentation
-  Standard_EXPORT virtual void BuildElements (const Handle(Prs3d_Presentation)& Prs, const TColStd_PackedMapOfInteger& IDs, TColStd_PackedMapOfInteger& IDsToExclude, const Standard_Integer DisplayMode) const;
-  
+  Standard_EXPORT virtual void BuildElements (const Handle(Prs3d_Presentation)& Prs,
+                                              const TColStd_PackedMapOfInteger& IDs,
+                                              TColStd_PackedMapOfInteger& IDsToExclude,
+                                              const Standard_Integer DisplayMode) const;
+
   //! Builds presentation of hilighted entity
-  Standard_EXPORT virtual void BuildHilightPrs (const Handle(Prs3d_Presentation)& Prs, const TColStd_PackedMapOfInteger& IDs, const Standard_Boolean IsElement) const;
-  
+  Standard_EXPORT virtual void BuildHilightPrs (const Handle(Prs3d_Presentation)& Prs,
+                                                const TColStd_PackedMapOfInteger& IDs,
+                                                const Standard_Boolean IsElement) const;
+
   //! Add to array polygons or polylines representing volume
-  Standard_EXPORT static void AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo, const TColStd_Array1OfReal& Nodes, const Standard_Integer NbNodes, const Handle(Graphic3d_ArrayOfPrimitives)& Array, const Standard_Boolean IsReflected, const Standard_Boolean IsShrinked, const Standard_Boolean IsSelect, const Standard_Real ShrinkCoef);
-  
+  Standard_EXPORT static void AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo,
+                                            const TColStd_Array1OfReal& Nodes,
+                                            const Standard_Integer NbNodes,
+                                            const Handle(Graphic3d_ArrayOfPrimitives)& Array,
+                                            const Standard_Boolean IsReflected,
+                                            const Standard_Boolean IsShrinked,
+                                            const Standard_Boolean IsSelect,
+                                            const Standard_Real ShrinkCoef);
+
   //! Calculate how many polygons or polylines are necessary to draw passed topology
-  Standard_EXPORT static void HowManyPrimitives (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo, const Standard_Boolean AsPolygons, const Standard_Boolean IsSelect, const Standard_Integer NbNodes, Standard_Integer& Vertices, Standard_Integer& Bounds);
+  Standard_EXPORT static void HowManyPrimitives (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo,
+                                                 const Standard_Boolean AsPolygons,
+                                                 const Standard_Boolean IsSelect,
+                                                 const Standard_Integer NbNodes,
+                                                 Standard_Integer& Vertices,
+                                                 Standard_Integer& Bounds);
 
+  //! Add to array of polylines some lines representing link
+  Standard_EXPORT void AddLinkPrs (const TColStd_Array1OfReal& theCoords,
+                                   const Handle(Graphic3d_ArrayOfSegments)& theLines,
+                                   const Standard_Boolean IsShrinked,
+                                   const Standard_Real ShrinkCoef) const;
 
+  //! Add to array of segments representing face's wire
+  Standard_EXPORT void AddFaceWirePrs (const TColStd_Array1OfReal& theCoords,
+                                       const Standard_Integer theNbNodes,
+                                       const Handle(Graphic3d_ArrayOfSegments)& theLines,
+                                       const Standard_Boolean theIsShrinked,
+                                       const Standard_Real theShrinkingCoef) const;
 
+  //! Add to array of polygons a polygon representing face
+  Standard_EXPORT void AddFaceSolidPrs (const Handle(MeshVS_DataSource)& theDataSource,
+                                        const Standard_Integer ID,
+                                        const TColStd_Array1OfReal& theCoords,
+                                        const Standard_Integer theNbNodes,
+                                        const Standard_Integer theMaxNodes,
+                                        const Handle(Graphic3d_ArrayOfTriangles)& theTriangles,
+                                        const Standard_Boolean theIsReflected,
+                                        const Standard_Boolean theIsShrinked,
+                                        const Standard_Real theShrinkCoef,
+                                        const Standard_Boolean theIsMeshSmoothShading) const;
 
   DEFINE_STANDARD_RTTIEXT(MeshVS_MeshPrsBuilder,MeshVS_PrsBuilder)
 
 protected:
 
-  
-  //! Add to array of polylines some lines representing link
-  Standard_EXPORT void AddLinkPrs (const TColStd_Array1OfReal& theCoords, const Handle(Graphic3d_ArrayOfSegments)& theLines, const Standard_Boolean IsShrinked, const Standard_Real ShrinkCoef) const;
-  
-  //! Add to array of segments representing face's wire
-  Standard_EXPORT void AddFaceWirePrs (const TColStd_Array1OfReal& theCoords, const Standard_Integer theNbNodes, const Handle(Graphic3d_ArrayOfSegments)& theLines, const Standard_Boolean theIsShrinked, const Standard_Real theShrinkingCoef) const;
-  
   //! Add to array of polygons a polygon representing face
-  Standard_EXPORT void AddFaceSolidPrs (const Standard_Integer ID, const TColStd_Array1OfReal& theCoords, const Standard_Integer theNbNodes, const Standard_Integer theMaxNodes, const Handle(Graphic3d_ArrayOfTriangles)& theTriangles, const Standard_Boolean theIsReflected, const Standard_Boolean theIsShrinked, const Standard_Real theShrinkCoef, const Standard_Boolean theIsMeshSmoothShading) const;
-  
+  Standard_EXPORT void AddFaceSolidPrs (const Standard_Integer ID,
+                                        const TColStd_Array1OfReal& theCoords,
+                                        const Standard_Integer theNbNodes,
+                                        const Standard_Integer theMaxNodes,
+                                        const Handle(Graphic3d_ArrayOfTriangles)& theTriangles,
+                                        const Standard_Boolean theIsReflected,
+                                        const Standard_Boolean theIsShrinked,
+                                        const Standard_Real theShrinkCoef,
+                                        const Standard_Boolean theIsMeshSmoothShading) const;
+
   //! Draw array of polygons and polylines in the certain order according to transparency
-  Standard_EXPORT void DrawArrays (const Handle(Prs3d_Presentation)& Prs, const Handle(Graphic3d_ArrayOfPrimitives)& thePolygons, const Handle(Graphic3d_ArrayOfPrimitives)& theLines, const Handle(Graphic3d_ArrayOfPrimitives)& theLinkLines, const Handle(Graphic3d_ArrayOfPrimitives)& theVolumesInShad, const Standard_Boolean IsPolygonsEdgesOff, const Standard_Boolean IsSelected, const Handle(Graphic3d_AspectFillArea3d)& theFillAsp, const Handle(Graphic3d_AspectLine3d)& theLineAsp) const;
-  
+  Standard_EXPORT void DrawArrays (const Handle(Prs3d_Presentation)& Prs,
+                                   const Handle(Graphic3d_ArrayOfPrimitives)& thePolygons,
+                                   const Handle(Graphic3d_ArrayOfPrimitives)& theLines,
+                                   const Handle(Graphic3d_ArrayOfPrimitives)& theLinkLines,
+                                   const Handle(Graphic3d_ArrayOfPrimitives)& theVolumesInShad,
+                                   const Standard_Boolean IsPolygonsEdgesOff,
+                                   const Standard_Boolean IsSelected,
+                                   const Handle(Graphic3d_AspectFillArea3d)& theFillAsp,
+                                   const Handle(Graphic3d_AspectLine3d)& theLineAsp) const;
+
   //! Default calculation of center of face or link. This method if useful for shrink mode presentation
   //! theCoords is array of nodes co-ordinates in the strict order X1, Y1, Z1, X2...
   //! NbNodes is number of nodes an element consist of
   //! xG, yG, zG are co-ordinates of center whose will be returned
-  Standard_EXPORT static void CalculateCenter (const TColStd_Array1OfReal& theCoords, const Standard_Integer NbNodes, Standard_Real& xG, Standard_Real& yG, Standard_Real& zG);
-
-
-
-private:
-
-
-
-
+  Standard_EXPORT static void CalculateCenter (const TColStd_Array1OfReal& theCoords,
+                                               const Standard_Integer NbNodes,
+                                               Standard_Real& xG,
+                                               Standard_Real& yG,
+                                               Standard_Real& zG);
 };
 
 
index 75448a84224cbfff50848709af5df4f02215eac3..092ed7f31087df1437a2031b7b097455d0c8ac30 100755 (executable)
@@ -107,6 +107,10 @@ OpenGl_GlCore44.hxx
 OpenGl_LayerList.cxx
 OpenGl_LayerList.hxx
 OpenGl_LayerFilter.hxx
+OpenGl_LOD.hxx
+OpenGl_LOD.cxx
+OpenGl_LODManager.hxx
+OpenGl_LODManager.cxx
 OpenGl_GraphicDriver.cxx
 OpenGl_GraphicDriver.hxx
 OpenGl_IndexBuffer.cxx
diff --git a/src/OpenGl/OpenGl_LOD.cxx b/src/OpenGl/OpenGl_LOD.cxx
new file mode 100644 (file)
index 0000000..1e7aea9
--- /dev/null
@@ -0,0 +1,29 @@
+// Created on: 2015-10-29
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <OpenGl_LOD.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (OpenGl_LOD, Graphic3d_LOD)
+
+//=======================================================================
+// function : NewGroup
+// purpose  :
+//=======================================================================
+Handle(Graphic3d_Group) OpenGl_LOD::NewGroup (const Handle(Graphic3d_Structure)& theParentStruct)
+{
+  Handle(OpenGl_Group) aGroup = new OpenGl_Group (theParentStruct);
+  myGroups.Append (aGroup);
+  return aGroup;
+}
diff --git a/src/OpenGl/OpenGl_LOD.hxx b/src/OpenGl/OpenGl_LOD.hxx
new file mode 100644 (file)
index 0000000..fccafd4
--- /dev/null
@@ -0,0 +1,38 @@
+// Created on: 2015-10-29
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_LOD_Header
+#define _OpenGl_LOD_Header
+
+#include <Graphic3d_LOD.hxx>
+#include <OpenGl_AspectFace.hxx>
+#include <OpenGl_AspectLine.hxx>
+#include <OpenGl_Structure.hxx>
+
+class OpenGl_LOD : public Graphic3d_LOD
+{
+public:
+
+  Standard_EXPORT OpenGl_LOD() : Graphic3d_LOD () {};
+  Standard_EXPORT ~OpenGl_LOD() {};
+
+  Standard_EXPORT virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& theParentStruct) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT (OpenGl_LOD, Graphic3d_LOD)
+};
+
+DEFINE_STANDARD_HANDLE (OpenGl_LOD, Graphic3d_LOD)
+
+#endif // _OpenGl_LOD_Header
diff --git a/src/OpenGl/OpenGl_LODManager.cxx b/src/OpenGl/OpenGl_LODManager.cxx
new file mode 100644 (file)
index 0000000..2700385
--- /dev/null
@@ -0,0 +1,77 @@
+// Created on: 2015-11-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Graphic3d_LOD.hxx>
+#include <OpenGl_LOD.hxx>
+#include <OpenGl_LODManager.hxx>
+
+#include <algorithm>
+
+IMPLEMENT_STANDARD_RTTIEXT (OpenGl_LODManager, Graphic3d_LODManager)
+
+namespace
+{
+  // Comparison operator for sorting LODs
+  class CompareLODS
+  {
+  public:
+   
+    CompareLODS (const NCollection_Vector<Handle(Graphic3d_LOD)>& theLODs)
+      : myLODs (theLODs) {}
+
+    Standard_Boolean operator() (const Handle(Graphic3d_LOD)& theLeft, const Handle(Graphic3d_LOD)& theRight) const
+    {
+      return theLeft->GetRange() < theRight->GetRange();
+    }
+
+  private:
+    void operator = (const CompareLODS&);
+
+  private:
+    const NCollection_Vector<Handle(Graphic3d_LOD)>& myLODs;
+  };
+}
+
+//=======================================================================
+// function : Creation
+// purpose  :
+//=======================================================================
+OpenGl_LODManager::OpenGl_LODManager (const Handle(Graphic3d_Structure)& theParentStructure)
+  : Graphic3d_LODManager (theParentStructure)
+{
+  Standard_ASSERT_RAISE (!theParentStructure.IsNull(),
+    "Parent structure of LOD manager is null!");
+}
+
+//=======================================================================
+// function : AddNewLOD
+// purpose  :
+//=======================================================================
+Handle(Graphic3d_LOD) OpenGl_LODManager::AddNewLOD()
+{
+  Handle(Graphic3d_LOD) aNewLOD = new OpenGl_LOD();
+  myLODs.Append (aNewLOD);
+  sortLODs();
+  return aNewLOD;
+}
+
+//=======================================================================
+// function : sortLODs
+// purpose  :
+//=======================================================================
+void OpenGl_LODManager::sortLODs()
+{
+  std::sort (myLODs.begin(), myLODs.end(), CompareLODS (myLODs));
+}
diff --git a/src/OpenGl/OpenGl_LODManager.hxx b/src/OpenGl/OpenGl_LODManager.hxx
new file mode 100644 (file)
index 0000000..5072e29
--- /dev/null
@@ -0,0 +1,38 @@
+// Created on: 2015-11-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_LODManager_Header
+#define _OpenGl_LODManager_Header
+
+#include <Graphic3d_LODManager.hxx>
+
+class OpenGl_LODManager : public Graphic3d_LODManager
+{
+public:
+  Standard_EXPORT OpenGl_LODManager (const Handle(Graphic3d_Structure)& theParentStructure);
+
+  Standard_EXPORT virtual ~OpenGl_LODManager() {};
+
+  Standard_EXPORT virtual Handle(Graphic3d_LOD) AddNewLOD() Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT (OpenGl_LODManager, Graphic3d_LODManager)
+
+protected:
+  Standard_EXPORT virtual void sortLODs() Standard_OVERRIDE;
+};
+
+DEFINE_STANDARD_HANDLE (OpenGl_LODManager, Graphic3d_LODManager)
+
+#endif // _OpenGl_LODManager_Header
index aa02af4e6a49dc35bf956a7c39c1481b9dd27258..fc9c7ec42e624ec9e93376040b547fdad5f145c4 100644 (file)
@@ -17,6 +17,8 @@
 #include <OpenGl_Context.hxx>
 #include <OpenGl_GlCore11.hxx>
 #include <OpenGl_GraphicDriver.hxx>
+#include <OpenGl_LOD.hxx>
+#include <OpenGl_LODManager.hxx>
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_StructureShadow.hxx>
@@ -25,6 +27,7 @@
 #include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
+#include <Graphic3d_LODManager.hxx>
 
 
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Structure,Graphic3d_CStructure)
@@ -424,6 +427,19 @@ Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Struc
   return aGroup;
 }
 
+// =======================================================================
+// function : NewLOD
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_LOD) OpenGl_Structure::NewLOD (const Handle(Graphic3d_Structure)& theStruct)
+{
+  if (myLODManager.IsNull())
+  {
+    myLODManager = new OpenGl_LODManager (theStruct);
+  }
+  return myLODManager->AddNewLOD();
+}
+
 // =======================================================================
 // function : RemoveGroup
 // purpose  :
@@ -504,7 +520,8 @@ void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorksp
     myInstancedStructure->renderGeometry (theWorkspace, theHasClosed);
   }
 
-  for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
+  const Graphic3d_SequenceOfGroup& aGroups = DrawGroups();
+  for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
   {
     theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
     aGroupIter.Value()->Render (theWorkspace);
@@ -543,6 +560,9 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
     return;
   }
 
+  if (!myLODManager.IsNull() && myLODManager->GetCurrentLODIdx (theWorkspace->View()->Camera()) == -1)
+    return;
+
   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
 
   // Render named status
@@ -763,3 +783,38 @@ Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3
 {
   return new OpenGl_StructureShadow (theManager, this);
 }
+
+//=======================================================================
+//function : SetDetailLevelRange
+//purpose  :
+//=======================================================================
+void OpenGl_Structure::SetDetailLevelRange (const Standard_Integer theIdOfLOD,
+                                            const Standard_Real theFrom,
+                                            const Standard_Real theTo)
+{
+  Standard_ASSERT_RAISE (theFrom < theTo,
+    "The upper boundary of the interval must be greater than lower one!");
+
+  if (theIdOfLOD < 0 || theIdOfLOD > myLODManager->NbOfDetailLevels())
+    return;
+
+  myLODManager->SetRange (theIdOfLOD, theFrom, theTo);
+}
+
+//=======================================================================
+//function : DrawGroups
+//purpose  :
+//=======================================================================
+const Graphic3d_SequenceOfGroup& OpenGl_Structure::DrawGroups() const
+{
+  return myLODManager.IsNull() ? myGroups : myLODManager->GetCurrentGroups();
+}
+
+//=======================================================================
+//function : NbDetailLevels
+//purpose  :
+//=======================================================================
+Standard_Integer OpenGl_Structure::NbDetailLevels() const
+{
+  return myLODManager->NbOfDetailLevels();
+}
index 6a4f2157c5fa849d13921b1b7dd4ce37a74177b2..53ada6de9854c3bec8e4b652ee0ccd1827e8f05a 100644 (file)
 
 class OpenGl_Structure;
 class OpenGl_GraphicDriver;
+class OpenGl_LOD;
 
 typedef NCollection_List<const OpenGl_Structure* > OpenGl_ListOfStructure;
+typedef NCollection_Vector<Handle(OpenGl_LOD)> OpenGl_VectorOfLODs;
 
 //! Implementation of low-level graphic structure.
 class OpenGl_Structure : public Graphic3d_CStructure
@@ -98,16 +100,20 @@ public:
   //! Create new group within this structure
   Standard_EXPORT virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& theStruct) Standard_OVERRIDE;
 
+  //! Create new LOD within this structure
+  Standard_EXPORT virtual Handle(Graphic3d_LOD) NewLOD (const Handle(Graphic3d_Structure)& theStruct) Standard_OVERRIDE;
+
   //! Remove group from this structure
   Standard_EXPORT virtual void RemoveGroup (const Handle(Graphic3d_Group)& theGroup) Standard_OVERRIDE;
 
+  Standard_EXPORT virtual void SetDetailLevelRange (const Standard_Integer theIdOfLOD,
+                                                    const Standard_Real theFrom,
+                                                    const Standard_Real theTo) Standard_OVERRIDE;
+
 public:
 
   //! @return graphic groups
-  virtual const Graphic3d_SequenceOfGroup& DrawGroups() const
-  {
-    return myGroups;
-  }
+  virtual const Graphic3d_SequenceOfGroup& DrawGroups() const;
 
   //! Access graphic driver
   OpenGl_GraphicDriver* GlDriver() const
@@ -197,6 +203,8 @@ public:
   //! Is the structure ray-tracable (contains ray-tracable elements)?
   Standard_Boolean IsRaytracable() const;
 
+  Standard_EXPORT virtual Standard_Integer NbDetailLevels() const Standard_OVERRIDE;
+
 protected:
 
   Standard_EXPORT virtual ~OpenGl_Structure();
index 011a8c7400559cc50bb2211514208ae815581094..c7c5d05c2e42c0dee5ef43f32af444e9353408b6 100644 (file)
@@ -22,6 +22,7 @@
 #include <Standard_Handle.hxx>
 
 class Graphic3d_Group;
+class Graphic3d_LOD;
 class Prs3d_Presentation;
 
 
@@ -44,22 +45,6 @@ public:
   //! objects in the display.
   //! A group also contains the attributes whose ranges are limited to the primitives in it.
   Standard_EXPORT static Handle(Graphic3d_Group) NewGroup (const Handle(Prs3d_Presentation)& Prs3d);
-
-
-
-
-protected:
-
-
-
-
-
-private:
-
-
-
-
-
 };
 
 
index c9eebc5d24e737a91870dc591bce712bea1dfcf0..34554995685bf43c6f69aec8b7e7448457f9e481 100644 (file)
@@ -4,3 +4,4 @@ TKService
 TKernel
 TKG3d
 TKG2d
+TKSTL
index 85fede675647f70a0bcf441b80564e23dd48e45b..df5edb6792b86893e7fcd2ab516b4bd7a04ae079 100644 (file)
@@ -55,6 +55,7 @@
 #include <TopoDS_Shape.hxx>
 #include <V3d_View.hxx>
 #include <ViewerTest.hxx>
+#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
 #include <VrmlAPI.hxx>
 #include <VrmlAPI_Writer.hxx>
 #include <VrmlData_DataMapOfShapeAppearance.hxx>
@@ -80,6 +81,7 @@
 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
                                            const Handle(AIS_InteractiveObject)& theAISObj,
                                            Standard_Boolean theReplaceIfExists = Standard_True);
+extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
 
 static Standard_Integer writestl
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
@@ -1202,6 +1204,358 @@ static Standard_Integer meshinfo(Draw_Interpretor& di,
   return 0;
 }
 
+#include <AIS_InteractiveObject.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
+#include <BRepTools.hxx>
+#include <MeshVS_LODDataSource.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <ViewerTest_AutoUpdater.hxx>
+//=======================================================================
+//function : VGenLods
+//purpose  : Generates sequence of LODs for the shape given
+//=======================================================================
+static int MeshGenLods (Draw_Interpretor& theDI,
+                        Standard_Integer  theArgNum,
+                        const char**      theArgs)
+{
+  if (theArgNum < 3)
+  {
+    std::cout << "Error! Wrong number of arguments. See usage:\n";
+    theDI.PrintHelp (theArgs[0]);
+    return 1;
+  }
+
+  Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
+  if (aCtx.IsNull())
+  {
+    std::cout << "Error! No opened viewer." << std::endl;
+    return 1;
+  }
+
+  Standard_CString aShapeName = theArgs[1];
+  const TopoDS_Shape aShape = DBRep::Get (aShapeName);
+  if (aShape.IsNull())
+  {
+    std::cout << "Error! No shape with the name " << aShapeName << "." << std::endl;
+    return 1;
+  }
+  const Standard_Integer aLodsNb = Draw::Atoi (theArgs[2]);
+  if (aLodsNb <= 0)
+  {
+    std::cout << "Error! Incorrect amount of LODs passed: " << aLodsNb << "." << std::endl;
+    std::cout << "Must be greater than zero." << std::endl;
+    return 1;
+  }
+  Standard_Boolean toPrintInfo = Standard_False;
+  TCollection_AsciiString aSavePath = "";
+  Handle(MeshVS_Mesh) aMesh = NULL;
+  if (theArgNum > 3)
+  {
+    for (Standard_Integer anArgIdx = 3; anArgIdx < theArgNum; ++anArgIdx)
+    {
+      TCollection_AsciiString anArg (theArgs[anArgIdx]);
+      anArg.LowerCase();
+      if (anArg == "-debug")
+      {
+        toPrintInfo = Standard_True;
+      }
+      else if (anArg == "-mesh")
+      {
+        aMesh = Handle(MeshVS_Mesh)::DownCast (GetMapOfAIS().Find2 (theArgs[++anArgIdx]));
+      }
+      else if (anArg == "-save")
+      {
+        aSavePath = TCollection_AsciiString (theArgs[++anArgIdx]);
+      }
+    }
+  }
+
+  // Determine max deflection of a shape
+  Handle(Poly_Triangulation) aFaceTrg;
+  TopLoc_Location aFaceLoc;
+  Standard_Real aMaxDefl = 0.0;
+  for (TopExp_Explorer anExplorer (aShape, TopAbs_FACE); anExplorer.More(); anExplorer.Next())
+  {
+    TopoDS_Face aCurFace = TopoDS::Face (anExplorer.Current());
+    aFaceTrg = BRep_Tool::Triangulation (aCurFace, aFaceLoc);
+    if (!aFaceTrg.IsNull())
+    {
+      if (aFaceTrg->Deflection() > aMaxDefl)
+        aMaxDefl = aFaceTrg->Deflection();
+    }
+  }
+
+  BRepTools::Clean (aShape);
+  BRepMesh_FastDiscret::Parameters aMeshParams;
+  aMeshParams.Deflection = aMaxDefl;
+  aMeshParams.Angle = 0.5;
+  aMeshParams.Relative =  Standard_False;
+  aMeshParams.InParallel = Standard_False;
+  aMeshParams.MinSize = Precision::Confusion();
+  aMeshParams.InternalVerticesMode = Standard_True;
+  aMeshParams.ControlSurfaceDeflection = Standard_True;
+  aMeshParams.AdaptiveMin = Standard_False;
+  BRepMesh_IncrementalMesh aBaseMesher (aShape, aMeshParams);
+  aBaseMesher.Perform();
+  ViewerTest_AutoUpdater anAutoUpd (aCtx, ViewerTest::CurrentView());
+
+
+  // compute the shape for each LOD
+  TopoDS_Shape* aLodShapes = new TopoDS_Shape[aLodsNb];
+  BRepBuilderAPI_Copy aMainCopyAlgo;
+  aMainCopyAlgo.Perform (aShape, Standard_True, Standard_True);
+  aLodShapes[0] = aMainCopyAlgo.Shape();
+  Standard_Real aDeflDecrFactor = aMaxDefl / aLodsNb;
+  for (Standard_Integer aLodIdx = 1; aLodIdx < aLodsNb; ++aLodIdx)
+  {
+    BRepBuilderAPI_Copy aCopyAlgo;
+    aCopyAlgo.Perform (aShape, Standard_True, Standard_True);
+    aLodShapes[aLodIdx] = aCopyAlgo.Shape();
+    BRepTools::Clean (aLodShapes[aLodIdx]);
+    BRepMesh_FastDiscret::Parameters aParams;
+    aParams.Deflection = aMaxDefl - aLodIdx * aDeflDecrFactor;
+    aParams.Angle = 0.5;
+    aParams.Relative =  Standard_False;
+    aParams.InParallel = Standard_False;
+    aParams.MinSize = Precision::Confusion();
+    aParams.InternalVerticesMode = Standard_True;
+    aParams.ControlSurfaceDeflection = Standard_True;
+    aParams.AdaptiveMin = Standard_False;
+    BRepMesh_IncrementalMesh aMesher (aLodShapes[aLodIdx], aParams);
+    aMesher.Perform();
+    if (toPrintInfo)
+    {
+      Standard_Integer aStatus = aMesher.GetStatusFlags();
+      std::cout << "LOD #" << aLodIdx << " meshing status: ";
+      if (!aStatus)
+        std::cout << " OK" << std::endl;
+      else
+      {
+        for (Standard_Integer aBitIdx = 0; aBitIdx < 4; ++aBitIdx)
+        {
+          if ((aStatus >> aBitIdx) & 1)
+          {
+            switch (aBitIdx + 1)
+            {
+            case 1:
+              std::cout << " OpenWire ";
+              break;
+            case 2:
+              std::cout << " SelfIntersectingWire ";
+              break;
+            case 3:
+              std::cout << " Failure ";
+              break;
+            case 4:
+              std::cout << " ReMesh ";
+              break;
+            }
+          }
+        }
+        std::cout << std::endl;
+      }
+    }
+  }
+
+  if (toPrintInfo)
+  {
+    std::cout << std::endl;
+    for (Standard_Integer aLodIdx = 0; aLodIdx < aLodsNb; ++aLodIdx)
+    {
+      std::cout << "LOD #" << aLodIdx + 1 << " info:" << std::endl;
+      if (aLodShapes[aLodIdx].IsNull())
+      {
+        std::cout << "The shape is null!" << std::endl;
+      }
+
+      Handle(Poly_Triangulation) aCurTrg;
+      TopLoc_Location aCurLoc;
+      Standard_Real aDefl = 0.0;
+      Standard_Integer aTrgsNb = 0, aNodesNb = 0;
+      for (TopExp_Explorer aShapeExp (aLodShapes[aLodIdx], TopAbs_FACE); aShapeExp.More(); aShapeExp.Next())
+      {
+        TopoDS_Face aCurFace = TopoDS::Face (aShapeExp.Current());
+        aCurTrg = BRep_Tool::Triangulation (aCurFace, aCurLoc);
+        if (!aCurTrg.IsNull())
+        {
+          aTrgsNb += aCurTrg->NbTriangles();
+          aNodesNb += aCurTrg->NbNodes();
+          if (aCurTrg->Deflection() > aDefl)
+            aDefl = aCurTrg->Deflection();
+        }
+      }
+      std::cout << "deflection  : " << aDefl << std::endl;
+      std::cout << "triangles nb: " << aTrgsNb << std::endl;
+      std::cout << "nodes nb    : " << aNodesNb << std::endl;
+      std::cout << std::endl;
+    }
+  }
+
+  if (!aMesh.IsNull() && aSavePath != "")
+  {
+    if (aSavePath.Value (aSavePath.Length()) != '/')
+    {
+      aSavePath = aSavePath + "/";
+    }
+    aSavePath = aSavePath + aShapeName + "_LOD";
+    for (Standard_Integer aLodIdx = 0; aLodIdx < aLodsNb; ++aLodIdx)
+    {
+      StlAPI_Writer aWriter;
+      aWriter.ASCIIMode() = Standard_False;
+      TCollection_AsciiString aPath = aSavePath + aLodIdx + ".stl";
+      StlAPI_ErrorStatus aStatus = aWriter.Write (aLodShapes[aLodIdx], aPath.ToCString());
+      switch (aStatus)
+      {
+      case StlAPI_CannotOpenFile:
+        std::cout << "Error! Cannot create/open a file with the name: " << aPath << std::endl;
+        break;
+      case StlAPI_StatusOK:
+      default:
+        std::cout << "LOD" << aLodIdx << " was written sucessfully to the file " << aPath << std::endl;
+      }
+    }
+  }
+
+  return 0;
+}
+
+#include <MeshVS_LODBuilder.hxx>
+static int MeshLod (Draw_Interpretor& theDI,
+                    Standard_Integer  theArgNum,
+                    const char**      theArgs)
+{
+  struct DetailLevelData
+  {
+  public:
+    DetailLevelData()
+      : myMesh (NULL),
+        myFrom (-DBL_MAX),
+        myTo (DBL_MAX) {}
+
+  public:
+    Handle(StlMesh_Mesh) myMesh;
+    Standard_Real        myFrom;
+    Standard_Real        myTo;
+  };
+
+  if (theArgNum < 3)
+  {
+    std::cout << "Error! Wrong number of arguments. See usage:\n";
+    theDI.PrintHelp (theArgs[0]);
+    return 1;
+  }
+
+  Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
+  if (aCtx.IsNull())
+  {
+    std::cout << "Error! No opened viewer." << std::endl;
+    return 1;
+  }
+
+  Standard_CString aShapeName = theArgs[1];
+  if (GetMapOfAIS().IsBound2 (aShapeName))
+  {
+    std::cout << "Error! The context already has an interactive object with the name " << aShapeName << "." << std::endl;
+    return 1;
+  }
+  const TCollection_AsciiString aPathToLODInfo = Draw::Atoi (theArgs[2]);
+  if (aPathToLODInfo == "")
+  {
+    std::cout << "Error! Path to LOD info must not be empty!" << std::endl;
+    return 1;
+  }
+
+  std::ifstream aLODInfoFile (theArgs[2]);
+  NCollection_List<DetailLevelData> myLODDataList;
+  Handle(StlMesh_Mesh) aLargestMesh;
+  for (std::string aLODInfoStr; getline (aLODInfoFile, aLODInfoStr);)
+  {
+    DetailLevelData aData;
+    std::istringstream aStream (aLODInfoStr);
+    std::vector<std::string> aTokens;
+    std::copy (std::istream_iterator<std::string> (aStream),
+               std::istream_iterator<std::string>(),
+               std::back_inserter (aTokens));
+    for (Standard_Integer aTokenIdx = 0; aTokenIdx < aTokens.size(); ++aTokenIdx)
+    {
+      if (aTokens[aTokenIdx] == "-path")
+      {
+        OSD_Path aFile (aTokens[++aTokenIdx].c_str());
+        Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
+        Handle(StlMesh_Mesh) aSTLMesh = RWStl::ReadFile (aFile, aProgress);
+        if (aSTLMesh.IsNull())
+        {
+          std::cout << "Error! Can not read LOD located at the path: " << aTokens[aTokenIdx] << std::endl;
+          return 1;
+        }
+        aData.myMesh = aSTLMesh;
+        if (aLargestMesh.IsNull() || aSTLMesh->Triangles().Length() > aLargestMesh->Triangles().Length())
+        {
+          aLargestMesh = aSTLMesh;
+        }
+      }
+      else if (aTokens[aTokenIdx] == "-from")
+      {
+        aData.myFrom = Draw::Atof (aTokens[++aTokenIdx].c_str());
+      }
+      else if (aTokens[aTokenIdx] == "-to")
+      {
+        aData.myTo = Draw::Atof (aTokens[++aTokenIdx].c_str());
+      }
+    }
+    myLODDataList.Append (aData);
+  }
+
+  if (aLargestMesh.IsNull())
+  {
+    std::cout << "Error! No meshes found in lod info file!" << std::endl;
+    return 1;
+  }
+
+  Handle(MeshVS_Mesh) anOriginMesh = new MeshVS_Mesh();
+  Handle(XSDRAWSTLVRML_DataSource) anOriginDataSource = new XSDRAWSTLVRML_DataSource (aLargestMesh);
+  anOriginMesh->SetDataSource (anOriginDataSource);
+  Handle(MeshVS_MeshPrsBuilder) anOriginBuilder = new MeshVS_MeshPrsBuilder (anOriginMesh.operator->());
+  anOriginMesh->AddBuilder (anOriginBuilder, Standard_True);
+  anOriginMesh->GetDrawer()->SetColor (MeshVS_DA_EdgeColor, Quantity_NOC_YELLOW);
+
+  for (NCollection_List<DetailLevelData>::Iterator aLodDataIter (myLODDataList); aLodDataIter.More(); aLodDataIter.Next())
+  {
+    Handle(MeshVS_LODDataSource) aLod = new MeshVS_LODDataSource (aLodDataIter.Value().myMesh);
+    anOriginMesh->AddDataSource (aLod);
+    Handle(MeshVS_LODBuilder) aLODBuilder = new MeshVS_LODBuilder (anOriginMesh.operator->());
+    aLODBuilder->SetDataSource (aLod);
+    aLODBuilder->SetDrawer (anOriginBuilder->GetDrawer());
+    anOriginMesh->AddBuilder (aLODBuilder);
+  }
+
+  // Hide all nodes by default
+  Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
+  Standard_Integer aLen = aLargestMesh->Vertices().Length();
+  for (Standard_Integer anIndex = 1; anIndex <= aLen; ++anIndex)
+    aNodes->ChangeMap().Add (anIndex);
+  anOriginMesh->SetHiddenNodes (aNodes);
+  anOriginMesh->SetSelectableNodes (aNodes);
+
+  VDisplayAISObject (aShapeName, anOriginMesh);
+  aCtx->Deactivate (anOriginMesh);
+
+  Standard_Integer aLodIdx = 0;
+  for (NCollection_List<DetailLevelData>::Iterator aLodDataIter (myLODDataList); aLodDataIter.More(); aLodDataIter.Next())
+  {
+    anOriginMesh->Presentation()->SetDetailLevelRange (aLodIdx, aLodDataIter.Value().myFrom, aLodDataIter.Value().myTo);
+  }
+
+  Draw::Set (aShapeName, new XSDRAWSTLVRML_DrawableMesh (anOriginMesh));
+  Handle(V3d_View) aView = ViewerTest::CurrentView();
+  if (!aView.IsNull())
+    aView->FitAll();
+
+  return 0;
+}
+
 //-----------------------------------------------------------------------------
 
 void  XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
@@ -1232,6 +1586,24 @@ void  XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
   theCommands.Add ("meshdeform",      "display deformed mesh",                        __FILE__, meshdeform,      g );
   theCommands.Add ("mesh_edge_width", "set width of edges",                           __FILE__, mesh_edge_width, g );
   theCommands.Add ("meshinfo",        "displays the number of nodes and triangles",   __FILE__, meshinfo,        g );
+  theCommands.Add ("meshgenlods",
+                   "meshgenlods shapeName lodsNb [-save pathToFolder] [-mesh meshName] [-debug]"
+                   "\n\t\t: Generates sequence of LODs for the shape with shapeName in amount of lodsNb."
+                   "\n\t\t: lodsNb means the exact amount of physical LODs to generate, e.g. the main"
+                   "\n\t\t: object's presentation is not considered as a separate level of detail here."
+                   "\n\t\t: [-debug] enables printing of meshing status and each LOD's info.",
+                   __FILE__, MeshGenLods, g);
+  theCommands.Add ("meshlod",
+                   "meshlod shapeName pathToFileWithLodInfo"
+                   "\n\t\t: Creates an object with the name shapeName that has LODs described in file stored at"
+                   "\n\t\t: pathToFileWithLodInfo. Each string in the file is a full description of LOD. It must"
+                   "\n\t\t: be filled using the following form:"
+                   "\n\t\t: -path pathToLOD [-from fromRange] [-to toRange], where"
+                   "\n\t\t: pathToLOD is a path to STL file with LOD mesh, fromRange and toRange define a depth"
+                   "\n\t\t: range where the LOD will be visible. Each of range parameters is optional, but in this"
+                   "\n\t\t: case, it will be equal to positive and negative max double correspondingly."
+                   "\n\t\t: It is assumed that ranges are non-overlapping segments of the real axis."
+                   __FILE__, MeshLod, g);
 }
 
 //==============================================================================
diff --git a/tests/bugs/vis/bug26812 b/tests/bugs/vis/bug26812
new file mode 100644 (file)
index 0000000..cb93e21
--- /dev/null
@@ -0,0 +1,24 @@
+set aPathToData ""
+set aTmpFolder ""
+
+pload ALL
+vinit
+meshlod m $aTmpFolder/lod_data.txt
+
+##########################################################################
+# to generate brep file for LODs generaion, it is requred to use
+# iges shapes. the following sequence of commands creates both
+# stl and brep files for the iges shape
+##########################################################################
+igesbrep $aPathToData/iges/bearing.iges res *
+vdisplay res
+# write created brep to file
+save res $aTmpFolder/bearing.brep
+trinfo res
+# copy maximal deflection value, then re-mesh the shape with proper
+# deflection
+tclean res
+incmesh res $maxDeflection
+# save corresponding stl with the same triangulation as will be used
+# for generaion of LODs
+writestl res $aTmpFolder/bearing.stl