#include <NCollection_Map.hxx>
#include <NCollection_DataMap.hxx>
-
+#include <Message_ProgressSentry.hxx>
#include <Standard_Integer.hxx>
#include <Precision.hxx>
#include <set>
#include <map>
+#include <memory>
#include <BRepMesh_MinStCut.hxx>
+#include <Eigen/Core>
+#include <Eigen/Sparse>
+
+// #define MEASURE_PERFORMANCE
+
IMPLEMENT_STANDARD_HANDLE (BRepMesh_RestoreOrientationTool, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_RestoreOrientationTool, Standard_Transient)
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.
class CoherencyTable
{
CoherencyTable (Standard_Size theMaxSize)
: myMaxSize (theMaxSize),
mySize (0),
- myTable (theMaxSize * theMaxSize, 0.0)
+ myTable (theMaxSize * theMaxSize, 0.f)
{
//
}
//! 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<Standard_ShortReal> (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<Standard_Real> (myTable[theI * myMaxSize + theJ]);
}
// function : Perform
// purpose :
// =======================================================================
-void BRepMesh_RestoreOrientationTool::Perform()
+void BRepMesh_RestoreOrientationTool::Perform (const Handle(Message_ProgressIndicator) thePI)
{
Standard_Real aMaxArea = std::numeric_limits<Standard_Real>::epsilon();
aTimer.Start();
#endif
- std::auto_ptr<CoherencyTable> aTable;
-
// Flipped flags for all patches.
std::vector<char> aFlipped (myPatches.size(), 0);
std::vector<char> aFlippedC (myPatches.size(), 0);
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<SparseCoherencyTable> 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];
aMaxCoherence = std::max (aMaxCoherence, aCoherence);
aTable->setCoherence (i, j, aCoherence);
- aTable->setCoherence (j, i, aCoherence);
}
}
}
+ if (!thePI.IsNull()) thePI->EndScope();
+
std::vector<BRepMesh_SuperPatch> aMetaPatches;
aMetaPatches.reserve (myPatches.size() * 3);
Standard_Real aCoherence = aTable->getCoherence (i, anIndex);
aTable->setCoherence (i, anIndex, -aCoherence);
- aTable->setCoherence (anIndex, i, -aCoherence);
}
}
aNewCoherence += aTable->getCoherence (i, aBestPair.SecondPatch->Index);
aTable->setCoherence (i, aNewPatch.Index, aNewCoherence);
- aTable->setCoherence (aNewPatch.Index, i, aNewCoherence);
}
}
// 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)
{
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;
#endif
// Optimization
- Energy* aGraph = new Energy (myPatches.size());
+ Energy* aGraph = new Energy ((Standard_Integer)myPatches.size());
std::vector<Energy::Var> aVariables (myPatches.size());