1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

Move to Eigen sparse matrix for coherency coefficients.

Progress indication.
This commit is contained in:
duv
2016-05-16 11:47:24 +03:00
parent ec88ba6508
commit da35d76ce6
2 changed files with 93 additions and 13 deletions

View File

@@ -27,7 +27,7 @@
#include <NCollection_Map.hxx> #include <NCollection_Map.hxx>
#include <NCollection_DataMap.hxx> #include <NCollection_DataMap.hxx>
#include <Message_ProgressSentry.hxx>
#include <Standard_Integer.hxx> #include <Standard_Integer.hxx>
#include <Precision.hxx> #include <Precision.hxx>
@@ -36,9 +36,15 @@
#include <set> #include <set>
#include <map> #include <map>
#include <memory>
#include <BRepMesh_MinStCut.hxx> #include <BRepMesh_MinStCut.hxx>
#include <Eigen/Core>
#include <Eigen/Sparse>
// #define MEASURE_PERFORMANCE
IMPLEMENT_STANDARD_HANDLE (BRepMesh_RestoreOrientationTool, Standard_Transient) IMPLEMENT_STANDARD_HANDLE (BRepMesh_RestoreOrientationTool, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_RestoreOrientationTool, Standard_Transient) IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_RestoreOrientationTool, Standard_Transient)
@@ -69,6 +75,60 @@ Standard_Integer sampleValue (Standard_Real theKsi, const std::vector<Standard_R
return static_cast<Standard_Integer> (std::lower_bound (theCDF.begin(), theCDF.end(), theKsi) - theCDF.begin()); return static_cast<Standard_Integer> (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<Standard_ShortReal> (theValue);
}
//! Returns coherence value.
Standard_Real getCoherence (Standard_Size theI, Standard_Size theJ)
{
if (theI < theJ) std::swap (theI, theJ);
return static_cast<Standard_Real> (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<Standard_ShortReal> myTable;
};
//! Utility class to manage coherence table. //! Utility class to manage coherence table.
class CoherencyTable class CoherencyTable
{ {
@@ -78,7 +138,7 @@ public:
CoherencyTable (Standard_Size theMaxSize) CoherencyTable (Standard_Size theMaxSize)
: myMaxSize (theMaxSize), : myMaxSize (theMaxSize),
mySize (0), mySize (0),
myTable (theMaxSize * theMaxSize, 0.0) myTable (theMaxSize * theMaxSize, 0.f)
{ {
// //
} }
@@ -86,12 +146,14 @@ public:
//! Sets coherence value. //! Sets coherence value.
void setCoherence (Standard_Size theI, Standard_Size theJ, Standard_Real theValue) void setCoherence (Standard_Size theI, Standard_Size theJ, Standard_Real theValue)
{ {
if (theI < theJ) std::swap (theI, theJ);
myTable[theI * myMaxSize + theJ] = static_cast<Standard_ShortReal> (theValue); myTable[theI * myMaxSize + theJ] = static_cast<Standard_ShortReal> (theValue);
} }
//! Returns coherence value. //! 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<Standard_Real> (myTable[theI * myMaxSize + theJ]); return static_cast<Standard_Real> (myTable[theI * myMaxSize + theJ]);
} }
@@ -584,7 +646,7 @@ Standard_Real BRepMesh_RestoreOrientationTool::computeCoherence (Handle (BRepMes
// function : Perform // function : Perform
// purpose : // purpose :
// ======================================================================= // =======================================================================
void BRepMesh_RestoreOrientationTool::Perform() void BRepMesh_RestoreOrientationTool::Perform (const Handle(Message_ProgressIndicator) thePI)
{ {
Standard_Real aMaxArea = std::numeric_limits<Standard_Real>::epsilon(); Standard_Real aMaxArea = std::numeric_limits<Standard_Real>::epsilon();
@@ -593,8 +655,6 @@ void BRepMesh_RestoreOrientationTool::Perform()
aTimer.Start(); aTimer.Start();
#endif #endif
std::auto_ptr<CoherencyTable> aTable;
// Flipped flags for all patches. // Flipped flags for all patches.
std::vector<char> aFlipped (myPatches.size(), 0); std::vector<char> aFlipped (myPatches.size(), 0);
std::vector<char> aFlippedC (myPatches.size(), 0); std::vector<char> 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()); const Standard_Real anEpsilon = std::max (1.0e-4, 1.0e-2 * myTriangulation.Box().Size().Modulus());
BVH_Vec3d anEpsilonVec (anEpsilon, anEpsilon, anEpsilon); BVH_Vec3d anEpsilonVec (anEpsilon, anEpsilon, anEpsilon);
std::unique_ptr<SparseCoherencyTable> aTable;
aTable->Reserve (myPatches.size());
if (!myVisibilityOnly) if (!myVisibilityOnly)
{ {
aTable.reset (new CoherencyTable (myPatches.size() * 3)); aTable.reset (new SparseCoherencyTable (myPatches.size() * 3));
aTable->SetSize (myPatches.size()); 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 // 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]; Handle (BRepMesh_TriangulatedPatch)& aTriPatch1 = myPatches[i];
@@ -628,11 +695,12 @@ void BRepMesh_RestoreOrientationTool::Perform()
aMaxCoherence = std::max (aMaxCoherence, aCoherence); aMaxCoherence = std::max (aMaxCoherence, aCoherence);
aTable->setCoherence (i, j, aCoherence); aTable->setCoherence (i, j, aCoherence);
aTable->setCoherence (j, i, aCoherence);
} }
} }
} }
if (!thePI.IsNull()) thePI->EndScope();
std::vector<BRepMesh_SuperPatch> aMetaPatches; std::vector<BRepMesh_SuperPatch> aMetaPatches;
aMetaPatches.reserve (myPatches.size() * 3); aMetaPatches.reserve (myPatches.size() * 3);
@@ -688,7 +756,6 @@ void BRepMesh_RestoreOrientationTool::Perform()
Standard_Real aCoherence = aTable->getCoherence (i, anIndex); Standard_Real aCoherence = aTable->getCoherence (i, anIndex);
aTable->setCoherence (i, anIndex, -aCoherence); 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); aNewCoherence += aTable->getCoherence (i, aBestPair.SecondPatch->Index);
aTable->setCoherence (i, aNewPatch.Index, aNewCoherence); 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 // Ensure that BVH already built before parallel section
myTriangulation.BVH(); myTriangulation.BVH();
if (!thePI.IsNull()) thePI->NewScope (myVisibilityOnly ? 100 : 20, "Visibility");
Message_ProgressSentry aPS (thePI, "Compute visibility", 0, aPatchesNb, 1);
// Compute visibility // Compute visibility
#pragma omp parallel for #pragma omp parallel for
for (Standard_Integer i = 0; i < aPatchesNb; ++i) for (Standard_Integer i = 0; i < aPatchesNb; ++i)
@@ -779,7 +848,17 @@ void BRepMesh_RestoreOrientationTool::Perform()
{ {
aTriPatch->FlipVisibility(); aTriPatch->FlipVisibility();
} }
if (!thePI.IsNull())
{
#pragma omp critical
{
aPS.Next();
} }
}
}
if (!thePI.IsNull()) thePI->EndScope();
#ifdef MEASURE_PERFORMANCE #ifdef MEASURE_PERFORMANCE
aTimer.Stop(); aTimer.Stop();
@@ -789,7 +868,7 @@ void BRepMesh_RestoreOrientationTool::Perform()
#endif #endif
// Optimization // Optimization
Energy* aGraph = new Energy (myPatches.size()); Energy* aGraph = new Energy ((Standard_Integer)myPatches.size());
std::vector<Energy::Var> aVariables (myPatches.size()); std::vector<Energy::Var> aVariables (myPatches.size());

View File

@@ -19,6 +19,7 @@
#include <Standard.hxx> #include <Standard.hxx>
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
#include <TopoDS_Face.hxx> #include <TopoDS_Face.hxx>
#include <Message_ProgressIndicator.hxx>
#include <BRepMesh_TriangulatedPatch.hxx> #include <BRepMesh_TriangulatedPatch.hxx>
@@ -102,7 +103,7 @@ public:
Standard_EXPORT void Init (const TopoDS_Shape& theShape); Standard_EXPORT void Init (const TopoDS_Shape& theShape);
//! Performs restoring of consistent orientation. //! Performs restoring of consistent orientation.
Standard_EXPORT void Perform(); Standard_EXPORT void Perform (const Handle(Message_ProgressIndicator) thePI = NULL);
//! Returns "Visibility only" mode. //! Returns "Visibility only" mode.
bool VisibilityOnly() const bool VisibilityOnly() const