From efb8c69bbc3d69c920aea7be712244c30c1a85e8 Mon Sep 17 00:00:00 2001 From: vpa Date: Wed, 25 Nov 2015 21:07:29 +0300 Subject: [PATCH] The procedure of LOD creation and management was refactored: - added LOD managers at Graphic3d and OpenGl levels; - the LODs are connected to structure via unique managers; - the metric could be redefined using custom LOD selectors; - LODs are now added to MeshVS_Mesh in Compute method and are listed as its data sources. --- src/Graphic3d/FILES | 5 + src/Graphic3d/Graphic3d_CStructure.hxx | 4 +- src/Graphic3d/Graphic3d_LOD.cxx | 30 +- src/Graphic3d/Graphic3d_LOD.hxx | 60 +- .../Graphic3d_LODDistanceSelector.cxx | 32 + .../Graphic3d_LODDistanceSelector.hxx | 38 ++ src/Graphic3d/Graphic3d_LODManager.cxx | 77 +++ src/Graphic3d/Graphic3d_LODManager.hxx | 75 +++ src/Graphic3d/Graphic3d_LODSelector.hxx | 37 ++ src/Graphic3d/Graphic3d_Structure.cxx | 2 +- src/MeshVS/FILES | 2 + src/MeshVS/MeshVS_LODBuilder.cxx | 546 ++++++++++++++++++ src/MeshVS/MeshVS_LODBuilder.hxx | 66 +++ src/MeshVS/MeshVS_LODDataSource.cxx | 507 ---------------- src/MeshVS/MeshVS_LODDataSource.hxx | 14 - src/MeshVS/MeshVS_Mesh.cxx | 28 + src/MeshVS/MeshVS_Mesh.hxx | 17 +- src/OpenGl/FILES | 3 +- src/OpenGl/OpenGl_LOD.cxx | 20 - src/OpenGl/OpenGl_LOD.hxx | 53 +- src/OpenGl/OpenGl_LODManager.cxx | 75 +++ .../{OpenGl_LOD.lxx => OpenGl_LODManager.hxx} | 28 +- src/OpenGl/OpenGl_Structure.cxx | 86 +-- src/OpenGl/OpenGl_Structure.hxx | 20 +- src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx | 2 +- 25 files changed, 1106 insertions(+), 721 deletions(-) create mode 100644 src/Graphic3d/Graphic3d_LODDistanceSelector.cxx create mode 100644 src/Graphic3d/Graphic3d_LODDistanceSelector.hxx create mode 100644 src/Graphic3d/Graphic3d_LODManager.cxx create mode 100644 src/Graphic3d/Graphic3d_LODManager.hxx create mode 100644 src/Graphic3d/Graphic3d_LODSelector.hxx create mode 100644 src/MeshVS/MeshVS_LODBuilder.cxx create mode 100644 src/MeshVS/MeshVS_LODBuilder.hxx create mode 100644 src/OpenGl/OpenGl_LODManager.cxx rename src/OpenGl/{OpenGl_LOD.lxx => OpenGl_LODManager.hxx} (50%) diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index ae7e43c780..3877676eae 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -79,6 +79,11 @@ 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 diff --git a/src/Graphic3d/Graphic3d_CStructure.hxx b/src/Graphic3d/Graphic3d_CStructure.hxx index 5a075b7f5d..c7ce04debf 100644 --- a/src/Graphic3d/Graphic3d_CStructure.hxx +++ b/src/Graphic3d/Graphic3d_CStructure.hxx @@ -29,6 +29,7 @@ class Graphic3d_GraphicDriver; class Graphic3d_StructureManager; class Graphic3d_LOD; +class Graphic3d_LODManager; //! Low-level graphic structure interface class Graphic3d_CStructure : public Standard_Transient @@ -114,7 +115,7 @@ public: virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& theStruct) = 0; //! Create new LOD within this structure - virtual Handle(Graphic3d_LOD) NewLOD() = 0; + 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; @@ -166,6 +167,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 index 060b093630..91bbc86d7e 100644 --- a/src/Graphic3d/Graphic3d_LOD.cxx +++ b/src/Graphic3d/Graphic3d_LOD.cxx @@ -28,32 +28,10 @@ Graphic3d_LOD::~Graphic3d_LOD() // function : SetRange // purpose : //======================================================================= -void Graphic3d_LOD::SetRange (const Standard_Real /*theFrom*/, const Standard_Real /*theTo*/) +void Graphic3d_LOD::SetRange (const Standard_Real theFrom, const Standard_Real theTo) { - return; -} - -//======================================================================= -// function : NewGroup -// purpose : -//======================================================================= -Handle(Graphic3d_Group) Graphic3d_LOD::NewGroup (const Handle(Graphic3d_Structure)& /*theParentStruct*/) -{ - return NULL; -} - -//======================================================================= -// function : ComputeMetrics -// purpose : -//======================================================================= -Standard_Real Graphic3d_LOD::ComputeMetrics (const Handle(Graphic3d_Camera)& theCamera, - const Handle(Graphic3d_CStructure)& theParentStruct) const -{ - if (theParentStruct.IsNull()) - return std::numeric_limits::max(); + Standard_ASSERT_RAISE (theFrom < theTo, + "The upper boundary of the interval must be greater than lower one!"); - Graphic3d_BndBox4f aBndBox = theParentStruct->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(); + myRange = Graphic3d_RangeOfLOD (theFrom, theTo); } diff --git a/src/Graphic3d/Graphic3d_LOD.hxx b/src/Graphic3d/Graphic3d_LOD.hxx index a3e41d184c..04d0eb5079 100644 --- a/src/Graphic3d/Graphic3d_LOD.hxx +++ b/src/Graphic3d/Graphic3d_LOD.hxx @@ -23,22 +23,72 @@ #include #include +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 myFrom < theVal; + } + + 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 Graphic3d_LOD() {}; Standard_EXPORT virtual ~Graphic3d_LOD(); - Standard_EXPORT virtual void SetRange (const Standard_Real theFrom, const Standard_Real theTo); - Standard_EXPORT virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& theParentStruct); + Standard_EXPORT void SetRange (const Standard_Real theFrom, const Standard_Real theTo); + + Standard_EXPORT const Graphic3d_RangeOfLOD& GetRange() const + { + return myRange; + } - Standard_EXPORT Standard_Real ComputeMetrics (const Handle(Graphic3d_Camera)& theCamera, - const Handle(Graphic3d_CStructure)& theParentStruct) const; + Standard_EXPORT virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& /*theParentStruct*/) + { + return NULL; + }; + + const Graphic3d_SequenceOfGroup& GetDrawGroups() const + { + return myGroups; + } DEFINE_STANDARD_RTTI (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) diff --git a/src/Graphic3d/Graphic3d_LODDistanceSelector.cxx b/src/Graphic3d/Graphic3d_LODDistanceSelector.cxx new file mode 100644 index 0000000000..e854217df3 --- /dev/null +++ b/src/Graphic3d/Graphic3d_LODDistanceSelector.cxx @@ -0,0 +1,32 @@ +// 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 +#include +#include +#include + +//======================================================================= +// 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 index 0000000000..6c2700dac3 --- /dev/null +++ b/src/Graphic3d/Graphic3d_LODDistanceSelector.hxx @@ -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 + +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_RTTI (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 index 0000000000..dcbaa2938f --- /dev/null +++ b/src/Graphic3d/Graphic3d_LODManager.cxx @@ -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 +#include + +//======================================================================= +// 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)) + return -1; + + for (Standard_Integer aLodIdx = 1; aLodIdx < myLODs.Size(); ++aLodIdx) + { + if (myLODs.Value (aLodIdx)->GetRange().IsIn (aMetric)) + { + myCurrentLODIdx = aLodIdx; + break; + } + } + + if (myLODs.Value (myLODs.Size() - 1)->GetRange().IsGreater (aMetric)) + myCurrentLODIdx = myLODs.Size() - 1; + + 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); +} + +//======================================================================= +// 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 index 0000000000..570f089e41 --- /dev/null +++ b/src/Graphic3d/Graphic3d_LODManager.hxx @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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_RTTI (Graphic3d_LODManager, Standard_Transient) + +protected: + Standard_EXPORT Graphic3d_LODManager (const Handle(Graphic3d_Structure)& theParentStructure); + + Standard_EXPORT virtual void sortLODs() {}; + +protected: + NCollection_Vector 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 index 0000000000..54d1d27d34 --- /dev/null +++ b/src/Graphic3d/Graphic3d_LODSelector.hxx @@ -0,0 +1,37 @@ +// 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 +#include +#include + +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 (Graphic3d_LODSelector, Standard_Transient) +}; + +DEFINE_STANDARD_HANDLE (Graphic3d_LODSelector, Standard_Transient) + +#endif // _Graphic3d_LODSelector_Header diff --git a/src/Graphic3d/Graphic3d_Structure.cxx b/src/Graphic3d/Graphic3d_Structure.cxx index cc6a629e1a..2465e89eda 100644 --- a/src/Graphic3d/Graphic3d_Structure.cxx +++ b/src/Graphic3d/Graphic3d_Structure.cxx @@ -1749,7 +1749,7 @@ Handle(Graphic3d_Group) Graphic3d_Structure::NewGroup() //============================================================================= Handle(Graphic3d_LOD) Graphic3d_Structure::NewLOD() { - return myCStructure->NewLOD(); + return myCStructure->NewLOD (this); } //============================================================================= diff --git a/src/MeshVS/FILES b/src/MeshVS/FILES index 7654ee848b..d8e133a751 100755 --- a/src/MeshVS/FILES +++ b/src/MeshVS/FILES @@ -41,6 +41,8 @@ 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 diff --git a/src/MeshVS/MeshVS_LODBuilder.cxx b/src/MeshVS/MeshVS_LODBuilder.cxx new file mode 100644 index 0000000000..ba7cb27009 --- /dev/null +++ b/src/MeshVS/MeshVS_LODBuilder.cxx @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +// 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) +{ + Standard_ASSERT_RAISE (!theDataSource.IsNull(), "LOD data source is null!"); +} + +//======================================================================= +// 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 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 index 0000000000..f9eb6cb4b7 --- /dev/null +++ b/src/MeshVS/MeshVS_LODBuilder.hxx @@ -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 +#include +#include + +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_RTTI (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 index 932a3f8a40..230b15811c 100644 --- a/src/MeshVS/MeshVS_LODDataSource.cxx +++ b/src/MeshVS/MeshVS_LODDataSource.cxx @@ -175,510 +175,3 @@ const TColStd_PackedMapOfInteger& MeshVS_LODDataSource::GetAllElements() const { return myTriangleIdxs; } - -//======================================================================= -// function : ComputePrs -// purpose : -//======================================================================= -void MeshVS_LODDataSource::ComputePrs (const Handle(AIS_InteractiveObject) theMesh) -{ - Handle(MeshVS_Mesh) aMesh = Handle(MeshVS_Mesh)::DownCast (theMesh); - if (aMesh.IsNull()) - return; - - // Standard_Boolean hasNodes = !myNodeIdxs.IsEmpty(); - Standard_Boolean hasTrgs = !myTriangleIdxs.IsEmpty(); - Handle(Prs3d_Presentation) aMainPrs = theMesh->Presentation(); - const Standard_Integer aDispMode = theMesh->DisplayMode(); - - //if (hasNodes) - //{ - // 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 (hasTrgs) - { - Standard_Integer aMaxNodesNb; - - Handle(MeshVS_MeshPrsBuilder) aBuilder = Handle(MeshVS_MeshPrsBuilder)::DownCast (aMesh->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 = (aDispMode & 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 = aDispMode == MeshVS_DMF_WireFrame; - Standard_Boolean isShading = aDispMode == MeshVS_DMF_Shading; - Standard_Boolean isShrink = aDispMode == 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 (myTriangleIdxs); - Handle(TColStd_HPackedMapOfInteger) aHiddenElems = aMesh->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 (!GetGeom (anIdxIter.Key(), Standard_True, aCoords, aNbNodes, aType)) - continue; - - if (aType == MeshVS_ET_Volume) - { - if (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 (GetGeomType (anIdxIter.Key(), Standard_True, aType) && aType == MeshVS_ET_Link) - { - Standard_Integer aNbNodes; - - if (GetNodesByElement (anIdxIter.Key(), aNodes, aNbNodes) && aNbNodes == 2) - { - aLinkNodes.Add (MeshVS_TwoNodes (aNodes(1), aNodes(2))); - } - } - } - } - - NCollection_Map aSegmentMap; - - for (anIdxIter.Reset(); anIdxIter.More(); anIdxIter.Next()) - { - const Standard_Integer aKey = anIdxIter.Key(); - - Standard_Integer NbNodes; - if (!GetGeom (aKey, Standard_True, aCoords, NbNodes, aType)) - continue; - - if (!GetNodesByElement (aKey, aNodes, NbNodes)) - continue; - - switch (aType) - { - case MeshVS_ET_Volume: - { - if (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 (this, 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 (aMainPrs, aFaceTriangles, aEdgeSegments, aLinkSegments, aVolmTriangles, - !toShowEdges, hasSelFlag, isSupressBackFaces, aFill, aBeam); - } -} - -//================================================================ -// Function : DrawArrays -// Purpose : -//================================================================ -void MeshVS_LODDataSource::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_LODDataSource.hxx b/src/MeshVS/MeshVS_LODDataSource.hxx index f3282c40d7..09efe71605 100644 --- a/src/MeshVS/MeshVS_LODDataSource.hxx +++ b/src/MeshVS/MeshVS_LODDataSource.hxx @@ -79,22 +79,8 @@ public: //! This method returns map of all elements the object consist of. Standard_EXPORT virtual const TColStd_PackedMapOfInteger& GetAllElements() const Standard_OVERRIDE; - Standard_EXPORT void ComputePrs (const Handle(AIS_InteractiveObject) theMesh); - DEFINE_STANDARD_RTTI (MeshVS_LODDataSource, MeshVS_DataSource) -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; - private: TColStd_PackedMapOfInteger myNodeIdxs; TColStd_PackedMapOfInteger myTriangleIdxs; diff --git a/src/MeshVS/MeshVS_Mesh.cxx b/src/MeshVS/MeshVS_Mesh.cxx index 894bd96ef0..fdcb32b7bb 100644 --- a/src/MeshVS/MeshVS_Mesh.cxx +++ b/src/MeshVS/MeshVS_Mesh.cxx @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -168,10 +169,16 @@ void MeshVS_Mesh::Compute ( const Handle(PrsMgr_PresentationManager3d)& thePrsMg thePresentation->Clear(); Standard_Integer len = myBuilders.Length(); + Handle(MeshVS_LODBuilder) aLODBldr; if ( theMode > 0 ) for ( Standard_Integer i=1; i<=len; i++ ) { Handle (MeshVS_PrsBuilder) aCurrent = myBuilders.Value ( i ); + if (!Handle(MeshVS_LODBuilder)::DownCast (aCurrent)) + { + aLODBldr = Handle(MeshVS_LODBuilder)::DownCast (aCurrent); + continue; + } if ( !aCurrent.IsNull() && aCurrent->TestFlags ( theMode ) ) { aCurrent->SetPresentationManager( thePrsMgr ); @@ -182,6 +189,18 @@ void MeshVS_Mesh::Compute ( const Handle(PrsMgr_PresentationManager3d)& thePrsMg } } + if (myLODDataSources.Size() > 0 && !aLODBldr.IsNull() && aLODBldr->TestFlags (theMode)) + { + for (Standard_Integer aLodIdx = 0; aLodIdx < myLODDataSources.Size(); ++aLodIdx) + { + const TColStd_PackedMapOfInteger aVertIdxs = myLODDataSources.Value (aLodIdx)->GetAllNodes(); + const TColStd_PackedMapOfInteger aTrgIdxs = myLODDataSources.Value (aLodIdx)->GetAllElements(); + if (HasNodes) + aLODBldr->Build (thePresentation, aVertIdxs, aNodesToExclude, Standard_False, theMode); + if (HasElements) + aLODBldr->Build (thePresentation, aTrgIdxs, aElemsToExclude, Standard_True, theMode); + } + } if ( ShowComputeTime ) { @@ -869,6 +888,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 : diff --git a/src/MeshVS/MeshVS_Mesh.hxx b/src/MeshVS/MeshVS_Mesh.hxx index c54c7385aa..c6f005daf9 100644 --- a/src/MeshVS/MeshVS_Mesh.hxx +++ b/src/MeshVS/MeshVS_Mesh.hxx @@ -127,7 +127,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; @@ -191,7 +194,6 @@ friend class MeshVS_PrsBuilder; protected: - MeshVS_DataMapOfIntegerOwner myNodeOwners; MeshVS_DataMapOfIntegerOwner myElementOwners; MeshVS_DataMapOfIntegerOwner my0DOwners; @@ -205,10 +207,8 @@ protected: Handle(MeshVS_Drawer) myHilightDrawer; Handle(SelectMgr_EntityOwner) myWholeMeshOwner; - private: - MeshVS_SequenceOfPrsBuilder myBuilders; Handle(MeshVS_PrsBuilder) myHilighter; Handle(TColStd_HPackedMapOfInteger) myHiddenElements; @@ -216,14 +216,7 @@ private: Handle(TColStd_HPackedMapOfInteger) mySelectableNodes; Handle(MeshVS_DataSource) myDataSource; MeshVS_MeshSelectionMethod mySelectionMethod; - - + NCollection_Vector myLODDataSources; }; - - - - - - #endif // _MeshVS_Mesh_HeaderFile diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index f2d843b72a..9b98ffc6b8 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -112,8 +112,9 @@ OpenGl_LayerList.cxx OpenGl_LayerList.hxx OpenGl_LayerFilter.hxx OpenGl_LOD.hxx -OpenGl_LOD.lxx 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 index 6fcbf98d6e..617ffa0b99 100644 --- a/src/OpenGl/OpenGl_LOD.cxx +++ b/src/OpenGl/OpenGl_LOD.cxx @@ -15,26 +15,6 @@ #include -//======================================================================= -// function : Construction -// purpose : -//======================================================================= -OpenGl_LOD::OpenGl_LOD() -: Graphic3d_LOD (), - myRange (-DBL_MAX, DBL_MAX) {} - -//======================================================================= -// function : SetRange -// purpose : -//======================================================================= -void OpenGl_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 = OpenGl_RangeOfLOD (theFrom, theTo); -} - //======================================================================= // function : NewGroup // purpose : diff --git a/src/OpenGl/OpenGl_LOD.hxx b/src/OpenGl/OpenGl_LOD.hxx index 925d0b9a98..b6b4a59990 100644 --- a/src/OpenGl/OpenGl_LOD.hxx +++ b/src/OpenGl/OpenGl_LOD.hxx @@ -21,67 +21,16 @@ #include #include -struct OpenGl_RangeOfLOD -{ -public: - OpenGl_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 myFrom < theVal; - } - - Standard_Boolean IsGreater (const Standard_Real theVal) const - { - return myTo < theVal; - } - - bool operator < (const OpenGl_RangeOfLOD& theOther) const - { - return myFrom < theOther.myFrom; - } - -private: - Standard_Real myFrom; - Standard_Real myTo; -}; - class OpenGl_LOD : public Graphic3d_LOD { public: - Standard_EXPORT OpenGl_LOD(); + Standard_EXPORT OpenGl_LOD() : Graphic3d_LOD () {}; Standard_EXPORT ~OpenGl_LOD() {}; - Standard_EXPORT virtual void SetRange (const Standard_Real theFrom, const Standard_Real theTo) Standard_OVERRIDE; - - inline const OpenGl_RangeOfLOD& GetRange() const - { - return myRange; - } - Standard_EXPORT virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& theParentStruct) Standard_OVERRIDE; - const Graphic3d_SequenceOfGroup& DrawGroups() const - { - return myGroups; - } - DEFINE_STANDARD_RTTI (OpenGl_LOD, Graphic3d_LOD) - -private: - OpenGl_RangeOfLOD myRange; }; DEFINE_STANDARD_HANDLE (OpenGl_LOD, Graphic3d_LOD) diff --git a/src/OpenGl/OpenGl_LODManager.cxx b/src/OpenGl/OpenGl_LODManager.cxx new file mode 100644 index 0000000000..2fa7c202df --- /dev/null +++ b/src/OpenGl/OpenGl_LODManager.cxx @@ -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. + +#include +#include +#include + +#include + +namespace +{ + // Comparison operator for sorting LODs + class CompareLODS + { + public: + + CompareLODS (const NCollection_Vector& 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& 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_LOD.lxx b/src/OpenGl/OpenGl_LODManager.hxx similarity index 50% rename from src/OpenGl/OpenGl_LOD.lxx rename to src/OpenGl/OpenGl_LODManager.hxx index b896d2c7bc..914525a14f 100644 --- a/src/OpenGl/OpenGl_LOD.lxx +++ b/src/OpenGl/OpenGl_LODManager.hxx @@ -1,4 +1,4 @@ -// Created on: 2015-10-29 +// Created on: 2015-11-25 // Created by: Varvara POSKONINA // Copyright (c) 2005-2014 OPEN CASCADE SAS // @@ -13,10 +13,26 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -struct IsLessLOD +#ifndef _OpenGl_LODManager_Header +#define _OpenGl_LODManager_Header + +#include + +class OpenGl_LODManager : public Graphic3d_LODManager { - inline bool operator() (const Handle(OpenGl_LOD)& theLod1, const Handle(OpenGl_LOD)& theLod2) const - { - return theLod1->GetRange() < theLod2->GetRange(); - } +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_RTTI (OpenGl_LODManager, Graphic3d_LODManager) + +protected: + Standard_EXPORT virtual void sortLODs() Standard_OVERRIDE; }; + +DEFINE_STANDARD_HANDLE (OpenGl_LODManager, Graphic3d_LODManager) + +#endif // _OpenGl_LODManager_Header diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index 9430ec32e6..7f531629e5 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include +#include //! Auxiliary class for bounding box presentation @@ -128,8 +130,7 @@ OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& th myIsRaytracable (Standard_False), myModificationState (0), myIsCulled (Standard_True), - myIsMirrored (Standard_False), - myCurrentLodId (-1) + myIsMirrored (Standard_False) { // } @@ -437,11 +438,13 @@ Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Struc // function : NewLOD // purpose : // ======================================================================= -Handle(Graphic3d_LOD) OpenGl_Structure::NewLOD() +Handle(Graphic3d_LOD) OpenGl_Structure::NewLOD (const Handle(Graphic3d_Structure)& theStruct) { - Handle(OpenGl_LOD) aLOD = new OpenGl_LOD(); - myLODVec.Append (aLOD); - return aLOD; + if (myLODManager.IsNull()) + { + myLODManager = new OpenGl_LODManager (theStruct); + } + return myLODManager->AddNewLOD(); } // ======================================================================= @@ -538,14 +541,8 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con return; } - Handle(OpenGl_LOD) aLODToRender; - if (myLODVec.Size() > 0) - { - findCurrentLOD (theWorkspace); - if (myCurrentLodId == -1) - return; - aLODToRender = myLODVec.Value (myCurrentLodId); - } + if (!myLODManager.IsNull() && myLODManager->GetCurrentLODIdx (theWorkspace->View()->Camera()) == -1) + return; const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); @@ -669,7 +666,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con } // Render groups - const Graphic3d_SequenceOfGroup& aGroups = !aLODToRender.IsNull() ? aLODToRender->DrawGroups() : DrawGroups(); + const Graphic3d_SequenceOfGroup& aGroups = DrawGroups(); for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next()) { aGroupIter.Value()->Render (theWorkspace); @@ -788,63 +785,36 @@ Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3 } //======================================================================= -//function : binSearchLOD +//function : SetDetailLevelRange //purpose : //======================================================================= -Standard_Integer OpenGl_Structure::binSearchLOD (const Standard_Integer theFirst, - const Standard_Integer theLast, - const Standard_Real theMetrics) const +void OpenGl_Structure::SetDetailLevelRange (const Standard_Integer theIdOfLOD, + const Standard_Real theFrom, + const Standard_Real theTo) { - if (theFirst > theLast) - return -1; - else - { - Standard_Integer aMid = (theFirst + theLast) / 2; + Standard_ASSERT_RAISE (theFrom < theTo, + "The upper boundary of the interval must be greater than lower one!"); - if (myLODVec.Value (aMid)->GetRange().IsIn (theMetrics)) - return aMid; - else - if (myLODVec.Value (aMid)->GetRange().IsLess (theMetrics)) - return binSearchLOD (aMid + 1, theLast, theMetrics); - else - return binSearchLOD (theFirst, aMid - 1, theMetrics); - } + if (theIdOfLOD < 0 || theIdOfLOD > myLODManager->NbOfDetailLevels()) + return; + + myLODManager->SetRange (theIdOfLOD, theFrom, theTo); } //======================================================================= -//function : findCurrentLOD +//function : DrawGroups //purpose : //======================================================================= -void OpenGl_Structure::findCurrentLOD (const Handle(OpenGl_Workspace)& theWorkspace) const +const Graphic3d_SequenceOfGroup& OpenGl_Structure::DrawGroups() const { - Standard_Real aMetric = myLODVec.Value (0)->ComputeMetrics (theWorkspace->View()->Camera(), this); - std::cout << aMetric << std::endl; - if (myCurrentLodId != -1 && myLODVec.Value (myCurrentLodId)->GetRange().IsIn (aMetric)) - return; - - if (myLODVec.Last()->GetRange().IsGreater (aMetric)) - { - myCurrentLodId = myLODVec.Size() - 1; - return; - } - - myCurrentLodId = binSearchLOD (0, (Standard_Integer)myLODVec.Size() - 1, aMetric); + return myLODManager.IsNull() ? myGroups : myLODManager->GetCurrentGroups(); } //======================================================================= -//function : SetDetailLevelRange +//function : NbDetailLevels //purpose : //======================================================================= -void OpenGl_Structure::SetDetailLevelRange (const Standard_Integer theIdOfLOD, - const Standard_Real theFrom, - const Standard_Real theTo) +Standard_Integer OpenGl_Structure::NbDetailLevels() const { - Standard_ASSERT_RAISE (theFrom < theTo, - "The upper boundary of the interval must be greater than lower one!"); - - if (theIdOfLOD < 0 || theIdOfLOD > myLODVec.Size()) - return; - - myLODVec.Value( theIdOfLOD)->SetRange (theFrom, theTo); - std::sort (myLODVec.begin(), myLODVec.end(), IsLessLOD()); + return myLODManager->NbOfDetailLevels(); } diff --git a/src/OpenGl/OpenGl_Structure.hxx b/src/OpenGl/OpenGl_Structure.hxx index 1485ec60f6..a102155688 100644 --- a/src/OpenGl/OpenGl_Structure.hxx +++ b/src/OpenGl/OpenGl_Structure.hxx @@ -101,7 +101,7 @@ public: Standard_EXPORT virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& theStruct); //! Create new LOD within this structure - Standard_EXPORT virtual Handle(Graphic3d_LOD) NewLOD() Standard_OVERRIDE; + 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); @@ -113,10 +113,7 @@ public: 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 @@ -201,10 +198,7 @@ public: //! Is the structure ray-tracable (contains ray-tracable elements)? Standard_Boolean IsRaytracable() const; - Standard_EXPORT virtual Standard_Integer NbDetailLevels() const Standard_OVERRIDE - { - return (Standard_Integer)myLODVec.Size(); - } + Standard_EXPORT virtual Standard_Integer NbDetailLevels() const Standard_OVERRIDE; protected: @@ -213,10 +207,6 @@ protected: //! Updates ray-tracable status for structure and its parents. void UpdateStateIfRaytracable (const Standard_Boolean toCheck = Standard_True) const; -private: - void findCurrentLOD (const Handle(OpenGl_Workspace)& theWorkspace) const; - Standard_Integer binSearchLOD (const Standard_Integer theFirst, const Standard_Integer theLast, const Standard_Real theMetrics) const; - protected: OpenGl_Matrix* myTransformation; @@ -237,10 +227,6 @@ protected: Standard_Boolean myIsMirrored; //!< Used to tell OpenGl to interpret polygons in clockwise order. -private: - mutable OpenGl_VectorOfLODs myLODVec; - mutable Standard_Integer myCurrentLodId; - public: DEFINE_STANDARD_RTTI(OpenGl_Structure, Graphic3d_CStructure) // Type definition diff --git a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx index 1123970390..3fcaf9f9a2 100644 --- a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx +++ b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx @@ -1487,7 +1487,7 @@ static int MeshLod (Draw_Interpretor& theDI, } Handle(MeshVS_LODDataSource) aLod = new MeshVS_LODDataSource (aSTLMesh); - aLod->ComputePrs (aMesh); + aMesh->AddDataSource (aLod); Standard_Integer aIdOfLod = aMesh->Presentation()->NbDetailLevels(); aMesh->Presentation()->SetDetailLevelRange (aIdOfLod - 1, aFromRange, aToRange); -- 2.39.5