From da35d76ce69e412f0a275e3f9dc2aac79cddb5f0 Mon Sep 17 00:00:00 2001 From: duv Date: Mon, 16 May 2016 11:47:24 +0300 Subject: [PATCH] Move to Eigen sparse matrix for coherency coefficients. Progress indication. --- .../BRepMesh_RestoreOrientationTool.cxx | 103 ++++++++++++++++-- .../BRepMesh_RestoreOrientationTool.hxx | 3 +- 2 files changed, 93 insertions(+), 13 deletions(-) diff --git a/src/BRepMesh/BRepMesh_RestoreOrientationTool.cxx b/src/BRepMesh/BRepMesh_RestoreOrientationTool.cxx index 44cdc8a48d..2f9a3ed845 100644 --- a/src/BRepMesh/BRepMesh_RestoreOrientationTool.cxx +++ b/src/BRepMesh/BRepMesh_RestoreOrientationTool.cxx @@ -27,7 +27,7 @@ #include #include - +#include #include #include @@ -36,9 +36,15 @@ #include #include +#include #include +#include +#include + +// #define MEASURE_PERFORMANCE + IMPLEMENT_STANDARD_HANDLE (BRepMesh_RestoreOrientationTool, Standard_Transient) IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_RestoreOrientationTool, Standard_Transient) @@ -69,6 +75,60 @@ Standard_Integer sampleValue (Standard_Real theKsi, const std::vector (std::lower_bound (theCDF.begin(), theCDF.end(), theKsi) - theCDF.begin()); } +//! Utility class to manage coherence table. +class SparseCoherencyTable +{ +public: + + //! Allocates square coherency table with theMaxSize * theMaxSize maximum number of elements. + SparseCoherencyTable (Standard_Size theMaxSize) + : myMaxSize (theMaxSize), + mySize (0), + myTable ((Standard_Integer)theMaxSize, + (Standard_Integer)theMaxSize) + { + // + } + + void Reserve (Standard_Size theNumElements) + { + myTable.reserve ((Standard_Integer)theNumElements); + } + + //! Sets coherence value. + void setCoherence (Standard_Size theI, Standard_Size theJ, Standard_Real theValue) + { + if (theI < theJ) std::swap (theI, theJ); + myTable.coeffRef ((Standard_Integer)theI, (Standard_Integer)theJ) = static_cast (theValue); + } + + //! Returns coherence value. + Standard_Real getCoherence (Standard_Size theI, Standard_Size theJ) + { + if (theI < theJ) std::swap (theI, theJ); + return static_cast (myTable.coeff ((Standard_Integer)theI, (Standard_Integer)theJ)); + } + + //! Returns actual table size. + Standard_Size Size() + { + return mySize; + } + + //! Sets actual table size. + void SetSize (Standard_Size theSize) + { + mySize = theSize; + } + +private: + + Standard_Size myMaxSize; + Standard_Size mySize; + + Eigen::SparseMatrix myTable; +}; + //! Utility class to manage coherence table. class CoherencyTable { @@ -78,7 +138,7 @@ public: CoherencyTable (Standard_Size theMaxSize) : myMaxSize (theMaxSize), mySize (0), - myTable (theMaxSize * theMaxSize, 0.0) + myTable (theMaxSize * theMaxSize, 0.f) { // } @@ -86,12 +146,14 @@ public: //! Sets coherence value. void setCoherence (Standard_Size theI, Standard_Size theJ, Standard_Real theValue) { + if (theI < theJ) std::swap (theI, theJ); myTable[theI * myMaxSize + theJ] = static_cast (theValue); } //! Returns coherence value. - Standard_Real getCoherence (size_t theI, size_t theJ) + Standard_Real getCoherence (Standard_Size theI, Standard_Size theJ) { + if (theI < theJ) std::swap (theI, theJ); return static_cast (myTable[theI * myMaxSize + theJ]); } @@ -584,7 +646,7 @@ Standard_Real BRepMesh_RestoreOrientationTool::computeCoherence (Handle (BRepMes // function : Perform // purpose : // ======================================================================= -void BRepMesh_RestoreOrientationTool::Perform() +void BRepMesh_RestoreOrientationTool::Perform (const Handle(Message_ProgressIndicator) thePI) { Standard_Real aMaxArea = std::numeric_limits::epsilon(); @@ -593,8 +655,6 @@ void BRepMesh_RestoreOrientationTool::Perform() aTimer.Start(); #endif - std::auto_ptr aTable; - // Flipped flags for all patches. std::vector aFlipped (myPatches.size(), 0); std::vector aFlippedC (myPatches.size(), 0); @@ -604,13 +664,20 @@ void BRepMesh_RestoreOrientationTool::Perform() const Standard_Real anEpsilon = std::max (1.0e-4, 1.0e-2 * myTriangulation.Box().Size().Modulus()); BVH_Vec3d anEpsilonVec (anEpsilon, anEpsilon, anEpsilon); + std::unique_ptr aTable; + + aTable->Reserve (myPatches.size()); + if (!myVisibilityOnly) { - aTable.reset (new CoherencyTable (myPatches.size() * 3)); + aTable.reset (new SparseCoherencyTable (myPatches.size() * 3)); aTable->SetSize (myPatches.size()); + if (!thePI.IsNull()) thePI->NewScope ( 80, "Coherence" ); + Message_ProgressSentry aPS (thePI, "Compute initial coherence", 0.0, (Standard_Real) (myPatches.size() - 1), 1.0); + // Compute coherence - for (Standard_Size i = 0; i < myPatches.size() - 1; ++i) + for (Standard_Size i = 0; i < myPatches.size() - 1; ++i, aPS.Next()) { Handle (BRepMesh_TriangulatedPatch)& aTriPatch1 = myPatches[i]; @@ -628,11 +695,12 @@ void BRepMesh_RestoreOrientationTool::Perform() aMaxCoherence = std::max (aMaxCoherence, aCoherence); aTable->setCoherence (i, j, aCoherence); - aTable->setCoherence (j, i, aCoherence); } } } + if (!thePI.IsNull()) thePI->EndScope(); + std::vector aMetaPatches; aMetaPatches.reserve (myPatches.size() * 3); @@ -688,7 +756,6 @@ void BRepMesh_RestoreOrientationTool::Perform() Standard_Real aCoherence = aTable->getCoherence (i, anIndex); aTable->setCoherence (i, anIndex, -aCoherence); - aTable->setCoherence (anIndex, i, -aCoherence); } } @@ -709,7 +776,6 @@ void BRepMesh_RestoreOrientationTool::Perform() aNewCoherence += aTable->getCoherence (i, aBestPair.SecondPatch->Index); aTable->setCoherence (i, aNewPatch.Index, aNewCoherence); - aTable->setCoherence (aNewPatch.Index, i, aNewCoherence); } } @@ -767,6 +833,9 @@ void BRepMesh_RestoreOrientationTool::Perform() // Ensure that BVH already built before parallel section myTriangulation.BVH(); + if (!thePI.IsNull()) thePI->NewScope (myVisibilityOnly ? 100 : 20, "Visibility"); + Message_ProgressSentry aPS (thePI, "Compute visibility", 0, aPatchesNb, 1); + // Compute visibility #pragma omp parallel for for (Standard_Integer i = 0; i < aPatchesNb; ++i) @@ -779,8 +848,18 @@ void BRepMesh_RestoreOrientationTool::Perform() { aTriPatch->FlipVisibility(); } + + if (!thePI.IsNull()) + { + #pragma omp critical + { + aPS.Next(); + } + } } + if (!thePI.IsNull()) thePI->EndScope(); + #ifdef MEASURE_PERFORMANCE aTimer.Stop(); std::cout << "Visibility time: " << aTimer.ElapsedTime() << std::endl; @@ -789,7 +868,7 @@ void BRepMesh_RestoreOrientationTool::Perform() #endif // Optimization - Energy* aGraph = new Energy (myPatches.size()); + Energy* aGraph = new Energy ((Standard_Integer)myPatches.size()); std::vector aVariables (myPatches.size()); diff --git a/src/BRepMesh/BRepMesh_RestoreOrientationTool.hxx b/src/BRepMesh/BRepMesh_RestoreOrientationTool.hxx index 1704fc8bb0..d13289aeb4 100644 --- a/src/BRepMesh/BRepMesh_RestoreOrientationTool.hxx +++ b/src/BRepMesh/BRepMesh_RestoreOrientationTool.hxx @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -102,7 +103,7 @@ public: Standard_EXPORT void Init (const TopoDS_Shape& theShape); //! Performs restoring of consistent orientation. - Standard_EXPORT void Perform(); + Standard_EXPORT void Perform (const Handle(Message_ProgressIndicator) thePI = NULL); //! Returns "Visibility only" mode. bool VisibilityOnly() const -- 2.39.5