Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/freestyle/intern/view_map
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/freestyle/intern/view_map')
-rw-r--r--source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp123
-rw-r--r--source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h58
-rw-r--r--source/blender/freestyle/intern/view_map/AutoPtrHelper.h44
-rw-r--r--source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp165
-rw-r--r--source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h58
-rw-r--r--source/blender/freestyle/intern/view_map/BoxGrid.cpp300
-rw-r--r--source/blender/freestyle/intern/view_map/BoxGrid.h553
-rw-r--r--source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp422
-rw-r--r--source/blender/freestyle/intern/view_map/CulledOccluderSource.h41
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp1218
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.h381
-rw-r--r--source/blender/freestyle/intern/view_map/Functions0D.cpp548
-rw-r--r--source/blender/freestyle/intern/view_map/Functions0D.h577
-rw-r--r--source/blender/freestyle/intern/view_map/Functions1D.cpp340
-rw-r--r--source/blender/freestyle/intern/view_map/Functions1D.h905
-rw-r--r--source/blender/freestyle/intern/view_map/GridDensityProvider.h218
-rw-r--r--source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp80
-rw-r--r--source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h31
-rw-r--r--source/blender/freestyle/intern/view_map/Interface0D.cpp62
-rw-r--r--source/blender/freestyle/intern/view_map/Interface0D.h459
-rw-r--r--source/blender/freestyle/intern/view_map/Interface1D.cpp28
-rw-r--r--source/blender/freestyle/intern/view_map/Interface1D.h245
-rw-r--r--source/blender/freestyle/intern/view_map/OccluderSource.cpp149
-rw-r--r--source/blender/freestyle/intern/view_map/OccluderSource.h53
-rw-r--r--source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp122
-rw-r--r--source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h56
-rw-r--r--source/blender/freestyle/intern/view_map/Silhouette.cpp331
-rw-r--r--source/blender/freestyle/intern/view_map/Silhouette.h3466
-rw-r--r--source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp372
-rw-r--r--source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h181
-rw-r--r--source/blender/freestyle/intern/view_map/SphericalGrid.cpp303
-rw-r--r--source/blender/freestyle/intern/view_map/SphericalGrid.h571
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.cpp384
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.h201
-rw-r--r--source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp1311
-rw-r--r--source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h403
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.cpp952
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.h3102
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h1383
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp4316
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.h424
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIO.cpp2161
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIO.h50
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIterators.h969
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp10
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.h279
46 files changed, 14376 insertions, 14029 deletions
diff --git a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
index 37273b0dd1e..6c5cbc71a76 100644
--- a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
@@ -25,91 +25,102 @@
namespace Freestyle {
-ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4],
+ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource &source,
+ const real proscenium[4],
unsigned numCells)
-: GridDensityProvider(source), numCells(numCells)
+ : GridDensityProvider(source), numCells(numCells)
{
- initialize (proscenium);
+ initialize(proscenium);
}
-ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform, unsigned numCells)
-: GridDensityProvider(source), numCells(numCells)
+ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform,
+ unsigned numCells)
+ : GridDensityProvider(source), numCells(numCells)
{
- real proscenium[4];
- calculateQuickProscenium(transform, bbox, proscenium);
+ real proscenium[4];
+ calculateQuickProscenium(transform, bbox, proscenium);
- initialize (proscenium);
+ initialize(proscenium);
}
-ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells)
-: GridDensityProvider(source), numCells(numCells)
+ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource &source,
+ unsigned numCells)
+ : GridDensityProvider(source), numCells(numCells)
{
- real proscenium[4];
- calculateOptimalProscenium(source, proscenium);
+ real proscenium[4];
+ calculateOptimalProscenium(source, proscenium);
- initialize (proscenium);
+ initialize(proscenium);
}
-ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider() {}
+ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider()
+{
+}
void ArbitraryGridDensityProvider::initialize(const real proscenium[4])
{
- float prosceniumWidth = (proscenium[1] - proscenium[0]);
- float prosceniumHeight = (proscenium[3] - proscenium[2]);
- real cellArea = prosceniumWidth * prosceniumHeight / numCells;
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << prosceniumWidth << " x " << prosceniumHeight << " grid with cells of area " << cellArea << "." << endl;
- }
-
- _cellSize = sqrt(cellArea);
- // Now we know how many cells make each side of our grid
- _cellsX = ceil(prosceniumWidth / _cellSize);
- _cellsY = ceil(prosceniumHeight / _cellSize);
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
- }
-
- // Make sure the grid exceeds the proscenium by a small amount
- float safetyZone = 0.1f;
- if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
- _cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
- }
- if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
- _cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
- }
-
- // Find grid origin
- _cellOrigin[0] = ((proscenium[0] + proscenium[1]) / 2.0) - (_cellsX / 2.0) * _cellSize;
- _cellOrigin[1] = ((proscenium[2] + proscenium[3]) / 2.0) - (_cellsY / 2.0) * _cellSize;
+ float prosceniumWidth = (proscenium[1] - proscenium[0]);
+ float prosceniumHeight = (proscenium[3] - proscenium[2]);
+ real cellArea = prosceniumWidth * prosceniumHeight / numCells;
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << prosceniumWidth << " x " << prosceniumHeight << " grid with cells of area " << cellArea
+ << "." << endl;
+ }
+
+ _cellSize = sqrt(cellArea);
+ // Now we know how many cells make each side of our grid
+ _cellsX = ceil(prosceniumWidth / _cellSize);
+ _cellsY = ceil(prosceniumHeight / _cellSize);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
+ }
+
+ // Make sure the grid exceeds the proscenium by a small amount
+ float safetyZone = 0.1f;
+ if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
+ _cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
+ }
+ if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
+ _cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
+ }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
+ }
+
+ // Find grid origin
+ _cellOrigin[0] = ((proscenium[0] + proscenium[1]) / 2.0) - (_cellsX / 2.0) * _cellSize;
+ _cellOrigin[1] = ((proscenium[2] + proscenium[3]) / 2.0) - (_cellsY / 2.0) * _cellSize;
}
ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigned numCells)
-: numCells(numCells)
+ : numCells(numCells)
{
}
-ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory() {}
+ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory()
+{
+}
-AutoPtr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source,
- const real proscenium[4])
+AutoPtr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source, const real proscenium[4])
{
- return AutoPtr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, proscenium, numCells));
+ return AutoPtr<GridDensityProvider>(
+ new ArbitraryGridDensityProvider(source, proscenium, numCells));
}
-AutoPtr<GridDensityProvider>
-ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform)
+AutoPtr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source, const BBox<Vec3r> &bbox, const GridHelpers::Transform &transform)
{
- return AutoPtr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
+ return AutoPtr<GridDensityProvider>(
+ new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
}
-AutoPtr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+AutoPtr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source)
{
- return AutoPtr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
+ return AutoPtr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
index 8b616002279..97aae3d653c 100644
--- a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
@@ -26,41 +26,45 @@
namespace Freestyle {
-class ArbitraryGridDensityProvider : public GridDensityProvider
-{
- // Disallow copying and assignment
- ArbitraryGridDensityProvider(const ArbitraryGridDensityProvider& other);
- ArbitraryGridDensityProvider& operator=(const ArbitraryGridDensityProvider& other);
+class ArbitraryGridDensityProvider : public GridDensityProvider {
+ // Disallow copying and assignment
+ ArbitraryGridDensityProvider(const ArbitraryGridDensityProvider &other);
+ ArbitraryGridDensityProvider &operator=(const ArbitraryGridDensityProvider &other);
-public:
- ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells);
- ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform, unsigned numCells);
- ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells);
- virtual ~ArbitraryGridDensityProvider();
+ public:
+ ArbitraryGridDensityProvider(OccluderSource &source,
+ const real proscenium[4],
+ unsigned numCells);
+ ArbitraryGridDensityProvider(OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform,
+ unsigned numCells);
+ ArbitraryGridDensityProvider(OccluderSource &source, unsigned numCells);
+ virtual ~ArbitraryGridDensityProvider();
-protected:
- unsigned numCells;
+ protected:
+ unsigned numCells;
-private:
- void initialize (const real proscenium[4]);
+ private:
+ void initialize(const real proscenium[4]);
};
-class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory
-{
-public:
- ArbitraryGridDensityProviderFactory(unsigned numCells);
- ~ArbitraryGridDensityProviderFactory();
+class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory {
+ public:
+ ArbitraryGridDensityProviderFactory(unsigned numCells);
+ ~ArbitraryGridDensityProviderFactory();
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform);
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source,
+ const real proscenium[4]);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source);
-protected:
- unsigned numCells;
+ protected:
+ unsigned numCells;
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
+#endif // __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
diff --git a/source/blender/freestyle/intern/view_map/AutoPtrHelper.h b/source/blender/freestyle/intern/view_map/AutoPtrHelper.h
index 2554d303b08..9da109ab2a6 100644
--- a/source/blender/freestyle/intern/view_map/AutoPtrHelper.h
+++ b/source/blender/freestyle/intern/view_map/AutoPtrHelper.h
@@ -27,28 +27,36 @@
namespace Freestyle {
#if __cplusplus > 199711L
-template<typename T>
-class AutoPtr : public std::unique_ptr<T> {
-public:
- AutoPtr() : std::unique_ptr<T>() {}
- AutoPtr(T *ptr) : std::unique_ptr<T>(ptr) {}
-
- /* TODO(sergey): Is there more clear way to do this? */
- template<typename X>
- AutoPtr(AutoPtr<X>& other) : std::unique_ptr<T>(other.get()) {
- other.release();
- }
+template<typename T> class AutoPtr : public std::unique_ptr<T> {
+ public:
+ AutoPtr() : std::unique_ptr<T>()
+ {
+ }
+ AutoPtr(T *ptr) : std::unique_ptr<T>(ptr)
+ {
+ }
+
+ /* TODO(sergey): Is there more clear way to do this? */
+ template<typename X> AutoPtr(AutoPtr<X> &other) : std::unique_ptr<T>(other.get())
+ {
+ other.release();
+ }
};
#else
-template<typename T>
-class AutoPtr : public std::auto_ptr<T> {
-public:
- AutoPtr() : std::auto_ptr<T>() {}
- AutoPtr(T *ptr) : std::auto_ptr<T>(ptr) {}
- AutoPtr(std::auto_ptr_ref<T> ref) : std::auto_ptr<T>(ref) {}
+template<typename T> class AutoPtr : public std::auto_ptr<T> {
+ public:
+ AutoPtr() : std::auto_ptr<T>()
+ {
+ }
+ AutoPtr(T *ptr) : std::auto_ptr<T>(ptr)
+ {
+ }
+ AutoPtr(std::auto_ptr_ref<T> ref) : std::auto_ptr<T>(ref)
+ {
+ }
};
#endif
-} /* namespace Freestyle */
+} /* namespace Freestyle */
#endif // __FREESTYLE_AUTOPTR_HELPER_H__
diff --git a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
index 8fc3fe810af..1384dc0f78b 100644
--- a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
@@ -25,112 +25,123 @@
namespace Freestyle {
-AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4],
+AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource &source,
+ const real proscenium[4],
real sizeFactor)
-: GridDensityProvider(source)
+ : GridDensityProvider(source)
{
- initialize (proscenium, sizeFactor);
+ initialize(proscenium, sizeFactor);
}
-AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform, real sizeFactor)
-: GridDensityProvider(source)
+AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(
+ OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform,
+ real sizeFactor)
+ : GridDensityProvider(source)
{
- real proscenium[4];
- calculateQuickProscenium(transform, bbox, proscenium);
+ real proscenium[4];
+ calculateQuickProscenium(transform, bbox, proscenium);
- initialize(proscenium, sizeFactor);
+ initialize(proscenium, sizeFactor);
}
-AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor)
-: GridDensityProvider(source)
+AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource &source,
+ real sizeFactor)
+ : GridDensityProvider(source)
{
- real proscenium[4];
- calculateOptimalProscenium(source, proscenium);
+ real proscenium[4];
+ calculateOptimalProscenium(source, proscenium);
- initialize(proscenium, sizeFactor);
+ initialize(proscenium, sizeFactor);
}
-AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider() {}
+AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider()
+{
+}
void AverageAreaGridDensityProvider::initialize(const real proscenium[4], real sizeFactor)
{
- float prosceniumWidth = (proscenium[1] - proscenium[0]);
- float prosceniumHeight = (proscenium[3] - proscenium[2]);
-
- real cellArea = 0.0;
- unsigned numFaces = 0;
- for (source.begin(); source.isValid(); source.next()) {
- Polygon3r& poly(source.getGridSpacePolygon());
- Vec3r min, max;
- poly.getBBox(min, max);
- cellArea += (max[0] - min[0]) * (max[1] - min[1]);
- ++numFaces;
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Total area: " << cellArea << ". Number of faces: " << numFaces << "." << endl;
- }
- cellArea /= numFaces;
- cellArea *= sizeFactor;
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Building grid with average area " << cellArea << endl;
- }
-
- _cellSize = sqrt(cellArea);
- unsigned maxCells = 931; // * 1.1 = 1024
- if (std::max(prosceniumWidth, prosceniumHeight) / _cellSize > maxCells) {
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Scene-dependent cell size (" << _cellSize << " square) is too small." << endl;
- }
- _cellSize = std::max(prosceniumWidth, prosceniumHeight) / maxCells;
- }
- // Now we know how many cells make each side of our grid
- _cellsX = ceil(prosceniumWidth / _cellSize);
- _cellsY = ceil(prosceniumHeight / _cellSize);
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
- }
-
- // Make sure the grid exceeds the proscenium by a small amount
- float safetyZone = 0.1f;
- if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
- _cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
- }
- if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
- _cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
- }
-
- // Find grid origin
- _cellOrigin[0] = ((proscenium[0] + proscenium[1]) / 2.0) - (_cellsX / 2.0) * _cellSize;
- _cellOrigin[1] = ((proscenium[2] + proscenium[3]) / 2.0) - (_cellsY / 2.0) * _cellSize;
+ float prosceniumWidth = (proscenium[1] - proscenium[0]);
+ float prosceniumHeight = (proscenium[3] - proscenium[2]);
+
+ real cellArea = 0.0;
+ unsigned numFaces = 0;
+ for (source.begin(); source.isValid(); source.next()) {
+ Polygon3r &poly(source.getGridSpacePolygon());
+ Vec3r min, max;
+ poly.getBBox(min, max);
+ cellArea += (max[0] - min[0]) * (max[1] - min[1]);
+ ++numFaces;
+ }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Total area: " << cellArea << ". Number of faces: " << numFaces << "." << endl;
+ }
+ cellArea /= numFaces;
+ cellArea *= sizeFactor;
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Building grid with average area " << cellArea << endl;
+ }
+
+ _cellSize = sqrt(cellArea);
+ unsigned maxCells = 931; // * 1.1 = 1024
+ if (std::max(prosceniumWidth, prosceniumHeight) / _cellSize > maxCells) {
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Scene-dependent cell size (" << _cellSize << " square) is too small." << endl;
+ }
+ _cellSize = std::max(prosceniumWidth, prosceniumHeight) / maxCells;
+ }
+ // Now we know how many cells make each side of our grid
+ _cellsX = ceil(prosceniumWidth / _cellSize);
+ _cellsY = ceil(prosceniumHeight / _cellSize);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
+ }
+
+ // Make sure the grid exceeds the proscenium by a small amount
+ float safetyZone = 0.1f;
+ if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
+ _cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
+ }
+ if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
+ _cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
+ }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
+ }
+
+ // Find grid origin
+ _cellOrigin[0] = ((proscenium[0] + proscenium[1]) / 2.0) - (_cellsX / 2.0) * _cellSize;
+ _cellOrigin[1] = ((proscenium[2] + proscenium[3]) / 2.0) - (_cellsY / 2.0) * _cellSize;
}
AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(real sizeFactor)
-: sizeFactor(sizeFactor)
+ : sizeFactor(sizeFactor)
{
}
-AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory() {}
+AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory()
+{
+}
-AutoPtr<GridDensityProvider>
-AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
+AutoPtr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source, const real proscenium[4])
{
- return AutoPtr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
+ return AutoPtr<GridDensityProvider>(
+ new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
}
-AutoPtr<GridDensityProvider>
-AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform)
+AutoPtr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source, const BBox<Vec3r> &bbox, const GridHelpers::Transform &transform)
{
- return AutoPtr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
+ return AutoPtr<GridDensityProvider>(
+ new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
}
-AutoPtr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+AutoPtr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source)
{
- return AutoPtr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
+ return AutoPtr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
index e422ad2ba8d..f530cf35569 100644
--- a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
@@ -26,38 +26,42 @@
namespace Freestyle {
-class AverageAreaGridDensityProvider : public GridDensityProvider
-{
- // Disallow copying and assignment
- AverageAreaGridDensityProvider(const AverageAreaGridDensityProvider& other);
- AverageAreaGridDensityProvider& operator=(const AverageAreaGridDensityProvider& other);
-
-public:
- AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor);
- AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform, real sizeFactor);
- AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor);
- virtual ~AverageAreaGridDensityProvider();
-
-private:
- void initialize (const real proscenium[4], real sizeFactor);
+class AverageAreaGridDensityProvider : public GridDensityProvider {
+ // Disallow copying and assignment
+ AverageAreaGridDensityProvider(const AverageAreaGridDensityProvider &other);
+ AverageAreaGridDensityProvider &operator=(const AverageAreaGridDensityProvider &other);
+
+ public:
+ AverageAreaGridDensityProvider(OccluderSource &source,
+ const real proscenium[4],
+ real sizeFactor);
+ AverageAreaGridDensityProvider(OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform,
+ real sizeFactor);
+ AverageAreaGridDensityProvider(OccluderSource &source, real sizeFactor);
+ virtual ~AverageAreaGridDensityProvider();
+
+ private:
+ void initialize(const real proscenium[4], real sizeFactor);
};
-class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory
-{
-public:
- AverageAreaGridDensityProviderFactory(real sizeFactor);
- ~AverageAreaGridDensityProviderFactory();
+class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory {
+ public:
+ AverageAreaGridDensityProviderFactory(real sizeFactor);
+ ~AverageAreaGridDensityProviderFactory();
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform);
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source,
+ const real proscenium[4]);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source);
-protected:
- real sizeFactor;
+ protected:
+ real sizeFactor;
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
+#endif // __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.cpp b/source/blender/freestyle/intern/view_map/BoxGrid.cpp
index 396688fe62c..5a490e3c7cc 100644
--- a/source/blender/freestyle/intern/view_map/BoxGrid.cpp
+++ b/source/blender/freestyle/intern/view_map/BoxGrid.cpp
@@ -38,199 +38,217 @@ namespace Freestyle {
// Cell
/////////
-BoxGrid::Cell::Cell() {}
+BoxGrid::Cell::Cell()
+{
+}
-BoxGrid::Cell::~Cell() {}
+BoxGrid::Cell::~Cell()
+{
+}
void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
{
- const real epsilon = 1.0e-06;
- boundary[0] = x - epsilon;
- boundary[1] = x + sizeX + epsilon;
- boundary[2] = y - epsilon;
- boundary[3] = y + sizeY + epsilon;
+ const real epsilon = 1.0e-06;
+ boundary[0] = x - epsilon;
+ boundary[1] = x + sizeX + epsilon;
+ boundary[2] = y - epsilon;
+ boundary[3] = y + sizeY + epsilon;
}
-bool BoxGrid::Cell::compareOccludersByShallowestPoint(const BoxGrid::OccluderData *a, const BoxGrid::OccluderData *b)
+bool BoxGrid::Cell::compareOccludersByShallowestPoint(const BoxGrid::OccluderData *a,
+ const BoxGrid::OccluderData *b)
{
- return a->shallowest < b->shallowest;
+ return a->shallowest < b->shallowest;
}
void BoxGrid::Cell::indexPolygons()
{
- // Sort occluders by their shallowest points.
- sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
+ // Sort occluders by their shallowest points.
+ sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
}
// Iterator
//////////////////
-BoxGrid::Iterator::Iterator (BoxGrid& grid, Vec3r& center, real /*epsilon*/)
-: _target(grid.transform(center)), _foundOccludee(false)
+BoxGrid::Iterator::Iterator(BoxGrid &grid, Vec3r &center, real /*epsilon*/)
+ : _target(grid.transform(center)), _foundOccludee(false)
{
- // Find target cell
- _cell = grid.findCell(_target);
+ // Find target cell
+ _cell = grid.findCell(_target);
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Searching for occluders of edge centered at " << _target << " in cell [" <<
- 1_cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2] <<
- ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Searching for occluders of edge centered at " << _target << " in cell ["
+ << 1_cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2] << ", "
+ << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
+ }
#endif
- // Set iterator
- _current = _cell->faces.begin();
+ // Set iterator
+ _current = _cell->faces.begin();
}
-BoxGrid::Iterator::~Iterator() {}
+BoxGrid::Iterator::~Iterator()
+{
+}
// BoxGrid
/////////////////
-BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
+BoxGrid::BoxGrid(OccluderSource &source,
+ GridDensityProvider &density,
+ ViewMap *viewMap,
+ Vec3r &viewpoint,
bool enableQI)
-: _viewpoint(viewpoint), _enableQI(enableQI)
-{
- // Generate Cell structure
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Generate Cell structure" << endl;
- }
- assignCells(source, density, viewMap);
-
- // Fill Cells
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Distribute occluders" << endl;
- }
- distributePolygons(source);
-
- // Reorganize Cells
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Reorganize cells" << endl;
- }
- reorganizeCells();
-
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Ready to use BoxGrid" << endl;
- }
-}
-
-BoxGrid::~BoxGrid() {}
-
-void BoxGrid::assignCells (OccluderSource& /*source*/, GridDensityProvider& density, ViewMap *viewMap)
-{
- _cellSize = density.cellSize();
- _cellsX = density.cellsX();
- _cellsY = density.cellsY();
- _cellOrigin[0] = density.cellOrigin(0);
- _cellOrigin[1] = density.cellOrigin(1);
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
- cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
- }
-
- // Now allocate the cell table and fill it with default (empty) cells
- _cells.resize(_cellsX * _cellsY);
- for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
- (*i) = NULL;
- }
-
- // Identify cells that will be used, and set the dimensions for each
- ViewMap::fedges_container& fedges = viewMap->FEdges();
- for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
- if ((*f)->isInImage()) {
- Vec3r point = transform((*f)->center3d());
- unsigned int i, j;
- getCellCoordinates(point, i, j);
- if (_cells[i * _cellsY + j] == NULL) {
- // This is an uninitialized cell
- real x, y, width, height;
-
- x = _cellOrigin[0] + _cellSize * i;
- width = _cellSize;
-
- y = _cellOrigin[1] + _cellSize * j;
- height = _cellSize;
-
- // Initialize cell
- Cell *b = _cells[i * _cellsY + j] = new Cell();
- b->setDimensions(x, y, width, height);
- }
- }
- }
-}
-
-void BoxGrid::distributePolygons(OccluderSource& source)
-{
- unsigned long nFaces = 0;
- unsigned long nKeptFaces = 0;
-
- for (source.begin(); source.isValid(); source.next()) {
- OccluderData *occluder = NULL;
-
- try {
- if (insertOccluder(source, occluder)) {
- _faces.push_back(occluder);
- ++nKeptFaces;
- }
- }
- catch (...) {
- // If an exception was thrown, _faces.push_back() cannot have succeeded.
- // occluder is not owned by anyone, and must be deleted.
- // If the exception was thrown before or during new OccluderData(), then
- // occluder is NULL, and this delete is harmless.
- delete occluder;
- throw;
- }
- ++nFaces;
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
- }
+ : _viewpoint(viewpoint), _enableQI(enableQI)
+{
+ // Generate Cell structure
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Generate Cell structure" << endl;
+ }
+ assignCells(source, density, viewMap);
+
+ // Fill Cells
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Distribute occluders" << endl;
+ }
+ distributePolygons(source);
+
+ // Reorganize Cells
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Reorganize cells" << endl;
+ }
+ reorganizeCells();
+
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Ready to use BoxGrid" << endl;
+ }
+}
+
+BoxGrid::~BoxGrid()
+{
+}
+
+void BoxGrid::assignCells(OccluderSource & /*source*/,
+ GridDensityProvider &density,
+ ViewMap *viewMap)
+{
+ _cellSize = density.cellSize();
+ _cellsX = density.cellsX();
+ _cellsY = density.cellsY();
+ _cellOrigin[0] = density.cellOrigin(0);
+ _cellOrigin[1] = density.cellOrigin(1);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square."
+ << endl;
+ cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
+ }
+
+ // Now allocate the cell table and fill it with default (empty) cells
+ _cells.resize(_cellsX * _cellsY);
+ for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
+ (*i) = NULL;
+ }
+
+ // Identify cells that will be used, and set the dimensions for each
+ ViewMap::fedges_container &fedges = viewMap->FEdges();
+ for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend;
+ ++f) {
+ if ((*f)->isInImage()) {
+ Vec3r point = transform((*f)->center3d());
+ unsigned int i, j;
+ getCellCoordinates(point, i, j);
+ if (_cells[i * _cellsY + j] == NULL) {
+ // This is an uninitialized cell
+ real x, y, width, height;
+
+ x = _cellOrigin[0] + _cellSize * i;
+ width = _cellSize;
+
+ y = _cellOrigin[1] + _cellSize * j;
+ height = _cellSize;
+
+ // Initialize cell
+ Cell *b = _cells[i * _cellsY + j] = new Cell();
+ b->setDimensions(x, y, width, height);
+ }
+ }
+ }
+}
+
+void BoxGrid::distributePolygons(OccluderSource &source)
+{
+ unsigned long nFaces = 0;
+ unsigned long nKeptFaces = 0;
+
+ for (source.begin(); source.isValid(); source.next()) {
+ OccluderData *occluder = NULL;
+
+ try {
+ if (insertOccluder(source, occluder)) {
+ _faces.push_back(occluder);
+ ++nKeptFaces;
+ }
+ }
+ catch (...) {
+ // If an exception was thrown, _faces.push_back() cannot have succeeded.
+ // occluder is not owned by anyone, and must be deleted.
+ // If the exception was thrown before or during new OccluderData(), then
+ // occluder is NULL, and this delete is harmless.
+ delete occluder;
+ throw;
+ }
+ ++nFaces;
+ }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
+ }
}
void BoxGrid::reorganizeCells()
{
- // Sort the occluders by shallowest point
- for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
- if (*i != NULL) {
- (*i)->indexPolygons();
- }
- }
+ // Sort the occluders by shallowest point
+ for (vector<Cell *>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
+ if (*i != NULL) {
+ (*i)->indexPolygons();
+ }
+ }
}
-void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
+void BoxGrid::getCellCoordinates(const Vec3r &point, unsigned &x, unsigned &y)
{
- x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
- y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
+ x = min(_cellsX - 1, (unsigned)floor(max((double)0.0f, point[0] - _cellOrigin[0]) / _cellSize));
+ y = min(_cellsY - 1, (unsigned)floor(max((double)0.0f, point[1] - _cellOrigin[1]) / _cellSize));
}
-BoxGrid::Cell *BoxGrid::findCell(const Vec3r& point)
+BoxGrid::Cell *BoxGrid::findCell(const Vec3r &point)
{
- unsigned int x, y;
- getCellCoordinates(point, x, y);
- return _cells[x * _cellsY + y];
+ unsigned int x, y;
+ getCellCoordinates(point, x, y);
+ return _cells[x * _cellsY + y];
}
bool BoxGrid::orthographicProjection() const
{
- return true;
+ return true;
}
-const Vec3r& BoxGrid::viewpoint() const
+const Vec3r &BoxGrid::viewpoint() const
{
- return _viewpoint;
+ return _viewpoint;
}
bool BoxGrid::enableQI() const
{
- return _enableQI;
+ return _enableQI;
}
-BoxGrid::Transform::Transform() : GridHelpers::Transform() {}
+BoxGrid::Transform::Transform() : GridHelpers::Transform()
+{
+}
-Vec3r BoxGrid::Transform::operator()(const Vec3r& point) const
+Vec3r BoxGrid::Transform::operator()(const Vec3r &point) const
{
- return Vec3r(point[0], point[1], -point[2]);
+ return Vec3r(point[0], point[1], -point[2]);
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.h b/source/blender/freestyle/intern/view_map/BoxGrid.h
index 9d2a3c7ea4c..83c379102f5 100644
--- a/source/blender/freestyle/intern/view_map/BoxGrid.h
+++ b/source/blender/freestyle/intern/view_map/BoxGrid.h
@@ -45,380 +45,379 @@
#include "BKE_global.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
-class BoxGrid
-{
-public:
- // Helper classes
- struct OccluderData
- {
- explicit OccluderData(OccluderSource& source, Polygon3r& p);
- Polygon3r poly;
- Polygon3r cameraSpacePolygon;
- real shallowest, deepest;
- // N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
- // However, code comments make it clear that userdata is deprecated, so we avoid the temptation
- // to save 4 or 8 bytes.
- WFace *face;
+class BoxGrid {
+ public:
+ // Helper classes
+ struct OccluderData {
+ explicit OccluderData(OccluderSource &source, Polygon3r &p);
+ Polygon3r poly;
+ Polygon3r cameraSpacePolygon;
+ real shallowest, deepest;
+ // N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
+ // However, code comments make it clear that userdata is deprecated, so we avoid the temptation
+ // to save 4 or 8 bytes.
+ WFace *face;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid:OccluderData")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid:OccluderData")
#endif
- };
-
-private:
- struct Cell
- {
- // Can't store Cell in a vector without copy and assign
- // Cell(const Cell& other);
- // Cell& operator=(const Cell& other);
-
- explicit Cell();
- ~Cell();
-
- static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
-
- void setDimensions(real x, real y, real sizeX, real sizeY);
- void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
- void indexPolygons();
-
- real boundary[4];
- //deque<OccluderData*> faces;
- vector<OccluderData*> faces;
- };
-
-public:
- /* Iterator needs to allow the user to avoid full 3D comparison in two cases:
- *
- * (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
- *
- * (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
- *
- * In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an
- * occludee candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder
- * could possibly be a better occludee.
- */
- class Iterator
- {
- public:
- // epsilon is not used in this class, but other grids with the same interface may need an epsilon
- explicit Iterator(BoxGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
- ~Iterator();
- void initBeforeTarget();
- void initAfterTarget();
- void nextOccluder();
- void nextOccludee();
- bool validBeforeTarget();
- bool validAfterTarget();
- WFace *getWFace() const;
- Polygon3r *getCameraSpacePolygon();
- void reportDepth(Vec3r origin, Vec3r u, real t);
-
- private:
- bool testOccluder(bool wantOccludee);
- void markCurrentOccludeeCandidate(real depth);
-
- Cell *_cell;
- Vec3r _target;
- bool _foundOccludee;
- real _occludeeDepth;
- //deque<OccluderData*>::iterator _current, _occludeeCandidate;
- vector<OccluderData*>::iterator _current, _occludeeCandidate;
+ };
+
+ private:
+ struct Cell {
+ // Can't store Cell in a vector without copy and assign
+ // Cell(const Cell& other);
+ // Cell& operator=(const Cell& other);
+
+ explicit Cell();
+ ~Cell();
+
+ static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
+
+ void setDimensions(real x, real y, real sizeX, real sizeY);
+ void checkAndInsert(OccluderSource &source, Polygon3r &poly, OccluderData *&occluder);
+ void indexPolygons();
+
+ real boundary[4];
+ //deque<OccluderData*> faces;
+ vector<OccluderData *> faces;
+ };
+
+ public:
+ /* Iterator needs to allow the user to avoid full 3D comparison in two cases:
+ *
+ * (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
+ *
+ * (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
+ *
+ * In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an
+ * occludee candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder
+ * could possibly be a better occludee.
+ */
+ class Iterator {
+ public:
+ // epsilon is not used in this class, but other grids with the same interface may need an epsilon
+ explicit Iterator(BoxGrid &grid, Vec3r &center, real epsilon = 1.0e-06);
+ ~Iterator();
+ void initBeforeTarget();
+ void initAfterTarget();
+ void nextOccluder();
+ void nextOccludee();
+ bool validBeforeTarget();
+ bool validAfterTarget();
+ WFace *getWFace() const;
+ Polygon3r *getCameraSpacePolygon();
+ void reportDepth(Vec3r origin, Vec3r u, real t);
+
+ private:
+ bool testOccluder(bool wantOccludee);
+ void markCurrentOccludeeCandidate(real depth);
+
+ Cell *_cell;
+ Vec3r _target;
+ bool _foundOccludee;
+ real _occludeeDepth;
+ //deque<OccluderData*>::iterator _current, _occludeeCandidate;
+ vector<OccluderData *>::iterator _current, _occludeeCandidate;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid:Iterator")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid:Iterator")
#endif
- };
-
- class Transform : public GridHelpers::Transform
- {
- public:
- explicit Transform();
- explicit Transform(Transform& other);
- Vec3r operator()(const Vec3r& point) const;
- };
-
-private:
- // Prevent implicit copies and assignments.
- BoxGrid(const BoxGrid& other);
- BoxGrid& operator=(const BoxGrid& other);
-
-public:
- explicit BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
- bool enableQI);
- virtual ~BoxGrid();
-
- // Generate Cell structure
- void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
- // Fill Cells
- void distributePolygons(OccluderSource& source);
- // Insert one polygon into each matching cell, return true if any cell consumes the polygon
- bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
- // Sort occluders in each cell
- void reorganizeCells();
-
- Cell *findCell(const Vec3r& point);
-
- // Accessors:
- bool orthographicProjection() const;
- const Vec3r& viewpoint() const;
- bool enableQI() const;
- Transform transform;
-
-private:
- void getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y);
-
- typedef PointerSequence<vector<Cell*>, Cell*> cellContainer;
- //typedef PointerSequence<deque<OccluderData*>, OccluderData*> occluderContainer;
- typedef PointerSequence<vector<OccluderData*>, OccluderData*> occluderContainer;
- unsigned _cellsX, _cellsY;
- float _cellSize;
- float _cellOrigin[2];
- cellContainer _cells;
- occluderContainer _faces;
- Vec3r _viewpoint;
- bool _enableQI;
+ };
+
+ class Transform : public GridHelpers::Transform {
+ public:
+ explicit Transform();
+ explicit Transform(Transform &other);
+ Vec3r operator()(const Vec3r &point) const;
+ };
+
+ private:
+ // Prevent implicit copies and assignments.
+ BoxGrid(const BoxGrid &other);
+ BoxGrid &operator=(const BoxGrid &other);
+
+ public:
+ explicit BoxGrid(OccluderSource &source,
+ GridDensityProvider &density,
+ ViewMap *viewMap,
+ Vec3r &viewpoint,
+ bool enableQI);
+ virtual ~BoxGrid();
+
+ // Generate Cell structure
+ void assignCells(OccluderSource &source, GridDensityProvider &density, ViewMap *viewMap);
+ // Fill Cells
+ void distributePolygons(OccluderSource &source);
+ // Insert one polygon into each matching cell, return true if any cell consumes the polygon
+ bool insertOccluder(OccluderSource &source, OccluderData *&occluder);
+ // Sort occluders in each cell
+ void reorganizeCells();
+
+ Cell *findCell(const Vec3r &point);
+
+ // Accessors:
+ bool orthographicProjection() const;
+ const Vec3r &viewpoint() const;
+ bool enableQI() const;
+ Transform transform;
+
+ private:
+ void getCellCoordinates(const Vec3r &point, unsigned &x, unsigned &y);
+
+ typedef PointerSequence<vector<Cell *>, Cell *> cellContainer;
+ //typedef PointerSequence<deque<OccluderData*>, OccluderData*> occluderContainer;
+ typedef PointerSequence<vector<OccluderData *>, OccluderData *> occluderContainer;
+ unsigned _cellsX, _cellsY;
+ float _cellSize;
+ float _cellOrigin[2];
+ cellContainer _cells;
+ occluderContainer _faces;
+ Vec3r _viewpoint;
+ bool _enableQI;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid")
#endif
};
inline void BoxGrid::Iterator::initBeforeTarget()
{
- _current = _cell->faces.begin();
- while (_current != _cell->faces.end() && !testOccluder(false)) {
- ++_current;
- }
+ _current = _cell->faces.begin();
+ while (_current != _cell->faces.end() && !testOccluder(false)) {
+ ++_current;
+ }
}
inline void BoxGrid::Iterator::initAfterTarget()
{
- if (_foundOccludee) {
+ if (_foundOccludee) {
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\tStarting occludee search from occludeeCandidate at depth " <<
- _occludeeDepth << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth
+ << std::endl;
+ }
#endif
- _current = _occludeeCandidate;
- return;
- }
+ _current = _occludeeCandidate;
+ return;
+ }
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\tStarting occludee search from current position" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\tStarting occludee search from current position" << std::endl;
+ }
#endif
- while (_current != _cell->faces.end() && !testOccluder(true)) {
- ++_current;
- }
+ while (_current != _cell->faces.end() && !testOccluder(true)) {
+ ++_current;
+ }
}
inline bool BoxGrid::Iterator::testOccluder(bool wantOccludee)
{
- // End-of-list is not even a valid iterator position
- if (_current == _cell->faces.end()) {
- // Returning true seems strange, but it will break us out of whatever loop is calling testOccluder,
- // and _current = _cell->face.end() will make the calling routine give up.
- return true;
- }
+ // End-of-list is not even a valid iterator position
+ if (_current == _cell->faces.end()) {
+ // Returning true seems strange, but it will break us out of whatever loop is calling testOccluder,
+ // and _current = _cell->face.end() will make the calling routine give up.
+ return true;
+ }
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
- for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
- std::cout << ", " << (*_current)->poly.getVertices()[i];
- }
- std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
+ for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
+ std::cout << ", " << (*_current)->poly.getVertices()[i];
+ }
+ std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
+ }
#endif
- // If we have an occluder candidate and we are unambiguously after it, abort
- if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
+ // If we have an occluder candidate and we are unambiguously after it, abort
+ if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
+ }
#endif
- _current = _cell->faces.end();
+ _current = _cell->faces.end();
- // See note above
- return true;
- }
+ // See note above
+ return true;
+ }
- // Specific continue or stop conditions when searching for each type
- if (wantOccludee) {
- if ((*_current)->deepest < _target[2]) {
+ // Specific continue or stop conditions when searching for each type
+ if (wantOccludee) {
+ if ((*_current)->deepest < _target[2]) {
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
+ }
#endif
- return false;
- }
- }
- else {
- if ((*_current)->shallowest > _target[2]) {
+ return false;
+ }
+ }
+ else {
+ if ((*_current)->shallowest > _target[2]) {
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
+ }
#endif
- return true;
- }
- }
+ return true;
+ }
+ }
- // Depthwise, this is a valid occluder.
+ // Depthwise, this is a valid occluder.
- // Check to see if target is in the 2D bounding box
- Vec3r bbMin, bbMax;
- (*_current)->poly.getBBox(bbMin, bbMax);
- if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
+ // Check to see if target is in the 2D bounding box
+ Vec3r bbMin, bbMax;
+ (*_current)->poly.getBBox(bbMin, bbMax);
+ if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] ||
+ _target[1] > bbMax[1]) {
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tSkipping: bounding box violation" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tSkipping: bounding box violation" << std::endl;
+ }
#endif
- return false;
- }
+ return false;
+ }
- // We've done all the corner cutting we can.
- // Let the caller work out whether or not the geometry is correct.
- return true;
+ // We've done all the corner cutting we can.
+ // Let the caller work out whether or not the geometry is correct.
+ return true;
}
inline void BoxGrid::Iterator::reportDepth(Vec3r origin, Vec3r u, real t)
{
- // The reported depth is the length of a ray in camera space
- // We need to convert it into a Z-value in grid space
- real depth = -(origin + (u * t))[2];
+ // The reported depth is the length of a ray in camera space
+ // We need to convert it into a Z-value in grid space
+ real depth = -(origin + (u * t))[2];
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tReporting depth of occluder/ee: " << depth;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tReporting depth of occluder/ee: " << depth;
+ }
#endif
- if (depth > _target[2]) {
+ if (depth > _target[2]) {
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << " is deeper than target" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << " is deeper than target" << std::endl;
+ }
#endif
- // If the current occluder is the best occludee so far, save it.
- if (! _foundOccludee || _occludeeDepth > depth) {
- markCurrentOccludeeCandidate(depth);
- }
- }
- else {
+ // If the current occluder is the best occludee so far, save it.
+ if (!_foundOccludee || _occludeeDepth > depth) {
+ markCurrentOccludeeCandidate(depth);
+ }
+ }
+ else {
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << std::endl;
+ }
#endif
- }
+ }
}
inline void BoxGrid::Iterator::nextOccluder()
{
- if (_current != _cell->faces.end()) {
- do {
- ++_current;
- } while (_current != _cell->faces.end() && ! testOccluder(false));
- }
+ if (_current != _cell->faces.end()) {
+ do {
+ ++_current;
+ } while (_current != _cell->faces.end() && !testOccluder(false));
+ }
}
inline void BoxGrid::Iterator::nextOccludee()
{
- if (_current != _cell->faces.end()) {
- do {
- ++_current;
- } while (_current != _cell->faces.end() && ! testOccluder(true));
- }
+ if (_current != _cell->faces.end()) {
+ do {
+ ++_current;
+ } while (_current != _cell->faces.end() && !testOccluder(true));
+ }
}
inline bool BoxGrid::Iterator::validBeforeTarget()
{
- return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
+ return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
}
inline bool BoxGrid::Iterator::validAfterTarget()
{
- return _current != _cell->faces.end();
+ return _current != _cell->faces.end();
}
inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth)
{
#if BOX_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
+ }
#endif
- _occludeeCandidate = _current;
- _occludeeDepth = depth;
- _foundOccludee = true;
+ _occludeeCandidate = _current;
+ _occludeeDepth = depth;
+ _foundOccludee = true;
}
inline WFace *BoxGrid::Iterator::getWFace() const
{
- return (*_current)->face;
+ return (*_current)->face;
}
inline Polygon3r *BoxGrid::Iterator::getCameraSpacePolygon()
{
- return &((*_current)->cameraSpacePolygon);
+ return &((*_current)->cameraSpacePolygon);
}
-inline BoxGrid::OccluderData::OccluderData(OccluderSource& source, Polygon3r& p)
-: poly(p),
- cameraSpacePolygon(source.getCameraSpacePolygon()),
- face(source.getWFace())
+inline BoxGrid::OccluderData::OccluderData(OccluderSource &source, Polygon3r &p)
+ : poly(p), cameraSpacePolygon(source.getCameraSpacePolygon()), face(source.getWFace())
{
- // Set shallowest and deepest based on bbox
- Vec3r min, max;
- poly.getBBox(min, max);
- shallowest = min[2];
- deepest = max[2];
+ // Set shallowest and deepest based on bbox
+ Vec3r min, max;
+ poly.getBBox(min, max);
+ shallowest = min[2];
+ deepest = max[2];
}
-inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
+inline void BoxGrid::Cell::checkAndInsert(OccluderSource &source,
+ Polygon3r &poly,
+ OccluderData *&occluder)
{
- if (GridHelpers::insideProscenium (boundary, poly)) {
- if (occluder == NULL) {
- // Disposal of occluder will be handled in BoxGrid::distributePolygons(),
- // or automatically by BoxGrid::_faces;
- occluder = new OccluderData(source, poly);
- }
- faces.push_back(occluder);
- }
+ if (GridHelpers::insideProscenium(boundary, poly)) {
+ if (occluder == NULL) {
+ // Disposal of occluder will be handled in BoxGrid::distributePolygons(),
+ // or automatically by BoxGrid::_faces;
+ occluder = new OccluderData(source, poly);
+ }
+ faces.push_back(occluder);
+ }
}
-inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
+inline bool BoxGrid::insertOccluder(OccluderSource &source, OccluderData *&occluder)
{
- Polygon3r& poly(source.getGridSpacePolygon());
- occluder = NULL;
-
- Vec3r bbMin, bbMax;
- poly.getBBox(bbMin, bbMax);
- // Check overlapping cells
- unsigned startX, startY, endX, endY;
- getCellCoordinates(bbMin, startX, startY);
- getCellCoordinates(bbMax, endX, endY);
-
- for (unsigned int i = startX; i <= endX; ++i) {
- for (unsigned int j = startY; j <= endY; ++j) {
- if (_cells[i * _cellsY + j] != NULL) {
- _cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
- }
- }
- }
-
- return occluder != NULL;
+ Polygon3r &poly(source.getGridSpacePolygon());
+ occluder = NULL;
+
+ Vec3r bbMin, bbMax;
+ poly.getBBox(bbMin, bbMax);
+ // Check overlapping cells
+ unsigned startX, startY, endX, endY;
+ getCellCoordinates(bbMin, startX, startY);
+ getCellCoordinates(bbMax, endX, endY);
+
+ for (unsigned int i = startX; i <= endX; ++i) {
+ for (unsigned int j = startY; j <= endY; ++j) {
+ if (_cells[i * _cellsY + j] != NULL) {
+ _cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
+ }
+ }
+ }
+
+ return occluder != NULL;
}
} /* namespace Freestyle */
-#endif // __FREESTYLE_BOX_GRID_H__
+#endif // __FREESTYLE_BOX_GRID_H__
diff --git a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
index 28e4b0251de..214852001b6 100644
--- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
+++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
@@ -27,250 +27,254 @@
namespace Freestyle {
-CulledOccluderSource::CulledOccluderSource(const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap,
+CulledOccluderSource::CulledOccluderSource(const GridHelpers::Transform &t,
+ WingedEdge &we,
+ ViewMap &viewMap,
bool extensiveFEdgeSearch)
-: OccluderSource(t, we), rejected(0), gridSpaceOccluderProsceniumInitialized(false)
+ : OccluderSource(t, we), rejected(0), gridSpaceOccluderProsceniumInitialized(false)
{
- cullViewEdges(viewMap, extensiveFEdgeSearch);
+ cullViewEdges(viewMap, extensiveFEdgeSearch);
- // If we have not found any visible FEdges during our cull, then there is nothing to iterate over.
- // Short-circuit everything.
- valid = gridSpaceOccluderProsceniumInitialized;
+ // If we have not found any visible FEdges during our cull, then there is nothing to iterate over.
+ // Short-circuit everything.
+ valid = gridSpaceOccluderProsceniumInitialized;
- if (valid && ! testCurrent()) {
- next();
- }
+ if (valid && !testCurrent()) {
+ next();
+ }
}
-CulledOccluderSource::~CulledOccluderSource() {}
+CulledOccluderSource::~CulledOccluderSource()
+{
+}
bool CulledOccluderSource::testCurrent()
{
- if (valid) {
- // The test for gridSpaceOccluderProsceniumInitialized should not be necessary
- return gridSpaceOccluderProsceniumInitialized &&
- GridHelpers::insideProscenium(gridSpaceOccluderProscenium, cachedPolygon);
- }
- return false;
+ if (valid) {
+ // The test for gridSpaceOccluderProsceniumInitialized should not be necessary
+ return gridSpaceOccluderProsceniumInitialized &&
+ GridHelpers::insideProscenium(gridSpaceOccluderProscenium, cachedPolygon);
+ }
+ return false;
}
bool CulledOccluderSource::next()
{
- while (OccluderSource::next()) {
- if (testCurrent()) {
- ++rejected;
- return true;
- }
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "Finished generating occluders. Rejected " << rejected << " faces." << std::endl;
- }
- return false;
+ while (OccluderSource::next()) {
+ if (testCurrent()) {
+ ++rejected;
+ return true;
+ }
+ }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "Finished generating occluders. Rejected " << rejected << " faces." << std::endl;
+ }
+ return false;
}
void CulledOccluderSource::getOccluderProscenium(real proscenium[4])
{
- for (unsigned int i = 0; i < 4; ++i) {
- proscenium[i] = gridSpaceOccluderProscenium[i];
- }
+ for (unsigned int i = 0; i < 4; ++i) {
+ proscenium[i] = gridSpaceOccluderProscenium[i];
+ }
}
-static inline real distance2D(const Vec3r & point, const real origin[2])
+static inline real distance2D(const Vec3r &point, const real origin[2])
{
- return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
+ return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
}
static inline bool crossesProscenium(real proscenium[4], FEdge *fe)
{
- Vec2r min(proscenium[0], proscenium[2]);
- Vec2r max(proscenium[1], proscenium[3]);
- Vec2r A(fe->vertexA()->getProjectedX(), fe->vertexA()->getProjectedY());
- Vec2r B(fe->vertexB()->getProjectedX(), fe->vertexB()->getProjectedY());
+ Vec2r min(proscenium[0], proscenium[2]);
+ Vec2r max(proscenium[1], proscenium[3]);
+ Vec2r A(fe->vertexA()->getProjectedX(), fe->vertexA()->getProjectedY());
+ Vec2r B(fe->vertexB()->getProjectedX(), fe->vertexB()->getProjectedY());
- return GeomUtils::intersect2dSeg2dArea (min, max, A, B);
+ return GeomUtils::intersect2dSeg2dArea(min, max, A, B);
}
-static inline bool insideProscenium(real proscenium[4], const Vec3r& point)
+static inline bool insideProscenium(real proscenium[4], const Vec3r &point)
{
- return !(point[0] < proscenium[0] || point[0] > proscenium[1] ||
- point[1] < proscenium[2] || point[1] > proscenium[3]);
+ return !(point[0] < proscenium[0] || point[0] > proscenium[1] || point[1] < proscenium[2] ||
+ point[1] > proscenium[3]);
}
-void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch)
+void CulledOccluderSource::cullViewEdges(ViewMap &viewMap, bool extensiveFEdgeSearch)
{
- // Cull view edges by marking them as non-displayable.
- // This avoids the complications of trying to delete edges from the ViewMap.
-
- // Non-displayable view edges will be skipped over during visibility calculation.
-
- // View edges will be culled according to their position w.r.t. the viewport proscenium (viewport + 5% border,
- // or some such).
-
- // Get proscenium boundary for culling
- real viewProscenium[4];
- GridHelpers::getDefaultViewProscenium(viewProscenium);
- real prosceniumOrigin[2];
- prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
- prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Proscenium culling:" << endl;
- cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2] <<
- ", " << viewProscenium[3] << "]"<< endl;
- cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]"<< endl;
- }
-
- // A separate occluder proscenium will also be maintained, starting out the same as the viewport proscenium, and
- // expanding as necessary so that it encompasses the center point of at least one feature edge in each
- // retained view edge.
- // The occluder proscenium will be used later to cull occluding triangles before they are inserted into the Grid.
- // The occluder proscenium starts out the same size as the view proscenium
- GridHelpers::getDefaultViewProscenium(occluderProscenium);
-
- // XXX Freestyle is inconsistent in its use of ViewMap::viewedges_container and vector<ViewEdge*>::iterator.
- // Probably all occurences of vector<ViewEdge*>::iterator should be replaced ViewMap::viewedges_container
- // throughout the code.
- // For each view edge
- ViewMap::viewedges_container::iterator ve, veend;
-
- for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
- // Overview:
- // Search for a visible feature edge
- // If none: mark view edge as non-displayable
- // Otherwise:
- // Find a feature edge with center point inside occluder proscenium.
- // If none exists, find the feature edge with center point closest to viewport origin.
- // Expand occluder proscenium to enclose center point.
-
- // For each feature edge, while bestOccluderTarget not found and view edge not visibile
- bool bestOccluderTargetFound = false;
- FEdge *bestOccluderTarget = NULL;
- real bestOccluderDistance = 0.0;
- FEdge *festart = (*ve)->fedgeA();
- FEdge *fe = festart;
- // All ViewEdges start culled
- (*ve)->setIsInImage(false);
-
- // For simple visibility calculation: mark a feature edge that is known to have a center point inside
- // the occluder proscenium. Cull all other feature edges.
- do {
- // All FEdges start culled
- fe->setIsInImage(false);
-
- // Look for the visible edge that can most easily be included in the occluder proscenium.
- if (!bestOccluderTargetFound) {
- // If center point is inside occluder proscenium,
- if (insideProscenium(occluderProscenium, fe->center2d())) {
- // Use this feature edge for visibility deterimination
- fe->setIsInImage(true);
- expandGridSpaceOccluderProscenium(fe);
- // Mark bestOccluderTarget as found
- bestOccluderTargetFound = true;
- bestOccluderTarget = fe;
- }
- else {
- real d = distance2D(fe->center2d(), prosceniumOrigin);
- // If center point is closer to viewport origin than current target
- if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
- // Then store as bestOccluderTarget
- bestOccluderDistance = d;
- bestOccluderTarget = fe;
- }
- }
- }
-
- // If feature edge crosses the view proscenium
- if (!(*ve)->isInImage() && crossesProscenium(viewProscenium, fe)) {
- // Then the view edge will be included in the image
- (*ve)->setIsInImage(true);
- }
- fe = fe->nextEdge();
- } while (fe != NULL && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));
-
- // Either we have run out of FEdges, or we already have the one edge we need to determine visibility
- // Cull all remaining edges.
- while (fe != NULL && fe != festart) {
- fe->setIsInImage(false);
- fe = fe->nextEdge();
- }
-
- // If bestOccluderTarget was not found inside the occluder proscenium,
- // we need to expand the occluder proscenium to include it.
- if ((*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound) {
- // Expand occluder proscenium to enclose bestOccluderTarget
- Vec3r point = bestOccluderTarget->center2d();
- if (point[0] < occluderProscenium[0]) {
- occluderProscenium[0] = point[0];
- }
- else if (point[0] > occluderProscenium[1]) {
- occluderProscenium[1] = point[0];
- }
- if (point[1] < occluderProscenium[2]) {
- occluderProscenium[2] = point[1];
- }
- else if (point[1] > occluderProscenium[3]) {
- occluderProscenium[3] = point[1];
- }
- // Use bestOccluderTarget for visibility determination
- bestOccluderTarget->setIsInImage(true);
- }
- }
-
- // We are done calculating the occluder proscenium.
- // Expand the occluder proscenium by an epsilon to avoid rounding errors.
- const real epsilon = 1.0e-6;
- occluderProscenium[0] -= epsilon;
- occluderProscenium[1] += epsilon;
- occluderProscenium[2] -= epsilon;
- occluderProscenium[3] += epsilon;
-
- // For "Normal" or "Fast" style visibility computation only:
-
- // For more detailed visibility calculation, make a second pass through the view map, marking all feature edges
- // with center points inside the final occluder proscenium. All of these feature edges can be considered during
- // visibility calculation.
-
- // So far we have only found one FEdge per ViewEdge. The "Normal" and "Fast" styles of visibility computation
- // want to consider many FEdges for each ViewEdge.
- // Here we re-scan the view map to find any usable FEdges that we skipped on the first pass, or that have become
- // usable because the occluder proscenium has been expanded since the edge was visited on the first pass.
- if (extensiveFEdgeSearch) {
- // For each view edge,
- for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
- if (!(*ve)->isInImage()) {
- continue;
- }
- // For each feature edge,
- FEdge *festart = (*ve)->fedgeA();
- FEdge *fe = festart;
- do {
- // If not (already) visible and center point inside occluder proscenium,
- if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
- // Use the feature edge for visibility determination
- fe->setIsInImage(true);
- expandGridSpaceOccluderProscenium(fe);
- }
- fe = fe->nextEdge();
- } while (fe != NULL && fe != festart);
- }
- }
-
- // Up until now, all calculations have been done in camera space.
- // However, the occluder source's iteration and the grid that consumes the occluders both work in gridspace,
- // so we need a version of the occluder proscenium in gridspace.
- // Set the gridspace occlude proscenium
+ // Cull view edges by marking them as non-displayable.
+ // This avoids the complications of trying to delete edges from the ViewMap.
+
+ // Non-displayable view edges will be skipped over during visibility calculation.
+
+ // View edges will be culled according to their position w.r.t. the viewport proscenium (viewport + 5% border,
+ // or some such).
+
+ // Get proscenium boundary for culling
+ real viewProscenium[4];
+ GridHelpers::getDefaultViewProscenium(viewProscenium);
+ real prosceniumOrigin[2];
+ prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
+ prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Proscenium culling:" << endl;
+ cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", "
+ << viewProscenium[2] << ", " << viewProscenium[3] << "]" << endl;
+ cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]" << endl;
+ }
+
+ // A separate occluder proscenium will also be maintained, starting out the same as the viewport proscenium, and
+ // expanding as necessary so that it encompasses the center point of at least one feature edge in each
+ // retained view edge.
+ // The occluder proscenium will be used later to cull occluding triangles before they are inserted into the Grid.
+ // The occluder proscenium starts out the same size as the view proscenium
+ GridHelpers::getDefaultViewProscenium(occluderProscenium);
+
+ // XXX Freestyle is inconsistent in its use of ViewMap::viewedges_container and vector<ViewEdge*>::iterator.
+ // Probably all occurences of vector<ViewEdge*>::iterator should be replaced ViewMap::viewedges_container
+ // throughout the code.
+ // For each view edge
+ ViewMap::viewedges_container::iterator ve, veend;
+
+ for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
+ // Overview:
+ // Search for a visible feature edge
+ // If none: mark view edge as non-displayable
+ // Otherwise:
+ // Find a feature edge with center point inside occluder proscenium.
+ // If none exists, find the feature edge with center point closest to viewport origin.
+ // Expand occluder proscenium to enclose center point.
+
+ // For each feature edge, while bestOccluderTarget not found and view edge not visibile
+ bool bestOccluderTargetFound = false;
+ FEdge *bestOccluderTarget = NULL;
+ real bestOccluderDistance = 0.0;
+ FEdge *festart = (*ve)->fedgeA();
+ FEdge *fe = festart;
+ // All ViewEdges start culled
+ (*ve)->setIsInImage(false);
+
+ // For simple visibility calculation: mark a feature edge that is known to have a center point inside
+ // the occluder proscenium. Cull all other feature edges.
+ do {
+ // All FEdges start culled
+ fe->setIsInImage(false);
+
+ // Look for the visible edge that can most easily be included in the occluder proscenium.
+ if (!bestOccluderTargetFound) {
+ // If center point is inside occluder proscenium,
+ if (insideProscenium(occluderProscenium, fe->center2d())) {
+ // Use this feature edge for visibility deterimination
+ fe->setIsInImage(true);
+ expandGridSpaceOccluderProscenium(fe);
+ // Mark bestOccluderTarget as found
+ bestOccluderTargetFound = true;
+ bestOccluderTarget = fe;
+ }
+ else {
+ real d = distance2D(fe->center2d(), prosceniumOrigin);
+ // If center point is closer to viewport origin than current target
+ if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
+ // Then store as bestOccluderTarget
+ bestOccluderDistance = d;
+ bestOccluderTarget = fe;
+ }
+ }
+ }
+
+ // If feature edge crosses the view proscenium
+ if (!(*ve)->isInImage() && crossesProscenium(viewProscenium, fe)) {
+ // Then the view edge will be included in the image
+ (*ve)->setIsInImage(true);
+ }
+ fe = fe->nextEdge();
+ } while (fe != NULL && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));
+
+ // Either we have run out of FEdges, or we already have the one edge we need to determine visibility
+ // Cull all remaining edges.
+ while (fe != NULL && fe != festart) {
+ fe->setIsInImage(false);
+ fe = fe->nextEdge();
+ }
+
+ // If bestOccluderTarget was not found inside the occluder proscenium,
+ // we need to expand the occluder proscenium to include it.
+ if ((*ve)->isInImage() && bestOccluderTarget != NULL && !bestOccluderTargetFound) {
+ // Expand occluder proscenium to enclose bestOccluderTarget
+ Vec3r point = bestOccluderTarget->center2d();
+ if (point[0] < occluderProscenium[0]) {
+ occluderProscenium[0] = point[0];
+ }
+ else if (point[0] > occluderProscenium[1]) {
+ occluderProscenium[1] = point[0];
+ }
+ if (point[1] < occluderProscenium[2]) {
+ occluderProscenium[2] = point[1];
+ }
+ else if (point[1] > occluderProscenium[3]) {
+ occluderProscenium[3] = point[1];
+ }
+ // Use bestOccluderTarget for visibility determination
+ bestOccluderTarget->setIsInImage(true);
+ }
+ }
+
+ // We are done calculating the occluder proscenium.
+ // Expand the occluder proscenium by an epsilon to avoid rounding errors.
+ const real epsilon = 1.0e-6;
+ occluderProscenium[0] -= epsilon;
+ occluderProscenium[1] += epsilon;
+ occluderProscenium[2] -= epsilon;
+ occluderProscenium[3] += epsilon;
+
+ // For "Normal" or "Fast" style visibility computation only:
+
+ // For more detailed visibility calculation, make a second pass through the view map, marking all feature edges
+ // with center points inside the final occluder proscenium. All of these feature edges can be considered during
+ // visibility calculation.
+
+ // So far we have only found one FEdge per ViewEdge. The "Normal" and "Fast" styles of visibility computation
+ // want to consider many FEdges for each ViewEdge.
+ // Here we re-scan the view map to find any usable FEdges that we skipped on the first pass, or that have become
+ // usable because the occluder proscenium has been expanded since the edge was visited on the first pass.
+ if (extensiveFEdgeSearch) {
+ // For each view edge,
+ for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
+ if (!(*ve)->isInImage()) {
+ continue;
+ }
+ // For each feature edge,
+ FEdge *festart = (*ve)->fedgeA();
+ FEdge *fe = festart;
+ do {
+ // If not (already) visible and center point inside occluder proscenium,
+ if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
+ // Use the feature edge for visibility determination
+ fe->setIsInImage(true);
+ expandGridSpaceOccluderProscenium(fe);
+ }
+ fe = fe->nextEdge();
+ } while (fe != NULL && fe != festart);
+ }
+ }
+
+ // Up until now, all calculations have been done in camera space.
+ // However, the occluder source's iteration and the grid that consumes the occluders both work in gridspace,
+ // so we need a version of the occluder proscenium in gridspace.
+ // Set the gridspace occlude proscenium
}
void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge *fe)
{
- if (gridSpaceOccluderProsceniumInitialized) {
- GridHelpers::expandProscenium(gridSpaceOccluderProscenium, transform(fe->center3d()));
- }
- else {
- const Vec3r& point = transform(fe->center3d());
- gridSpaceOccluderProscenium[0] = gridSpaceOccluderProscenium[1] = point[0];
- gridSpaceOccluderProscenium[2] = gridSpaceOccluderProscenium[3] = point[1];
- gridSpaceOccluderProsceniumInitialized = true;
- }
+ if (gridSpaceOccluderProsceniumInitialized) {
+ GridHelpers::expandProscenium(gridSpaceOccluderProscenium, transform(fe->center3d()));
+ }
+ else {
+ const Vec3r &point = transform(fe->center3d());
+ gridSpaceOccluderProscenium[0] = gridSpaceOccluderProscenium[1] = point[0];
+ gridSpaceOccluderProscenium[2] = gridSpaceOccluderProscenium[3] = point[1];
+ gridSpaceOccluderProsceniumInitialized = true;
+ }
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/CulledOccluderSource.h b/source/blender/freestyle/intern/view_map/CulledOccluderSource.h
index de782eda64c..3457fb6ca10 100644
--- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.h
+++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.h
@@ -27,34 +27,35 @@
namespace Freestyle {
-class CulledOccluderSource : public OccluderSource
-{
- // Disallow copying and assignment
- CulledOccluderSource(const CulledOccluderSource& other);
- CulledOccluderSource& operator=(const CulledOccluderSource& other);
+class CulledOccluderSource : public OccluderSource {
+ // Disallow copying and assignment
+ CulledOccluderSource(const CulledOccluderSource &other);
+ CulledOccluderSource &operator=(const CulledOccluderSource &other);
-public:
- CulledOccluderSource(const GridHelpers::Transform& transform, WingedEdge& we, ViewMap& viewMap,
- bool extensiveFEdgeSearch = true);
- virtual ~CulledOccluderSource();
+ public:
+ CulledOccluderSource(const GridHelpers::Transform &transform,
+ WingedEdge &we,
+ ViewMap &viewMap,
+ bool extensiveFEdgeSearch = true);
+ virtual ~CulledOccluderSource();
- void cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch);
+ void cullViewEdges(ViewMap &viewMap, bool extensiveFEdgeSearch);
- bool next();
+ bool next();
- void getOccluderProscenium(real proscenium[4]);
+ void getOccluderProscenium(real proscenium[4]);
-private:
- bool testCurrent();
- void expandGridSpaceOccluderProscenium(FEdge *fe);
+ private:
+ bool testCurrent();
+ void expandGridSpaceOccluderProscenium(FEdge *fe);
- real occluderProscenium[4];
- real gridSpaceOccluderProscenium[4];
+ real occluderProscenium[4];
+ real gridSpaceOccluderProscenium[4];
- unsigned long rejected;
- bool gridSpaceOccluderProsceniumInitialized;
+ unsigned long rejected;
+ bool gridSpaceOccluderProsceniumInitialized;
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
+#endif // __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
index a195db76fe7..bb2b95be84e 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
@@ -30,511 +30,512 @@
namespace Freestyle {
-void FEdgeXDetector::processShapes(WingedEdge& we)
+void FEdgeXDetector::processShapes(WingedEdge &we)
{
- bool progressBarDisplay = false;
+ bool progressBarDisplay = false;
#if 0
- Vec3r Min, Max;
+ Vec3r Min, Max;
#endif
- vector<WShape*> wshapes = we.getWShapes();
- WXShape *wxs;
-
- if (_pProgressBar != NULL) {
- _pProgressBar->reset();
- _pProgressBar->setLabelText("Detecting feature lines");
- _pProgressBar->setTotalSteps(wshapes.size() * 3);
- _pProgressBar->setProgress(0);
- progressBarDisplay = true;
- }
-
- for (vector<WShape*>::const_iterator it = wshapes.begin(); it != wshapes.end(); it++) {
- if (_pRenderMonitor && _pRenderMonitor->testBreak())
- break;
- wxs = dynamic_cast<WXShape*>(*it);
+ vector<WShape *> wshapes = we.getWShapes();
+ WXShape *wxs;
+
+ if (_pProgressBar != NULL) {
+ _pProgressBar->reset();
+ _pProgressBar->setLabelText("Detecting feature lines");
+ _pProgressBar->setTotalSteps(wshapes.size() * 3);
+ _pProgressBar->setProgress(0);
+ progressBarDisplay = true;
+ }
+
+ for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); it++) {
+ if (_pRenderMonitor && _pRenderMonitor->testBreak())
+ break;
+ wxs = dynamic_cast<WXShape *>(*it);
#if 0
- wxs->bbox(Min, Max);
- _bbox_diagonal = (Max - Min).norm();
+ wxs->bbox(Min, Max);
+ _bbox_diagonal = (Max - Min).norm();
#endif
- if (_changes) {
- vector<WFace*>& wfaces = wxs->GetFaceList();
- for (vector<WFace*>::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; ++wf) {
- WXFace *wxf = dynamic_cast<WXFace*>(*wf);
- wxf->Clear();
- }
- _computeViewIndependent = true;
- }
- else if (!(wxs)->getComputeViewIndependentFlag()) {
- wxs->Reset();
- _computeViewIndependent = false;
- }
- else {
- _computeViewIndependent = true;
- }
- preProcessShape(wxs);
- if (progressBarDisplay)
- _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
- processBorderShape(wxs);
- if (_computeMaterialBoundaries)
- processMaterialBoundaryShape(wxs);
- processCreaseShape(wxs);
- if (_computeRidgesAndValleys)
- processRidgesAndValleysShape(wxs);
- if (_computeSuggestiveContours)
- processSuggestiveContourShape(wxs);
- processSilhouetteShape(wxs);
- processEdgeMarksShape(wxs);
- if (progressBarDisplay)
- _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
-
- // build smooth edges:
- buildSmoothEdges(wxs);
-
- // Post processing for suggestive contours
- if (_computeSuggestiveContours)
- postProcessSuggestiveContourShape(wxs);
- if (progressBarDisplay)
- _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
-
- wxs->setComputeViewIndependentFlag(false);
- _computeViewIndependent = false;
- _changes = false;
-
- // reset user data
- (*it)->ResetUserData();
- }
+ if (_changes) {
+ vector<WFace *> &wfaces = wxs->GetFaceList();
+ for (vector<WFace *>::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend;
+ ++wf) {
+ WXFace *wxf = dynamic_cast<WXFace *>(*wf);
+ wxf->Clear();
+ }
+ _computeViewIndependent = true;
+ }
+ else if (!(wxs)->getComputeViewIndependentFlag()) {
+ wxs->Reset();
+ _computeViewIndependent = false;
+ }
+ else {
+ _computeViewIndependent = true;
+ }
+ preProcessShape(wxs);
+ if (progressBarDisplay)
+ _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
+ processBorderShape(wxs);
+ if (_computeMaterialBoundaries)
+ processMaterialBoundaryShape(wxs);
+ processCreaseShape(wxs);
+ if (_computeRidgesAndValleys)
+ processRidgesAndValleysShape(wxs);
+ if (_computeSuggestiveContours)
+ processSuggestiveContourShape(wxs);
+ processSilhouetteShape(wxs);
+ processEdgeMarksShape(wxs);
+ if (progressBarDisplay)
+ _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
+
+ // build smooth edges:
+ buildSmoothEdges(wxs);
+
+ // Post processing for suggestive contours
+ if (_computeSuggestiveContours)
+ postProcessSuggestiveContourShape(wxs);
+ if (progressBarDisplay)
+ _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
+
+ wxs->setComputeViewIndependentFlag(false);
+ _computeViewIndependent = false;
+ _changes = false;
+
+ // reset user data
+ (*it)->ResetUserData();
+ }
}
// GENERAL STUFF
////////////////
void FEdgeXDetector::preProcessShape(WXShape *iWShape)
{
- _meanK1 = 0;
- _meanKr = 0;
- _minK1 = FLT_MAX;
- _maxK1 = -FLT_MAX;
- _minKr = FLT_MAX;
- _maxKr = -FLT_MAX;
- _nPoints = 0;
+ _meanK1 = 0;
+ _meanKr = 0;
+ _minK1 = FLT_MAX;
+ _maxK1 = -FLT_MAX;
+ _minKr = FLT_MAX;
+ _maxKr = -FLT_MAX;
+ _nPoints = 0;
#if 0
- _meanEdgeSize = iWShape->getMeanEdgeSize();
+ _meanEdgeSize = iWShape->getMeanEdgeSize();
#else
- _meanEdgeSize = iWShape->ComputeMeanEdgeSize();
+ _meanEdgeSize = iWShape->ComputeMeanEdgeSize();
#endif
- vector<WFace*>& wfaces = iWShape->GetFaceList();
- vector<WFace*>::iterator f, fend;
- // view dependant stuff
- for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
- preProcessFace((WXFace *)(*f));
- }
-
- if (_computeRidgesAndValleys || _computeSuggestiveContours) {
- vector<WVertex*>& wvertices = iWShape->getVertexList();
- for (vector<WVertex*>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
- // Compute curvatures
- WXVertex *wxv = dynamic_cast<WXVertex*>(*wv);
- computeCurvatures(wxv);
- }
- _meanK1 /= (real)(_nPoints);
- _meanKr /= (real)(_nPoints);
- }
+ vector<WFace *> &wfaces = iWShape->GetFaceList();
+ vector<WFace *>::iterator f, fend;
+ // view dependant stuff
+ for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
+ preProcessFace((WXFace *)(*f));
+ }
+
+ if (_computeRidgesAndValleys || _computeSuggestiveContours) {
+ vector<WVertex *> &wvertices = iWShape->getVertexList();
+ for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend;
+ ++wv) {
+ // Compute curvatures
+ WXVertex *wxv = dynamic_cast<WXVertex *>(*wv);
+ computeCurvatures(wxv);
+ }
+ _meanK1 /= (real)(_nPoints);
+ _meanKr /= (real)(_nPoints);
+ }
}
void FEdgeXDetector::preProcessFace(WXFace *iFace)
{
- Vec3f firstPoint = iFace->GetVertex(0)->GetVertex();
- Vec3f N = iFace->GetNormal();
-
- // Compute the dot product between V (=_Viewpoint - firstPoint) and N:
- Vec3f V;
- if (_orthographicProjection) {
- V = Vec3f(0.0f, 0.0f, _Viewpoint.z() - firstPoint.z());
- }
- else {
- V = Vec3f(_Viewpoint - firstPoint);
- }
- N.normalize();
- V.normalize();
- iFace->setDotP(N * V);
-
- // compute the distance between the face center and the viewpoint:
- if (_orthographicProjection) {
- iFace->setZ(iFace->center().z() - _Viewpoint.z());
- }
- else {
- Vec3f dist_vec(iFace->center() - _Viewpoint);
- iFace->setZ(dist_vec.norm());
- }
+ Vec3f firstPoint = iFace->GetVertex(0)->GetVertex();
+ Vec3f N = iFace->GetNormal();
+
+ // Compute the dot product between V (=_Viewpoint - firstPoint) and N:
+ Vec3f V;
+ if (_orthographicProjection) {
+ V = Vec3f(0.0f, 0.0f, _Viewpoint.z() - firstPoint.z());
+ }
+ else {
+ V = Vec3f(_Viewpoint - firstPoint);
+ }
+ N.normalize();
+ V.normalize();
+ iFace->setDotP(N * V);
+
+ // compute the distance between the face center and the viewpoint:
+ if (_orthographicProjection) {
+ iFace->setZ(iFace->center().z() - _Viewpoint.z());
+ }
+ else {
+ Vec3f dist_vec(iFace->center() - _Viewpoint);
+ iFace->setZ(dist_vec.norm());
+ }
}
void FEdgeXDetector::computeCurvatures(WXVertex *vertex)
{
- // TODO: for some reason, the 'vertex' may have no associated edges
- // (i.e., WVertex::_EdgeList is empty), which causes a crash due to
- // a subsequent call of WVertex::_EdgeList.front().
- if (vertex->GetEdges().empty()) {
- if (G.debug & G_DEBUG_FREESTYLE) {
- printf("Warning: WVertex %d has no associated edges.\n", vertex->GetId());
- }
- return;
- }
-
- // CURVATURE LAYER
- // store all the curvature datas for each vertex
-
- //soc unused - real K1, K2
- real cos2theta, sin2theta;
- Vec3r e1, n, v;
- // one vertex curvature info :
- CurvatureInfo *C;
- float radius = _sphereRadius * _meanEdgeSize;
-
- // view independent stuff
- if (_computeViewIndependent) {
- C = new CurvatureInfo();
- vertex->setCurvatures(C);
- OGF::NormalCycle ncycle;
- ncycle.begin();
- if (radius > 0) {
- OGF::compute_curvature_tensor(vertex, radius, ncycle);
- }
- else {
- OGF::compute_curvature_tensor_one_ring(vertex, ncycle);
- }
- ncycle.end();
- C->K1 = ncycle.kmin();
- C->K2 = ncycle.kmax();
- C->e1 = ncycle.Kmax(); //ncycle.kmin() * ncycle.Kmax();
- C->e2 = ncycle.Kmin(); //ncycle.kmax() * ncycle.Kmin();
-
- real absK1 = fabs(C->K1);
- _meanK1 += absK1;
- if (absK1 > _maxK1)
- _maxK1 = absK1;
- if (absK1 < _minK1)
- _minK1 = absK1;
- }
- // view dependant
- C = vertex->curvatures();
- if (C == 0)
- return;
-
- // compute radial curvature :
- n = C->e1 ^ C->e2;
- if (_orthographicProjection) {
- v = Vec3r(0.0, 0.0, _Viewpoint.z() - vertex->GetVertex().z());
- }
- else {
- v = Vec3r(_Viewpoint - vertex->GetVertex());
- }
- C->er = v - (v * n) * n;
- C->er.normalize();
- e1 = C->e1;
- e1.normalize();
- cos2theta = C->er * e1;
- cos2theta *= cos2theta;
- sin2theta = 1 - cos2theta;
- C->Kr = C->K1 * cos2theta + C->K2 * sin2theta;
- real absKr = fabs(C->Kr);
- _meanKr += absKr;
- if (absKr > _maxKr)
- _maxKr = absKr;
- if (absKr < _minKr)
- _minKr = absKr;
-
- ++_nPoints;
+ // TODO: for some reason, the 'vertex' may have no associated edges
+ // (i.e., WVertex::_EdgeList is empty), which causes a crash due to
+ // a subsequent call of WVertex::_EdgeList.front().
+ if (vertex->GetEdges().empty()) {
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ printf("Warning: WVertex %d has no associated edges.\n", vertex->GetId());
+ }
+ return;
+ }
+
+ // CURVATURE LAYER
+ // store all the curvature datas for each vertex
+
+ //soc unused - real K1, K2
+ real cos2theta, sin2theta;
+ Vec3r e1, n, v;
+ // one vertex curvature info :
+ CurvatureInfo *C;
+ float radius = _sphereRadius * _meanEdgeSize;
+
+ // view independent stuff
+ if (_computeViewIndependent) {
+ C = new CurvatureInfo();
+ vertex->setCurvatures(C);
+ OGF::NormalCycle ncycle;
+ ncycle.begin();
+ if (radius > 0) {
+ OGF::compute_curvature_tensor(vertex, radius, ncycle);
+ }
+ else {
+ OGF::compute_curvature_tensor_one_ring(vertex, ncycle);
+ }
+ ncycle.end();
+ C->K1 = ncycle.kmin();
+ C->K2 = ncycle.kmax();
+ C->e1 = ncycle.Kmax(); //ncycle.kmin() * ncycle.Kmax();
+ C->e2 = ncycle.Kmin(); //ncycle.kmax() * ncycle.Kmin();
+
+ real absK1 = fabs(C->K1);
+ _meanK1 += absK1;
+ if (absK1 > _maxK1)
+ _maxK1 = absK1;
+ if (absK1 < _minK1)
+ _minK1 = absK1;
+ }
+ // view dependant
+ C = vertex->curvatures();
+ if (C == 0)
+ return;
+
+ // compute radial curvature :
+ n = C->e1 ^ C->e2;
+ if (_orthographicProjection) {
+ v = Vec3r(0.0, 0.0, _Viewpoint.z() - vertex->GetVertex().z());
+ }
+ else {
+ v = Vec3r(_Viewpoint - vertex->GetVertex());
+ }
+ C->er = v - (v * n) * n;
+ C->er.normalize();
+ e1 = C->e1;
+ e1.normalize();
+ cos2theta = C->er * e1;
+ cos2theta *= cos2theta;
+ sin2theta = 1 - cos2theta;
+ C->Kr = C->K1 * cos2theta + C->K2 * sin2theta;
+ real absKr = fabs(C->Kr);
+ _meanKr += absKr;
+ if (absKr > _maxKr)
+ _maxKr = absKr;
+ if (absKr < _minKr)
+ _minKr = absKr;
+
+ ++_nPoints;
}
// SILHOUETTE
/////////////
void FEdgeXDetector::processSilhouetteShape(WXShape *iWShape)
{
- // Make a first pass on every polygons in order to compute all their silhouette relative values:
- vector<WFace*>& wfaces = iWShape->GetFaceList();
- vector<WFace*>::iterator f, fend;
- for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
- ProcessSilhouetteFace((WXFace *)(*f));
- }
-
- // Make a pass on the edges to detect the silhouette edges that are not smooth
- vector<WEdge*>::iterator we, weend;
- vector<WEdge*> &wedges = iWShape->getEdgeList();
- for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
- ProcessSilhouetteEdge((WXEdge *)(*we));
- }
+ // Make a first pass on every polygons in order to compute all their silhouette relative values:
+ vector<WFace *> &wfaces = iWShape->GetFaceList();
+ vector<WFace *>::iterator f, fend;
+ for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
+ ProcessSilhouetteFace((WXFace *)(*f));
+ }
+
+ // Make a pass on the edges to detect the silhouette edges that are not smooth
+ vector<WEdge *>::iterator we, weend;
+ vector<WEdge *> &wedges = iWShape->getEdgeList();
+ for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
+ ProcessSilhouetteEdge((WXEdge *)(*we));
+ }
}
void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
{
- // SILHOUETTE LAYER
- Vec3f normal;
- // Compute the dot products between View direction and N at each vertex of the face:
- Vec3f point;
- int closestPointId = 0;
- float dist, minDist = FLT_MAX;
- int numVertices = iFace->numberOfVertices();
- WXFaceLayer *faceLayer = new WXFaceLayer(iFace, Nature::SILHOUETTE, true);
- for (int i = 0; i < numVertices; i++) {
- point = iFace->GetVertex(i)->GetVertex();
- normal = iFace->GetVertexNormal(i);
- normal.normalize();
- Vec3f V;
- if (_orthographicProjection) {
- V = Vec3f(0.0f, 0.0f, _Viewpoint.z() - point.z());
- }
- else {
- V = Vec3f(_Viewpoint - point);
- }
- V.normalize();
- float d = normal * V;
- faceLayer->PushDotP(d);
- // Find the point the closest to the viewpoint
- if (_orthographicProjection) {
- dist = point.z() - _Viewpoint.z();
- }
- else {
- Vec3f dist_vec(point - _Viewpoint);
- dist = dist_vec.norm();
- }
- if (dist < minDist) {
- minDist = dist;
- closestPointId = i;
- }
- }
- // Set the closest point id:
- faceLayer->setClosestPointIndex(closestPointId);
- // Add this layer to the face:
- iFace->AddSmoothLayer(faceLayer);
+ // SILHOUETTE LAYER
+ Vec3f normal;
+ // Compute the dot products between View direction and N at each vertex of the face:
+ Vec3f point;
+ int closestPointId = 0;
+ float dist, minDist = FLT_MAX;
+ int numVertices = iFace->numberOfVertices();
+ WXFaceLayer *faceLayer = new WXFaceLayer(iFace, Nature::SILHOUETTE, true);
+ for (int i = 0; i < numVertices; i++) {
+ point = iFace->GetVertex(i)->GetVertex();
+ normal = iFace->GetVertexNormal(i);
+ normal.normalize();
+ Vec3f V;
+ if (_orthographicProjection) {
+ V = Vec3f(0.0f, 0.0f, _Viewpoint.z() - point.z());
+ }
+ else {
+ V = Vec3f(_Viewpoint - point);
+ }
+ V.normalize();
+ float d = normal * V;
+ faceLayer->PushDotP(d);
+ // Find the point the closest to the viewpoint
+ if (_orthographicProjection) {
+ dist = point.z() - _Viewpoint.z();
+ }
+ else {
+ Vec3f dist_vec(point - _Viewpoint);
+ dist = dist_vec.norm();
+ }
+ if (dist < minDist) {
+ minDist = dist;
+ closestPointId = i;
+ }
+ }
+ // Set the closest point id:
+ faceLayer->setClosestPointIndex(closestPointId);
+ // Add this layer to the face:
+ iFace->AddSmoothLayer(faceLayer);
}
void FEdgeXDetector::ProcessSilhouetteEdge(WXEdge *iEdge)
{
- if (iEdge->nature() & Nature::BORDER)
- return;
- // SILHOUETTE ?
- //-------------
- WXFace *fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
- WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
-
- if ((fA->front()) ^ (fB->front())) { // fA->visible XOR fB->visible (true if one is 0 and the other is 1)
- // The only edges we want to set as silhouette edges in this way are the ones with 2 different normals
- // for 1 vertex for these two faces
- //--------------------
- // In reality we only test the normals for 1 of the 2 vertices.
- if (fA->GetVertexNormal(iEdge->GetaVertex()) == fB->GetVertexNormal(iEdge->GetaVertex()))
- return;
- iEdge->AddNature(Nature::SILHOUETTE);
- if (fB->front())
- iEdge->setOrder(1);
- else
- iEdge->setOrder(-1);
- }
+ if (iEdge->nature() & Nature::BORDER)
+ return;
+ // SILHOUETTE ?
+ //-------------
+ WXFace *fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
+ WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
+
+ if ((fA->front()) ^
+ (fB->front())) { // fA->visible XOR fB->visible (true if one is 0 and the other is 1)
+ // The only edges we want to set as silhouette edges in this way are the ones with 2 different normals
+ // for 1 vertex for these two faces
+ //--------------------
+ // In reality we only test the normals for 1 of the 2 vertices.
+ if (fA->GetVertexNormal(iEdge->GetaVertex()) == fB->GetVertexNormal(iEdge->GetaVertex()))
+ return;
+ iEdge->AddNature(Nature::SILHOUETTE);
+ if (fB->front())
+ iEdge->setOrder(1);
+ else
+ iEdge->setOrder(-1);
+ }
}
// BORDER
/////////
void FEdgeXDetector::processBorderShape(WXShape *iWShape)
{
- if (!_computeViewIndependent)
- return;
- // Make a pass on the edges to detect the BORDER
- vector<WEdge*>::iterator we, weend;
- vector<WEdge*> &wedges = iWShape->getEdgeList();
- for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
- ProcessBorderEdge((WXEdge *)(*we));
- }
+ if (!_computeViewIndependent)
+ return;
+ // Make a pass on the edges to detect the BORDER
+ vector<WEdge *>::iterator we, weend;
+ vector<WEdge *> &wedges = iWShape->getEdgeList();
+ for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
+ ProcessBorderEdge((WXEdge *)(*we));
+ }
}
void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge)
{
- // first check whether it is a border edge: BORDER ?
- //---------
- if (iEdge->GetaFace() == 0) {
- // it is a border edge
- iEdge->AddNature(Nature::BORDER);
- }
+ // first check whether it is a border edge: BORDER ?
+ //---------
+ if (iEdge->GetaFace() == 0) {
+ // it is a border edge
+ iEdge->AddNature(Nature::BORDER);
+ }
}
-
// CREASE
/////////
void FEdgeXDetector::processCreaseShape(WXShape *iWShape)
{
- if (!_computeViewIndependent)
- return;
-
- // Make a pass on the edges to detect the CREASE
- vector<WEdge*>::iterator we, weend;
- vector<WEdge*> &wedges = iWShape->getEdgeList();
- for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
- ProcessCreaseEdge((WXEdge *)(*we));
- }
+ if (!_computeViewIndependent)
+ return;
+
+ // Make a pass on the edges to detect the CREASE
+ vector<WEdge *>::iterator we, weend;
+ vector<WEdge *> &wedges = iWShape->getEdgeList();
+ for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
+ ProcessCreaseEdge((WXEdge *)(*we));
+ }
}
void FEdgeXDetector::ProcessCreaseEdge(WXEdge *iEdge)
{
- // CREASE ?
- //---------
- if (iEdge->nature() & Nature::BORDER)
- return;
- WXFace *fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
- WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
-
- WVertex *aVertex = iEdge->GetaVertex();
- if ((fA->GetVertexNormal(aVertex) * fB->GetVertexNormal(aVertex)) <= _creaseAngle)
- iEdge->AddNature(Nature::CREASE);
+ // CREASE ?
+ //---------
+ if (iEdge->nature() & Nature::BORDER)
+ return;
+ WXFace *fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
+ WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
+
+ WVertex *aVertex = iEdge->GetaVertex();
+ if ((fA->GetVertexNormal(aVertex) * fB->GetVertexNormal(aVertex)) <= _creaseAngle)
+ iEdge->AddNature(Nature::CREASE);
}
// RIDGES AND VALLEYS
/////////////////////
void FEdgeXDetector::processRidgesAndValleysShape(WXShape *iWShape)
{
- // Don't forget to add the built layer to the face at the end of the ProcessFace:
- //iFace->AddSmoothLayer(faceLayer);
-
- if (!_computeViewIndependent)
- return;
-
- // Here the curvatures must already have been computed
- vector<WFace*>& wfaces = iWShape->GetFaceList();
- vector<WFace*>::iterator f, fend;
- for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
- ProcessRidgeFace((WXFace *)(*f));
- }
+ // Don't forget to add the built layer to the face at the end of the ProcessFace:
+ //iFace->AddSmoothLayer(faceLayer);
+
+ if (!_computeViewIndependent)
+ return;
+
+ // Here the curvatures must already have been computed
+ vector<WFace *> &wfaces = iWShape->GetFaceList();
+ vector<WFace *>::iterator f, fend;
+ for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
+ ProcessRidgeFace((WXFace *)(*f));
+ }
}
-
// RIDGES
/////////
void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
{
- WXFaceLayer *flayer = new WXFaceLayer(iFace, Nature::RIDGE | Nature::VALLEY, false);
- iFace->AddSmoothLayer(flayer);
-
- unsigned int numVertices = iFace->numberOfVertices();
- for (unsigned int i = 0; i < numVertices; ++i) {
- WVertex *wv = iFace->GetVertex(i);
- WXVertex *wxv = dynamic_cast<WXVertex*>(wv);
- flayer->PushDotP(wxv->curvatures()->K1);
- }
-
-#if 0 // XXX fabs(flayer->dotP(i)) < threshold cannot be true
- real threshold = 0;
- //real threshold = _maxK1 - (_maxK1 - _meanK1) / 20.0;
-
- if (flayer->nPosDotP() != numVertices) {
- if ((fabs(flayer->dotP(0)) < threshold) && (fabs(flayer->dotP(1)) < threshold) &&
- (fabs(flayer->dotP(2)) < threshold))
- {
- flayer->ReplaceDotP(0, 0);
- flayer->ReplaceDotP(1, 0);
- flayer->ReplaceDotP(2, 0);
- }
- }
+ WXFaceLayer *flayer = new WXFaceLayer(iFace, Nature::RIDGE | Nature::VALLEY, false);
+ iFace->AddSmoothLayer(flayer);
+
+ unsigned int numVertices = iFace->numberOfVertices();
+ for (unsigned int i = 0; i < numVertices; ++i) {
+ WVertex *wv = iFace->GetVertex(i);
+ WXVertex *wxv = dynamic_cast<WXVertex *>(wv);
+ flayer->PushDotP(wxv->curvatures()->K1);
+ }
+
+#if 0 // XXX fabs(flayer->dotP(i)) < threshold cannot be true
+ real threshold = 0;
+ //real threshold = _maxK1 - (_maxK1 - _meanK1) / 20.0;
+
+ if (flayer->nPosDotP() != numVertices) {
+ if ((fabs(flayer->dotP(0)) < threshold) && (fabs(flayer->dotP(1)) < threshold) &&
+ (fabs(flayer->dotP(2)) < threshold))
+ {
+ flayer->ReplaceDotP(0, 0);
+ flayer->ReplaceDotP(1, 0);
+ flayer->ReplaceDotP(2, 0);
+ }
+ }
#endif
}
#if 0
void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
{
- // RIDGE LAYER
- // Compute the RidgeFunction, that is the derivative of the ppal curvature along e1 at each vertex of the face
- WVertex *v;
- Vec3r v1v2;
- real t;
- vector<WXFaceLayer*> SmoothLayers;
- WXFaceLayer *faceLayer;
- Face_Curvature_Info *layer_info;
- real K1_a(0), K1_b(0);
- Vec3r Inter_a, Inter_b;
-
- // find the ridge layer of the face
- iFace->retrieveSmoothLayers(Nature::RIDGE, SmoothLayers);
- if ( SmoothLayers.size()!=1 )
- return;
- faceLayer = SmoothLayers[0];
- // retrieve the curvature info of this layer
- layer_info = (Face_Curvature_Info *)faceLayer->userdata;
-
- int numVertices = iFace->numberOfVertices();
- for (int i = 0; i < numVertices; i++) {
- v = iFace->GetVertex(i);
- // vec_curvature_info[i] contains the curvature info of this vertex
- Vec3r e2 = layer_info->vec_curvature_info[i]->K2*layer_info->vec_curvature_info[i]->e2;
- Vec3r e1 = layer_info->vec_curvature_info[i]->K1*layer_info->vec_curvature_info[i]->e1;
- e2.normalize();
-
- WVertex::face_iterator fit = v->faces_begin();
- WVertex::face_iterator fitend = v->faces_end();
- for (; fit != fitend; ++fit) {
- WXFace *wxf = dynamic_cast<WXFace*>(*fit);
- WOEdge *oppositeEdge;
- if (!(wxf->getOppositeEdge(v, oppositeEdge)))
- continue;
- v1v2 = oppositeEdge->GetbVertex()->GetVertex() - oppositeEdge->GetaVertex()->GetVertex();
- GeomUtils::intersection_test res;
- res = GeomUtils::intersectRayPlane(oppositeEdge->GetaVertex()->GetVertex(), v1v2, e2, -(v->GetVertex()*e2),
- t, 1.0e-06);
- if ((res == GeomUtils::DO_INTERSECT) && (t >= 0.0) && (t <= 1.0)) {
- vector<WXFaceLayer*> second_ridge_layer;
- wxf->retrieveSmoothLayers(Nature::RIDGE, second_ridge_layer);
- if (second_ridge_layer.size() != 1)
- continue;
- Face_Curvature_Info *second_layer_info = (Face_Curvature_Info*)second_ridge_layer[0]->userdata;
-
- unsigned index1 = wxf->GetIndex(oppositeEdge->GetaVertex());
- unsigned index2 = wxf->GetIndex(oppositeEdge->GetbVertex());
- real K1_1 = second_layer_info->vec_curvature_info[index1]->K1;
- real K1_2 = second_layer_info->vec_curvature_info[index2]->K1;
- real K1 = (1.0 - t) * K1_1 + t * K1_2;
- Vec3r inter((1.0 - t) * oppositeEdge->GetaVertex()->GetVertex() +
- t * oppositeEdge->GetbVertex()->GetVertex());
- Vec3r vtmp(inter - v->GetVertex());
- // is it K1_a or K1_b ?
- if (vtmp * e1 > 0) {
- K1_b = K1;
- Inter_b = inter;
- }
- else {
- K1_a = K1;
- Inter_a = inter;
- }
- }
- }
- // Once we have K1 along the ppal direction compute the derivative : K1b - K1a put it in DotP
- //real d = fabs(K1_b) - fabs(K1_a);
- real d = 0;
- real threshold = _meanK1 + (_maxK1 - _meanK1) / 7.0;
- //real threshold = _meanK1;
- //if ((fabs(K1_b) > threshold) || ((fabs(K1_a) > threshold)))
- d = (K1_b) - (K1_a) / (Inter_b - Inter_a).norm();
- faceLayer->PushDotP(d);
- //faceLayer->PushDotP(layer_info->vec_curvature_info[i]->K1);
- }
-
- // Make the values relevant by checking whether all principal directions have the "same" direction:
- Vec3r e0((layer_info->vec_curvature_info[0]->K1 * layer_info->vec_curvature_info[0]->e1));
- e0.normalize();
- Vec3r e1((layer_info->vec_curvature_info[1]->K1 * layer_info->vec_curvature_info[1]->e1));
- e1.normalize();
- Vec3r e2((layer_info->vec_curvature_info[2]->K1 * layer_info->vec_curvature_info[2]->e1));
- e2.normalize();
- if (e0 * e1 < 0)
- // invert dotP[1]
- faceLayer->ReplaceDotP(1, -faceLayer->dotP(1));
- if (e0 * e2 < 0)
- // invert dotP[2]
- faceLayer->ReplaceDotP(2, -faceLayer->dotP(2));
-
-#if 0 // remove the weakest values;
- real minDiff = (_maxK1 - _minK1) / 10.0;
- real minDiff = _meanK1;
- if ((faceLayer->dotP(0) < minDiff) && (faceLayer->dotP(1) < minDiff) && (faceLayer->dotP(2) < minDiff)) {
- faceLayer->ReplaceDotP(0, 0);
- faceLayer->ReplaceDotP(1, 0);
- faceLayer->ReplaceDotP(2, 0);
- }
-#endif
+ // RIDGE LAYER
+ // Compute the RidgeFunction, that is the derivative of the ppal curvature along e1 at each vertex of the face
+ WVertex *v;
+ Vec3r v1v2;
+ real t;
+ vector<WXFaceLayer*> SmoothLayers;
+ WXFaceLayer *faceLayer;
+ Face_Curvature_Info *layer_info;
+ real K1_a(0), K1_b(0);
+ Vec3r Inter_a, Inter_b;
+
+ // find the ridge layer of the face
+ iFace->retrieveSmoothLayers(Nature::RIDGE, SmoothLayers);
+ if ( SmoothLayers.size()!=1 )
+ return;
+ faceLayer = SmoothLayers[0];
+ // retrieve the curvature info of this layer
+ layer_info = (Face_Curvature_Info *)faceLayer->userdata;
+
+ int numVertices = iFace->numberOfVertices();
+ for (int i = 0; i < numVertices; i++) {
+ v = iFace->GetVertex(i);
+ // vec_curvature_info[i] contains the curvature info of this vertex
+ Vec3r e2 = layer_info->vec_curvature_info[i]->K2*layer_info->vec_curvature_info[i]->e2;
+ Vec3r e1 = layer_info->vec_curvature_info[i]->K1*layer_info->vec_curvature_info[i]->e1;
+ e2.normalize();
+
+ WVertex::face_iterator fit = v->faces_begin();
+ WVertex::face_iterator fitend = v->faces_end();
+ for (; fit != fitend; ++fit) {
+ WXFace *wxf = dynamic_cast<WXFace*>(*fit);
+ WOEdge *oppositeEdge;
+ if (!(wxf->getOppositeEdge(v, oppositeEdge)))
+ continue;
+ v1v2 = oppositeEdge->GetbVertex()->GetVertex() - oppositeEdge->GetaVertex()->GetVertex();
+ GeomUtils::intersection_test res;
+ res = GeomUtils::intersectRayPlane(oppositeEdge->GetaVertex()->GetVertex(), v1v2, e2, -(v->GetVertex()*e2),
+ t, 1.0e-06);
+ if ((res == GeomUtils::DO_INTERSECT) && (t >= 0.0) && (t <= 1.0)) {
+ vector<WXFaceLayer*> second_ridge_layer;
+ wxf->retrieveSmoothLayers(Nature::RIDGE, second_ridge_layer);
+ if (second_ridge_layer.size() != 1)
+ continue;
+ Face_Curvature_Info *second_layer_info = (Face_Curvature_Info*)second_ridge_layer[0]->userdata;
+
+ unsigned index1 = wxf->GetIndex(oppositeEdge->GetaVertex());
+ unsigned index2 = wxf->GetIndex(oppositeEdge->GetbVertex());
+ real K1_1 = second_layer_info->vec_curvature_info[index1]->K1;
+ real K1_2 = second_layer_info->vec_curvature_info[index2]->K1;
+ real K1 = (1.0 - t) * K1_1 + t * K1_2;
+ Vec3r inter((1.0 - t) * oppositeEdge->GetaVertex()->GetVertex() +
+ t * oppositeEdge->GetbVertex()->GetVertex());
+ Vec3r vtmp(inter - v->GetVertex());
+ // is it K1_a or K1_b ?
+ if (vtmp * e1 > 0) {
+ K1_b = K1;
+ Inter_b = inter;
+ }
+ else {
+ K1_a = K1;
+ Inter_a = inter;
+ }
+ }
+ }
+ // Once we have K1 along the ppal direction compute the derivative : K1b - K1a put it in DotP
+ //real d = fabs(K1_b) - fabs(K1_a);
+ real d = 0;
+ real threshold = _meanK1 + (_maxK1 - _meanK1) / 7.0;
+ //real threshold = _meanK1;
+ //if ((fabs(K1_b) > threshold) || ((fabs(K1_a) > threshold)))
+ d = (K1_b) - (K1_a) / (Inter_b - Inter_a).norm();
+ faceLayer->PushDotP(d);
+ //faceLayer->PushDotP(layer_info->vec_curvature_info[i]->K1);
+ }
+
+ // Make the values relevant by checking whether all principal directions have the "same" direction:
+ Vec3r e0((layer_info->vec_curvature_info[0]->K1 * layer_info->vec_curvature_info[0]->e1));
+ e0.normalize();
+ Vec3r e1((layer_info->vec_curvature_info[1]->K1 * layer_info->vec_curvature_info[1]->e1));
+ e1.normalize();
+ Vec3r e2((layer_info->vec_curvature_info[2]->K1 * layer_info->vec_curvature_info[2]->e1));
+ e2.normalize();
+ if (e0 * e1 < 0)
+ // invert dotP[1]
+ faceLayer->ReplaceDotP(1, -faceLayer->dotP(1));
+ if (e0 * e2 < 0)
+ // invert dotP[2]
+ faceLayer->ReplaceDotP(2, -faceLayer->dotP(2));
+
+# if 0 // remove the weakest values;
+ real minDiff = (_maxK1 - _minK1) / 10.0;
+ real minDiff = _meanK1;
+ if ((faceLayer->dotP(0) < minDiff) && (faceLayer->dotP(1) < minDiff) && (faceLayer->dotP(2) < minDiff)) {
+ faceLayer->ReplaceDotP(0, 0);
+ faceLayer->ReplaceDotP(1, 0);
+ faceLayer->ReplaceDotP(2, 0);
+ }
+# endif
}
#endif
@@ -543,221 +544,226 @@ void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
void FEdgeXDetector::processSuggestiveContourShape(WXShape *iWShape)
{
- // Here the curvatures must already have been computed
- vector<WFace*>& wfaces = iWShape->GetFaceList();
- vector<WFace*>::iterator f, fend;
- for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
- ProcessSuggestiveContourFace((WXFace *)(*f));
- }
+ // Here the curvatures must already have been computed
+ vector<WFace *> &wfaces = iWShape->GetFaceList();
+ vector<WFace *>::iterator f, fend;
+ for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
+ ProcessSuggestiveContourFace((WXFace *)(*f));
+ }
}
void FEdgeXDetector::ProcessSuggestiveContourFace(WXFace *iFace)
{
- WXFaceLayer *faceLayer = new WXFaceLayer(iFace, Nature::SUGGESTIVE_CONTOUR, true);
- iFace->AddSmoothLayer(faceLayer);
-
- unsigned int numVertices = iFace->numberOfVertices();
- for (unsigned int i = 0; i < numVertices; ++i) {
- WVertex *wv = iFace->GetVertex(i);
- WXVertex *wxv = dynamic_cast<WXVertex*>(wv);
- faceLayer->PushDotP(wxv->curvatures()->Kr);
- }
-
-#if 0 // FIXME: find a more clever way to compute the threshold
- real threshold = _meanKr;
- if (faceLayer->nPosDotP()!=numVertices) {
- if ((fabs(faceLayer->dotP(0)) < threshold) && (fabs(faceLayer->dotP(1)) < threshold) &&
- (fabs(faceLayer->dotP(2)) < threshold))
- {
- faceLayer->ReplaceDotP(0, 0);
- faceLayer->ReplaceDotP(1, 0);
- faceLayer->ReplaceDotP(2, 0);
- }
- }
+ WXFaceLayer *faceLayer = new WXFaceLayer(iFace, Nature::SUGGESTIVE_CONTOUR, true);
+ iFace->AddSmoothLayer(faceLayer);
+
+ unsigned int numVertices = iFace->numberOfVertices();
+ for (unsigned int i = 0; i < numVertices; ++i) {
+ WVertex *wv = iFace->GetVertex(i);
+ WXVertex *wxv = dynamic_cast<WXVertex *>(wv);
+ faceLayer->PushDotP(wxv->curvatures()->Kr);
+ }
+
+#if 0 // FIXME: find a more clever way to compute the threshold
+ real threshold = _meanKr;
+ if (faceLayer->nPosDotP()!=numVertices) {
+ if ((fabs(faceLayer->dotP(0)) < threshold) && (fabs(faceLayer->dotP(1)) < threshold) &&
+ (fabs(faceLayer->dotP(2)) < threshold))
+ {
+ faceLayer->ReplaceDotP(0, 0);
+ faceLayer->ReplaceDotP(1, 0);
+ faceLayer->ReplaceDotP(2, 0);
+ }
+ }
#endif
}
void FEdgeXDetector::postProcessSuggestiveContourShape(WXShape *iShape)
{
- vector<WFace*>& wfaces = iShape->GetFaceList();
- vector<WFace*>::iterator f, fend;
- for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
- postProcessSuggestiveContourFace((WXFace *)(*f));
- }
+ vector<WFace *> &wfaces = iShape->GetFaceList();
+ vector<WFace *>::iterator f, fend;
+ for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
+ postProcessSuggestiveContourFace((WXFace *)(*f));
+ }
}
void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace)
{
- // Compute the derivative of the radial curvature in the radial direction, at the two extremities
- // of the smooth edge.
- // If the derivative is smaller than a given threshold _kr_derivative_epsilon, discard the edge.
-
- // Find the suggestive contour layer of the face (zero or one edge).
- vector<WXFaceLayer*> sc_layers;
- iFace->retrieveSmoothEdgesLayers(Nature::SUGGESTIVE_CONTOUR, sc_layers);
- if (sc_layers.empty())
- return;
-
- WXFaceLayer *sc_layer;
- sc_layer = sc_layers[0];
-
- // Compute the derivative value at each vertex of the face, and add it in a vector.
- vector<real> kr_derivatives;
-
- unsigned vertices_nb = iFace->numberOfVertices();
- WXVertex *v, *opposite_vertex_a, *opposite_vertex_b;
- WXFace *wxf;
- WOEdge *opposite_edge;
- Vec3r normal_vec, radial_normal_vec, er_vec, v_vec, inter, inter1, inter2, tmp_vec;
- GeomUtils::intersection_test res;
- real kr(0), kr1(0), kr2(0), t;
-
- for (unsigned int i = 0; i < vertices_nb; ++i) {
- v = (WXVertex *)(iFace->GetVertex(i));
-
- // v is a singular vertex, skip it.
- if (v->isBoundary()) {
- kr_derivatives.push_back(0);
- continue;
- }
-
- v_vec = v->GetVertex();
- er_vec = v->curvatures()->er;
-
- // For each vertex, iterate on its adjacent faces.
- for (WVertex::face_iterator fit = v->faces_begin(), fitend = v->faces_end(); fit != fitend; ++fit) {
- wxf = dynamic_cast<WXFace*>(*fit);
- if (!wxf->getOppositeEdge(v, opposite_edge))
- continue;
-
- opposite_vertex_a = (WXVertex *)opposite_edge->GetaVertex();
- opposite_vertex_b = (WXVertex *)opposite_edge->GetbVertex();
- normal_vec = wxf->GetVertexNormal(v); // FIXME: what about e1 ^ e2 ?
- radial_normal_vec = er_vec ^ normal_vec;
-
- // Test whether the radial plan intersects with the edge at the opposite of v.
- res = GeomUtils::intersectRayPlane(opposite_vertex_a->GetVertex(), opposite_edge->GetVec(),
- radial_normal_vec, -(v_vec * radial_normal_vec),
- t, 1.0e-06);
-
- // If there is an intersection, compute the value of the derivative ath that point.
- if ((res == GeomUtils::DO_INTERSECT) && (t >= 0) && (t <= 1)) {
- kr = t * opposite_vertex_a->curvatures()->Kr + (1 - t) * opposite_vertex_b->curvatures()->Kr;
- inter = opposite_vertex_a->GetVertex() + t * opposite_edge->GetVec();
- tmp_vec = inter - v->GetVertex();
- // Is it kr1 or kr2?
- if (tmp_vec * er_vec > 0) {
- kr2 = kr;
- inter2 = inter;
- }
- else {
- kr1 = kr;
- inter1 = inter;
- }
- }
- }
-
- // Now we have kr1 and kr2 along the radial direction, for one vertex of iFace.
- // We have to compute the derivative of kr for that vertex, equal to:
- // (kr2 - kr1) / dist(inter1, inter2).
- // Then we add it to the vector of derivatives.
- v->curvatures()->dKr = (kr2 - kr1) / (inter2 - inter1).norm();
- kr_derivatives.push_back(v->curvatures()->dKr);
- }
-
- // At that point, we have the derivatives for each vertex of iFace.
- // All we have to do now is to use linear interpolation to compute the values at the extremities of the smooth edge.
- WXSmoothEdge *sc_edge = sc_layer->getSmoothEdge();
- WOEdge *sc_oedge = sc_edge->woea();
- t = sc_edge->ta();
- if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
- (1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon)
- {
- sc_layer->removeSmoothEdge();
- return;
- }
- sc_oedge = sc_edge->woeb();
- t = sc_edge->tb();
- if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
- (1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon)
- {
- sc_layer->removeSmoothEdge();
- }
+ // Compute the derivative of the radial curvature in the radial direction, at the two extremities
+ // of the smooth edge.
+ // If the derivative is smaller than a given threshold _kr_derivative_epsilon, discard the edge.
+
+ // Find the suggestive contour layer of the face (zero or one edge).
+ vector<WXFaceLayer *> sc_layers;
+ iFace->retrieveSmoothEdgesLayers(Nature::SUGGESTIVE_CONTOUR, sc_layers);
+ if (sc_layers.empty())
+ return;
+
+ WXFaceLayer *sc_layer;
+ sc_layer = sc_layers[0];
+
+ // Compute the derivative value at each vertex of the face, and add it in a vector.
+ vector<real> kr_derivatives;
+
+ unsigned vertices_nb = iFace->numberOfVertices();
+ WXVertex *v, *opposite_vertex_a, *opposite_vertex_b;
+ WXFace *wxf;
+ WOEdge *opposite_edge;
+ Vec3r normal_vec, radial_normal_vec, er_vec, v_vec, inter, inter1, inter2, tmp_vec;
+ GeomUtils::intersection_test res;
+ real kr(0), kr1(0), kr2(0), t;
+
+ for (unsigned int i = 0; i < vertices_nb; ++i) {
+ v = (WXVertex *)(iFace->GetVertex(i));
+
+ // v is a singular vertex, skip it.
+ if (v->isBoundary()) {
+ kr_derivatives.push_back(0);
+ continue;
+ }
+
+ v_vec = v->GetVertex();
+ er_vec = v->curvatures()->er;
+
+ // For each vertex, iterate on its adjacent faces.
+ for (WVertex::face_iterator fit = v->faces_begin(), fitend = v->faces_end(); fit != fitend;
+ ++fit) {
+ wxf = dynamic_cast<WXFace *>(*fit);
+ if (!wxf->getOppositeEdge(v, opposite_edge))
+ continue;
+
+ opposite_vertex_a = (WXVertex *)opposite_edge->GetaVertex();
+ opposite_vertex_b = (WXVertex *)opposite_edge->GetbVertex();
+ normal_vec = wxf->GetVertexNormal(v); // FIXME: what about e1 ^ e2 ?
+ radial_normal_vec = er_vec ^ normal_vec;
+
+ // Test whether the radial plan intersects with the edge at the opposite of v.
+ res = GeomUtils::intersectRayPlane(opposite_vertex_a->GetVertex(),
+ opposite_edge->GetVec(),
+ radial_normal_vec,
+ -(v_vec * radial_normal_vec),
+ t,
+ 1.0e-06);
+
+ // If there is an intersection, compute the value of the derivative ath that point.
+ if ((res == GeomUtils::DO_INTERSECT) && (t >= 0) && (t <= 1)) {
+ kr = t * opposite_vertex_a->curvatures()->Kr +
+ (1 - t) * opposite_vertex_b->curvatures()->Kr;
+ inter = opposite_vertex_a->GetVertex() + t * opposite_edge->GetVec();
+ tmp_vec = inter - v->GetVertex();
+ // Is it kr1 or kr2?
+ if (tmp_vec * er_vec > 0) {
+ kr2 = kr;
+ inter2 = inter;
+ }
+ else {
+ kr1 = kr;
+ inter1 = inter;
+ }
+ }
+ }
+
+ // Now we have kr1 and kr2 along the radial direction, for one vertex of iFace.
+ // We have to compute the derivative of kr for that vertex, equal to:
+ // (kr2 - kr1) / dist(inter1, inter2).
+ // Then we add it to the vector of derivatives.
+ v->curvatures()->dKr = (kr2 - kr1) / (inter2 - inter1).norm();
+ kr_derivatives.push_back(v->curvatures()->dKr);
+ }
+
+ // At that point, we have the derivatives for each vertex of iFace.
+ // All we have to do now is to use linear interpolation to compute the values at the extremities of the smooth edge.
+ WXSmoothEdge *sc_edge = sc_layer->getSmoothEdge();
+ WOEdge *sc_oedge = sc_edge->woea();
+ t = sc_edge->ta();
+ if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
+ (1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] <
+ _kr_derivative_epsilon) {
+ sc_layer->removeSmoothEdge();
+ return;
+ }
+ sc_oedge = sc_edge->woeb();
+ t = sc_edge->tb();
+ if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
+ (1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] <
+ _kr_derivative_epsilon) {
+ sc_layer->removeSmoothEdge();
+ }
}
// MATERIAL_BOUNDARY
////////////////////
void FEdgeXDetector::processMaterialBoundaryShape(WXShape *iWShape)
{
- if (!_computeViewIndependent)
- return;
- // Make a pass on the edges to detect material boundaries
- vector<WEdge*>::iterator we, weend;
- vector<WEdge*> &wedges = iWShape->getEdgeList();
- for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
- ProcessMaterialBoundaryEdge((WXEdge *)(*we));
- }
+ if (!_computeViewIndependent)
+ return;
+ // Make a pass on the edges to detect material boundaries
+ vector<WEdge *>::iterator we, weend;
+ vector<WEdge *> &wedges = iWShape->getEdgeList();
+ for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
+ ProcessMaterialBoundaryEdge((WXEdge *)(*we));
+ }
}
void FEdgeXDetector::ProcessMaterialBoundaryEdge(WXEdge *iEdge)
{
- // check whether the edge is a material boundary?
- WFace *aFace = iEdge->GetaFace();
- WFace *bFace = iEdge->GetbFace();
- if (aFace && bFace && aFace->frs_materialIndex() != bFace->frs_materialIndex()) {
- iEdge->AddNature(Nature::MATERIAL_BOUNDARY);
- }
+ // check whether the edge is a material boundary?
+ WFace *aFace = iEdge->GetaFace();
+ WFace *bFace = iEdge->GetbFace();
+ if (aFace && bFace && aFace->frs_materialIndex() != bFace->frs_materialIndex()) {
+ iEdge->AddNature(Nature::MATERIAL_BOUNDARY);
+ }
}
// EDGE MARKS
/////////////
void FEdgeXDetector::processEdgeMarksShape(WXShape *iShape)
{
- // Make a pass on the edges to detect material boundaries
- vector<WEdge*>::iterator we, weend;
- vector<WEdge*> &wedges = iShape->getEdgeList();
- for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
- ProcessEdgeMarks((WXEdge *)(*we));
- }
+ // Make a pass on the edges to detect material boundaries
+ vector<WEdge *>::iterator we, weend;
+ vector<WEdge *> &wedges = iShape->getEdgeList();
+ for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
+ ProcessEdgeMarks((WXEdge *)(*we));
+ }
}
void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge)
{
- if (iEdge->GetMark()) {
- iEdge->AddNature(Nature::EDGE_MARK);
- }
+ if (iEdge->GetMark()) {
+ iEdge->AddNature(Nature::EDGE_MARK);
+ }
}
// Build Smooth edges
/////////////////////
void FEdgeXDetector::buildSmoothEdges(WXShape *iShape)
{
- bool hasSmoothEdges = false;
-
- // Make a last pass to build smooth edges from the previous stored values:
- //--------------------------------------------------------------------------
- vector<WFace*>& wfaces = iShape->GetFaceList();
- for (vector<WFace *>::iterator f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
- vector<WXFaceLayer *>& faceLayers = ((WXFace *)(*f))->getSmoothLayers();
- for (vector<WXFaceLayer *>::iterator wxfl = faceLayers.begin(), wxflend = faceLayers.end();
- wxfl != wxflend;
- ++wxfl)
- {
- if ((*wxfl)->BuildSmoothEdge())
- hasSmoothEdges = true;
- }
- }
-
- if (hasSmoothEdges && !_computeRidgesAndValleys && !_computeSuggestiveContours) {
- vector<WVertex *>& wvertices = iShape->getVertexList();
- for (vector<WVertex*>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
- // Compute curvatures
- WXVertex *wxv = dynamic_cast<WXVertex *>(*wv);
- computeCurvatures(wxv);
- }
- _meanK1 /= (real)(_nPoints);
- _meanKr /= (real)(_nPoints);
- }
+ bool hasSmoothEdges = false;
+
+ // Make a last pass to build smooth edges from the previous stored values:
+ //--------------------------------------------------------------------------
+ vector<WFace *> &wfaces = iShape->GetFaceList();
+ for (vector<WFace *>::iterator f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
+ vector<WXFaceLayer *> &faceLayers = ((WXFace *)(*f))->getSmoothLayers();
+ for (vector<WXFaceLayer *>::iterator wxfl = faceLayers.begin(), wxflend = faceLayers.end();
+ wxfl != wxflend;
+ ++wxfl) {
+ if ((*wxfl)->BuildSmoothEdge())
+ hasSmoothEdges = true;
+ }
+ }
+
+ if (hasSmoothEdges && !_computeRidgesAndValleys && !_computeSuggestiveContours) {
+ vector<WVertex *> &wvertices = iShape->getVertexList();
+ for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend;
+ ++wv) {
+ // Compute curvatures
+ WXVertex *wxv = dynamic_cast<WXVertex *>(*wv);
+ computeCurvatures(wxv);
+ }
+ _meanK1 /= (real)(_nPoints);
+ _meanKr /= (real)(_nPoints);
+ }
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
index 9143a2b507d..61e0c9267a1 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
@@ -36,7 +36,7 @@
#include "BLI_math.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
@@ -44,203 +44,204 @@ namespace Freestyle {
using namespace Geometry;
/*! This class takes as input a WXEdge structure and fills it */
-class FEdgeXDetector
-{
-public:
- FEdgeXDetector()
- {
- _pProgressBar = NULL;
- _pRenderMonitor = NULL;
- _computeViewIndependent = true;
+class FEdgeXDetector {
+ public:
+ FEdgeXDetector()
+ {
+ _pProgressBar = NULL;
+ _pRenderMonitor = NULL;
+ _computeViewIndependent = true;
#if 0
- _bbox_diagonal = 1.0;
+ _bbox_diagonal = 1.0;
#endif
- _meanEdgeSize = 0;
- _computeRidgesAndValleys = true;
- _computeSuggestiveContours = true;
- _computeMaterialBoundaries = true;
- _sphereRadius = 1.0;
- _orthographicProjection = false;
- _faceSmoothness = false;
- _changes = false;
- _kr_derivative_epsilon = 0.0;
- _creaseAngle = 0.7; // angle of 134.43 degrees
- }
-
- virtual ~FEdgeXDetector() {}
-
- /*! Process shapes from a WingedEdge containing a list of WShapes */
- virtual void processShapes(WingedEdge&);
-
- // GENERAL STUFF
- virtual void preProcessShape(WXShape *iShape);
- virtual void preProcessFace(WXFace *iFace);
- virtual void computeCurvatures(WXVertex *iVertex);
-
- // SILHOUETTE
- virtual void processSilhouetteShape(WXShape *iShape);
- virtual void ProcessSilhouetteFace(WXFace *iFace);
- virtual void ProcessSilhouetteEdge(WXEdge *iEdge);
-
- // CREASE
- virtual void processCreaseShape(WXShape *iShape);
- virtual void ProcessCreaseEdge(WXEdge *iEdge);
-
- /*! Sets the minimum angle for detecting crease edges
- * \param angle:
- * The angular threshold in degrees (between 0 and 180) for detecting crease edges. An edge is considered
- * a crease edge if the angle between two faces sharing the edge is smaller than the given threshold.
- */
- // XXX angle should be in radian...
- inline void setCreaseAngle(float angle)
- {
- if (angle < 0.0)
- angle = 0.0;
- else if (angle > 180.0)
- angle = 180.0;
- angle = cos(M_PI * (180.0 - angle) / 180.0);
- if (angle != _creaseAngle) {
- _creaseAngle = angle;
- _changes = true;
- }
- }
-
- // BORDER
- virtual void processBorderShape(WXShape *iShape);
- virtual void ProcessBorderEdge(WXEdge *iEdge);
-
- // RIDGES AND VALLEYS
- virtual void processRidgesAndValleysShape(WXShape *iShape);
- virtual void ProcessRidgeFace(WXFace *iFace);
-
- // SUGGESTIVE CONTOURS
- virtual void processSuggestiveContourShape(WXShape *iShape);
- virtual void ProcessSuggestiveContourFace(WXFace *iFace);
- virtual void postProcessSuggestiveContourShape(WXShape *iShape);
- virtual void postProcessSuggestiveContourFace(WXFace *iFace);
- /*! Sets the minimal derivative of the radial curvature for suggestive contours
- * \param dkr:
- * The minimal derivative of the radial curvature
- */
- inline void setSuggestiveContourKrDerivativeEpsilon(float dkr)
- {
- if (dkr != _kr_derivative_epsilon) {
- _kr_derivative_epsilon = dkr;
- _changes = true;
- }
- }
-
- // MATERIAL BOUNDARY
- virtual void processMaterialBoundaryShape(WXShape *iWShape);
- virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge);
-
- // EDGE MARKS
- virtual void processEdgeMarksShape(WXShape *iShape);
- virtual void ProcessEdgeMarks(WXEdge *iEdge);
-
- // EVERYBODY
- virtual void buildSmoothEdges(WXShape *iShape);
-
- /*! Sets the current viewpoint */
- inline void setViewpoint(const Vec3f& ivp)
- {
- _Viewpoint = ivp;
- }
-
- inline void enableOrthographicProjection(bool b)
- {
- _orthographicProjection = b;
- }
-
- inline void enableRidgesAndValleysFlag(bool b)
- {
- _computeRidgesAndValleys = b;
- }
-
- inline void enableSuggestiveContours(bool b)
- {
- _computeSuggestiveContours = b;
- }
-
- inline void enableMaterialBoundaries(bool b)
- {
- _computeMaterialBoundaries = b;
- }
-
- inline void enableFaceSmoothness(bool b)
- {
- if (b != _faceSmoothness) {
- _faceSmoothness = b;
- _changes = true;
- }
- }
-
- inline void enableFaceMarks(bool b)
- {
- if (b != _faceMarks) {
- _faceMarks = b;
- _changes = true;
- }
- }
-
- /*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation)
- * \param r:
- * The radius of the sphere expressed as a ratio of the mean edge size
- */
- inline void setSphereRadius(float r)
- {
- if (r != _sphereRadius) {
- _sphereRadius = r;
- _changes = true;
- }
- }
-
- inline void setProgressBar(ProgressBar *iProgressBar)
- {
- _pProgressBar = iProgressBar;
- }
-
- inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
- {
- _pRenderMonitor = iRenderMonitor;
- }
-
-protected:
- Vec3f _Viewpoint;
+ _meanEdgeSize = 0;
+ _computeRidgesAndValleys = true;
+ _computeSuggestiveContours = true;
+ _computeMaterialBoundaries = true;
+ _sphereRadius = 1.0;
+ _orthographicProjection = false;
+ _faceSmoothness = false;
+ _changes = false;
+ _kr_derivative_epsilon = 0.0;
+ _creaseAngle = 0.7; // angle of 134.43 degrees
+ }
+
+ virtual ~FEdgeXDetector()
+ {
+ }
+
+ /*! Process shapes from a WingedEdge containing a list of WShapes */
+ virtual void processShapes(WingedEdge &);
+
+ // GENERAL STUFF
+ virtual void preProcessShape(WXShape *iShape);
+ virtual void preProcessFace(WXFace *iFace);
+ virtual void computeCurvatures(WXVertex *iVertex);
+
+ // SILHOUETTE
+ virtual void processSilhouetteShape(WXShape *iShape);
+ virtual void ProcessSilhouetteFace(WXFace *iFace);
+ virtual void ProcessSilhouetteEdge(WXEdge *iEdge);
+
+ // CREASE
+ virtual void processCreaseShape(WXShape *iShape);
+ virtual void ProcessCreaseEdge(WXEdge *iEdge);
+
+ /*! Sets the minimum angle for detecting crease edges
+ * \param angle:
+ * The angular threshold in degrees (between 0 and 180) for detecting crease edges. An edge is considered
+ * a crease edge if the angle between two faces sharing the edge is smaller than the given threshold.
+ */
+ // XXX angle should be in radian...
+ inline void setCreaseAngle(float angle)
+ {
+ if (angle < 0.0)
+ angle = 0.0;
+ else if (angle > 180.0)
+ angle = 180.0;
+ angle = cos(M_PI * (180.0 - angle) / 180.0);
+ if (angle != _creaseAngle) {
+ _creaseAngle = angle;
+ _changes = true;
+ }
+ }
+
+ // BORDER
+ virtual void processBorderShape(WXShape *iShape);
+ virtual void ProcessBorderEdge(WXEdge *iEdge);
+
+ // RIDGES AND VALLEYS
+ virtual void processRidgesAndValleysShape(WXShape *iShape);
+ virtual void ProcessRidgeFace(WXFace *iFace);
+
+ // SUGGESTIVE CONTOURS
+ virtual void processSuggestiveContourShape(WXShape *iShape);
+ virtual void ProcessSuggestiveContourFace(WXFace *iFace);
+ virtual void postProcessSuggestiveContourShape(WXShape *iShape);
+ virtual void postProcessSuggestiveContourFace(WXFace *iFace);
+ /*! Sets the minimal derivative of the radial curvature for suggestive contours
+ * \param dkr:
+ * The minimal derivative of the radial curvature
+ */
+ inline void setSuggestiveContourKrDerivativeEpsilon(float dkr)
+ {
+ if (dkr != _kr_derivative_epsilon) {
+ _kr_derivative_epsilon = dkr;
+ _changes = true;
+ }
+ }
+
+ // MATERIAL BOUNDARY
+ virtual void processMaterialBoundaryShape(WXShape *iWShape);
+ virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge);
+
+ // EDGE MARKS
+ virtual void processEdgeMarksShape(WXShape *iShape);
+ virtual void ProcessEdgeMarks(WXEdge *iEdge);
+
+ // EVERYBODY
+ virtual void buildSmoothEdges(WXShape *iShape);
+
+ /*! Sets the current viewpoint */
+ inline void setViewpoint(const Vec3f &ivp)
+ {
+ _Viewpoint = ivp;
+ }
+
+ inline void enableOrthographicProjection(bool b)
+ {
+ _orthographicProjection = b;
+ }
+
+ inline void enableRidgesAndValleysFlag(bool b)
+ {
+ _computeRidgesAndValleys = b;
+ }
+
+ inline void enableSuggestiveContours(bool b)
+ {
+ _computeSuggestiveContours = b;
+ }
+
+ inline void enableMaterialBoundaries(bool b)
+ {
+ _computeMaterialBoundaries = b;
+ }
+
+ inline void enableFaceSmoothness(bool b)
+ {
+ if (b != _faceSmoothness) {
+ _faceSmoothness = b;
+ _changes = true;
+ }
+ }
+
+ inline void enableFaceMarks(bool b)
+ {
+ if (b != _faceMarks) {
+ _faceMarks = b;
+ _changes = true;
+ }
+ }
+
+ /*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation)
+ * \param r:
+ * The radius of the sphere expressed as a ratio of the mean edge size
+ */
+ inline void setSphereRadius(float r)
+ {
+ if (r != _sphereRadius) {
+ _sphereRadius = r;
+ _changes = true;
+ }
+ }
+
+ inline void setProgressBar(ProgressBar *iProgressBar)
+ {
+ _pProgressBar = iProgressBar;
+ }
+
+ inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
+ {
+ _pRenderMonitor = iRenderMonitor;
+ }
+
+ protected:
+ Vec3f _Viewpoint;
#if 0
- real _bbox_diagonal; // diagonal of the current processed shape bbox
+ real _bbox_diagonal; // diagonal of the current processed shape bbox
#endif
- //oldtmp values
- bool _computeViewIndependent;
- real _meanK1;
- real _meanKr;
- real _minK1;
- real _minKr;
- real _maxK1;
- real _maxKr;
- unsigned _nPoints;
- real _meanEdgeSize;
- bool _orthographicProjection;
-
- bool _computeRidgesAndValleys;
- bool _computeSuggestiveContours;
- bool _computeMaterialBoundaries;
- bool _faceSmoothness;
- bool _faceMarks;
- float _sphereRadius; // expressed as a ratio of the mean edge size
- float _creaseAngle; // [-1, 1] compared with the inner product of face normals
- bool _changes;
-
- float _kr_derivative_epsilon;
-
- ProgressBar *_pProgressBar;
- RenderMonitor *_pRenderMonitor;
+ //oldtmp values
+ bool _computeViewIndependent;
+ real _meanK1;
+ real _meanKr;
+ real _minK1;
+ real _minKr;
+ real _maxK1;
+ real _maxKr;
+ unsigned _nPoints;
+ real _meanEdgeSize;
+ bool _orthographicProjection;
+
+ bool _computeRidgesAndValleys;
+ bool _computeSuggestiveContours;
+ bool _computeMaterialBoundaries;
+ bool _faceSmoothness;
+ bool _faceMarks;
+ float _sphereRadius; // expressed as a ratio of the mean edge size
+ float _creaseAngle; // [-1, 1] compared with the inner product of face normals
+ bool _changes;
+
+ float _kr_derivative_epsilon;
+
+ ProgressBar *_pProgressBar;
+ RenderMonitor *_pRenderMonitor;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeXDetector")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeXDetector")
#endif
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_FEDGE_X_DETECTOR_H__
+#endif // __FREESTYLE_FEDGE_X_DETECTOR_H__
diff --git a/source/blender/freestyle/intern/view_map/Functions0D.cpp b/source/blender/freestyle/intern/view_map/Functions0D.cpp
index aca8fce2983..5b04b66eeeb 100644
--- a/source/blender/freestyle/intern/view_map/Functions0D.cpp
+++ b/source/blender/freestyle/intern/view_map/Functions0D.cpp
@@ -31,336 +31,338 @@ namespace Freestyle {
namespace Functions0D {
// Internal function
-FEdge *getFEdge(Interface0D& it1, Interface0D& it2)
+FEdge *getFEdge(Interface0D &it1, Interface0D &it2)
{
- return it1.getFEdge(it2);
+ return it1.getFEdge(it2);
}
-void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2)
+void getFEdges(Interface0DIterator &it, FEdge *&fe1, FEdge *&fe2)
{
- // count number of vertices
- Interface0DIterator prev = it, next = it;
- ++next;
- int count = 1;
- if (!it.isBegin() && !next.isEnd()) {
- count = 3;
- }
- if (count < 3) {
- // if we only have 2 vertices
- FEdge *fe = 0;
- Interface0DIterator tmp = it;
- if (it.isBegin()) {
- ++tmp;
- fe = it->getFEdge(*tmp);
- }
- else {
- --tmp;
- fe = it->getFEdge(*tmp);
- }
- fe1 = fe;
- fe2 = NULL;
- }
- else {
- // we have more than 2 vertices
- bool begin = false, last = false;
- Interface0DIterator previous = it;
- if (!previous.isBegin())
- --previous;
- else
- begin = true;
- Interface0DIterator next = it;
- ++next;
- if (next.isEnd())
- last = true;
- if (begin) {
- fe1 = it->getFEdge(*next);
- fe2 = NULL;
- }
- else if (last) {
- fe1 = previous->getFEdge(*it);
- fe2 = NULL;
- }
- else {
- fe1 = previous->getFEdge(*it);
- fe2 = it->getFEdge(*next);
- }
- }
+ // count number of vertices
+ Interface0DIterator prev = it, next = it;
+ ++next;
+ int count = 1;
+ if (!it.isBegin() && !next.isEnd()) {
+ count = 3;
+ }
+ if (count < 3) {
+ // if we only have 2 vertices
+ FEdge *fe = 0;
+ Interface0DIterator tmp = it;
+ if (it.isBegin()) {
+ ++tmp;
+ fe = it->getFEdge(*tmp);
+ }
+ else {
+ --tmp;
+ fe = it->getFEdge(*tmp);
+ }
+ fe1 = fe;
+ fe2 = NULL;
+ }
+ else {
+ // we have more than 2 vertices
+ bool begin = false, last = false;
+ Interface0DIterator previous = it;
+ if (!previous.isBegin())
+ --previous;
+ else
+ begin = true;
+ Interface0DIterator next = it;
+ ++next;
+ if (next.isEnd())
+ last = true;
+ if (begin) {
+ fe1 = it->getFEdge(*next);
+ fe2 = NULL;
+ }
+ else if (last) {
+ fe1 = previous->getFEdge(*it);
+ fe2 = NULL;
+ }
+ else {
+ fe1 = previous->getFEdge(*it);
+ fe2 = it->getFEdge(*next);
+ }
+ }
}
void getViewEdges(Interface0DIterator &it, ViewEdge *&ve1, ViewEdge *&ve2)
{
- FEdge *fe1, *fe2;
- getFEdges(it, fe1, fe2);
- ve1 = fe1->viewedge();
- if (fe2 != NULL) {
- ve2 = fe2->viewedge();
- if (ve2 == ve1)
- ve2 = NULL;
- }
- else {
- ve2 = NULL;
- }
+ FEdge *fe1, *fe2;
+ getFEdges(it, fe1, fe2);
+ ve1 = fe1->viewedge();
+ if (fe2 != NULL) {
+ ve2 = fe2->viewedge();
+ if (ve2 == ve1)
+ ve2 = NULL;
+ }
+ else {
+ ve2 = NULL;
+ }
}
-ViewShape *getShapeF0D(Interface0DIterator& it)
+ViewShape *getShapeF0D(Interface0DIterator &it)
{
- ViewEdge *ve1, *ve2;
- getViewEdges(it, ve1, ve2);
- return ve1->viewShape();
+ ViewEdge *ve1, *ve2;
+ getViewEdges(it, ve1, ve2);
+ return ve1->viewShape();
}
-void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders)
+void getOccludersF0D(Interface0DIterator &it, set<ViewShape *> &oOccluders)
{
- ViewEdge *ve1, *ve2;
- getViewEdges(it, ve1, ve2);
- occluder_container::const_iterator oit = ve1->occluders_begin();
- occluder_container::const_iterator oitend = ve1->occluders_end();
-
- for (; oit != oitend; ++oit)
- oOccluders.insert((*oit));
-
- if (ve2 != NULL) {
- oit = ve2->occluders_begin();
- oitend = ve2->occluders_end();
- for (; oit != oitend; ++oit)
- oOccluders.insert((*oit));
- }
+ ViewEdge *ve1, *ve2;
+ getViewEdges(it, ve1, ve2);
+ occluder_container::const_iterator oit = ve1->occluders_begin();
+ occluder_container::const_iterator oitend = ve1->occluders_end();
+
+ for (; oit != oitend; ++oit)
+ oOccluders.insert((*oit));
+
+ if (ve2 != NULL) {
+ oit = ve2->occluders_begin();
+ oitend = ve2->occluders_end();
+ for (; oit != oitend; ++oit)
+ oOccluders.insert((*oit));
+ }
}
-ViewShape *getOccludeeF0D(Interface0DIterator& it)
+ViewShape *getOccludeeF0D(Interface0DIterator &it)
{
- ViewEdge *ve1, *ve2;
- getViewEdges(it, ve1, ve2);
- ViewShape *aShape = ve1->aShape();
- return aShape;
+ ViewEdge *ve1, *ve2;
+ getViewEdges(it, ve1, ve2);
+ ViewShape *aShape = ve1->aShape();
+ return aShape;
}
//
-int VertexOrientation2DF0D::operator()(Interface0DIterator& iter)
+int VertexOrientation2DF0D::operator()(Interface0DIterator &iter)
{
- Vec2f A, C;
- Vec2f B(iter->getProjectedX(), iter->getProjectedY());
- if (iter.isBegin()) {
- A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
- }
- else {
- Interface0DIterator previous = iter;
- --previous ;
- A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
- }
- Interface0DIterator next = iter;
- ++next;
- if (next.isEnd())
- C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
- else
- C = Vec2f(next->getProjectedX(), next->getProjectedY());
-
- Vec2f AB(B - A);
- if (AB.norm() != 0)
- AB.normalize();
- Vec2f BC(C - B);
- if (BC.norm() != 0)
- BC.normalize();
- result = AB + BC;
- if (result.norm() != 0)
- result.normalize();
- return 0;
+ Vec2f A, C;
+ Vec2f B(iter->getProjectedX(), iter->getProjectedY());
+ if (iter.isBegin()) {
+ A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
+ }
+ else {
+ Interface0DIterator previous = iter;
+ --previous;
+ A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
+ }
+ Interface0DIterator next = iter;
+ ++next;
+ if (next.isEnd())
+ C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
+ else
+ C = Vec2f(next->getProjectedX(), next->getProjectedY());
+
+ Vec2f AB(B - A);
+ if (AB.norm() != 0)
+ AB.normalize();
+ Vec2f BC(C - B);
+ if (BC.norm() != 0)
+ BC.normalize();
+ result = AB + BC;
+ if (result.norm() != 0)
+ result.normalize();
+ return 0;
}
-int VertexOrientation3DF0D::operator()(Interface0DIterator& iter)
+int VertexOrientation3DF0D::operator()(Interface0DIterator &iter)
{
- Vec3r A, C;
- Vec3r B(iter->getX(), iter->getY(), iter->getZ());
- if (iter.isBegin()) {
- A = Vec3r(iter->getX(), iter->getY(), iter->getZ());
- }
- else {
- Interface0DIterator previous = iter;
- --previous ;
- A = Vec3r(previous->getX(), previous->getY(), previous->getZ());
- }
- Interface0DIterator next = iter;
- ++next ;
- if (next.isEnd())
- C = Vec3r(iter->getX(), iter->getY(), iter->getZ());
- else
- C = Vec3r(next->getX(), next->getY(), next->getZ());
-
- Vec3r AB(B - A);
- if (AB.norm() != 0)
- AB.normalize();
- Vec3r BC(C - B);
- if (BC.norm() != 0)
- BC.normalize();
- result = AB + BC;
- if (result.norm() != 0)
- result.normalize();
- return 0;
+ Vec3r A, C;
+ Vec3r B(iter->getX(), iter->getY(), iter->getZ());
+ if (iter.isBegin()) {
+ A = Vec3r(iter->getX(), iter->getY(), iter->getZ());
+ }
+ else {
+ Interface0DIterator previous = iter;
+ --previous;
+ A = Vec3r(previous->getX(), previous->getY(), previous->getZ());
+ }
+ Interface0DIterator next = iter;
+ ++next;
+ if (next.isEnd())
+ C = Vec3r(iter->getX(), iter->getY(), iter->getZ());
+ else
+ C = Vec3r(next->getX(), next->getY(), next->getZ());
+
+ Vec3r AB(B - A);
+ if (AB.norm() != 0)
+ AB.normalize();
+ Vec3r BC(C - B);
+ if (BC.norm() != 0)
+ BC.normalize();
+ result = AB + BC;
+ if (result.norm() != 0)
+ result.normalize();
+ return 0;
}
-int Curvature2DAngleF0D::operator()(Interface0DIterator& iter)
+int Curvature2DAngleF0D::operator()(Interface0DIterator &iter)
{
- Interface0DIterator tmp1 = iter, tmp2 = iter;
- ++tmp2;
- unsigned count = 1;
- while ((!tmp1.isBegin()) && (count < 3)) {
- --tmp1;
- ++count;
- }
- while ((!tmp2.isEnd()) && (count < 3)) {
- ++tmp2;
- ++count;
- }
- if (count < 3) {
- // if we only have 2 vertices
- result = 0;
- return 0;
- }
-
- Interface0DIterator v = iter;
- if (iter.isBegin())
- ++v;
- Interface0DIterator next = v;
- ++next;
- if (next.isEnd()) {
- next = v;
- --v;
- }
- Interface0DIterator prev = v;
- --prev;
-
- Vec2r A(prev->getProjectedX(), prev->getProjectedY());
- Vec2r B(v->getProjectedX(), v->getProjectedY());
- Vec2r C(next->getProjectedX(), next->getProjectedY());
- Vec2r AB(B - A);
- Vec2r BC(C - B);
- Vec2r N1(-AB[1], AB[0]);
- if (N1.norm() != 0)
- N1.normalize();
- Vec2r N2(-BC[1], BC[0]);
- if (N2.norm() != 0)
- N2.normalize();
- if ((N1.norm() == 0) && (N2.norm() == 0)) {
- Exception::raiseException();
- result = 0;
- return -1;
- }
- double cosin = N1 * N2;
- if (cosin > 1)
- cosin = 1;
- if (cosin < -1)
- cosin = -1;
- result = acos(cosin);
- return 0;
+ Interface0DIterator tmp1 = iter, tmp2 = iter;
+ ++tmp2;
+ unsigned count = 1;
+ while ((!tmp1.isBegin()) && (count < 3)) {
+ --tmp1;
+ ++count;
+ }
+ while ((!tmp2.isEnd()) && (count < 3)) {
+ ++tmp2;
+ ++count;
+ }
+ if (count < 3) {
+ // if we only have 2 vertices
+ result = 0;
+ return 0;
+ }
+
+ Interface0DIterator v = iter;
+ if (iter.isBegin())
+ ++v;
+ Interface0DIterator next = v;
+ ++next;
+ if (next.isEnd()) {
+ next = v;
+ --v;
+ }
+ Interface0DIterator prev = v;
+ --prev;
+
+ Vec2r A(prev->getProjectedX(), prev->getProjectedY());
+ Vec2r B(v->getProjectedX(), v->getProjectedY());
+ Vec2r C(next->getProjectedX(), next->getProjectedY());
+ Vec2r AB(B - A);
+ Vec2r BC(C - B);
+ Vec2r N1(-AB[1], AB[0]);
+ if (N1.norm() != 0)
+ N1.normalize();
+ Vec2r N2(-BC[1], BC[0]);
+ if (N2.norm() != 0)
+ N2.normalize();
+ if ((N1.norm() == 0) && (N2.norm() == 0)) {
+ Exception::raiseException();
+ result = 0;
+ return -1;
+ }
+ double cosin = N1 * N2;
+ if (cosin > 1)
+ cosin = 1;
+ if (cosin < -1)
+ cosin = -1;
+ result = acos(cosin);
+ return 0;
}
-int ZDiscontinuityF0D::operator()(Interface0DIterator& iter)
+int ZDiscontinuityF0D::operator()(Interface0DIterator &iter)
{
- FEdge *fe1, *fe2;
- getFEdges(iter, fe1, fe2);
- result = fe1->z_discontinuity();
- if (fe2 != NULL) {
- result += fe2->z_discontinuity();
- result /= 2.0f;
- }
- return 0;
+ FEdge *fe1, *fe2;
+ getFEdges(iter, fe1, fe2);
+ result = fe1->z_discontinuity();
+ if (fe2 != NULL) {
+ result += fe2->z_discontinuity();
+ result /= 2.0f;
+ }
+ return 0;
}
-int Normal2DF0D::operator()(Interface0DIterator& iter)
+int Normal2DF0D::operator()(Interface0DIterator &iter)
{
- FEdge *fe1, *fe2;
- getFEdges(iter, fe1, fe2);
- Vec3f e1(fe1->orientation2d());
- Vec2f n1(e1[1], -e1[0]);
- Vec2f n(n1);
- if (fe2 != NULL) {
- Vec3f e2(fe2->orientation2d());
- Vec2f n2(e2[1], -e2[0]);
- n += n2;
- }
- n.normalize();
- result = n;
- return 0;
+ FEdge *fe1, *fe2;
+ getFEdges(iter, fe1, fe2);
+ Vec3f e1(fe1->orientation2d());
+ Vec2f n1(e1[1], -e1[0]);
+ Vec2f n(n1);
+ if (fe2 != NULL) {
+ Vec3f e2(fe2->orientation2d());
+ Vec2f n2(e2[1], -e2[0]);
+ n += n2;
+ }
+ n.normalize();
+ result = n;
+ return 0;
}
-int MaterialF0D::operator()(Interface0DIterator& iter)
+int MaterialF0D::operator()(Interface0DIterator &iter)
{
- FEdge *fe1, *fe2;
- getFEdges(iter, fe1, fe2);
- if (fe1 == NULL)
- return -1;
- if (fe1->isSmooth())
- result = ((FEdgeSmooth *)fe1)->frs_material();
- else
- result = ((FEdgeSharp *)fe1)->bFrsMaterial();
+ FEdge *fe1, *fe2;
+ getFEdges(iter, fe1, fe2);
+ if (fe1 == NULL)
+ return -1;
+ if (fe1->isSmooth())
+ result = ((FEdgeSmooth *)fe1)->frs_material();
+ else
+ result = ((FEdgeSharp *)fe1)->bFrsMaterial();
#if 0
- const SShape *sshape = getShapeF0D(iter);
- return sshape->material();
+ const SShape *sshape = getShapeF0D(iter);
+ return sshape->material();
#endif
- return 0;
+ return 0;
}
-int ShapeIdF0D::operator()(Interface0DIterator& iter)
+int ShapeIdF0D::operator()(Interface0DIterator &iter)
{
- ViewShape *vshape = getShapeF0D(iter);
- result = vshape->getId();
- return 0;
+ ViewShape *vshape = getShapeF0D(iter);
+ result = vshape->getId();
+ return 0;
}
-int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter)
+int QuantitativeInvisibilityF0D::operator()(Interface0DIterator &iter)
{
- ViewEdge *ve1, *ve2;
- getViewEdges(iter, ve1, ve2);
- unsigned int qi1, qi2;
- qi1 = ve1->qi();
- if (ve2 != NULL) {
- qi2 = ve2->qi();
- if (qi2 != qi1) {
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
- }
- }
- }
- result = qi1;
- return 0;
+ ViewEdge *ve1, *ve2;
+ getViewEdges(iter, ve1, ve2);
+ unsigned int qi1, qi2;
+ qi1 = ve1->qi();
+ if (ve2 != NULL) {
+ qi2 = ve2->qi();
+ if (qi2 != qi1) {
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId()
+ << endl;
+ }
+ }
+ }
+ result = qi1;
+ return 0;
}
-int CurveNatureF0D::operator()(Interface0DIterator& iter)
+int CurveNatureF0D::operator()(Interface0DIterator &iter)
{
- Nature::EdgeNature nat = 0;
- ViewEdge *ve1, *ve2;
- getViewEdges(iter, ve1, ve2);
- nat |= ve1->getNature();
- if (ve2 != NULL)
- nat |= ve2->getNature();
- result = nat;
- return 0;
+ Nature::EdgeNature nat = 0;
+ ViewEdge *ve1, *ve2;
+ getViewEdges(iter, ve1, ve2);
+ nat |= ve1->getNature();
+ if (ve2 != NULL)
+ nat |= ve2->getNature();
+ result = nat;
+ return 0;
}
-int GetOccludersF0D::operator()(Interface0DIterator& iter)
+int GetOccludersF0D::operator()(Interface0DIterator &iter)
{
- set<ViewShape*> occluders;
- getOccludersF0D(iter, occluders);
- result.clear();
- //vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end());
- for (set<ViewShape*>::iterator it = occluders.begin(), itend = occluders.end(); it != itend; ++it) {
- result.push_back((*it));
- }
- return 0;
+ set<ViewShape *> occluders;
+ getOccludersF0D(iter, occluders);
+ result.clear();
+ //vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end());
+ for (set<ViewShape *>::iterator it = occluders.begin(), itend = occluders.end(); it != itend;
+ ++it) {
+ result.push_back((*it));
+ }
+ return 0;
}
-int GetShapeF0D::operator()(Interface0DIterator& iter)
+int GetShapeF0D::operator()(Interface0DIterator &iter)
{
- result = getShapeF0D(iter);
- return 0;
+ result = getShapeF0D(iter);
+ return 0;
}
-int GetOccludeeF0D::operator()(Interface0DIterator& iter)
+int GetOccludeeF0D::operator()(Interface0DIterator &iter)
{
- result = getOccludeeF0D(iter);
- return 0;
+ result = getOccludeeF0D(iter);
+ return 0;
}
-} // end of namespace Functions0D
+} // end of namespace Functions0D
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/Functions0D.h b/source/blender/freestyle/intern/view_map/Functions0D.h
index 108a124fe78..ecf94b29d60 100644
--- a/source/blender/freestyle/intern/view_map/Functions0D.h
+++ b/source/blender/freestyle/intern/view_map/Functions0D.h
@@ -37,7 +37,7 @@
#include "../system/Precision.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
@@ -70,44 +70,44 @@ using namespace Geometry;
* - UnaryFunction0DViewShape
* - UnaryFunction0DVoid
*/
-template <class T>
-class UnaryFunction0D
-{
-public:
- T result;
- void *py_uf0D;
-
- /*! The type of the value returned by the functor. */
- typedef T ReturnedValueType;
-
- /*! Default constructor. */
- UnaryFunction0D()
- {
- py_uf0D = NULL;
- }
-
- /*! Destructor; */
- virtual ~UnaryFunction0D() {}
-
- /*! Returns the string "UnaryFunction0D" */
- virtual string getName() const
- {
- return "UnaryFunction0D";
- }
-
- /*! The operator ().
- * \param iter:
- * An Interface0DIterator pointing onto the point at which we wish to evaluate the function.
- * \return the result of the function of type T.
- */
- /* FIXME move the implementation to Functions0D.cpp */
- virtual int operator()(Interface0DIterator& iter)
- {
- return Director_BPy_UnaryFunction0D___call__(this, py_uf0D, iter);
- }
+template<class T> class UnaryFunction0D {
+ public:
+ T result;
+ void *py_uf0D;
+
+ /*! The type of the value returned by the functor. */
+ typedef T ReturnedValueType;
+
+ /*! Default constructor. */
+ UnaryFunction0D()
+ {
+ py_uf0D = NULL;
+ }
+
+ /*! Destructor; */
+ virtual ~UnaryFunction0D()
+ {
+ }
+
+ /*! Returns the string "UnaryFunction0D" */
+ virtual string getName() const
+ {
+ return "UnaryFunction0D";
+ }
+
+ /*! The operator ().
+ * \param iter:
+ * An Interface0DIterator pointing onto the point at which we wish to evaluate the function.
+ * \return the result of the function of type T.
+ */
+ /* FIXME move the implementation to Functions0D.cpp */
+ virtual int operator()(Interface0DIterator &iter)
+ {
+ return Director_BPy_UnaryFunction0D___call__(this, py_uf0D, iter);
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction0D")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction0D")
#endif
};
@@ -129,7 +129,7 @@ public:
%template(UnaryFunction0DId) UnaryFunction0D<Id>;
%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
-#endif // SWIG
+#endif // SWIG
//
// Functions definitions
@@ -141,205 +141,194 @@ namespace Functions0D {
// GetXF0D
/*! Returns the X 3D coordinate of an Interface0D. */
-class GetXF0D : public UnaryFunction0D<double>
-{
-public:
- /*! Returns the string "GetXF0D" */
- string getName() const
- {
- return "GetXF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter)
- {
- result = iter->getX();
- return 0;
- }
+class GetXF0D : public UnaryFunction0D<double> {
+ public:
+ /*! Returns the string "GetXF0D" */
+ string getName() const
+ {
+ return "GetXF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter)
+ {
+ result = iter->getX();
+ return 0;
+ }
};
// GetYF0D
/*! Returns the Y 3D coordinate of an Interface0D. */
-class GetYF0D : public UnaryFunction0D<double>
-{
-public:
- /*! Returns the string "GetYF0D" */
- string getName() const
- {
- return "GetYF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter)
- {
- result = iter->getY();
- return 0;
- }
+class GetYF0D : public UnaryFunction0D<double> {
+ public:
+ /*! Returns the string "GetYF0D" */
+ string getName() const
+ {
+ return "GetYF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter)
+ {
+ result = iter->getY();
+ return 0;
+ }
};
// GetZF0D
/*! Returns the Z 3D coordinate of an Interface0D. */
-class GetZF0D : public UnaryFunction0D<double>
-{
-public:
- /*! Returns the string "GetZF0D" */
- string getName() const
- {
- return "GetZF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter)
- {
- result = iter->getZ();
- return 0;
- }
+class GetZF0D : public UnaryFunction0D<double> {
+ public:
+ /*! Returns the string "GetZF0D" */
+ string getName() const
+ {
+ return "GetZF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter)
+ {
+ result = iter->getZ();
+ return 0;
+ }
};
// GetProjectedXF0D
/*! Returns the X 3D projected coordinate of an Interface0D. */
-class GetProjectedXF0D : public UnaryFunction0D<double>
-{
-public:
- /*! Returns the string "GetProjectedXF0D" */
- string getName() const
- {
- return "GetProjectedXF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter)
- {
- result = iter->getProjectedX();
- return 0;
- }
+class GetProjectedXF0D : public UnaryFunction0D<double> {
+ public:
+ /*! Returns the string "GetProjectedXF0D" */
+ string getName() const
+ {
+ return "GetProjectedXF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter)
+ {
+ result = iter->getProjectedX();
+ return 0;
+ }
};
// GetProjectedYF0D
/*! Returns the Y projected 3D coordinate of an Interface0D. */
-class GetProjectedYF0D : public UnaryFunction0D<double>
-{
-public:
- /*! Returns the string "GetProjectedYF0D" */
- string getName() const
- {
- return "GetProjectedYF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter)
- {
- result = iter->getProjectedY();
- return 0;
- }
+class GetProjectedYF0D : public UnaryFunction0D<double> {
+ public:
+ /*! Returns the string "GetProjectedYF0D" */
+ string getName() const
+ {
+ return "GetProjectedYF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter)
+ {
+ result = iter->getProjectedY();
+ return 0;
+ }
};
// GetProjectedZF0D
/*! Returns the Z projected 3D coordinate of an Interface0D. */
-class GetProjectedZF0D : public UnaryFunction0D<double>
-{
-public:
- /*! Returns the string "GetProjectedZF0D" */
- string getName() const
- {
- return "GetProjectedZF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter)
- {
- result = iter->getProjectedZ();
- return 0;
- }
+class GetProjectedZF0D : public UnaryFunction0D<double> {
+ public:
+ /*! Returns the string "GetProjectedZF0D" */
+ string getName() const
+ {
+ return "GetProjectedZF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter)
+ {
+ result = iter->getProjectedZ();
+ return 0;
+ }
};
// GetCurvilinearAbscissaF0D
/*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
-class GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
-{
-public:
- /*! Returns the string "GetCurvilinearAbscissaF0D" */
- string getName() const
- {
- return "GetCurvilinearAbscissaF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter)
- {
- result = iter.t();
- return 0;
- }
+class GetCurvilinearAbscissaF0D : public UnaryFunction0D<float> {
+ public:
+ /*! Returns the string "GetCurvilinearAbscissaF0D" */
+ string getName() const
+ {
+ return "GetCurvilinearAbscissaF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter)
+ {
+ result = iter.t();
+ return 0;
+ }
};
// GetParameterF0D
/*! Returns the parameter of an Interface0D in the context of its 1D element. */
-class GetParameterF0D : public UnaryFunction0D<float>
-{
-public:
- /*! Returns the string "GetCurvilinearAbscissaF0D" */
- string getName() const
- {
- return "GetParameterF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter)
- {
- result = iter.u();
- return 0;
- }
+class GetParameterF0D : public UnaryFunction0D<float> {
+ public:
+ /*! Returns the string "GetCurvilinearAbscissaF0D" */
+ string getName() const
+ {
+ return "GetParameterF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter)
+ {
+ result = iter.u();
+ return 0;
+ }
};
// VertexOrientation2DF0D
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
-class VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
-{
-public:
- /*! Returns the string "VertexOrientation2DF0D" */
- string getName() const
- {
- return "VertexOrientation2DF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class VertexOrientation2DF0D : public UnaryFunction0D<Vec2f> {
+ public:
+ /*! Returns the string "VertexOrientation2DF0D" */
+ string getName() const
+ {
+ return "VertexOrientation2DF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// VertexOrientation3DF0D
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
-class VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
-{
-public:
- /*! Returns the string "VertexOrientation3DF0D" */
- string getName() const
- {
- return "VertexOrientation3DF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class VertexOrientation3DF0D : public UnaryFunction0D<Vec3f> {
+ public:
+ /*! Returns the string "VertexOrientation3DF0D" */
+ string getName() const
+ {
+ return "VertexOrientation3DF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// Curvature2DAngleF0D
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element to which the Interface0DIterator&
* belongs to and evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
-class Curvature2DAngleF0D : public UnaryFunction0D<double>
-{
-public:
- /*! Returns the string "Curvature2DAngleF0D" */
- string getName() const
- {
- return "Curvature2DAngleF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class Curvature2DAngleF0D : public UnaryFunction0D<double> {
+ public:
+ /*! Returns the string "Curvature2DAngleF0D" */
+ string getName() const
+ {
+ return "Curvature2DAngleF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// ZDiscontinuity
@@ -347,34 +336,32 @@ public:
* This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no object is occluded
* by the shape to which the Interface0D belongs to, 1 is returned.
*/
-class ZDiscontinuityF0D : public UnaryFunction0D<double>
-{
-public:
- /*! Returns the string "ZDiscontinuityF0D" */
- string getName() const
- {
- return "ZDiscontinuityF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class ZDiscontinuityF0D : public UnaryFunction0D<double> {
+ public:
+ /*! Returns the string "ZDiscontinuityF0D" */
+ string getName() const
+ {
+ return "ZDiscontinuityF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// Normal2DF0D
/*! Returns a Vec2f giving the normalized 2D normal to the 1D element to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
-class Normal2DF0D : public UnaryFunction0D<Vec2f>
-{
-public:
- /*! Returns the string "Normal2DF0D" */
- string getName() const
- {
- return "Normal2DF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class Normal2DF0D : public UnaryFunction0D<Vec2f> {
+ public:
+ /*! Returns the string "Normal2DF0D" */
+ string getName() const
+ {
+ return "Normal2DF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// MaterialF0D
@@ -386,17 +373,16 @@ public:
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getMaterial functor.
*/
-class MaterialF0D : public UnaryFunction0D<FrsMaterial>
-{
-public:
- /*! Returns the string "MaterialF0D" */
- string getName() const
- {
- return "MaterialF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class MaterialF0D : public UnaryFunction0D<FrsMaterial> {
+ public:
+ /*! Returns the string "MaterialF0D" */
+ string getName() const
+ {
+ return "MaterialF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// ShapeIdF0D
@@ -407,17 +393,16 @@ public:
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getShapeIdF0D functor.
*/
-class ShapeIdF0D : public UnaryFunction0D<Id>
-{
-public:
- /*! Returns the string "ShapeIdF0D" */
- string getName() const
- {
- return "ShapeIdF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class ShapeIdF0D : public UnaryFunction0D<Id> {
+ public:
+ /*! Returns the string "ShapeIdF0D" */
+ string getName() const
+ {
+ return "ShapeIdF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// QiF0D
@@ -428,102 +413,96 @@ public:
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getQIF0D functor.
*/
-class QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
-{
-public:
- /*! Returns the string "QuantitativeInvisibilityF0D" */
- string getName() const
- {
- return "QuantitativeInvisibilityF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int> {
+ public:
+ /*! Returns the string "QuantitativeInvisibilityF0D" */
+ string getName() const
+ {
+ return "QuantitativeInvisibilityF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// CurveNatureF0D
/*! Returns the Nature::EdgeNature of the 1D element the Interface0DIterator& belongs to. */
-class CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
-{
-public:
- /*! Returns the string "QuantitativeInvisibilityF0D" */
- string getName() const
- {
- return "CurveNatureF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature> {
+ public:
+ /*! Returns the string "QuantitativeInvisibilityF0D" */
+ string getName() const
+ {
+ return "CurveNatureF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// GetShapeF0D
/*! Returns the ViewShape* containing the Interface0D */
-class GetShapeF0D : public UnaryFunction0D< ViewShape*>
-{
-public:
- /*! Returns the string "GetShapeF0D" */
- string getName() const
- {
- return "GetShapeF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class GetShapeF0D : public UnaryFunction0D<ViewShape *> {
+ public:
+ /*! Returns the string "GetShapeF0D" */
+ string getName() const
+ {
+ return "GetShapeF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// GetOccludersF0D
/*! Returns a vector containing the ViewShape* occluding the Interface0D */
-class GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
-{
-public:
- /*! Returns the string "GetOccludersF0D" */
- string getName() const
- {
- return "GetOccludersF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class GetOccludersF0D : public UnaryFunction0D<std::vector<ViewShape *>> {
+ public:
+ /*! Returns the string "GetOccludersF0D" */
+ string getName() const
+ {
+ return "GetOccludersF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
// GetOccludeeF0D
/*! Returns the ViewShape* "occluded" by the Interface0D */
-class GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
-{
-public:
- /*! Returns the string "GetOccludeeF0D" */
- string getName() const
- {
- return "GetOccludeeF0D";
- }
-
- /*! the () operator. */
- int operator()(Interface0DIterator& iter);
+class GetOccludeeF0D : public UnaryFunction0D<ViewShape *> {
+ public:
+ /*! Returns the string "GetOccludeeF0D" */
+ string getName() const
+ {
+ return "GetOccludeeF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator &iter);
};
-
/////////////////////////// Internal ////////////////////////////
// getFEdge
-FEdge *getFEdge(Interface0D& it1, Interface0D& it2);
+FEdge *getFEdge(Interface0D &it1, Interface0D &it2);
// getFEdges
-void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
+void getFEdges(Interface0DIterator &it, FEdge *&fe1, FEdge *&fe2);
// getViewEdges
-void getViewEdges(Interface0DIterator& it, ViewEdge *&ve1, ViewEdge *&ve2);
+void getViewEdges(Interface0DIterator &it, ViewEdge *&ve1, ViewEdge *&ve2);
// getShapeF0D
-ViewShape *getShapeF0D(Interface0DIterator& it);
+ViewShape *getShapeF0D(Interface0DIterator &it);
// getOccludersF0D
-void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
+void getOccludersF0D(Interface0DIterator &it, std::set<ViewShape *> &oOccluders);
// getOccludeeF0D
-ViewShape *getOccludeeF0D(Interface0DIterator& it);
+ViewShape *getOccludeeF0D(Interface0DIterator &it);
-} // end of namespace Functions0D
+} // end of namespace Functions0D
} /* namespace Freestyle */
-#endif // __FREESTYLE_FUNCTIONS_0D_H__
+#endif // __FREESTYLE_FUNCTIONS_0D_H__
diff --git a/source/blender/freestyle/intern/view_map/Functions1D.cpp b/source/blender/freestyle/intern/view_map/Functions1D.cpp
index 31f3b65a2b7..0c0ab9fd631 100644
--- a/source/blender/freestyle/intern/view_map/Functions1D.cpp
+++ b/source/blender/freestyle/intern/view_map/Functions1D.cpp
@@ -27,237 +27,239 @@ namespace Freestyle {
namespace Functions1D {
-int GetXF1D::operator()(Interface1D& inter)
+int GetXF1D::operator()(Interface1D &inter)
{
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
}
-int GetYF1D::operator()(Interface1D& inter)
+int GetYF1D::operator()(Interface1D &inter)
{
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
}
-int GetZF1D::operator()(Interface1D& inter)
+int GetZF1D::operator()(Interface1D &inter)
{
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
}
-int GetProjectedXF1D::operator()(Interface1D& inter)
+int GetProjectedXF1D::operator()(Interface1D &inter)
{
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
}
-int GetProjectedYF1D::operator()(Interface1D& inter)
+int GetProjectedYF1D::operator()(Interface1D &inter)
{
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
}
-int GetProjectedZF1D::operator()(Interface1D& inter)
+int GetProjectedZF1D::operator()(Interface1D &inter)
{
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
}
-int Orientation2DF1D::operator()(Interface1D& inter)
+int Orientation2DF1D::operator()(Interface1D &inter)
{
- FEdge *fe = dynamic_cast<FEdge*>(&inter);
- if (fe) {
- Vec3r res = fe->orientation2d();
- result = Vec2f(res[0], res[1]);
- }
- else {
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- }
- return 0;
+ FEdge *fe = dynamic_cast<FEdge *>(&inter);
+ if (fe) {
+ Vec3r res = fe->orientation2d();
+ result = Vec2f(res[0], res[1]);
+ }
+ else {
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ }
+ return 0;
}
-int Orientation3DF1D::operator()(Interface1D& inter)
+int Orientation3DF1D::operator()(Interface1D &inter)
{
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
}
-int ZDiscontinuityF1D::operator()(Interface1D& inter)
+int ZDiscontinuityF1D::operator()(Interface1D &inter)
{
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
}
-int QuantitativeInvisibilityF1D::operator()(Interface1D& inter)
+int QuantitativeInvisibilityF1D::operator()(Interface1D &inter)
{
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve) {
- result = ve->qi();
- return 0;
- }
- FEdge *fe = dynamic_cast<FEdge*>(&inter);
- if (fe) {
- result = fe->qi();
- return 0;
- }
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve) {
+ result = ve->qi();
+ return 0;
+ }
+ FEdge *fe = dynamic_cast<FEdge *>(&inter);
+ if (fe) {
+ result = fe->qi();
+ return 0;
+ }
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
}
-int CurveNatureF1D::operator()(Interface1D& inter)
+int CurveNatureF1D::operator()(Interface1D &inter)
{
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve) {
- result = ve->getNature();
- }
- else {
- // we return a nature that contains every natures of the viewedges spanned by the chain.
- Nature::EdgeNature nat = Nature::NO_FEATURE;
- Interface0DIterator it = inter.verticesBegin();
- while (!it.isEnd()) {
- nat |= _func(it);
- ++it;
- }
- result = nat;
- }
- return 0;
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve) {
+ result = ve->getNature();
+ }
+ else {
+ // we return a nature that contains every natures of the viewedges spanned by the chain.
+ Nature::EdgeNature nat = Nature::NO_FEATURE;
+ Interface0DIterator it = inter.verticesBegin();
+ while (!it.isEnd()) {
+ nat |= _func(it);
+ ++it;
+ }
+ result = nat;
+ }
+ return 0;
}
-int TimeStampF1D::operator()(Interface1D& inter)
+int TimeStampF1D::operator()(Interface1D &inter)
{
- TimeStamp *timestamp = TimeStamp::instance();
- inter.setTimeStamp(timestamp->getTimeStamp());
- return 0;
+ TimeStamp *timestamp = TimeStamp::instance();
+ inter.setTimeStamp(timestamp->getTimeStamp());
+ return 0;
}
-int ChainingTimeStampF1D::operator()(Interface1D& inter)
+int ChainingTimeStampF1D::operator()(Interface1D &inter)
{
- TimeStamp *timestamp = TimeStamp::instance();
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve)
- ve->setChainingTimeStamp(timestamp->getTimeStamp());
- return 0;
+ TimeStamp *timestamp = TimeStamp::instance();
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve)
+ ve->setChainingTimeStamp(timestamp->getTimeStamp());
+ return 0;
}
-int IncrementChainingTimeStampF1D::operator()(Interface1D& inter)
+int IncrementChainingTimeStampF1D::operator()(Interface1D &inter)
{
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve)
- ve->setChainingTimeStamp(ve->getChainingTimeStamp() + 1);
- return 0;
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve)
+ ve->setChainingTimeStamp(ve->getChainingTimeStamp() + 1);
+ return 0;
}
-int GetShapeF1D::operator()(Interface1D& inter)
+int GetShapeF1D::operator()(Interface1D &inter)
{
- vector<ViewShape*> shapesVector;
- set<ViewShape*> shapesSet;
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve) {
- shapesVector.push_back(ve->viewShape());
- }
- else {
- Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
- for (; it != itend; ++it)
- shapesSet.insert(Functions0D::getShapeF0D(it));
- shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
- }
- result = shapesVector;
- return 0;
+ vector<ViewShape *> shapesVector;
+ set<ViewShape *> shapesSet;
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve) {
+ shapesVector.push_back(ve->viewShape());
+ }
+ else {
+ Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
+ for (; it != itend; ++it)
+ shapesSet.insert(Functions0D::getShapeF0D(it));
+ shapesVector.insert<set<ViewShape *>::iterator>(
+ shapesVector.begin(), shapesSet.begin(), shapesSet.end());
+ }
+ result = shapesVector;
+ return 0;
}
-int GetOccludersF1D::operator()(Interface1D& inter)
+int GetOccludersF1D::operator()(Interface1D &inter)
{
- vector<ViewShape*> shapesVector;
- set<ViewShape*> shapesSet;
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve) {
- result = ve->occluders();
- }
- else {
- Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
- for (; it != itend; ++it) {
- Functions0D::getOccludersF0D(it, shapesSet);
- }
- shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
- result = shapesVector;
- }
- return 0;
+ vector<ViewShape *> shapesVector;
+ set<ViewShape *> shapesSet;
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve) {
+ result = ve->occluders();
+ }
+ else {
+ Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
+ for (; it != itend; ++it) {
+ Functions0D::getOccludersF0D(it, shapesSet);
+ }
+ shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
+ result = shapesVector;
+ }
+ return 0;
}
-int GetOccludeeF1D::operator()(Interface1D& inter)
+int GetOccludeeF1D::operator()(Interface1D &inter)
{
- vector<ViewShape*> shapesVector;
- set<ViewShape*> shapesSet;
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve) {
- ViewShape *aShape = ve->aShape();
- if (aShape) {
- shapesVector.push_back(aShape);
- }
- }
- else {
- Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
- for (; it != itend; ++it) {
- shapesSet.insert(Functions0D::getOccludeeF0D(it));
- }
- shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
- }
- result = shapesVector;
- return 0;
+ vector<ViewShape *> shapesVector;
+ set<ViewShape *> shapesSet;
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve) {
+ ViewShape *aShape = ve->aShape();
+ if (aShape) {
+ shapesVector.push_back(aShape);
+ }
+ }
+ else {
+ Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
+ for (; it != itend; ++it) {
+ shapesSet.insert(Functions0D::getOccludeeF0D(it));
+ }
+ shapesVector.insert<set<ViewShape *>::iterator>(
+ shapesVector.begin(), shapesSet.begin(), shapesSet.end());
+ }
+ result = shapesVector;
+ return 0;
}
// Internal
////////////
-void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
+void getOccludeeF1D(Interface1D &inter, set<ViewShape *> &oShapes)
{
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve) {
- ViewShape *aShape = ve->aShape();
- if (aShape == 0) {
- oShapes.insert((ViewShape*)0);
- return;
- }
- oShapes.insert(aShape);
- }
- else {
- Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
- for (; it != itend; ++it)
- oShapes.insert(Functions0D::getOccludeeF0D(it));
- }
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve) {
+ ViewShape *aShape = ve->aShape();
+ if (aShape == 0) {
+ oShapes.insert((ViewShape *)0);
+ return;
+ }
+ oShapes.insert(aShape);
+ }
+ else {
+ Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
+ for (; it != itend; ++it)
+ oShapes.insert(Functions0D::getOccludeeF0D(it));
+ }
}
-void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes)
+void getOccludersF1D(Interface1D &inter, set<ViewShape *> &oShapes)
{
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve) {
- vector<ViewShape*>& occluders = ve->occluders();
- oShapes.insert<vector<ViewShape*>::iterator>(occluders.begin(), occluders.end());
- }
- else {
- Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
- for (; it != itend; ++it) {
- set<ViewShape*> shapes;
- Functions0D::getOccludersF0D(it, shapes);
- for (set<ViewShape*>::iterator s = shapes.begin(), send = shapes.end(); s != send; ++s)
- oShapes.insert(*s);
- }
- }
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve) {
+ vector<ViewShape *> &occluders = ve->occluders();
+ oShapes.insert<vector<ViewShape *>::iterator>(occluders.begin(), occluders.end());
+ }
+ else {
+ Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
+ for (; it != itend; ++it) {
+ set<ViewShape *> shapes;
+ Functions0D::getOccludersF0D(it, shapes);
+ for (set<ViewShape *>::iterator s = shapes.begin(), send = shapes.end(); s != send; ++s)
+ oShapes.insert(*s);
+ }
+ }
}
-void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
+void getShapeF1D(Interface1D &inter, set<ViewShape *> &oShapes)
{
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve) {
- oShapes.insert(ve->viewShape());
- }
- else {
- Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
- for (; it != itend; ++it)
- oShapes.insert(Functions0D::getShapeF0D(it));
- }
+ ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
+ if (ve) {
+ oShapes.insert(ve->viewShape());
+ }
+ else {
+ Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
+ for (; it != itend; ++it)
+ oShapes.insert(Functions0D::getShapeF0D(it));
+ }
}
-} // end of namespace Functions1D
+} // end of namespace Functions1D
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/Functions1D.h b/source/blender/freestyle/intern/view_map/Functions1D.h
index 9101e380a40..581ab9c459a 100644
--- a/source/blender/freestyle/intern/view_map/Functions1D.h
+++ b/source/blender/freestyle/intern/view_map/Functions1D.h
@@ -33,7 +33,7 @@
#include "../python/Director.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
@@ -57,121 +57,120 @@ namespace Freestyle {
* - UnaryFunction1DVectorViewShape
* - UnaryFunction1DVoid
*/
-template <class T>
-class UnaryFunction1D
-{
-public:
- T result;
- void *py_uf1D;
-
- /*! The type of the value returned by the functor. */
- typedef T ReturnedValueType;
-
- /*! Default constructor */
- UnaryFunction1D()
- {
- _integration = MEAN;
- }
-
- /*! Builds a UnaryFunction1D from an integration type.
- * \param iType:
- * In case the result for the Interface1D would be obtained by evaluating a 0D function over the different
- * Interface0D of the Interface1D, \a iType tells which integration method to use.
- * The default integration method is the MEAN.
- */
- UnaryFunction1D(IntegrationType iType)
- {
- _integration = iType;
- }
-
- /*! destructor. */
- virtual ~UnaryFunction1D() {}
-
- /*! returns the string "UnaryFunction1D". */
- virtual string getName() const
- {
- return "UnaryFunction1D";
- }
-
- /*! The operator ().
- * \param inter:
- * The Interface1D on which we wish to evaluate the function.
- * \return the result of the function of type T.
- */
- /* FIXME move the implementation to Functions1D.cpp */
- virtual int operator()(Interface1D& inter)
- {
- return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
- }
-
- /*! Sets the integration method */
- void setIntegrationType(IntegrationType integration)
- {
- _integration = integration;
- }
-
- /*! Returns the integration method. */
- IntegrationType getIntegrationType() const
- {
- return _integration;
- }
-
-protected:
- IntegrationType _integration;
+template<class T> class UnaryFunction1D {
+ public:
+ T result;
+ void *py_uf1D;
+
+ /*! The type of the value returned by the functor. */
+ typedef T ReturnedValueType;
+
+ /*! Default constructor */
+ UnaryFunction1D()
+ {
+ _integration = MEAN;
+ }
+
+ /*! Builds a UnaryFunction1D from an integration type.
+ * \param iType:
+ * In case the result for the Interface1D would be obtained by evaluating a 0D function over the different
+ * Interface0D of the Interface1D, \a iType tells which integration method to use.
+ * The default integration method is the MEAN.
+ */
+ UnaryFunction1D(IntegrationType iType)
+ {
+ _integration = iType;
+ }
+
+ /*! destructor. */
+ virtual ~UnaryFunction1D()
+ {
+ }
+
+ /*! returns the string "UnaryFunction1D". */
+ virtual string getName() const
+ {
+ return "UnaryFunction1D";
+ }
+
+ /*! The operator ().
+ * \param inter:
+ * The Interface1D on which we wish to evaluate the function.
+ * \return the result of the function of type T.
+ */
+ /* FIXME move the implementation to Functions1D.cpp */
+ virtual int operator()(Interface1D &inter)
+ {
+ return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
+ }
+
+ /*! Sets the integration method */
+ void setIntegrationType(IntegrationType integration)
+ {
+ _integration = integration;
+ }
+
+ /*! Returns the integration method. */
+ IntegrationType getIntegrationType() const
+ {
+ return _integration;
+ }
+
+ protected:
+ IntegrationType _integration;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction1D")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction1D")
#endif
};
+class UnaryFunction1D_void {
+ public:
+ void *py_uf1D;
-class UnaryFunction1D_void
-{
-public:
- void *py_uf1D;
+ UnaryFunction1D_void()
+ {
+ _integration = MEAN;
+ }
- UnaryFunction1D_void()
- {
- _integration = MEAN;
- }
+ UnaryFunction1D_void(IntegrationType iType)
+ {
+ _integration = iType;
+ }
- UnaryFunction1D_void(IntegrationType iType)
- {
- _integration = iType;
- }
+ virtual ~UnaryFunction1D_void()
+ {
+ }
- virtual ~UnaryFunction1D_void() {}
+ virtual string getName() const
+ {
+ return "UnaryFunction1D_void";
+ }
- virtual string getName() const
- {
- return "UnaryFunction1D_void";
- }
+ /* FIXME move the implementation to Functions1D.cpp */
+ int operator()(Interface1D &inter)
+ {
+ return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
+ }
- /* FIXME move the implementation to Functions1D.cpp */
- int operator()(Interface1D& inter)
- {
- return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
- }
+ void setIntegrationType(IntegrationType integration)
+ {
+ _integration = integration;
+ }
- void setIntegrationType(IntegrationType integration)
- {
- _integration = integration;
- }
+ IntegrationType getIntegrationType() const
+ {
+ return _integration;
+ }
- IntegrationType getIntegrationType() const
- {
- return _integration;
- }
-
-protected:
- IntegrationType _integration;
+ protected:
+ IntegrationType _integration;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction1D_void")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction1D_void")
#endif
};
-
//
// Functions definitions
//
@@ -181,194 +180,202 @@ namespace Functions1D {
// GetXF1D
/*! Returns the X 3D coordinate of an Interface1D. */
-class GetXF1D : public UnaryFunction1D<double>
-{
-private:
- Functions0D::GetXF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- GetXF1D(IntegrationType iType) : UnaryFunction1D<double>(iType) {}
-
- /*! Returns the string "GetXF1D" */
- string getName() const
- {
- return "GetXF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class GetXF1D : public UnaryFunction1D<double> {
+ private:
+ Functions0D::GetXF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ GetXF1D(IntegrationType iType) : UnaryFunction1D<double>(iType)
+ {
+ }
+
+ /*! Returns the string "GetXF1D" */
+ string getName() const
+ {
+ return "GetXF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// GetYF1D
/*! Returns the Y 3D coordinate of an Interface1D. */
-class GetYF1D : public UnaryFunction1D<double>
-{
-private:
-Functions0D::GetYF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
-
- /*! Returns the string "GetYF1D" */
- string getName() const
- {
- return "GetYF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class GetYF1D : public UnaryFunction1D<double> {
+ private:
+ Functions0D::GetYF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType)
+ {
+ }
+
+ /*! Returns the string "GetYF1D" */
+ string getName() const
+ {
+ return "GetYF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// GetZF1D
/*! Returns the Z 3D coordinate of an Interface1D. */
-class GetZF1D : public UnaryFunction1D<double>
-{
-private:
- Functions0D::GetZF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
-
- /*! Returns the string "GetZF1D" */
- string getName() const
- {
- return "GetZF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class GetZF1D : public UnaryFunction1D<double> {
+ private:
+ Functions0D::GetZF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType)
+ {
+ }
+
+ /*! Returns the string "GetZF1D" */
+ string getName() const
+ {
+ return "GetZF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// GetProjectedXF1D
/*! Returns the projected X 3D coordinate of an Interface1D. */
-class GetProjectedXF1D : public UnaryFunction1D<double>
-{
-private:
- Functions0D::GetProjectedXF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
-
- /*! Returns the string "GetProjectedXF1D" */
- string getName() const
- {
- return "GetProjectedXF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class GetProjectedXF1D : public UnaryFunction1D<double> {
+ private:
+ Functions0D::GetProjectedXF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType)
+ {
+ }
+
+ /*! Returns the string "GetProjectedXF1D" */
+ string getName() const
+ {
+ return "GetProjectedXF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// GetProjectedYF1D
/*! Returns the projected Y 3D coordinate of an Interface1D. */
-class GetProjectedYF1D : public UnaryFunction1D<double>
-{
-private:
- Functions0D::GetProjectedYF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
-
- /*! Returns the string "GetProjectedYF1D" */
- string getName() const
- {
- return "GetProjectedYF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class GetProjectedYF1D : public UnaryFunction1D<double> {
+ private:
+ Functions0D::GetProjectedYF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType)
+ {
+ }
+
+ /*! Returns the string "GetProjectedYF1D" */
+ string getName() const
+ {
+ return "GetProjectedYF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// GetProjectedZF1D
/*! Returns the projected Z 3D coordinate of an Interface1D. */
-class GetProjectedZF1D : public UnaryFunction1D<double>
-{
-private:
- Functions0D::GetProjectedZF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
-
- /*! Returns the string "GetProjectedZF1D" */
- string getName() const
- {
- return "GetProjectedZF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class GetProjectedZF1D : public UnaryFunction1D<double> {
+ private:
+ Functions0D::GetProjectedZF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType)
+ {
+ }
+
+ /*! Returns the string "GetProjectedZF1D" */
+ string getName() const
+ {
+ return "GetProjectedZF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// Orientation2DF1D
/*! Returns the 2D orientation as a Vec2f*/
-class Orientation2DF1D : public UnaryFunction1D<Vec2f>
-{
-private:
- Functions0D::VertexOrientation2DF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- Orientation2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {}
-
- /*! Returns the string "Orientation2DF1D" */
- string getName() const
- {
- return "Orientation2DF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class Orientation2DF1D : public UnaryFunction1D<Vec2f> {
+ private:
+ Functions0D::VertexOrientation2DF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ Orientation2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType)
+ {
+ }
+
+ /*! Returns the string "Orientation2DF1D" */
+ string getName() const
+ {
+ return "Orientation2DF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// Orientation3DF1D
/*! Returns the 3D orientation as a Vec3f. */
-class Orientation3DF1D : public UnaryFunction1D<Vec3f>
-{
-private:
- Functions0D::VertexOrientation3DF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- Orientation3DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec3f>(iType) {}
-
- /*! Returns the string "Orientation3DF1D" */
- string getName() const
- {
- return "Orientation3DF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class Orientation3DF1D : public UnaryFunction1D<Vec3f> {
+ private:
+ Functions0D::VertexOrientation3DF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ Orientation3DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec3f>(iType)
+ {
+ }
+
+ /*! Returns the string "Orientation3DF1D" */
+ string getName() const
+ {
+ return "Orientation3DF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// ZDiscontinuityF1D
@@ -376,26 +383,27 @@ public:
* This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no object is occluded
* by the shape to which the Interface1D belongs to, 1 is returned.
*/
-class ZDiscontinuityF1D : public UnaryFunction1D<double>
-{
-private:
- Functions0D::ZDiscontinuityF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
-
- /*! Returns the string "ZDiscontinuityF1D" */
- string getName() const
- {
- return "ZDiscontinuityF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class ZDiscontinuityF1D : public UnaryFunction1D<double> {
+ private:
+ Functions0D::ZDiscontinuityF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType)
+ {
+ }
+
+ /*! Returns the string "ZDiscontinuityF1D" */
+ string getName() const
+ {
+ return "ZDiscontinuityF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// QuantitativeInvisibilityF1D
@@ -404,26 +412,27 @@ public:
* results of a chaining (chain, stroke), then it might be made of several 1D elements of different
* Quantitative Invisibilities.
*/
-class QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned>
-{
-private:
- Functions0D::QuantitativeInvisibilityF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- QuantitativeInvisibilityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<unsigned int>(iType) {}
-
- /*! Returns the string "QuantitativeInvisibilityF1D" */
- string getName() const
- {
- return "QuantitativeInvisibilityF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned> {
+ private:
+ Functions0D::QuantitativeInvisibilityF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ QuantitativeInvisibilityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<unsigned int>(iType)
+ {
+ }
+
+ /*! Returns the string "QuantitativeInvisibilityF1D" */
+ string getName() const
+ {
+ return "QuantitativeInvisibilityF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// CurveNatureF1D
@@ -432,198 +441,200 @@ public:
* Indeed, the Interface1D might result from the gathering of several 1D elements, each one being of a different
* nature. An integration method, such as the MEAN, might give, in this case, irrelevant results.
*/
-class CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature>
-{
-private:
- Functions0D::CurveNatureF0D _func;
-
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- CurveNatureF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Nature::EdgeNature>(iType) {}
-
- /*! Returns the string "CurveNatureF1D" */
- string getName() const
- {
- return "CurveNatureF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature> {
+ private:
+ Functions0D::CurveNatureF0D _func;
+
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ CurveNatureF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Nature::EdgeNature>(iType)
+ {
+ }
+
+ /*! Returns the string "CurveNatureF1D" */
+ string getName() const
+ {
+ return "CurveNatureF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// TimeStampF1D
/*! Returns the time stamp of the Interface1D. */
-class TimeStampF1D : public UnaryFunction1D_void
-{
-public:
- /*! Returns the string "TimeStampF1D" */
- string getName() const
- {
- return "TimeStampF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class TimeStampF1D : public UnaryFunction1D_void {
+ public:
+ /*! Returns the string "TimeStampF1D" */
+ string getName() const
+ {
+ return "TimeStampF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// IncrementChainingTimeStampF1D
/*! Increments the chaining time stamp of the Interface1D. */
-class IncrementChainingTimeStampF1D : public UnaryFunction1D_void
-{
-public:
- /*! Returns the string "IncrementChainingTimeStampF1D" */
- string getName() const
- {
- return "IncrementChainingTimeStampF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class IncrementChainingTimeStampF1D : public UnaryFunction1D_void {
+ public:
+ /*! Returns the string "IncrementChainingTimeStampF1D" */
+ string getName() const
+ {
+ return "IncrementChainingTimeStampF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// ChainingTimeStampF1D
/*! Sets the chaining time stamp of the Interface1D. */
-class ChainingTimeStampF1D : public UnaryFunction1D_void
-{
-public:
- /*! Returns the string "ChainingTimeStampF1D" */
- string getName() const
- {
- return "ChainingTimeStampF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class ChainingTimeStampF1D : public UnaryFunction1D_void {
+ public:
+ /*! Returns the string "ChainingTimeStampF1D" */
+ string getName() const
+ {
+ return "ChainingTimeStampF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
-
// Curvature2DAngleF1D
/*! Returns the 2D curvature as an angle for an Interface1D. */
-class Curvature2DAngleF1D : public UnaryFunction1D<double>
-{
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- Curvature2DAngleF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
-
- /*! Returns the string "Curvature2DAngleF1D" */
- string getName() const
- {
- return "Curvature2DAngleF1D";
- }
-
- /*! the () operator.*/
- int operator()(Interface1D& inter)
- {
- result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
- }
-
-private:
- Functions0D::Curvature2DAngleF0D _fun;
+class Curvature2DAngleF1D : public UnaryFunction1D<double> {
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ Curvature2DAngleF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType)
+ {
+ }
+
+ /*! Returns the string "Curvature2DAngleF1D" */
+ string getName() const
+ {
+ return "Curvature2DAngleF1D";
+ }
+
+ /*! the () operator.*/
+ int operator()(Interface1D &inter)
+ {
+ result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
+ }
+
+ private:
+ Functions0D::Curvature2DAngleF0D _fun;
};
// Normal2DF1D
/*! Returns the 2D normal for an interface 1D. */
-class Normal2DF1D : public UnaryFunction1D<Vec2f>
-{
-public:
- /*! Builds the functor.
- * \param iType:
- * The integration method used to compute a single value from a set of values.
- */
- Normal2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {}
-
- /*! Returns the string "Normal2DF1D" */
- string getName() const
- {
- return "Normal2DF1D";
- }
-
- /*! the () operator.*/
- int operator()(Interface1D& inter)
- {
- result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
- }
-
-private:
- Functions0D::Normal2DF0D _fun;
+class Normal2DF1D : public UnaryFunction1D<Vec2f> {
+ public:
+ /*! Builds the functor.
+ * \param iType:
+ * The integration method used to compute a single value from a set of values.
+ */
+ Normal2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType)
+ {
+ }
+
+ /*! Returns the string "Normal2DF1D" */
+ string getName() const
+ {
+ return "Normal2DF1D";
+ }
+
+ /*! the () operator.*/
+ int operator()(Interface1D &inter)
+ {
+ result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
+ }
+
+ private:
+ Functions0D::Normal2DF0D _fun;
};
// GetShapeF1D
/*! Returns list of shapes covered by this Interface1D. */
-class GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
-{
-public:
- /*! Builds the functor. */
- GetShapeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
-
- /*! Returns the string "GetShapeF1D" */
- string getName() const
- {
- return "GetShapeF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape *>> {
+ public:
+ /*! Builds the functor. */
+ GetShapeF1D() : UnaryFunction1D<std::vector<ViewShape *>>()
+ {
+ }
+
+ /*! Returns the string "GetShapeF1D" */
+ string getName() const
+ {
+ return "GetShapeF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// GetOccludersF1D
/*! Returns list of occluding shapes covered by this Interface1D. */
-class GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape*> >
-{
-public:
- /*! Builds the functor. */
- GetOccludersF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
-
- /*! Returns the string "GetOccludersF1D" */
- string getName() const
- {
- return "GetOccludersF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape *>> {
+ public:
+ /*! Builds the functor. */
+ GetOccludersF1D() : UnaryFunction1D<std::vector<ViewShape *>>()
+ {
+ }
+
+ /*! Returns the string "GetOccludersF1D" */
+ string getName() const
+ {
+ return "GetOccludersF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// GetOccludeeF1D
/*! Returns list of occluded shapes covered by this Interface1D. */
-class GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
-{
-public:
- /*! Builds the functor. */
- GetOccludeeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
-
- /*! Returns the string "GetOccludeeF1D" */
- string getName() const
- {
- return "GetOccludeeF1D";
- }
-
- /*! the () operator. */
- int operator()(Interface1D& inter);
+class GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape *>> {
+ public:
+ /*! Builds the functor. */
+ GetOccludeeF1D() : UnaryFunction1D<std::vector<ViewShape *>>()
+ {
+ }
+
+ /*! Returns the string "GetOccludeeF1D" */
+ string getName() const
+ {
+ return "GetOccludeeF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D &inter);
};
// internal
////////////
// getOccludeeF1D
-void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
+void getOccludeeF1D(Interface1D &inter, set<ViewShape *> &oShapes);
// getOccludersF1D
-void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes);
+void getOccludersF1D(Interface1D &inter, set<ViewShape *> &oShapes);
// getShapeF1D
-void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
+void getShapeF1D(Interface1D &inter, set<ViewShape *> &oShapes);
-} // end of namespace Functions1D
+} // end of namespace Functions1D
} /* namespace Freestyle */
-#endif // __FREESTYLE_FUNCTIONS_1D_H__
+#endif // __FREESTYLE_FUNCTIONS_1D_H__
diff --git a/source/blender/freestyle/intern/view_map/GridDensityProvider.h b/source/blender/freestyle/intern/view_map/GridDensityProvider.h
index a01569b958a..dacdb345c86 100644
--- a/source/blender/freestyle/intern/view_map/GridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/GridDensityProvider.h
@@ -34,129 +34,137 @@
#include "BKE_global.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
-class GridDensityProvider
-{
- // Disallow copying and assignment
- GridDensityProvider(const GridDensityProvider& other);
- GridDensityProvider& operator=(const GridDensityProvider& other);
-
-public:
- GridDensityProvider(OccluderSource& source) : source(source) {}
-
- virtual ~GridDensityProvider() {};
-
- float cellSize()
- {
- return _cellSize;
- }
-
- unsigned cellsX()
- {
- return _cellsX;
- }
-
- unsigned cellsY()
- {
- return _cellsY;
- }
-
- float cellOrigin(int index)
- {
- if (index < 2) {
- return _cellOrigin[index];
- }
- else {
- throw new out_of_range("GridDensityProvider::cellOrigin can take only indexes of 0 or 1.");
- }
- }
-
- static void calculateOptimalProscenium(OccluderSource& source, real proscenium[4])
- {
- source.begin();
- if (source.isValid()) {
- const Vec3r& initialPoint = source.getGridSpacePolygon().getVertices()[0];
- proscenium[0] = proscenium[1] = initialPoint[0];
- proscenium[2] = proscenium[3] = initialPoint[1];
- while (source.isValid()) {
- GridHelpers::expandProscenium (proscenium, source.getGridSpacePolygon());
- source.next();
- }
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] <<
- ", " << proscenium[3] << ")" << endl;
- }
- }
-
- static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox,
- real proscenium[4])
- {
- // Transform the coordinates of the 8 corners of the 3D bounding box
- real xm = bbox.getMin()[0], xM = bbox.getMax()[0];
- real ym = bbox.getMin()[1], yM = bbox.getMax()[1];
- real zm = bbox.getMin()[2], zM = bbox.getMax()[2];
- Vec3r p1 = transform(Vec3r(xm, ym, zm));
- Vec3r p2 = transform(Vec3r(xm, ym, zM));
- Vec3r p3 = transform(Vec3r(xm, yM, zm));
- Vec3r p4 = transform(Vec3r(xm, yM, zM));
- Vec3r p5 = transform(Vec3r(xM, ym, zm));
- Vec3r p6 = transform(Vec3r(xM, ym, zM));
- Vec3r p7 = transform(Vec3r(xM, yM, zm));
- Vec3r p8 = transform(Vec3r(xM, yM, zM));
- // Determine the proscenium face according to the min and max values of the transformed x and y coordinates
- proscenium[0] = std::min(std::min(std::min(p1.x(), p2.x()), std::min(p3.x(), p4.x())),
- std::min(std::min(p5.x(), p6.x()), std::min(p7.x(), p8.x())));
- proscenium[1] = std::max(std::max(std::max(p1.x(), p2.x()), std::max(p3.x(), p4.x())),
- std::max(std::max(p5.x(), p6.x()), std::max(p7.x(), p8.x())));
- proscenium[2] = std::min(std::min(std::min(p1.y(), p2.y()), std::min(p3.y(), p4.y())),
- std::min(std::min(p5.y(), p6.y()), std::min(p7.y(), p8.y())));
- proscenium[3] = std::max(std::max(std::max(p1.y(), p2.y()), std::max(p3.y(), p4.y())),
- std::max(std::max(p5.y(), p6.y()), std::max(p7.y(), p8.y())));
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Proscenium: " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " <<
- proscenium[3] << endl;
- }
- }
-
-protected:
- OccluderSource& source;
- unsigned _cellsX, _cellsY;
- float _cellSize;
- float _cellOrigin[2];
+class GridDensityProvider {
+ // Disallow copying and assignment
+ GridDensityProvider(const GridDensityProvider &other);
+ GridDensityProvider &operator=(const GridDensityProvider &other);
+
+ public:
+ GridDensityProvider(OccluderSource &source) : source(source)
+ {
+ }
+
+ virtual ~GridDensityProvider(){};
+
+ float cellSize()
+ {
+ return _cellSize;
+ }
+
+ unsigned cellsX()
+ {
+ return _cellsX;
+ }
+
+ unsigned cellsY()
+ {
+ return _cellsY;
+ }
+
+ float cellOrigin(int index)
+ {
+ if (index < 2) {
+ return _cellOrigin[index];
+ }
+ else {
+ throw new out_of_range("GridDensityProvider::cellOrigin can take only indexes of 0 or 1.");
+ }
+ }
+
+ static void calculateOptimalProscenium(OccluderSource &source, real proscenium[4])
+ {
+ source.begin();
+ if (source.isValid()) {
+ const Vec3r &initialPoint = source.getGridSpacePolygon().getVertices()[0];
+ proscenium[0] = proscenium[1] = initialPoint[0];
+ proscenium[2] = proscenium[3] = initialPoint[1];
+ while (source.isValid()) {
+ GridHelpers::expandProscenium(proscenium, source.getGridSpacePolygon());
+ source.next();
+ }
+ }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2]
+ << ", " << proscenium[3] << ")" << endl;
+ }
+ }
+
+ static void calculateQuickProscenium(const GridHelpers::Transform &transform,
+ const BBox<Vec3r> &bbox,
+ real proscenium[4])
+ {
+ // Transform the coordinates of the 8 corners of the 3D bounding box
+ real xm = bbox.getMin()[0], xM = bbox.getMax()[0];
+ real ym = bbox.getMin()[1], yM = bbox.getMax()[1];
+ real zm = bbox.getMin()[2], zM = bbox.getMax()[2];
+ Vec3r p1 = transform(Vec3r(xm, ym, zm));
+ Vec3r p2 = transform(Vec3r(xm, ym, zM));
+ Vec3r p3 = transform(Vec3r(xm, yM, zm));
+ Vec3r p4 = transform(Vec3r(xm, yM, zM));
+ Vec3r p5 = transform(Vec3r(xM, ym, zm));
+ Vec3r p6 = transform(Vec3r(xM, ym, zM));
+ Vec3r p7 = transform(Vec3r(xM, yM, zm));
+ Vec3r p8 = transform(Vec3r(xM, yM, zM));
+ // Determine the proscenium face according to the min and max values of the transformed x and y coordinates
+ proscenium[0] = std::min(std::min(std::min(p1.x(), p2.x()), std::min(p3.x(), p4.x())),
+ std::min(std::min(p5.x(), p6.x()), std::min(p7.x(), p8.x())));
+ proscenium[1] = std::max(std::max(std::max(p1.x(), p2.x()), std::max(p3.x(), p4.x())),
+ std::max(std::max(p5.x(), p6.x()), std::max(p7.x(), p8.x())));
+ proscenium[2] = std::min(std::min(std::min(p1.y(), p2.y()), std::min(p3.y(), p4.y())),
+ std::min(std::min(p5.y(), p6.y()), std::min(p7.y(), p8.y())));
+ proscenium[3] = std::max(std::max(std::max(p1.y(), p2.y()), std::max(p3.y(), p4.y())),
+ std::max(std::max(p5.y(), p6.y()), std::max(p7.y(), p8.y())));
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Proscenium: " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2]
+ << ", " << proscenium[3] << endl;
+ }
+ }
+
+ protected:
+ OccluderSource &source;
+ unsigned _cellsX, _cellsY;
+ float _cellSize;
+ float _cellOrigin[2];
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GridDensityProvider")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GridDensityProvider")
#endif
};
-class GridDensityProviderFactory
-{
- // Disallow copying and assignment
- GridDensityProviderFactory(const GridDensityProviderFactory& other);
- GridDensityProviderFactory& operator=(const GridDensityProviderFactory& other);
+class GridDensityProviderFactory {
+ // Disallow copying and assignment
+ GridDensityProviderFactory(const GridDensityProviderFactory &other);
+ GridDensityProviderFactory &operator=(const GridDensityProviderFactory &other);
-public:
- GridDensityProviderFactory() {}
+ public:
+ GridDensityProviderFactory()
+ {
+ }
- virtual AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) = 0;
+ virtual AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source,
+ const real proscenium[4]) = 0;
- virtual AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform) = 0;
+ virtual AutoPtr<GridDensityProvider> newGridDensityProvider(
+ OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform) = 0;
- virtual AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) = 0;
+ virtual AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source) = 0;
- virtual ~GridDensityProviderFactory () {}
+ virtual ~GridDensityProviderFactory()
+ {
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GridDensityProviderFactory")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GridDensityProviderFactory")
#endif
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_GRID_DENSITY_PROVIDER_H__
+#endif // __FREESTYLE_GRID_DENSITY_PROVIDER_H__
diff --git a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
index 676ce8046ad..55bc02b8358 100644
--- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
+++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
@@ -23,53 +23,61 @@
namespace Freestyle {
-HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces)
-: sizeFactor(sizeFactor), numFaces(numFaces)
+HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor,
+ unsigned numFaces)
+ : sizeFactor(sizeFactor), numFaces(numFaces)
{
}
-HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory() {}
+HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory()
+{
+}
-AutoPtr<GridDensityProvider>
-HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
+AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source, const real proscenium[4])
{
- AutoPtr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
- AutoPtr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
- if (avg->cellSize() > p23->cellSize()) {
- return (AutoPtr<GridDensityProvider>) p23;
- }
- else {
- return (AutoPtr<GridDensityProvider>) avg;
- }
+ AutoPtr<AverageAreaGridDensityProvider> avg(
+ new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
+ AutoPtr<Pow23GridDensityProvider> p23(
+ new Pow23GridDensityProvider(source, proscenium, numFaces));
+ if (avg->cellSize() > p23->cellSize()) {
+ return (AutoPtr<GridDensityProvider>)p23;
+ }
+ else {
+ return (AutoPtr<GridDensityProvider>)avg;
+ }
}
-AutoPtr<GridDensityProvider>
-HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform)
+AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source, const BBox<Vec3r> &bbox, const GridHelpers::Transform &transform)
{
- AutoPtr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox,
- transform, sizeFactor));
- AutoPtr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
- if (avg->cellSize() > p23->cellSize()) {
- return (AutoPtr<GridDensityProvider>) p23;
- }
- else {
- return (AutoPtr<GridDensityProvider>) avg;
- }
+ AutoPtr<AverageAreaGridDensityProvider> avg(
+ new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
+ AutoPtr<Pow23GridDensityProvider> p23(
+ new Pow23GridDensityProvider(source, bbox, transform, numFaces));
+ if (avg->cellSize() > p23->cellSize()) {
+ return (AutoPtr<GridDensityProvider>)p23;
+ }
+ else {
+ return (AutoPtr<GridDensityProvider>)avg;
+ }
}
-AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source)
{
- real proscenium[4];
- GridDensityProvider::calculateOptimalProscenium(source, proscenium);
- AutoPtr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
- AutoPtr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
- if (avg->cellSize() > p23->cellSize()) {
- return (AutoPtr<GridDensityProvider>) p23;
- }
- else {
- return (AutoPtr<GridDensityProvider>) avg;
- }
+ real proscenium[4];
+ GridDensityProvider::calculateOptimalProscenium(source, proscenium);
+ AutoPtr<AverageAreaGridDensityProvider> avg(
+ new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
+ AutoPtr<Pow23GridDensityProvider> p23(
+ new Pow23GridDensityProvider(source, proscenium, numFaces));
+ if (avg->cellSize() > p23->cellSize()) {
+ return (AutoPtr<GridDensityProvider>)p23;
+ }
+ else {
+ return (AutoPtr<GridDensityProvider>)avg;
+ }
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
index 87f602945f1..b32a284cb61 100644
--- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
+++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
@@ -30,22 +30,23 @@
namespace Freestyle {
-class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory
-{
-public:
- HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
- ~HeuristicGridDensityProviderFactory();
-
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform);
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
-
-protected:
- real sizeFactor;
- unsigned numFaces;
+class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory {
+ public:
+ HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
+ ~HeuristicGridDensityProviderFactory();
+
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source,
+ const real proscenium[4]);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source);
+
+ protected:
+ real sizeFactor;
+ unsigned numFaces;
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
+#endif // __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
diff --git a/source/blender/freestyle/intern/view_map/Interface0D.cpp b/source/blender/freestyle/intern/view_map/Interface0D.cpp
index 17331bb613f..fc5a797cc87 100644
--- a/source/blender/freestyle/intern/view_map/Interface0D.cpp
+++ b/source/blender/freestyle/intern/view_map/Interface0D.cpp
@@ -28,92 +28,92 @@ namespace Freestyle {
real Interface0D::getX() const
{
- PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
+ return 0;
}
real Interface0D::getY() const
{
- PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
+ return 0;
}
real Interface0D::getZ() const
{
- PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
+ return 0;
}
Geometry::Vec3r Interface0D::getPoint3D() const
{
- PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
+ return 0;
}
real Interface0D::getProjectedX() const
{
- PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
+ return 0;
}
real Interface0D::getProjectedY() const
{
- PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
+ return 0;
}
real Interface0D::getProjectedZ() const
{
- PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
+ return 0;
}
Geometry::Vec2r Interface0D::getPoint2D() const
{
- PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
+ return 0;
}
-FEdge *Interface0D::getFEdge(Interface0D&)
+FEdge *Interface0D::getFEdge(Interface0D &)
{
- PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
+ return 0;
}
Id Interface0D::getId() const
{
- PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
+ return 0;
}
Nature::VertexNature Interface0D::getNature() const
{
- PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
- return Nature::POINT;
+ PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
+ return Nature::POINT;
}
SVertex *Interface0D::castToSVertex()
{
- PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
+ return 0;
}
ViewVertex *Interface0D::castToViewVertex()
{
- PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
+ return 0;
}
NonTVertex *Interface0D::castToNonTVertex()
{
- PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
+ return 0;
}
TVertex *Interface0D::castToTVertex()
{
- PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
+ return 0;
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/Interface0D.h b/source/blender/freestyle/intern/view_map/Interface0D.h
index 88214bb80a1..bab996d9308 100644
--- a/source/blender/freestyle/intern/view_map/Interface0D.h
+++ b/source/blender/freestyle/intern/view_map/Interface0D.h
@@ -34,7 +34,7 @@
#include "../winged_edge/Nature.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
using namespace std;
@@ -53,121 +53,121 @@ class NonTVertex;
class TVertex;
/*! Base class for any 0D element. */
-class Interface0D
-{
-public:
- /*! Default constructor */
- Interface0D() {}
+class Interface0D {
+ public:
+ /*! Default constructor */
+ Interface0D()
+ {
+ }
- /*! Destructor */
- virtual ~Interface0D() {};
+ /*! Destructor */
+ virtual ~Interface0D(){};
- /*! Returns the string "Interface0D". */
- virtual string getExactTypeName() const
- {
- return "Interface0D";
- }
+ /*! Returns the string "Interface0D". */
+ virtual string getExactTypeName() const
+ {
+ return "Interface0D";
+ }
- // Data access methods
+ // Data access methods
- /*! Returns the 3D x coordinate of the point. */
- virtual real getX() const;
+ /*! Returns the 3D x coordinate of the point. */
+ virtual real getX() const;
- /*! Returns the 3D y coordinate of the point. */
- virtual real getY() const;
+ /*! Returns the 3D y coordinate of the point. */
+ virtual real getY() const;
- /*! Returns the 3D z coordinate of the point. */
- virtual real getZ() const;
+ /*! Returns the 3D z coordinate of the point. */
+ virtual real getZ() const;
- /*! Returns the 3D point. */
- virtual Geometry::Vec3r getPoint3D() const;
+ /*! Returns the 3D point. */
+ virtual Geometry::Vec3r getPoint3D() const;
- /*! Returns the 2D x coordinate of the point. */
- virtual real getProjectedX() const;
+ /*! Returns the 2D x coordinate of the point. */
+ virtual real getProjectedX() const;
- /*! Returns the 2D y coordinate of the point. */
- virtual real getProjectedY() const;
+ /*! Returns the 2D y coordinate of the point. */
+ virtual real getProjectedY() const;
- /*! Returns the 2D z coordinate of the point. */
- virtual real getProjectedZ() const;
+ /*! Returns the 2D z coordinate of the point. */
+ virtual real getProjectedZ() const;
- /*! Returns the 2D point. */
- virtual Geometry::Vec2r getPoint2D() const;
+ /*! Returns the 2D point. */
+ virtual Geometry::Vec2r getPoint2D() const;
- /*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */
- virtual FEdge *getFEdge(Interface0D&);
+ /*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */
+ virtual FEdge *getFEdge(Interface0D &);
- /*! Returns the Id of the point. */
- virtual Id getId() const;
+ /*! Returns the Id of the point. */
+ virtual Id getId() const;
- /*! Returns the nature of the point. */
- virtual Nature::VertexNature getNature() const;
+ /*! Returns the nature of the point. */
+ virtual Nature::VertexNature getNature() const;
- /*! Cast the Interface0D in SVertex if it can be. */
- virtual SVertex *castToSVertex();
+ /*! Cast the Interface0D in SVertex if it can be. */
+ virtual SVertex *castToSVertex();
- /*! Cast the Interface0D in ViewVertex if it can be. */
- virtual ViewVertex *castToViewVertex();
+ /*! Cast the Interface0D in ViewVertex if it can be. */
+ virtual ViewVertex *castToViewVertex();
- /*! Cast the Interface0D in NonTVertex if it can be. */
- virtual NonTVertex *castToNonTVertex();
+ /*! Cast the Interface0D in NonTVertex if it can be. */
+ virtual NonTVertex *castToNonTVertex();
- /*! Cast the Interface0D in TVertex if it can be. */
- virtual TVertex *castToTVertex();
+ /*! Cast the Interface0D in TVertex if it can be. */
+ virtual TVertex *castToTVertex();
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Interface0D")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Interface0D")
#endif
};
-
//
// Interface0DIteratorNested
//
//////////////////////////////////////////////////
-class Interface0DIteratorNested : public Iterator
-{
-public:
- virtual ~Interface0DIteratorNested() {}
+class Interface0DIteratorNested : public Iterator {
+ public:
+ virtual ~Interface0DIteratorNested()
+ {
+ }
- virtual string getExactTypeName() const
- {
- return "Interface0DIteratorNested";
- }
+ virtual string getExactTypeName() const
+ {
+ return "Interface0DIteratorNested";
+ }
- virtual Interface0D& operator*() = 0;
+ virtual Interface0D &operator*() = 0;
- virtual Interface0D *operator->()
- {
- return &(operator*());
- }
+ virtual Interface0D *operator->()
+ {
+ return &(operator*());
+ }
- virtual int increment() = 0;
+ virtual int increment() = 0;
- virtual int decrement() = 0;
+ virtual int decrement() = 0;
- virtual bool isBegin() const = 0;
+ virtual bool isBegin() const = 0;
- virtual bool isEnd() const = 0;
+ virtual bool isEnd() const = 0;
- virtual bool operator==(const Interface0DIteratorNested& it) const = 0;
+ virtual bool operator==(const Interface0DIteratorNested &it) const = 0;
- virtual bool operator!=(const Interface0DIteratorNested& it) const
- {
- return !(*this == it);
- }
+ virtual bool operator!=(const Interface0DIteratorNested &it) const
+ {
+ return !(*this == it);
+ }
- /*! Returns the curvilinear abscissa */
- virtual float t() const = 0;
+ /*! Returns the curvilinear abscissa */
+ virtual float t() const = 0;
- /*! Returns the point parameter 0<u<1 */
- virtual float u() const = 0;
+ /*! Returns the point parameter 0<u<1 */
+ virtual float u() const = 0;
- virtual Interface0DIteratorNested *copy() const = 0;
+ virtual Interface0DIteratorNested *copy() const = 0;
};
-
//
// Interface0DIterator
//
@@ -179,163 +179,162 @@ public:
* \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
* Otherwise, incrementing \a it1 will also increment \a it2.
*/
-class Interface0DIterator : public Iterator
-{
-public:
- Interface0DIterator(Interface0DIteratorNested *it = NULL)
- {
- _iterator = it;
- }
-
- /*! Copy constructor */
- Interface0DIterator(const Interface0DIterator& it)
- {
- _iterator = it._iterator->copy();
- }
-
- /*! Destructor */
- virtual ~Interface0DIterator()
- {
- if (_iterator)
- delete _iterator;
- }
-
- /*! Operator =
- * \attention In the scripting language, you must call \code it2 = Interface0DIterator(it1) \endcode instead of
- * \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
- * Otherwise, incrementing \a it1 will also increment \a it2.
- */
- Interface0DIterator& operator=(const Interface0DIterator& it)
- {
- if (_iterator)
- delete _iterator;
- _iterator = it._iterator->copy();
- return *this;
- }
-
- /*! Returns the string "Interface0DIterator". */
- virtual string getExactTypeName() const
- {
- if (!_iterator)
- return "Interface0DIterator";
- return _iterator->getExactTypeName() + "Proxy";
- }
-
- // FIXME test it != 0 (exceptions ?)
-
- /*! Returns a reference to the pointed Interface0D.
- * In the scripting language, you must call "getObject()" instead using this operator.
- */
- Interface0D& operator*()
- {
- return _iterator->operator*();
- }
-
- /*! Returns a pointer to the pointed Interface0D.
- * Can't be called in the scripting language.
- */
- Interface0D *operator->()
- {
- return &(operator*());
- }
-
- /*! Increments. In the scripting language, call "increment()". */
- Interface0DIterator& operator++()
- {
- _iterator->increment();
- return *this;
- }
-
- /*! Increments. In the scripting language, call "increment()". */
- Interface0DIterator operator++(int)
- {
- Interface0DIterator ret(*this);
- _iterator->increment();
- return ret;
- }
-
- /*! Decrements. In the scripting language, call "decrement()". */
- Interface0DIterator& operator--()
- {
- _iterator->decrement();
- return *this;
- }
-
- /*! Decrements. In the scripting language, call "decrement()". */
- Interface0DIterator operator--(int)
- {
- Interface0DIterator ret(*this);
- _iterator->decrement();
- return ret;
- }
-
- /*! Increments. */
- virtual int increment()
- {
- return _iterator->increment();
- }
-
- /*! Decrements. */
- virtual int decrement()
- {
- return _iterator->decrement();
- }
-
- /*! Returns true if the pointed Interface0D is the first of the 1D element containing the points over which
- * we're iterating.
- */
- virtual bool isBegin() const
- {
- return _iterator->isBegin();
- }
-
- /*! Returns true if the pointed Interface0D is after the after the last point of the 1D element we're
- * iterating from. */
- virtual bool isEnd() const
- {
- return _iterator->isEnd();
- }
-
- /*! Returns true when the iterator is pointing to the final valid element. */
- virtual bool atLast() const
- {
- if (_iterator->isEnd())
- return false;
-
- _iterator->increment();
- bool result = _iterator->isEnd();
- _iterator->decrement();
- return result;
- }
-
- /*! operator == . */
- bool operator==(const Interface0DIterator& it) const
- {
- return _iterator->operator==(*(it._iterator));
- }
-
- /*! operator != . */
- bool operator!=(const Interface0DIterator& it) const
- {
- return !(*this == it);
- }
-
- /*! Returns the curvilinear abscissa. */
- inline float t() const
- {
- return _iterator->t();
- }
-
- /*! Returns the point parameter in the curve 0<=u<=1. */
- inline float u() const
- {
- return _iterator->u();
- }
-
-protected:
- Interface0DIteratorNested *_iterator;
+class Interface0DIterator : public Iterator {
+ public:
+ Interface0DIterator(Interface0DIteratorNested *it = NULL)
+ {
+ _iterator = it;
+ }
+
+ /*! Copy constructor */
+ Interface0DIterator(const Interface0DIterator &it)
+ {
+ _iterator = it._iterator->copy();
+ }
+
+ /*! Destructor */
+ virtual ~Interface0DIterator()
+ {
+ if (_iterator)
+ delete _iterator;
+ }
+
+ /*! Operator =
+ * \attention In the scripting language, you must call \code it2 = Interface0DIterator(it1) \endcode instead of
+ * \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
+ * Otherwise, incrementing \a it1 will also increment \a it2.
+ */
+ Interface0DIterator &operator=(const Interface0DIterator &it)
+ {
+ if (_iterator)
+ delete _iterator;
+ _iterator = it._iterator->copy();
+ return *this;
+ }
+
+ /*! Returns the string "Interface0DIterator". */
+ virtual string getExactTypeName() const
+ {
+ if (!_iterator)
+ return "Interface0DIterator";
+ return _iterator->getExactTypeName() + "Proxy";
+ }
+
+ // FIXME test it != 0 (exceptions ?)
+
+ /*! Returns a reference to the pointed Interface0D.
+ * In the scripting language, you must call "getObject()" instead using this operator.
+ */
+ Interface0D &operator*()
+ {
+ return _iterator->operator*();
+ }
+
+ /*! Returns a pointer to the pointed Interface0D.
+ * Can't be called in the scripting language.
+ */
+ Interface0D *operator->()
+ {
+ return &(operator*());
+ }
+
+ /*! Increments. In the scripting language, call "increment()". */
+ Interface0DIterator &operator++()
+ {
+ _iterator->increment();
+ return *this;
+ }
+
+ /*! Increments. In the scripting language, call "increment()". */
+ Interface0DIterator operator++(int)
+ {
+ Interface0DIterator ret(*this);
+ _iterator->increment();
+ return ret;
+ }
+
+ /*! Decrements. In the scripting language, call "decrement()". */
+ Interface0DIterator &operator--()
+ {
+ _iterator->decrement();
+ return *this;
+ }
+
+ /*! Decrements. In the scripting language, call "decrement()". */
+ Interface0DIterator operator--(int)
+ {
+ Interface0DIterator ret(*this);
+ _iterator->decrement();
+ return ret;
+ }
+
+ /*! Increments. */
+ virtual int increment()
+ {
+ return _iterator->increment();
+ }
+
+ /*! Decrements. */
+ virtual int decrement()
+ {
+ return _iterator->decrement();
+ }
+
+ /*! Returns true if the pointed Interface0D is the first of the 1D element containing the points over which
+ * we're iterating.
+ */
+ virtual bool isBegin() const
+ {
+ return _iterator->isBegin();
+ }
+
+ /*! Returns true if the pointed Interface0D is after the after the last point of the 1D element we're
+ * iterating from. */
+ virtual bool isEnd() const
+ {
+ return _iterator->isEnd();
+ }
+
+ /*! Returns true when the iterator is pointing to the final valid element. */
+ virtual bool atLast() const
+ {
+ if (_iterator->isEnd())
+ return false;
+
+ _iterator->increment();
+ bool result = _iterator->isEnd();
+ _iterator->decrement();
+ return result;
+ }
+
+ /*! operator == . */
+ bool operator==(const Interface0DIterator &it) const
+ {
+ return _iterator->operator==(*(it._iterator));
+ }
+
+ /*! operator != . */
+ bool operator!=(const Interface0DIterator &it) const
+ {
+ return !(*this == it);
+ }
+
+ /*! Returns the curvilinear abscissa. */
+ inline float t() const
+ {
+ return _iterator->t();
+ }
+
+ /*! Returns the point parameter in the curve 0<=u<=1. */
+ inline float u() const
+ {
+ return _iterator->u();
+ }
+
+ protected:
+ Interface0DIteratorNested *_iterator;
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_INTERFACE_0D_H__
+#endif // __FREESTYLE_INTERFACE_0D_H__
diff --git a/source/blender/freestyle/intern/view_map/Interface1D.cpp b/source/blender/freestyle/intern/view_map/Interface1D.cpp
index 4f3c46bbf01..ef219365831 100644
--- a/source/blender/freestyle/intern/view_map/Interface1D.cpp
+++ b/source/blender/freestyle/intern/view_map/Interface1D.cpp
@@ -28,44 +28,44 @@ namespace Freestyle {
Interface0DIterator Interface1D::verticesBegin()
{
- PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
- return Interface0DIterator();
+ PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
+ return Interface0DIterator();
}
Interface0DIterator Interface1D::verticesEnd()
{
- PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
- return Interface0DIterator();
+ PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
+ return Interface0DIterator();
}
Interface0DIterator Interface1D::pointsBegin(float /*t*/)
{
- PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
- return Interface0DIterator();
+ PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
+ return Interface0DIterator();
}
Interface0DIterator Interface1D::pointsEnd(float /*t*/)
{
- PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
- return Interface0DIterator();
+ PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
+ return Interface0DIterator();
}
real Interface1D::getLength2D() const
{
- PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
- return 0;
+ PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
+ return 0;
}
Id Interface1D::getId() const
{
- PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
- return Id(0, 0);
+ PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
+ return Id(0, 0);
}
Nature::EdgeNature Interface1D::getNature() const
{
- PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
- return Nature::NO_FEATURE;
+ PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
+ return Nature::NO_FEATURE;
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/Interface1D.h b/source/blender/freestyle/intern/view_map/Interface1D.h
index de190f22e2d..e56a58096f8 100644
--- a/source/blender/freestyle/intern/view_map/Interface1D.h
+++ b/source/blender/freestyle/intern/view_map/Interface1D.h
@@ -34,7 +34,7 @@
#include "../winged_edge/Nature.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
using namespace std;
@@ -46,11 +46,11 @@ namespace Freestyle {
* from each 0D element of a 1D element.
*/
typedef enum {
- MEAN, /*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/
- MIN, /*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/
- MAX, /*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/
- FIRST, /*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/
- LAST, /*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/
+ MEAN, /*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/
+ MIN, /*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/
+ MAX, /*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/
+ FIRST, /*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/
+ LAST, /*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/
} IntegrationType;
/*! Returns a single value from a set of values evaluated at each 0D element of this 1D element.
@@ -65,54 +65,56 @@ typedef enum {
* The integration method used to compute a single value from a set of values.
* \return the single value obtained for the 1D element.
*/
-template <class T>
-T integrate(UnaryFunction0D<T>& fun, Interface0DIterator it, Interface0DIterator it_end,
+template<class T>
+T integrate(UnaryFunction0D<T> &fun,
+ Interface0DIterator it,
+ Interface0DIterator it_end,
IntegrationType integration_type = MEAN)
{
- T res;
- unsigned size;
- switch (integration_type) {
- case MIN:
- fun(it);
- res = fun.result;
- ++it;
- for (; !it.isEnd(); ++it) {
- fun(it);
- if (fun.result < res)
- res = fun.result;
- }
- break;
- case MAX:
- fun(it);
- res = fun.result;
- ++it;
- for (; !it.isEnd(); ++it) {
- fun(it);
- if (fun.result > res)
- res = fun.result;
- }
- break;
- case FIRST:
- fun(it);
- res = fun.result;
- break;
- case LAST:
- fun(--it_end);
- res = fun.result;
- break;
- case MEAN:
- default:
- fun(it);
- res = fun.result;
- ++it;
- for (size = 1; !it.isEnd(); ++it, ++size) {
- fun(it);
- res += fun.result;
- }
- res /= (size ? size : 1);
- break;
- }
- return res;
+ T res;
+ unsigned size;
+ switch (integration_type) {
+ case MIN:
+ fun(it);
+ res = fun.result;
+ ++it;
+ for (; !it.isEnd(); ++it) {
+ fun(it);
+ if (fun.result < res)
+ res = fun.result;
+ }
+ break;
+ case MAX:
+ fun(it);
+ res = fun.result;
+ ++it;
+ for (; !it.isEnd(); ++it) {
+ fun(it);
+ if (fun.result > res)
+ res = fun.result;
+ }
+ break;
+ case FIRST:
+ fun(it);
+ res = fun.result;
+ break;
+ case LAST:
+ fun(--it_end);
+ res = fun.result;
+ break;
+ case MEAN:
+ default:
+ fun(it);
+ res = fun.result;
+ ++it;
+ for (size = 1; !it.isEnd(); ++it, ++size) {
+ fun(it);
+ res += fun.result;
+ }
+ res /= (size ? size : 1);
+ break;
+ }
+ return res;
}
//
@@ -121,80 +123,79 @@ T integrate(UnaryFunction0D<T>& fun, Interface0DIterator it, Interface0DIterator
//////////////////////////////////////////////////
/*! Base class for any 1D element. */
-class Interface1D
-{
-public:
- /*! Default constructor */
- Interface1D()
- {
- _timeStamp = 0;
- }
-
- /*! Destructor */
- virtual ~Interface1D() {};
-
- /*! Returns the string "Interface1D". */
- virtual string getExactTypeName() const
- {
- return "Interface1D";
- }
-
- // Iterator access
-
- /*! Returns an iterator over the Interface1D vertices, pointing to the first vertex. */
- virtual Interface0DIterator verticesBegin();
-
- /*! Returns an iterator over the Interface1D vertices, pointing after the last vertex. */
- virtual Interface0DIterator verticesEnd();
-
- /*! Returns an iterator over the Interface1D points, pointing to the first point. The difference with
- * verticesBegin() is that here we can iterate over points of the 1D element at a any given sampling.
- * Indeed, for each iteration, a virtual point is created.
- * \param t:
- * The sampling with which we want to iterate over points of this 1D element.
- */
- virtual Interface0DIterator pointsBegin(float t = 0.0f);
-
- /*! Returns an iterator over the Interface1D points, pointing after the last point. The difference with
- * verticesEnd() is that here we can iterate over points of the 1D element at a any given sampling.
- * Indeed, for each iteration, a virtual point is created.
- * \param t:
- * The sampling with which we want to iterate over points of this 1D element.
- */
- virtual Interface0DIterator pointsEnd(float t = 0.0f);
-
- // Data access methods
-
- /*! Returns the 2D length of the 1D element. */
- virtual real getLength2D() const;
-
- /*! Returns the Id of the 1D element. */
- virtual Id getId() const;
-
- // FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D)
- /*! Returns the nature of the 1D element. */
- virtual Nature::EdgeNature getNature() const;
-
- /*! Returns the time stamp of the 1D element. Mainly used for selection. */
- virtual unsigned getTimeStamp() const
- {
- return _timeStamp;
- }
-
- /*! Sets the time stamp for the 1D element. */
- inline void setTimeStamp(unsigned iTimeStamp)
- {
- _timeStamp = iTimeStamp;
- }
-
-protected:
- unsigned _timeStamp;
+class Interface1D {
+ public:
+ /*! Default constructor */
+ Interface1D()
+ {
+ _timeStamp = 0;
+ }
+
+ /*! Destructor */
+ virtual ~Interface1D(){};
+
+ /*! Returns the string "Interface1D". */
+ virtual string getExactTypeName() const
+ {
+ return "Interface1D";
+ }
+
+ // Iterator access
+
+ /*! Returns an iterator over the Interface1D vertices, pointing to the first vertex. */
+ virtual Interface0DIterator verticesBegin();
+
+ /*! Returns an iterator over the Interface1D vertices, pointing after the last vertex. */
+ virtual Interface0DIterator verticesEnd();
+
+ /*! Returns an iterator over the Interface1D points, pointing to the first point. The difference with
+ * verticesBegin() is that here we can iterate over points of the 1D element at a any given sampling.
+ * Indeed, for each iteration, a virtual point is created.
+ * \param t:
+ * The sampling with which we want to iterate over points of this 1D element.
+ */
+ virtual Interface0DIterator pointsBegin(float t = 0.0f);
+
+ /*! Returns an iterator over the Interface1D points, pointing after the last point. The difference with
+ * verticesEnd() is that here we can iterate over points of the 1D element at a any given sampling.
+ * Indeed, for each iteration, a virtual point is created.
+ * \param t:
+ * The sampling with which we want to iterate over points of this 1D element.
+ */
+ virtual Interface0DIterator pointsEnd(float t = 0.0f);
+
+ // Data access methods
+
+ /*! Returns the 2D length of the 1D element. */
+ virtual real getLength2D() const;
+
+ /*! Returns the Id of the 1D element. */
+ virtual Id getId() const;
+
+ // FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D)
+ /*! Returns the nature of the 1D element. */
+ virtual Nature::EdgeNature getNature() const;
+
+ /*! Returns the time stamp of the 1D element. Mainly used for selection. */
+ virtual unsigned getTimeStamp() const
+ {
+ return _timeStamp;
+ }
+
+ /*! Sets the time stamp for the 1D element. */
+ inline void setTimeStamp(unsigned iTimeStamp)
+ {
+ _timeStamp = iTimeStamp;
+ }
+
+ protected:
+ unsigned _timeStamp;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Interface1D")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Interface1D")
#endif
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_INTERFACE_1D_H__
+#endif // __FREESTYLE_INTERFACE_1D_H__
diff --git a/source/blender/freestyle/intern/view_map/OccluderSource.cpp b/source/blender/freestyle/intern/view_map/OccluderSource.cpp
index 90393825d28..7132e0172ae 100644
--- a/source/blender/freestyle/intern/view_map/OccluderSource.cpp
+++ b/source/blender/freestyle/intern/view_map/OccluderSource.cpp
@@ -27,116 +27,119 @@
namespace Freestyle {
-OccluderSource::OccluderSource(const GridHelpers::Transform& t, WingedEdge& we)
-: wingedEdge(we), valid(false), transform(t)
+OccluderSource::OccluderSource(const GridHelpers::Transform &t, WingedEdge &we)
+ : wingedEdge(we), valid(false), transform(t)
{
- begin();
+ begin();
}
-OccluderSource::~OccluderSource() {}
+OccluderSource::~OccluderSource()
+{
+}
void OccluderSource::buildCachedPolygon()
{
- vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()));
- // This doesn't work, because our functor's polymorphism won't survive the copy:
- // std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform);
- // so we have to do:
- for (vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i) {
- (*i) = transform(*i);
- }
- cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
+ vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()));
+ // This doesn't work, because our functor's polymorphism won't survive the copy:
+ // std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform);
+ // so we have to do:
+ for (vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i) {
+ (*i) = transform(*i);
+ }
+ cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
}
void OccluderSource::begin()
{
- vector<WShape*>& wshapes = wingedEdge.getWShapes();
- currentShape = wshapes.begin();
- shapesEnd = wshapes.end();
- valid = false;
- if (currentShape != shapesEnd) {
- vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
- currentFace = wFaces.begin();
- facesEnd = wFaces.end();
-
- if (currentFace != facesEnd) {
- buildCachedPolygon();
- valid = true;
- }
- }
+ vector<WShape *> &wshapes = wingedEdge.getWShapes();
+ currentShape = wshapes.begin();
+ shapesEnd = wshapes.end();
+ valid = false;
+ if (currentShape != shapesEnd) {
+ vector<WFace *> &wFaces = (*currentShape)->GetFaceList();
+ currentFace = wFaces.begin();
+ facesEnd = wFaces.end();
+
+ if (currentFace != facesEnd) {
+ buildCachedPolygon();
+ valid = true;
+ }
+ }
}
bool OccluderSource::next()
{
- if (valid) {
- ++currentFace;
- while (currentFace == facesEnd) {
- ++currentShape;
- if (currentShape == shapesEnd) {
- valid = false;
- return false;
- }
- else {
- vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
- currentFace = wFaces.begin();
- facesEnd = wFaces.end();
- }
- }
- buildCachedPolygon();
- return true;
- }
- return false;
+ if (valid) {
+ ++currentFace;
+ while (currentFace == facesEnd) {
+ ++currentShape;
+ if (currentShape == shapesEnd) {
+ valid = false;
+ return false;
+ }
+ else {
+ vector<WFace *> &wFaces = (*currentShape)->GetFaceList();
+ currentFace = wFaces.begin();
+ facesEnd = wFaces.end();
+ }
+ }
+ buildCachedPolygon();
+ return true;
+ }
+ return false;
}
bool OccluderSource::isValid()
{
- // Or:
- // return currentShapes != shapesEnd && currentFace != facesEnd;
- return valid;
+ // Or:
+ // return currentShapes != shapesEnd && currentFace != facesEnd;
+ return valid;
}
WFace *OccluderSource::getWFace()
{
- return valid ? *currentFace : NULL;
+ return valid ? *currentFace : NULL;
}
Polygon3r OccluderSource::getCameraSpacePolygon()
{
- return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()), (*currentFace)->GetNormal());
+ return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()),
+ (*currentFace)->GetNormal());
}
-Polygon3r& OccluderSource::getGridSpacePolygon()
+Polygon3r &OccluderSource::getGridSpacePolygon()
{
- return cachedPolygon;
+ return cachedPolygon;
}
void OccluderSource::getOccluderProscenium(real proscenium[4])
{
- begin();
- const Vec3r& initialPoint = cachedPolygon.getVertices()[0];
- proscenium[0] = proscenium[1] = initialPoint[0];
- proscenium[2] = proscenium[3] = initialPoint[1];
- while (isValid()) {
- GridHelpers::expandProscenium (proscenium, cachedPolygon);
- next();
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " <<
- proscenium[3] << ")" << endl;
- }
+ begin();
+ const Vec3r &initialPoint = cachedPolygon.getVertices()[0];
+ proscenium[0] = proscenium[1] = initialPoint[0];
+ proscenium[2] = proscenium[3] = initialPoint[1];
+ while (isValid()) {
+ GridHelpers::expandProscenium(proscenium, cachedPolygon);
+ next();
+ }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2]
+ << ", " << proscenium[3] << ")" << endl;
+ }
}
real OccluderSource::averageOccluderArea()
{
- real area = 0.0;
- unsigned numFaces = 0;
- for (begin(); isValid(); next()) {
- Vec3r min, max;
- cachedPolygon.getBBox(min, max);
- area += (max[0] - min[0]) * (max[1] - min[1]);
- ++numFaces;
- }
- area /= numFaces;
- return area;
+ real area = 0.0;
+ unsigned numFaces = 0;
+ for (begin(); isValid(); next()) {
+ Vec3r min, max;
+ cachedPolygon.getBBox(min, max);
+ area += (max[0] - min[0]) * (max[1] - min[1]);
+ ++numFaces;
+ }
+ area /= numFaces;
+ return area;
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/OccluderSource.h b/source/blender/freestyle/intern/view_map/OccluderSource.h
index fd7d9f38a0d..07df3b95347 100644
--- a/source/blender/freestyle/intern/view_map/OccluderSource.h
+++ b/source/blender/freestyle/intern/view_map/OccluderSource.h
@@ -27,49 +27,48 @@
#include "../winged_edge/WEdge.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
-class OccluderSource
-{
- // Disallow copying and assignment
- OccluderSource(const OccluderSource& other);
- OccluderSource& operator=(const OccluderSource& other);
+class OccluderSource {
+ // Disallow copying and assignment
+ OccluderSource(const OccluderSource &other);
+ OccluderSource &operator=(const OccluderSource &other);
-public:
- OccluderSource(const GridHelpers::Transform& transform, WingedEdge& we);
- virtual ~OccluderSource();
+ public:
+ OccluderSource(const GridHelpers::Transform &transform, WingedEdge &we);
+ virtual ~OccluderSource();
- void begin();
- virtual bool next();
- bool isValid();
+ void begin();
+ virtual bool next();
+ bool isValid();
- WFace *getWFace();
- Polygon3r getCameraSpacePolygon();
- Polygon3r& getGridSpacePolygon();
+ WFace *getWFace();
+ Polygon3r getCameraSpacePolygon();
+ Polygon3r &getGridSpacePolygon();
- virtual void getOccluderProscenium(real proscenium[4]);
- virtual real averageOccluderArea();
+ virtual void getOccluderProscenium(real proscenium[4]);
+ virtual real averageOccluderArea();
-protected:
- WingedEdge& wingedEdge;
- vector<WShape*>::const_iterator currentShape, shapesEnd;
- vector<WFace*>::const_iterator currentFace, facesEnd;
+ protected:
+ WingedEdge &wingedEdge;
+ vector<WShape *>::const_iterator currentShape, shapesEnd;
+ vector<WFace *>::const_iterator currentFace, facesEnd;
- bool valid;
+ bool valid;
- Polygon3r cachedPolygon;
- const GridHelpers::Transform& transform;
+ Polygon3r cachedPolygon;
+ const GridHelpers::Transform &transform;
- void buildCachedPolygon();
+ void buildCachedPolygon();
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OccluderSource")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OccluderSource")
#endif
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_OCCLUDER_SOURCE_H__
+#endif // __FREESTYLE_OCCLUDER_SOURCE_H__
diff --git a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
index 858e6b649eb..7e7f4e14882 100644
--- a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
@@ -25,90 +25,100 @@
namespace Freestyle {
-Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces)
-: GridDensityProvider(source), numFaces(numFaces)
+Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource &source,
+ const real proscenium[4],
+ unsigned numFaces)
+ : GridDensityProvider(source), numFaces(numFaces)
{
- initialize (proscenium);
+ initialize(proscenium);
}
-Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform, unsigned numFaces)
-: GridDensityProvider(source), numFaces(numFaces)
+Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform,
+ unsigned numFaces)
+ : GridDensityProvider(source), numFaces(numFaces)
{
- real proscenium[4];
- calculateQuickProscenium(transform, bbox, proscenium);
+ real proscenium[4];
+ calculateQuickProscenium(transform, bbox, proscenium);
- initialize (proscenium);
+ initialize(proscenium);
}
-Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces)
-: GridDensityProvider(source), numFaces(numFaces)
+Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource &source, unsigned numFaces)
+ : GridDensityProvider(source), numFaces(numFaces)
{
- real proscenium[4];
- calculateOptimalProscenium(source, proscenium);
+ real proscenium[4];
+ calculateOptimalProscenium(source, proscenium);
- initialize (proscenium);
+ initialize(proscenium);
}
-Pow23GridDensityProvider::~Pow23GridDensityProvider () {}
+Pow23GridDensityProvider::~Pow23GridDensityProvider()
+{
+}
void Pow23GridDensityProvider::initialize(const real proscenium[4])
{
- float prosceniumWidth = (proscenium[1] - proscenium[0]);
- float prosceniumHeight = (proscenium[3] - proscenium[2]);
- real cellArea = prosceniumWidth * prosceniumHeight / pow(numFaces, 2.0f / 3.0f);
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << prosceniumWidth << " x " << prosceniumHeight << " grid with cells of area " << cellArea << "." << endl;
- }
-
- _cellSize = sqrt(cellArea);
- // Now we know how many cells make each side of our grid
- _cellsX = ceil(prosceniumWidth / _cellSize);
- _cellsY = ceil(prosceniumHeight / _cellSize);
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
- }
-
- // Make sure the grid exceeds the proscenium by a small amount
- float safetyZone = 0.1;
- if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
- _cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
- }
- if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
- _cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
- }
-
- // Find grid origin
- _cellOrigin[0] = ((proscenium[0] + proscenium[1]) / 2.0) - (_cellsX / 2.0) * _cellSize;
- _cellOrigin[1] = ((proscenium[2] + proscenium[3]) / 2.0) - (_cellsY / 2.0) * _cellSize;
+ float prosceniumWidth = (proscenium[1] - proscenium[0]);
+ float prosceniumHeight = (proscenium[3] - proscenium[2]);
+ real cellArea = prosceniumWidth * prosceniumHeight / pow(numFaces, 2.0f / 3.0f);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << prosceniumWidth << " x " << prosceniumHeight << " grid with cells of area " << cellArea
+ << "." << endl;
+ }
+
+ _cellSize = sqrt(cellArea);
+ // Now we know how many cells make each side of our grid
+ _cellsX = ceil(prosceniumWidth / _cellSize);
+ _cellsY = ceil(prosceniumHeight / _cellSize);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
+ }
+
+ // Make sure the grid exceeds the proscenium by a small amount
+ float safetyZone = 0.1;
+ if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
+ _cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
+ }
+ if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
+ _cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
+ }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
+ }
+
+ // Find grid origin
+ _cellOrigin[0] = ((proscenium[0] + proscenium[1]) / 2.0) - (_cellsX / 2.0) * _cellSize;
+ _cellOrigin[1] = ((proscenium[2] + proscenium[3]) / 2.0) - (_cellsY / 2.0) * _cellSize;
}
Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFaces)
-: numFaces(numFaces)
+ : numFaces(numFaces)
{
}
-Pow23GridDensityProviderFactory::~Pow23GridDensityProviderFactory () {}
+Pow23GridDensityProviderFactory::~Pow23GridDensityProviderFactory()
+{
+}
-AutoPtr<GridDensityProvider>
-Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
+AutoPtr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source, const real proscenium[4])
{
- return AutoPtr<GridDensityProvider>(new Pow23GridDensityProvider(source, proscenium, numFaces));
+ return AutoPtr<GridDensityProvider>(new Pow23GridDensityProvider(source, proscenium, numFaces));
}
-AutoPtr<GridDensityProvider>
-Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform)
+AutoPtr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source, const BBox<Vec3r> &bbox, const GridHelpers::Transform &transform)
{
- return AutoPtr<GridDensityProvider>(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
+ return AutoPtr<GridDensityProvider>(
+ new Pow23GridDensityProvider(source, bbox, transform, numFaces));
}
-AutoPtr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+AutoPtr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(
+ OccluderSource &source)
{
- return AutoPtr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
+ return AutoPtr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
index 72fc56e4ef1..52d57e3030e 100644
--- a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
@@ -26,41 +26,43 @@
namespace Freestyle {
-class Pow23GridDensityProvider : public GridDensityProvider
-{
- // Disallow copying and assignment
- Pow23GridDensityProvider(const Pow23GridDensityProvider& other);
- Pow23GridDensityProvider& operator=(const Pow23GridDensityProvider& other);
+class Pow23GridDensityProvider : public GridDensityProvider {
+ // Disallow copying and assignment
+ Pow23GridDensityProvider(const Pow23GridDensityProvider &other);
+ Pow23GridDensityProvider &operator=(const Pow23GridDensityProvider &other);
-public:
- Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces);
- Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform,
- unsigned numFaces);
- Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces);
- virtual ~Pow23GridDensityProvider();
+ public:
+ Pow23GridDensityProvider(OccluderSource &source, const real proscenium[4], unsigned numFaces);
+ Pow23GridDensityProvider(OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform,
+ unsigned numFaces);
+ Pow23GridDensityProvider(OccluderSource &source, unsigned numFaces);
+ virtual ~Pow23GridDensityProvider();
-protected:
- unsigned numFaces;
+ protected:
+ unsigned numFaces;
-private:
- void initialize(const real proscenium[4]);
+ private:
+ void initialize(const real proscenium[4]);
};
-class Pow23GridDensityProviderFactory : public GridDensityProviderFactory
-{
-public:
- Pow23GridDensityProviderFactory(unsigned numFaces);
- ~Pow23GridDensityProviderFactory();
+class Pow23GridDensityProviderFactory : public GridDensityProviderFactory {
+ public:
+ Pow23GridDensityProviderFactory(unsigned numFaces);
+ ~Pow23GridDensityProviderFactory();
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform);
- AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source,
+ const real proscenium[4]);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source,
+ const BBox<Vec3r> &bbox,
+ const GridHelpers::Transform &transform);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource &source);
-protected:
- unsigned numFaces;
+ protected:
+ unsigned numFaces;
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
+#endif // __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
diff --git a/source/blender/freestyle/intern/view_map/Silhouette.cpp b/source/blender/freestyle/intern/view_map/Silhouette.cpp
index 7934ccf8671..73bf38107cd 100644
--- a/source/blender/freestyle/intern/view_map/Silhouette.cpp
+++ b/source/blender/freestyle/intern/view_map/Silhouette.cpp
@@ -34,178 +34,174 @@ namespace Freestyle {
Nature::VertexNature SVertex::getNature() const
{
- Nature::VertexNature nature = Nature::S_VERTEX;
- if (_pViewVertex)
- nature |= _pViewVertex->getNature();
- return nature;
+ Nature::VertexNature nature = Nature::S_VERTEX;
+ if (_pViewVertex)
+ nature |= _pViewVertex->getNature();
+ return nature;
}
SVertex *SVertex::castToSVertex()
{
- return this;
+ return this;
}
ViewVertex *SVertex::castToViewVertex()
{
- return _pViewVertex;
+ return _pViewVertex;
}
NonTVertex *SVertex::castToNonTVertex()
{
- return dynamic_cast<NonTVertex*>(_pViewVertex);
+ return dynamic_cast<NonTVertex *>(_pViewVertex);
}
TVertex *SVertex::castToTVertex()
{
- return dynamic_cast<TVertex*>(_pViewVertex);
+ return dynamic_cast<TVertex *>(_pViewVertex);
}
float SVertex::shape_importance() const
{
- return shape()->importance();
+ return shape()->importance();
}
#if 0
Material SVertex::material() const
{
- return _Shape->material();
+ return _Shape->material();
}
#endif
Id SVertex::shape_id() const
{
- return _Shape->getId();
+ return _Shape->getId();
}
const SShape *SVertex::shape() const
{
- return _Shape;
+ return _Shape;
}
const int SVertex::qi() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->qi();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->qi();
}
occluder_container::const_iterator SVertex::occluders_begin() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluders_begin();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluders_begin();
}
occluder_container::const_iterator SVertex::occluders_end() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluders_end();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluders_end();
}
bool SVertex::occluders_empty() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluders_empty();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluders_empty();
}
int SVertex::occluders_size() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluders_size();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluders_size();
}
-const Polygon3r& SVertex::occludee() const
+const Polygon3r &SVertex::occludee() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occludee();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occludee();
}
const SShape *SVertex::occluded_shape() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluded_shape();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluded_shape();
}
const bool SVertex::occludee_empty() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occludee_empty();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occludee_empty();
}
real SVertex::z_discontinuity() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->z_discontinuity();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->z_discontinuity();
}
FEdge *SVertex::fedge()
{
- if (getNature() & Nature::T_VERTEX)
- return NULL;
- return _FEdges[0];
-}
-
-FEdge *SVertex::getFEdge(Interface0D& inter)
-{
- FEdge *result = NULL;
- SVertex *iVertexB = dynamic_cast<SVertex*>(&inter);
- if (!iVertexB)
- return result;
- vector<FEdge*>::const_iterator fe = _FEdges.begin(), feend = _FEdges.end();
- for (; fe != feend; ++fe) {
- if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB)) ||
- (((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB)))
- {
- result = (*fe);
- }
- }
- if ((result == 0) && (getNature() & Nature::T_VERTEX)) {
- SVertex *brother;
- ViewVertex *vvertex = viewvertex();
- TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
- if (tvertex) {
- brother = tvertex->frontSVertex();
- if (this == brother)
- brother = tvertex->backSVertex();
- const vector<FEdge*>& fedges = brother->fedges();
- for (fe = fedges.begin(), feend = fedges.end(); fe != feend; ++fe) {
- if ((((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB)) ||
- (((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB)))
- {
- result = (*fe);
- }
- }
- }
- }
- if ((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) {
- SVertex *brother;
- ViewVertex *vvertex = iVertexB->viewvertex();
- TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
- if (tvertex) {
- brother = tvertex->frontSVertex();
- if (iVertexB == brother)
- brother = tvertex->backSVertex();
- for (fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; ++fe) {
- if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother)) ||
- (((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother)))
- {
- result = (*fe);
- }
- }
- }
- }
-
- return result;
+ if (getNature() & Nature::T_VERTEX)
+ return NULL;
+ return _FEdges[0];
+}
+
+FEdge *SVertex::getFEdge(Interface0D &inter)
+{
+ FEdge *result = NULL;
+ SVertex *iVertexB = dynamic_cast<SVertex *>(&inter);
+ if (!iVertexB)
+ return result;
+ vector<FEdge *>::const_iterator fe = _FEdges.begin(), feend = _FEdges.end();
+ for (; fe != feend; ++fe) {
+ if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB)) ||
+ (((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB))) {
+ result = (*fe);
+ }
+ }
+ if ((result == 0) && (getNature() & Nature::T_VERTEX)) {
+ SVertex *brother;
+ ViewVertex *vvertex = viewvertex();
+ TVertex *tvertex = dynamic_cast<TVertex *>(vvertex);
+ if (tvertex) {
+ brother = tvertex->frontSVertex();
+ if (this == brother)
+ brother = tvertex->backSVertex();
+ const vector<FEdge *> &fedges = brother->fedges();
+ for (fe = fedges.begin(), feend = fedges.end(); fe != feend; ++fe) {
+ if ((((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB)) ||
+ (((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB))) {
+ result = (*fe);
+ }
+ }
+ }
+ }
+ if ((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) {
+ SVertex *brother;
+ ViewVertex *vvertex = iVertexB->viewvertex();
+ TVertex *tvertex = dynamic_cast<TVertex *>(vvertex);
+ if (tvertex) {
+ brother = tvertex->frontSVertex();
+ if (iVertexB == brother)
+ brother = tvertex->backSVertex();
+ for (fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; ++fe) {
+ if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother)) ||
+ (((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother))) {
+ result = (*fe);
+ }
+ }
+ }
+ }
+
+ return result;
}
-
/**********************************/
/* */
/* */
@@ -214,159 +210,158 @@ FEdge *SVertex::getFEdge(Interface0D& inter)
/* */
/**********************************/
-
int FEdge::viewedge_nature() const
{
- return _ViewEdge->getNature();
+ return _ViewEdge->getNature();
}
#if 0
float FEdge::viewedge_length() const
{
- return _ViewEdge->viewedge_length();
+ return _ViewEdge->viewedge_length();
}
#endif
const SShape *FEdge::occluded_shape() const
{
- ViewShape *aShape = _ViewEdge->aShape();
- if (aShape == 0)
- return 0;
- return aShape->sshape();
+ ViewShape *aShape = _ViewEdge->aShape();
+ if (aShape == 0)
+ return 0;
+ return aShape->sshape();
}
float FEdge::shape_importance() const
{
- return _VertexA->shape()->importance();
+ return _VertexA->shape()->importance();
}
int FEdge::invisibility() const
{
- return _ViewEdge->qi();
+ return _ViewEdge->qi();
}
occluder_container::const_iterator FEdge::occluders_begin() const
{
- return _ViewEdge->occluders_begin();
+ return _ViewEdge->occluders_begin();
}
occluder_container::const_iterator FEdge::occluders_end() const
{
- return _ViewEdge->occluders_end();
+ return _ViewEdge->occluders_end();
}
bool FEdge::occluders_empty() const
{
- return _ViewEdge->occluders_empty();
+ return _ViewEdge->occluders_empty();
}
int FEdge::occluders_size() const
{
- return _ViewEdge->occluders_size();
+ return _ViewEdge->occluders_size();
}
-const bool FEdge::occludee_empty() const
+const bool FEdge::occludee_empty() const
{
- return _ViewEdge->occludee_empty();
+ return _ViewEdge->occludee_empty();
}
Id FEdge::shape_id() const
{
- return _VertexA->shape()->getId();
+ return _VertexA->shape()->getId();
}
const SShape *FEdge::shape() const
{
- return _VertexA->shape();
+ return _VertexA->shape();
}
real FEdge::z_discontinuity() const
{
- if (!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) {
- return 0;
- }
+ if (!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) {
+ return 0;
+ }
- BBox<Vec3r> box = ViewMap::getInstance()->getScene3dBBox();
+ BBox<Vec3r> box = ViewMap::getInstance()->getScene3dBBox();
- Vec3r bbox_size_vec(box.getMax() - box.getMin());
- real bboxsize = bbox_size_vec.norm();
- if (occludee_empty()) {
- //return FLT_MAX;
- return 1.0;
- //return bboxsize;
- }
+ Vec3r bbox_size_vec(box.getMax() - box.getMin());
+ real bboxsize = bbox_size_vec.norm();
+ if (occludee_empty()) {
+ //return FLT_MAX;
+ return 1.0;
+ //return bboxsize;
+ }
#if 0
- real result;
- z_discontinuity_functor<SVertex> _functor;
- Evaluate<SVertex, z_discontinuity_functor<SVertex> >(&_functor, iCombination, result);
+ real result;
+ z_discontinuity_functor<SVertex> _functor;
+ Evaluate<SVertex, z_discontinuity_functor<SVertex> >(&_functor, iCombination, result);
#endif
- Vec3r middle((_VertexB->point3d() - _VertexA->point3d()));
- middle /= 2;
- Vec3r disc_vec(middle - _occludeeIntersection);
- real res = disc_vec.norm() / bboxsize;
+ Vec3r middle((_VertexB->point3d() - _VertexA->point3d()));
+ middle /= 2;
+ Vec3r disc_vec(middle - _occludeeIntersection);
+ real res = disc_vec.norm() / bboxsize;
- return res;
- //return fabs((middle.z() - _occludeeIntersection.z()));
+ return res;
+ //return fabs((middle.z() - _occludeeIntersection.z()));
}
#if 0
float FEdge::local_average_depth(int iCombination ) const
{
- float result;
- local_average_depth_functor<SVertex> functor;
- Evaluate(&functor, iCombination, result);
+ float result;
+ local_average_depth_functor<SVertex> functor;
+ Evaluate(&functor, iCombination, result);
- return result;
+ return result;
}
float FEdge::local_depth_variance(int iCombination ) const
{
- float result;
+ float result;
- local_depth_variance_functor<SVertex> functor;
+ local_depth_variance_functor<SVertex> functor;
- Evaluate(&functor, iCombination, result);
+ Evaluate(&functor, iCombination, result);
- return result;
+ return result;
}
real FEdge::local_average_density( float sigma, int iCombination) const
{
- float result;
+ float result;
- density_functor<SVertex> functor(sigma);
+ density_functor<SVertex> functor(sigma);
- Evaluate(&functor, iCombination, result);
+ Evaluate(&functor, iCombination, result);
- return result;
+ return result;
}
Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */)
{
- Vec3r Na = _VertexA->normal(oException);
- if (oException != Exception::NO_EXCEPTION)
- return Na;
- Vec3r Nb = _VertexB->normal(oException);
- if (oException != Exception::NO_EXCEPTION)
- return Nb;
- return (Na + Nb) / 2.0;
+ Vec3r Na = _VertexA->normal(oException);
+ if (oException != Exception::NO_EXCEPTION)
+ return Na;
+ Vec3r Nb = _VertexB->normal(oException);
+ if (oException != Exception::NO_EXCEPTION)
+ return Nb;
+ return (Na + Nb) / 2.0;
}
Vec3r FEdge::curvature2d_as_vector(int iCombination) const
{
- Vec3r result;
- curvature2d_as_vector_functor<SVertex> _functor;
- Evaluate<Vec3r, curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result);
- return result;
+ Vec3r result;
+ curvature2d_as_vector_functor<SVertex> _functor;
+ Evaluate<Vec3r, curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result);
+ return result;
}
real FEdge::curvature2d_as_angle(int iCombination) const
{
- real result;
- curvature2d_as_angle_functor<SVertex> _functor;
- Evaluate<real, curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result);
- return result;
+ real result;
+ curvature2d_as_angle_functor<SVertex> _functor;
+ Evaluate<real, curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result);
+ return result;
}
#endif
@@ -381,18 +376,18 @@ real FEdge::curvature2d_as_angle(int iCombination) const
#if 0
Material FEdge::material() const
{
- return _VertexA->shape()->material();
+ return _VertexA->shape()->material();
}
#endif
-const FrsMaterial& FEdgeSharp::aFrsMaterial() const
+const FrsMaterial &FEdgeSharp::aFrsMaterial() const
{
- return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
+ return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
}
-const FrsMaterial& FEdgeSharp::bFrsMaterial() const
+const FrsMaterial &FEdgeSharp::bFrsMaterial() const
{
- return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
+ return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
}
/**********************************/
@@ -403,9 +398,9 @@ const FrsMaterial& FEdgeSharp::bFrsMaterial() const
/* */
/**********************************/
-const FrsMaterial& FEdgeSmooth::frs_material() const
+const FrsMaterial &FEdgeSmooth::frs_material() const
{
- return _VertexA->shape()->frs_material(_FrsMaterialIndex);
+ return _VertexA->shape()->frs_material(_FrsMaterialIndex);
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/Silhouette.h b/source/blender/freestyle/intern/view_map/Silhouette.h
index 8005203072d..510aedf6cbf 100644
--- a/source/blender/freestyle/intern/view_map/Silhouette.h
+++ b/source/blender/freestyle/intern/view_map/Silhouette.h
@@ -43,7 +43,7 @@
#include "../winged_edge/Curvature.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
using namespace std;
@@ -53,7 +53,7 @@ namespace Freestyle {
using namespace Geometry;
class ViewShape;
-typedef vector<ViewShape*> occluder_container;
+typedef vector<ViewShape *> occluder_container;
/**********************************/
/* */
@@ -68,387 +68,386 @@ class ViewVertex;
class SShape;
/*! Class to define a vertex of the embedding. */
-class SVertex : public Interface0D
-{
-public: // Implementation of Interface0D
- /*! Returns the string "SVertex" .*/
- virtual string getExactTypeName() const
- {
- return "SVertex";
- }
-
- // Data access methods
- /*! Returns the 3D x coordinate of the vertex .*/
- virtual real getX() const
- {
- return _Point3D.x();
- }
-
- /*! Returns the 3D y coordinate of the vertex .*/
- virtual real getY() const
- {
- return _Point3D.y();
- }
-
- /*! Returns the 3D z coordinate of the vertex .*/
- virtual real getZ() const
- {
- return _Point3D.z();
- }
-
- /*! Returns the 3D point. */
- virtual Vec3r getPoint3D() const
- {
- return _Point3D;
- }
-
- /*! Returns the projected 3D x coordinate of the vertex .*/
- virtual real getProjectedX() const
- {
- return _Point2D.x();
- }
-
- /*! Returns the projected 3D y coordinate of the vertex .*/
- virtual real getProjectedY() const
- {
- return _Point2D.y();
- }
-
- /*! Returns the projected 3D z coordinate of the vertex .*/
- virtual real getProjectedZ() const
- {
- return _Point2D.z();
- }
-
- /*! Returns the 2D point. */
- virtual Vec2r getPoint2D() const
- {
- return Vec2r(_Point2D.x(), _Point2D.y());
- }
-
- /*! Returns the FEdge that lies between this Svertex and the Interface0D given as argument. */
- virtual FEdge *getFEdge(Interface0D&);
-
- /*! Returns the Id of the vertex .*/
- virtual Id getId() const
- {
- return _Id;
- }
-
- /*! Returns the nature of the vertex .*/
- virtual Nature::VertexNature getNature() const;
-
- /*! Cast the Interface0D in SVertex if it can be. */
- virtual SVertex *castToSVertex();
-
- /*! Cast the Interface0D in ViewVertex if it can be. */
- virtual ViewVertex *castToViewVertex();
-
- /*! Cast the Interface0D in NonTVertex if it can be. */
- virtual NonTVertex *castToNonTVertex();
-
- /*! Cast the Interface0D in TVertex if it can be. */
- virtual TVertex *castToTVertex();
-
-public:
- typedef vector<FEdge*> fedges_container;
-
-private:
- Id _Id;
- Vec3r _Point3D;
- Vec3r _Point2D;
- set<Vec3r> _Normals;
- vector<FEdge*> _FEdges; // the edges containing this vertex
- SShape *_Shape; // the shape to which belongs the vertex
- ViewVertex *_pViewVertex; // The associated viewvertex, in case there is one.
+class SVertex : public Interface0D {
+ public: // Implementation of Interface0D
+ /*! Returns the string "SVertex" .*/
+ virtual string getExactTypeName() const
+ {
+ return "SVertex";
+ }
+
+ // Data access methods
+ /*! Returns the 3D x coordinate of the vertex .*/
+ virtual real getX() const
+ {
+ return _Point3D.x();
+ }
+
+ /*! Returns the 3D y coordinate of the vertex .*/
+ virtual real getY() const
+ {
+ return _Point3D.y();
+ }
+
+ /*! Returns the 3D z coordinate of the vertex .*/
+ virtual real getZ() const
+ {
+ return _Point3D.z();
+ }
+
+ /*! Returns the 3D point. */
+ virtual Vec3r getPoint3D() const
+ {
+ return _Point3D;
+ }
+
+ /*! Returns the projected 3D x coordinate of the vertex .*/
+ virtual real getProjectedX() const
+ {
+ return _Point2D.x();
+ }
+
+ /*! Returns the projected 3D y coordinate of the vertex .*/
+ virtual real getProjectedY() const
+ {
+ return _Point2D.y();
+ }
+
+ /*! Returns the projected 3D z coordinate of the vertex .*/
+ virtual real getProjectedZ() const
+ {
+ return _Point2D.z();
+ }
+
+ /*! Returns the 2D point. */
+ virtual Vec2r getPoint2D() const
+ {
+ return Vec2r(_Point2D.x(), _Point2D.y());
+ }
+
+ /*! Returns the FEdge that lies between this Svertex and the Interface0D given as argument. */
+ virtual FEdge *getFEdge(Interface0D &);
+
+ /*! Returns the Id of the vertex .*/
+ virtual Id getId() const
+ {
+ return _Id;
+ }
+
+ /*! Returns the nature of the vertex .*/
+ virtual Nature::VertexNature getNature() const;
+
+ /*! Cast the Interface0D in SVertex if it can be. */
+ virtual SVertex *castToSVertex();
+
+ /*! Cast the Interface0D in ViewVertex if it can be. */
+ virtual ViewVertex *castToViewVertex();
+
+ /*! Cast the Interface0D in NonTVertex if it can be. */
+ virtual NonTVertex *castToNonTVertex();
+
+ /*! Cast the Interface0D in TVertex if it can be. */
+ virtual TVertex *castToTVertex();
+
+ public:
+ typedef vector<FEdge *> fedges_container;
+
+ private:
+ Id _Id;
+ Vec3r _Point3D;
+ Vec3r _Point2D;
+ set<Vec3r> _Normals;
+ vector<FEdge *> _FEdges; // the edges containing this vertex
+ SShape *_Shape; // the shape to which belongs the vertex
+ ViewVertex *_pViewVertex; // The associated viewvertex, in case there is one.
#if 0
- real _curvatureFredo;
- Vec2r _directionFredo;
+ real _curvatureFredo;
+ Vec2r _directionFredo;
#endif
- CurvatureInfo *_curvature_info;
-
-public:
- /*! A field that can be used by the user to store any data.
- * This field must be reseted afterwards using ResetUserData().
- */
- void *userdata;
-
- /*! Default constructor.*/
- inline SVertex()
- {
- _Id = 0;
- userdata = NULL;
- _Shape = NULL;
- _pViewVertex = 0;
- _curvature_info = 0;
- }
-
- /*! Builds a SVertex from 3D coordinates and an Id. */
- inline SVertex(const Vec3r &iPoint3D, const Id& id)
- {
- _Point3D = iPoint3D;
- _Id = id;
- userdata = NULL;
- _Shape = NULL;
- _pViewVertex = 0;
- _curvature_info = 0;
- }
-
- /*! Copy constructor. */
- inline SVertex(SVertex& iBrother)
- {
- _Id = iBrother._Id;
- _Point3D = iBrother.point3D();
- _Point2D = iBrother.point2D();
- _Normals = iBrother._Normals;
- _FEdges = iBrother.fedges();
- _Shape = iBrother.shape();
- _pViewVertex = iBrother._pViewVertex;
- if (!(iBrother._curvature_info))
- _curvature_info = 0;
- else
- _curvature_info = new CurvatureInfo(*(iBrother._curvature_info));
- iBrother.userdata = this;
- userdata = 0;
- }
-
- /*! Destructor. */
- virtual ~SVertex()
- {
- if (_curvature_info)
- delete _curvature_info;
- }
-
- /*! Cloning method. */
- virtual SVertex *duplicate()
- {
- SVertex *clone = new SVertex(*this);
- return clone;
- }
-
- /*! operator == */
- virtual bool operator==(const SVertex& iBrother)
- {
- return ((_Point2D == iBrother._Point2D) && (_Point3D == iBrother._Point3D));
- }
-
- /* accessors */
- inline const Vec3r& point3D() const
- {
- return _Point3D;
- }
-
- inline const Vec3r& point2D() const
- {
- return _Point2D;
- }
-
- /*! Returns the set of normals for this Vertex.
- * In a smooth surface, a vertex has exactly one normal.
- * In a sharp surface, a vertex can have any number of normals.
- */
- inline set<Vec3r> normals()
- {
- return _Normals;
- }
-
- /*! Returns the number of different normals for this vertex. */
- inline unsigned normalsSize() const
- {
- return _Normals.size();
- }
-
- inline const vector<FEdge*>& fedges()
- {
- return _FEdges;
- }
-
- inline fedges_container::iterator fedges_begin()
- {
- return _FEdges.begin();
- }
-
- inline fedges_container::iterator fedges_end()
- {
- return _FEdges.end();
- }
-
- inline SShape *shape()
- {
- return _Shape;
- }
-
- inline real z() const
- {
- return _Point2D[2];
- }
-
- /*! If this SVertex is also a ViewVertex, this method returns a pointer onto this ViewVertex.
- * 0 is returned otherwise.
- */
- inline ViewVertex *viewvertex()
- {
- return _pViewVertex;
- }
-
- /*! modifiers */
- /*! Sets the 3D coordinates of the SVertex. */
- inline void setPoint3D(const Vec3r &iPoint3D)
- {
- _Point3D = iPoint3D;
- }
-
- /*! Sets the 3D projected coordinates of the SVertex. */
- inline void setPoint2D(const Vec3r &iPoint2D)
- {
- _Point2D = iPoint2D;
- }
-
- /*! Adds a normal to the Svertex's set of normals. If the same normal is already in the set, nothing changes. */
- inline void AddNormal(const Vec3r& iNormal)
- {
- _Normals.insert(iNormal); // if iNormal in the set already exists, nothing is done
- }
-
- void setCurvatureInfo(CurvatureInfo *ci)
- {
- if (_curvature_info) // Q. is this an error condition? (T.K. 02-May-2011)
- delete _curvature_info;
- _curvature_info = ci;
- }
-
- const CurvatureInfo *getCurvatureInfo() const
- {
- return _curvature_info;
- }
+ CurvatureInfo *_curvature_info;
+
+ public:
+ /*! A field that can be used by the user to store any data.
+ * This field must be reseted afterwards using ResetUserData().
+ */
+ void *userdata;
+
+ /*! Default constructor.*/
+ inline SVertex()
+ {
+ _Id = 0;
+ userdata = NULL;
+ _Shape = NULL;
+ _pViewVertex = 0;
+ _curvature_info = 0;
+ }
+
+ /*! Builds a SVertex from 3D coordinates and an Id. */
+ inline SVertex(const Vec3r &iPoint3D, const Id &id)
+ {
+ _Point3D = iPoint3D;
+ _Id = id;
+ userdata = NULL;
+ _Shape = NULL;
+ _pViewVertex = 0;
+ _curvature_info = 0;
+ }
+
+ /*! Copy constructor. */
+ inline SVertex(SVertex &iBrother)
+ {
+ _Id = iBrother._Id;
+ _Point3D = iBrother.point3D();
+ _Point2D = iBrother.point2D();
+ _Normals = iBrother._Normals;
+ _FEdges = iBrother.fedges();
+ _Shape = iBrother.shape();
+ _pViewVertex = iBrother._pViewVertex;
+ if (!(iBrother._curvature_info))
+ _curvature_info = 0;
+ else
+ _curvature_info = new CurvatureInfo(*(iBrother._curvature_info));
+ iBrother.userdata = this;
+ userdata = 0;
+ }
+
+ /*! Destructor. */
+ virtual ~SVertex()
+ {
+ if (_curvature_info)
+ delete _curvature_info;
+ }
+
+ /*! Cloning method. */
+ virtual SVertex *duplicate()
+ {
+ SVertex *clone = new SVertex(*this);
+ return clone;
+ }
+
+ /*! operator == */
+ virtual bool operator==(const SVertex &iBrother)
+ {
+ return ((_Point2D == iBrother._Point2D) && (_Point3D == iBrother._Point3D));
+ }
+
+ /* accessors */
+ inline const Vec3r &point3D() const
+ {
+ return _Point3D;
+ }
+
+ inline const Vec3r &point2D() const
+ {
+ return _Point2D;
+ }
+
+ /*! Returns the set of normals for this Vertex.
+ * In a smooth surface, a vertex has exactly one normal.
+ * In a sharp surface, a vertex can have any number of normals.
+ */
+ inline set<Vec3r> normals()
+ {
+ return _Normals;
+ }
+
+ /*! Returns the number of different normals for this vertex. */
+ inline unsigned normalsSize() const
+ {
+ return _Normals.size();
+ }
+
+ inline const vector<FEdge *> &fedges()
+ {
+ return _FEdges;
+ }
+
+ inline fedges_container::iterator fedges_begin()
+ {
+ return _FEdges.begin();
+ }
+
+ inline fedges_container::iterator fedges_end()
+ {
+ return _FEdges.end();
+ }
+
+ inline SShape *shape()
+ {
+ return _Shape;
+ }
+
+ inline real z() const
+ {
+ return _Point2D[2];
+ }
+
+ /*! If this SVertex is also a ViewVertex, this method returns a pointer onto this ViewVertex.
+ * 0 is returned otherwise.
+ */
+ inline ViewVertex *viewvertex()
+ {
+ return _pViewVertex;
+ }
+
+ /*! modifiers */
+ /*! Sets the 3D coordinates of the SVertex. */
+ inline void setPoint3D(const Vec3r &iPoint3D)
+ {
+ _Point3D = iPoint3D;
+ }
+
+ /*! Sets the 3D projected coordinates of the SVertex. */
+ inline void setPoint2D(const Vec3r &iPoint2D)
+ {
+ _Point2D = iPoint2D;
+ }
+
+ /*! Adds a normal to the Svertex's set of normals. If the same normal is already in the set, nothing changes. */
+ inline void AddNormal(const Vec3r &iNormal)
+ {
+ _Normals.insert(iNormal); // if iNormal in the set already exists, nothing is done
+ }
+
+ void setCurvatureInfo(CurvatureInfo *ci)
+ {
+ if (_curvature_info) // Q. is this an error condition? (T.K. 02-May-2011)
+ delete _curvature_info;
+ _curvature_info = ci;
+ }
+
+ const CurvatureInfo *getCurvatureInfo() const
+ {
+ return _curvature_info;
+ }
#if 0
- /* Fredo's normal and curvature*/
- void setCurvatureFredo(real c)
- {
- _curvatureFredo = c;
- }
-
- void setDirectionFredo(Vec2r d)
- {
- _directionFredo = d;
- }
-
- real curvatureFredo ()
- {
- return _curvatureFredo;
- }
-
- const Vec2r directionFredo ()
- {
- return _directionFredo;
- }
+ /* Fredo's normal and curvature*/
+ void setCurvatureFredo(real c)
+ {
+ _curvatureFredo = c;
+ }
+
+ void setDirectionFredo(Vec2r d)
+ {
+ _directionFredo = d;
+ }
+
+ real curvatureFredo ()
+ {
+ return _curvatureFredo;
+ }
+
+ const Vec2r directionFredo ()
+ {
+ return _directionFredo;
+ }
#endif
- /*! Sets the Id */
- inline void setId(const Id& id)
- {
- _Id = id;
- }
-
- inline void setFEdges(const vector<FEdge*>& iFEdges)
- {
- _FEdges = iFEdges;
- }
-
- inline void setShape(SShape *iShape)
- {
- _Shape = iShape;
- }
-
- inline void setViewVertex(ViewVertex *iViewVertex)
- {
- _pViewVertex = iViewVertex;
- }
-
- /*! Add an FEdge to the list of edges emanating from this SVertex. */
- inline void AddFEdge(FEdge *iFEdge)
- {
- _FEdges.push_back(iFEdge);
- }
-
- /*! Remove an FEdge from the list of edges emanating from this SVertex. */
- inline void RemoveFEdge(FEdge *iFEdge)
- {
- for (vector<FEdge *>::iterator fe = _FEdges.begin(), fend = _FEdges.end(); fe != fend; fe++) {
- if (iFEdge == (*fe)) {
- _FEdges.erase(fe);
- break;
- }
- }
- }
-
- /* replaces edge 1 by edge 2 in the list of edges */
- inline void Replace(FEdge *e1, FEdge *e2)
- {
- vector<FEdge *>::iterator insertedfe;
- for (vector<FEdge *>::iterator fe = _FEdges.begin(), fend = _FEdges.end(); fe != fend; fe++) {
- if ((*fe) == e1) {
- insertedfe = _FEdges.insert(fe, e2);// inserts e2 before fe.
- // returns an iterator pointing toward e2. fe is invalidated.
- // we want to remove e1, but we can't use fe anymore:
- ++insertedfe; // insertedfe points now to e1
- _FEdges.erase(insertedfe);
- return;
- }
- }
- }
-
-public:
- /* Information access interface */
- FEdge *fedge(); // for non T vertex
-
- inline const Vec3r& point2d() const
- {
- return point2D();
- }
-
- inline const Vec3r& point3d() const
- {
- return point3D();
- }
-
- inline Vec3r normal() const
- {
- if (_Normals.size() == 1)
- return (*(_Normals.begin()));
- Exception::raiseException();
- return *(_Normals.begin());
- }
-
- //Material material() const ;
- Id shape_id() const;
- const SShape *shape() const;
- float shape_importance() const;
-
- const int qi() const;
- occluder_container::const_iterator occluders_begin() const;
- occluder_container::const_iterator occluders_end() const;
- bool occluders_empty() const;
- int occluders_size() const;
- const Polygon3r& occludee() const;
- const SShape *occluded_shape() const;
- const bool occludee_empty() const;
- real z_discontinuity() const;
+ /*! Sets the Id */
+ inline void setId(const Id &id)
+ {
+ _Id = id;
+ }
+
+ inline void setFEdges(const vector<FEdge *> &iFEdges)
+ {
+ _FEdges = iFEdges;
+ }
+
+ inline void setShape(SShape *iShape)
+ {
+ _Shape = iShape;
+ }
+
+ inline void setViewVertex(ViewVertex *iViewVertex)
+ {
+ _pViewVertex = iViewVertex;
+ }
+
+ /*! Add an FEdge to the list of edges emanating from this SVertex. */
+ inline void AddFEdge(FEdge *iFEdge)
+ {
+ _FEdges.push_back(iFEdge);
+ }
+
+ /*! Remove an FEdge from the list of edges emanating from this SVertex. */
+ inline void RemoveFEdge(FEdge *iFEdge)
+ {
+ for (vector<FEdge *>::iterator fe = _FEdges.begin(), fend = _FEdges.end(); fe != fend; fe++) {
+ if (iFEdge == (*fe)) {
+ _FEdges.erase(fe);
+ break;
+ }
+ }
+ }
+
+ /* replaces edge 1 by edge 2 in the list of edges */
+ inline void Replace(FEdge *e1, FEdge *e2)
+ {
+ vector<FEdge *>::iterator insertedfe;
+ for (vector<FEdge *>::iterator fe = _FEdges.begin(), fend = _FEdges.end(); fe != fend; fe++) {
+ if ((*fe) == e1) {
+ insertedfe = _FEdges.insert(fe, e2); // inserts e2 before fe.
+ // returns an iterator pointing toward e2. fe is invalidated.
+ // we want to remove e1, but we can't use fe anymore:
+ ++insertedfe; // insertedfe points now to e1
+ _FEdges.erase(insertedfe);
+ return;
+ }
+ }
+ }
+
+ public:
+ /* Information access interface */
+ FEdge *fedge(); // for non T vertex
+
+ inline const Vec3r &point2d() const
+ {
+ return point2D();
+ }
+
+ inline const Vec3r &point3d() const
+ {
+ return point3D();
+ }
+
+ inline Vec3r normal() const
+ {
+ if (_Normals.size() == 1)
+ return (*(_Normals.begin()));
+ Exception::raiseException();
+ return *(_Normals.begin());
+ }
+
+ //Material material() const ;
+ Id shape_id() const;
+ const SShape *shape() const;
+ float shape_importance() const;
+
+ const int qi() const;
+ occluder_container::const_iterator occluders_begin() const;
+ occluder_container::const_iterator occluders_end() const;
+ bool occluders_empty() const;
+ int occluders_size() const;
+ const Polygon3r &occludee() const;
+ const SShape *occluded_shape() const;
+ const bool occludee_empty() const;
+ real z_discontinuity() const;
#if 0
- inline float local_average_depth() const;
- inline float local_depth_variance() const;
- inline real local_average_density(float sigma = 2.3f) const;
- inline Vec3r shaded_color() const;
- inline Vec3r orientation2d() const;
- inline Vec3r orientation3d() const;
- inline Vec3r curvature2d_as_vector() const;
- /*! angle in radians */
- inline real curvature2d_as_angle() const;
+ inline float local_average_depth() const;
+ inline float local_depth_variance() const;
+ inline real local_average_density(float sigma = 2.3f) const;
+ inline Vec3r shaded_color() const;
+ inline Vec3r orientation2d() const;
+ inline Vec3r orientation3d() const;
+ inline Vec3r curvature2d_as_vector() const;
+ /*! angle in radians */
+ inline real curvature2d_as_angle() const;
#endif
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SVertex")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SVertex")
#endif
};
@@ -471,493 +470,494 @@ class ViewEdge;
* This class is specialized into a smooth and a sharp version since their properties slightly vary from
* one to the other.
*/
-class FEdge : public Interface1D
-{
-public: // Implementation of Interface0D
- /*! Returns the string "FEdge". */
- virtual string getExactTypeName() const
- {
- return "FEdge";
- }
-
- // Data access methods
-
- /*! Returns the 2D length of the FEdge. */
- virtual real getLength2D() const
- {
- if (!_VertexA || !_VertexB)
- return 0;
- return (_VertexB->getPoint2D() - _VertexA->getPoint2D()).norm();
- }
-
- /*! Returns the Id of the FEdge. */
- virtual Id getId() const
- {
- return _Id;
- }
-
-public:
- // An edge can only be of one kind (SILHOUETTE or BORDER, etc...)
- // For an multi-nature edge there must be several different FEdge.
- // DEBUG:
- // Vec3r A;
- // Vec3r u;
- // vector<Polygon3r> _Occludees;
- // Vec3r intersection;
- // vector<Vec3i> _Cells;
-
-protected:
- SVertex *_VertexA;
- SVertex *_VertexB;
- Id _Id;
- Nature::EdgeNature _Nature;
- //vector<Polygon3r> _Occluders; // visibility // NOT HANDLED BY THE COPY CONSTRUCTOR!!
-
- FEdge *_NextEdge; // next edge on the chain
- FEdge *_PreviousEdge;
- ViewEdge *_ViewEdge;
- // Sometimes we need to deport the visibility computation onto another edge. For example the exact edges use
- // edges of the mesh to compute their visibility
-
- Polygon3r _aFace; // The occluded face which lies on the right of a silhouette edge
- Vec3r _occludeeIntersection;
- bool _occludeeEmpty;
-
- bool _isSmooth;
-
- bool _isInImage;
-
- bool _isTemporary;
-
-public:
- /*! A field that can be used by the user to store any data.
- * This field must be reseted afterwards using ResetUserData().
- */
- void *userdata;
-
- /*! Default constructor */
- inline FEdge()
- {
- userdata = NULL;
- _VertexA = NULL;
- _VertexB = NULL;
- _Nature = Nature::NO_FEATURE;
- _NextEdge = NULL;
- _PreviousEdge = NULL;
- _ViewEdge = NULL;
- //_hasVisibilityPoint = false;
- _occludeeEmpty = true;
- _isSmooth = false;
- _isInImage = true;
- _isTemporary = false;
- }
-
- /*! Builds an FEdge going from vA to vB. */
- inline FEdge(SVertex *vA, SVertex *vB)
- {
- userdata = NULL;
- _VertexA = vA;
- _VertexB = vB;
- _Nature = Nature::NO_FEATURE;
- _NextEdge = NULL;
- _PreviousEdge = NULL;
- _ViewEdge = NULL;
- //_hasVisibilityPoint = false;
- _occludeeEmpty = true;
- _isSmooth = false;
- _isInImage = true;
- _isTemporary = false;
- }
-
- /*! Copy constructor */
- inline FEdge(FEdge& iBrother)
- {
- _VertexA = iBrother.vertexA();
- _VertexB = iBrother.vertexB();
- _NextEdge = iBrother.nextEdge();
- _PreviousEdge = iBrother._PreviousEdge;
- _Nature = iBrother.getNature();
- _Id = iBrother._Id;
- _ViewEdge = iBrother._ViewEdge;
- //_hasVisibilityPoint = iBrother._hasVisibilityPoint;
- //_VisibilityPointA = iBrother._VisibilityPointA;
- //_VisibilityPointB = iBrother._VisibilityPointB;
- _aFace = iBrother._aFace;
- _occludeeEmpty = iBrother._occludeeEmpty;
- _isSmooth = iBrother._isSmooth;
- _isInImage = iBrother._isInImage;
- _isTemporary = iBrother._isTemporary;
- iBrother.userdata = this;
- userdata = 0;
- }
-
- /*! Destructor */
- virtual ~FEdge() {}
-
- /*! Cloning method. */
- virtual FEdge *duplicate()
- {
- FEdge *clone = new FEdge(*this);
- return clone;
- }
-
- /* accessors */
- /*! Returns the first SVertex. */
- inline SVertex *vertexA()
- {
- return _VertexA;
- }
-
- /*! Returns the second SVertex. */
- inline SVertex *vertexB()
- {
- return _VertexB;
- }
-
- /*! Returns the first SVertex if i=0, the seccond SVertex if i=1. */
- inline SVertex *operator[](const unsigned short int& i) const
- {
- return (i % 2 == 0) ? _VertexA : _VertexB;
- }
-
- /*! Returns the nature of the FEdge. */
- inline Nature::EdgeNature getNature() const
- {
- return _Nature;
- }
-
- /*! Returns the FEdge following this one in the ViewEdge.
- * If this FEdge is the last of the ViewEdge, 0 is returned.
- */
- inline FEdge *nextEdge()
- {
- return _NextEdge;
- }
-
- /*! Returns the Edge preceding this one in the ViewEdge.
- * If this FEdge is the first one of the ViewEdge, 0 is returned.
- */
- inline FEdge *previousEdge()
- {
- return _PreviousEdge;
- }
-
- inline SShape *shape()
- {
- return _VertexA->shape();
- }
+class FEdge : public Interface1D {
+ public: // Implementation of Interface0D
+ /*! Returns the string "FEdge". */
+ virtual string getExactTypeName() const
+ {
+ return "FEdge";
+ }
+
+ // Data access methods
+
+ /*! Returns the 2D length of the FEdge. */
+ virtual real getLength2D() const
+ {
+ if (!_VertexA || !_VertexB)
+ return 0;
+ return (_VertexB->getPoint2D() - _VertexA->getPoint2D()).norm();
+ }
+
+ /*! Returns the Id of the FEdge. */
+ virtual Id getId() const
+ {
+ return _Id;
+ }
+
+ public:
+ // An edge can only be of one kind (SILHOUETTE or BORDER, etc...)
+ // For an multi-nature edge there must be several different FEdge.
+ // DEBUG:
+ // Vec3r A;
+ // Vec3r u;
+ // vector<Polygon3r> _Occludees;
+ // Vec3r intersection;
+ // vector<Vec3i> _Cells;
+
+ protected:
+ SVertex *_VertexA;
+ SVertex *_VertexB;
+ Id _Id;
+ Nature::EdgeNature _Nature;
+ //vector<Polygon3r> _Occluders; // visibility // NOT HANDLED BY THE COPY CONSTRUCTOR!!
+
+ FEdge *_NextEdge; // next edge on the chain
+ FEdge *_PreviousEdge;
+ ViewEdge *_ViewEdge;
+ // Sometimes we need to deport the visibility computation onto another edge. For example the exact edges use
+ // edges of the mesh to compute their visibility
+
+ Polygon3r _aFace; // The occluded face which lies on the right of a silhouette edge
+ Vec3r _occludeeIntersection;
+ bool _occludeeEmpty;
+
+ bool _isSmooth;
+
+ bool _isInImage;
+
+ bool _isTemporary;
+
+ public:
+ /*! A field that can be used by the user to store any data.
+ * This field must be reseted afterwards using ResetUserData().
+ */
+ void *userdata;
+
+ /*! Default constructor */
+ inline FEdge()
+ {
+ userdata = NULL;
+ _VertexA = NULL;
+ _VertexB = NULL;
+ _Nature = Nature::NO_FEATURE;
+ _NextEdge = NULL;
+ _PreviousEdge = NULL;
+ _ViewEdge = NULL;
+ //_hasVisibilityPoint = false;
+ _occludeeEmpty = true;
+ _isSmooth = false;
+ _isInImage = true;
+ _isTemporary = false;
+ }
+
+ /*! Builds an FEdge going from vA to vB. */
+ inline FEdge(SVertex *vA, SVertex *vB)
+ {
+ userdata = NULL;
+ _VertexA = vA;
+ _VertexB = vB;
+ _Nature = Nature::NO_FEATURE;
+ _NextEdge = NULL;
+ _PreviousEdge = NULL;
+ _ViewEdge = NULL;
+ //_hasVisibilityPoint = false;
+ _occludeeEmpty = true;
+ _isSmooth = false;
+ _isInImage = true;
+ _isTemporary = false;
+ }
+
+ /*! Copy constructor */
+ inline FEdge(FEdge &iBrother)
+ {
+ _VertexA = iBrother.vertexA();
+ _VertexB = iBrother.vertexB();
+ _NextEdge = iBrother.nextEdge();
+ _PreviousEdge = iBrother._PreviousEdge;
+ _Nature = iBrother.getNature();
+ _Id = iBrother._Id;
+ _ViewEdge = iBrother._ViewEdge;
+ //_hasVisibilityPoint = iBrother._hasVisibilityPoint;
+ //_VisibilityPointA = iBrother._VisibilityPointA;
+ //_VisibilityPointB = iBrother._VisibilityPointB;
+ _aFace = iBrother._aFace;
+ _occludeeEmpty = iBrother._occludeeEmpty;
+ _isSmooth = iBrother._isSmooth;
+ _isInImage = iBrother._isInImage;
+ _isTemporary = iBrother._isTemporary;
+ iBrother.userdata = this;
+ userdata = 0;
+ }
+
+ /*! Destructor */
+ virtual ~FEdge()
+ {
+ }
+
+ /*! Cloning method. */
+ virtual FEdge *duplicate()
+ {
+ FEdge *clone = new FEdge(*this);
+ return clone;
+ }
+
+ /* accessors */
+ /*! Returns the first SVertex. */
+ inline SVertex *vertexA()
+ {
+ return _VertexA;
+ }
+
+ /*! Returns the second SVertex. */
+ inline SVertex *vertexB()
+ {
+ return _VertexB;
+ }
+
+ /*! Returns the first SVertex if i=0, the seccond SVertex if i=1. */
+ inline SVertex *operator[](const unsigned short int &i) const
+ {
+ return (i % 2 == 0) ? _VertexA : _VertexB;
+ }
+
+ /*! Returns the nature of the FEdge. */
+ inline Nature::EdgeNature getNature() const
+ {
+ return _Nature;
+ }
+
+ /*! Returns the FEdge following this one in the ViewEdge.
+ * If this FEdge is the last of the ViewEdge, 0 is returned.
+ */
+ inline FEdge *nextEdge()
+ {
+ return _NextEdge;
+ }
+
+ /*! Returns the Edge preceding this one in the ViewEdge.
+ * If this FEdge is the first one of the ViewEdge, 0 is returned.
+ */
+ inline FEdge *previousEdge()
+ {
+ return _PreviousEdge;
+ }
+
+ inline SShape *shape()
+ {
+ return _VertexA->shape();
+ }
#if 0
- inline int invisibility() const
- {
- return _Occluders.size();
- }
+ inline int invisibility() const
+ {
+ return _Occluders.size();
+ }
#endif
- int invisibility() const;
+ int invisibility() const;
#if 0
- inline const vector<Polygon3r>& occluders() const
- {
- return _Occluders;
- }
+ inline const vector<Polygon3r>& occluders() const
+ {
+ return _Occluders;
+ }
#endif
- /*! Returns a pointer to the ViewEdge to which this FEdge belongs to. */
- inline ViewEdge *viewedge() const
- {
- return _ViewEdge;
- }
+ /*! Returns a pointer to the ViewEdge to which this FEdge belongs to. */
+ inline ViewEdge *viewedge() const
+ {
+ return _ViewEdge;
+ }
- inline Vec3r center3d()
- {
- return Vec3r((_VertexA->point3D() + _VertexB->point3D()) / 2.0);
- }
+ inline Vec3r center3d()
+ {
+ return Vec3r((_VertexA->point3D() + _VertexB->point3D()) / 2.0);
+ }
- inline Vec3r center2d()
- {
- return Vec3r((_VertexA->point2D() + _VertexB->point2D()) / 2.0);
- }
+ inline Vec3r center2d()
+ {
+ return Vec3r((_VertexA->point2D() + _VertexB->point2D()) / 2.0);
+ }
#if 0
- inline bool hasVisibilityPoint() const
- {
- return _hasVisibilityPoint;
- }
-
- inline Vec3r visibilityPointA() const
- {
- return _VisibilityPointA;
- }
-
- inline Vec3r visibilityPointB() const
- {
- return _VisibilityPointB;
- }
+ inline bool hasVisibilityPoint() const
+ {
+ return _hasVisibilityPoint;
+ }
+
+ inline Vec3r visibilityPointA() const
+ {
+ return _VisibilityPointA;
+ }
+
+ inline Vec3r visibilityPointB() const
+ {
+ return _VisibilityPointB;
+ }
#endif
- inline const Polygon3r& aFace() const
- {
- return _aFace;
- }
-
- inline const Vec3r& getOccludeeIntersection()
- {
- return _occludeeIntersection;
- }
-
- inline bool getOccludeeEmpty()
- {
- return _occludeeEmpty;
- }
-
- /*! Returns true if this FEdge is a smooth FEdge. */
- inline bool isSmooth() const
- {
- return _isSmooth;
- }
-
- inline bool isInImage () const
- {
- return _isInImage;
- }
-
- inline bool isTemporary() const
- {
- return _isTemporary;
- }
-
- /* modifiers */
- /*! Sets the first SVertex. */
- inline void setVertexA(SVertex *vA)
- {
- _VertexA = vA;
- }
-
- /*! Sets the second SVertex. */
- inline void setVertexB(SVertex *vB)
- {
- _VertexB = vB;
- }
-
- /*! Sets the FEdge Id . */
- inline void setId(const Id& id)
- {
- _Id = id;
- }
-
- /*! Sets the pointer to the next FEdge. */
- inline void setNextEdge(FEdge *iEdge)
- {
- _NextEdge = iEdge;
- }
-
- /*! Sets the pointer to the previous FEdge. */
- inline void setPreviousEdge(FEdge *iEdge)
- {
- _PreviousEdge = iEdge;
- }
-
- /*! Sets the nature of this FEdge. */
- inline void setNature(Nature::EdgeNature iNature)
- {
- _Nature = iNature;
- }
+ inline const Polygon3r &aFace() const
+ {
+ return _aFace;
+ }
+
+ inline const Vec3r &getOccludeeIntersection()
+ {
+ return _occludeeIntersection;
+ }
+
+ inline bool getOccludeeEmpty()
+ {
+ return _occludeeEmpty;
+ }
+
+ /*! Returns true if this FEdge is a smooth FEdge. */
+ inline bool isSmooth() const
+ {
+ return _isSmooth;
+ }
+
+ inline bool isInImage() const
+ {
+ return _isInImage;
+ }
+
+ inline bool isTemporary() const
+ {
+ return _isTemporary;
+ }
+
+ /* modifiers */
+ /*! Sets the first SVertex. */
+ inline void setVertexA(SVertex *vA)
+ {
+ _VertexA = vA;
+ }
+
+ /*! Sets the second SVertex. */
+ inline void setVertexB(SVertex *vB)
+ {
+ _VertexB = vB;
+ }
+
+ /*! Sets the FEdge Id . */
+ inline void setId(const Id &id)
+ {
+ _Id = id;
+ }
+
+ /*! Sets the pointer to the next FEdge. */
+ inline void setNextEdge(FEdge *iEdge)
+ {
+ _NextEdge = iEdge;
+ }
+
+ /*! Sets the pointer to the previous FEdge. */
+ inline void setPreviousEdge(FEdge *iEdge)
+ {
+ _PreviousEdge = iEdge;
+ }
+
+ /*! Sets the nature of this FEdge. */
+ inline void setNature(Nature::EdgeNature iNature)
+ {
+ _Nature = iNature;
+ }
#if 0
- inline void AddOccluder(Polygon3r& iPolygon)
- {
- _Occluders.push_back(iPolygon);
- }
+ inline void AddOccluder(Polygon3r& iPolygon)
+ {
+ _Occluders.push_back(iPolygon);
+ }
#endif
- /*! Sets the ViewEdge to which this FEdge belongs to. */
- inline void setViewEdge(ViewEdge *iViewEdge)
- {
- _ViewEdge = iViewEdge;
- }
+ /*! Sets the ViewEdge to which this FEdge belongs to. */
+ inline void setViewEdge(ViewEdge *iViewEdge)
+ {
+ _ViewEdge = iViewEdge;
+ }
#if 0
- inline void setHasVisibilityPoint(bool iBool)
- {
- _hasVisibilityPoint = iBool;
- }
-
- inline void setVisibilityPointA(const Vec3r& iPoint)
- {
- _VisibilityPointA = iPoint;
- }
-
- inline void setVisibilityPointB(const Vec3r& iPoint)
- {
- _VisibilityPointB = iPoint;
- }
+ inline void setHasVisibilityPoint(bool iBool)
+ {
+ _hasVisibilityPoint = iBool;
+ }
+
+ inline void setVisibilityPointA(const Vec3r& iPoint)
+ {
+ _VisibilityPointA = iPoint;
+ }
+
+ inline void setVisibilityPointB(const Vec3r& iPoint)
+ {
+ _VisibilityPointB = iPoint;
+ }
#endif
- inline void setaFace(Polygon3r& iFace)
- {
- _aFace = iFace;
- }
-
- inline void setOccludeeIntersection(const Vec3r& iPoint)
- {
- _occludeeIntersection = iPoint;
- }
-
- inline void setOccludeeEmpty(bool iempty)
- {
- _occludeeEmpty = iempty;
- }
-
- /*! Sets the flag telling whether this FEdge is smooth or sharp.
- * true for Smooth, false for Sharp.
- */
- inline void setSmooth(bool iFlag)
- {
- _isSmooth = iFlag;
- }
-
- inline void setIsInImage (bool iFlag)
- {
- _isInImage = iFlag;
- }
-
- inline void setTemporary(bool iFlag)
- {
- _isTemporary = iFlag;
- }
-
- /* checks whether two FEdge have a common vertex.
- * Returns a pointer on the common vertex if it exists, NULL otherwise.
- */
- static inline SVertex *CommonVertex(FEdge *iEdge1, FEdge *iEdge2)
- {
- if ((NULL == iEdge1) || (NULL == iEdge2))
- return NULL;
-
- SVertex *sv1 = iEdge1->vertexA();
- SVertex *sv2 = iEdge1->vertexB();
- SVertex *sv3 = iEdge2->vertexA();
- SVertex *sv4 = iEdge2->vertexB();
-
- if ((sv1 == sv3) || (sv1 == sv4)) {
- return sv1;
- }
- else if ((sv2 == sv3) || (sv2 == sv4)) {
- return sv2;
- }
-
- return NULL;
- }
-
- inline const SVertex *min2d() const
- {
- if (_VertexA->point2D() < _VertexB->point2D())
- return _VertexA;
- else
- return _VertexB;
- }
-
- inline const SVertex *max2d() const
- {
- if (_VertexA->point2D() < _VertexB->point2D())
- return _VertexB;
- else
- return _VertexA;
- }
-
- /* Information access interface */
-
- //Material material() const;
- Id shape_id() const;
- const SShape *shape() const;
- float shape_importance() const;
-
- inline const int qi() const
- {
- return invisibility();
- }
-
- occluder_container::const_iterator occluders_begin() const;
- occluder_container::const_iterator occluders_end() const;
- bool occluders_empty() const;
- int occluders_size() const;
-
- inline const Polygon3r& occludee() const
- {
- return aFace();
- }
-
- const SShape *occluded_shape() const;
+ inline void setaFace(Polygon3r &iFace)
+ {
+ _aFace = iFace;
+ }
+
+ inline void setOccludeeIntersection(const Vec3r &iPoint)
+ {
+ _occludeeIntersection = iPoint;
+ }
+
+ inline void setOccludeeEmpty(bool iempty)
+ {
+ _occludeeEmpty = iempty;
+ }
+
+ /*! Sets the flag telling whether this FEdge is smooth or sharp.
+ * true for Smooth, false for Sharp.
+ */
+ inline void setSmooth(bool iFlag)
+ {
+ _isSmooth = iFlag;
+ }
+
+ inline void setIsInImage(bool iFlag)
+ {
+ _isInImage = iFlag;
+ }
+
+ inline void setTemporary(bool iFlag)
+ {
+ _isTemporary = iFlag;
+ }
+
+ /* checks whether two FEdge have a common vertex.
+ * Returns a pointer on the common vertex if it exists, NULL otherwise.
+ */
+ static inline SVertex *CommonVertex(FEdge *iEdge1, FEdge *iEdge2)
+ {
+ if ((NULL == iEdge1) || (NULL == iEdge2))
+ return NULL;
+
+ SVertex *sv1 = iEdge1->vertexA();
+ SVertex *sv2 = iEdge1->vertexB();
+ SVertex *sv3 = iEdge2->vertexA();
+ SVertex *sv4 = iEdge2->vertexB();
+
+ if ((sv1 == sv3) || (sv1 == sv4)) {
+ return sv1;
+ }
+ else if ((sv2 == sv3) || (sv2 == sv4)) {
+ return sv2;
+ }
+
+ return NULL;
+ }
+
+ inline const SVertex *min2d() const
+ {
+ if (_VertexA->point2D() < _VertexB->point2D())
+ return _VertexA;
+ else
+ return _VertexB;
+ }
+
+ inline const SVertex *max2d() const
+ {
+ if (_VertexA->point2D() < _VertexB->point2D())
+ return _VertexB;
+ else
+ return _VertexA;
+ }
+
+ /* Information access interface */
+
+ //Material material() const;
+ Id shape_id() const;
+ const SShape *shape() const;
+ float shape_importance() const;
+
+ inline const int qi() const
+ {
+ return invisibility();
+ }
+
+ occluder_container::const_iterator occluders_begin() const;
+ occluder_container::const_iterator occluders_end() const;
+ bool occluders_empty() const;
+ int occluders_size() const;
+
+ inline const Polygon3r &occludee() const
+ {
+ return aFace();
+ }
+
+ const SShape *occluded_shape() const;
#if 0
- inline const bool occludee_empty() const
- {
- return _occludeeEmpty;
- }
+ inline const bool occludee_empty() const
+ {
+ return _occludeeEmpty;
+ }
#endif
- const bool occludee_empty() const;
- real z_discontinuity() const;
+ const bool occludee_empty() const;
+ real z_discontinuity() const;
#if 0
- inline float local_average_depth(int iCombination = 0) const;
- inline float local_depth_variance(int iCombination = 0) const;
- inline real local_average_density(float sigma = 2.3f, int iCombination = 0) const;
- inline Vec3r shaded_color(int iCombination = 0) const {}
+ inline float local_average_depth(int iCombination = 0) const;
+ inline float local_depth_variance(int iCombination = 0) const;
+ inline real local_average_density(float sigma = 2.3f, int iCombination = 0) const;
+ inline Vec3r shaded_color(int iCombination = 0) const {}
#endif
- int viewedge_nature() const;
+ int viewedge_nature() const;
- //float viewedge_length() const;
+ //float viewedge_length() const;
- inline Vec3r orientation2d() const
- {
- return Vec3r(_VertexB->point2d() - _VertexA->point2d());
- }
+ inline Vec3r orientation2d() const
+ {
+ return Vec3r(_VertexB->point2d() - _VertexA->point2d());
+ }
- inline Vec3r orientation3d() const
- {
- return Vec3r(_VertexB->point3d() - _VertexA->point3d());
- }
+ inline Vec3r orientation3d() const
+ {
+ return Vec3r(_VertexB->point3d() - _VertexA->point3d());
+ }
#if 0
- inline real curvature2d() const
- {
- return viewedge()->curvature2d((_VertexA->point2d() + _VertexB->point2d()) / 2.0);
- }
+ inline real curvature2d() const
+ {
+ return viewedge()->curvature2d((_VertexA->point2d() + _VertexB->point2d()) / 2.0);
+ }
- inline Vec3r curvature2d_as_vector(int iCombination = 0) const;
+ inline Vec3r curvature2d_as_vector(int iCombination = 0) const;
- /* angle in degrees*/
- inline real curvature2d_as_angle(int iCombination = 0) const;
+ /* angle in degrees*/
+ inline real curvature2d_as_angle(int iCombination = 0) const;
#endif
- // Iterator access (Interface1D)
- /*! Returns an iterator over the 2 (!) SVertex pointing to the first SVertex. */
- virtual inline Interface0DIterator verticesBegin();
-
- /*! Returns an iterator over the 2 (!) SVertex pointing after the last SVertex. */
- virtual inline Interface0DIterator verticesEnd();
-
- /*! Returns an iterator over the FEdge points, pointing to the first point. The difference with verticesBegin()
- * is that here we can iterate over points of the FEdge at a any given sampling.
- * Indeed, for each iteration, a virtual point is created.
- * \param t:
- * The sampling with which we want to iterate over points of this FEdge.
- */
- virtual inline Interface0DIterator pointsBegin(float t = 0.0f);
-
- /*! Returns an iterator over the FEdge points, pointing after the last point. The difference with verticesEnd()
- * is that here we can iterate over points of the FEdge at a any given sampling.
- * Indeed, for each iteration, a virtual point is created.
- * \param t:
- * The sampling with which we want to iterate over points of this FEdge.
- */
- virtual inline Interface0DIterator pointsEnd(float t = 0.0f);
+ // Iterator access (Interface1D)
+ /*! Returns an iterator over the 2 (!) SVertex pointing to the first SVertex. */
+ virtual inline Interface0DIterator verticesBegin();
+
+ /*! Returns an iterator over the 2 (!) SVertex pointing after the last SVertex. */
+ virtual inline Interface0DIterator verticesEnd();
+
+ /*! Returns an iterator over the FEdge points, pointing to the first point. The difference with verticesBegin()
+ * is that here we can iterate over points of the FEdge at a any given sampling.
+ * Indeed, for each iteration, a virtual point is created.
+ * \param t:
+ * The sampling with which we want to iterate over points of this FEdge.
+ */
+ virtual inline Interface0DIterator pointsBegin(float t = 0.0f);
+
+ /*! Returns an iterator over the FEdge points, pointing after the last point. The difference with verticesEnd()
+ * is that here we can iterate over points of the FEdge at a any given sampling.
+ * Indeed, for each iteration, a virtual point is created.
+ * \param t:
+ * The sampling with which we want to iterate over points of this FEdge.
+ */
+ virtual inline Interface0DIterator pointsEnd(float t = 0.0f);
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdge")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdge")
#endif
};
@@ -968,162 +968,161 @@ public:
namespace FEdgeInternal {
-class SVertexIterator : public Interface0DIteratorNested
-{
-public:
- SVertexIterator()
- {
- _vertex = NULL;
- _edge = NULL;
- }
-
- SVertexIterator(const SVertexIterator& vi)
- {
- _vertex = vi._vertex;
- _edge = vi._edge;
- }
-
- SVertexIterator(SVertex *v, FEdge *edge)
- {
- _vertex = v;
- _edge = edge;
- }
-
- SVertexIterator& operator=(const SVertexIterator& vi)
- {
- _vertex = vi._vertex;
- _edge = vi._edge;
- return *this;
- }
-
- virtual string getExactTypeName() const
- {
- return "SVertexIterator";
- }
-
- virtual SVertex& operator*()
- {
- return *_vertex;
- }
-
- virtual SVertex *operator->()
- {
- return &(operator*());
- }
-
- virtual SVertexIterator& operator++()
- {
- increment();
- return *this;
- }
-
- virtual SVertexIterator operator++(int)
- {
- SVertexIterator ret(*this);
- increment();
- return ret;
- }
-
- virtual SVertexIterator& operator--()
- {
- decrement();
- return *this;
- }
-
- virtual SVertexIterator operator--(int)
- {
- SVertexIterator ret(*this);
- decrement();
- return ret;
- }
-
- virtual int increment()
- {
- if (_vertex == _edge->vertexB()) {
- _vertex = 0;
- return 0;
- }
- _vertex = _edge->vertexB();
- return 0;
- }
-
- virtual int decrement()
- {
- if (_vertex == _edge->vertexA()) {
- _vertex = 0;
- return 0;
- }
- _vertex = _edge->vertexA();
- return 0;
- }
-
- virtual bool isBegin() const
- {
- return _vertex == _edge->vertexA();
- }
-
- virtual bool isEnd() const
- {
- return _vertex == _edge->vertexB();
- }
-
- virtual bool operator==(const Interface0DIteratorNested& it) const
- {
- const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator*>(&it);
- if (!it_exact)
- return false;
- return ((_vertex == it_exact->_vertex) && (_edge == it_exact->_edge));
- }
-
- virtual float t() const
- {
- if (_vertex == _edge->vertexA()) {
- return 0.0f;
- }
- return ((float)_edge->getLength2D());
- }
- virtual float u() const
- {
- if (_vertex == _edge->vertexA()) {
- return 0.0f;
- }
- return 1.0f;
- }
-
- virtual SVertexIterator *copy() const
- {
- return new SVertexIterator(*this);
- }
-
-private:
- SVertex *_vertex;
- FEdge *_edge;
+class SVertexIterator : public Interface0DIteratorNested {
+ public:
+ SVertexIterator()
+ {
+ _vertex = NULL;
+ _edge = NULL;
+ }
+
+ SVertexIterator(const SVertexIterator &vi)
+ {
+ _vertex = vi._vertex;
+ _edge = vi._edge;
+ }
+
+ SVertexIterator(SVertex *v, FEdge *edge)
+ {
+ _vertex = v;
+ _edge = edge;
+ }
+
+ SVertexIterator &operator=(const SVertexIterator &vi)
+ {
+ _vertex = vi._vertex;
+ _edge = vi._edge;
+ return *this;
+ }
+
+ virtual string getExactTypeName() const
+ {
+ return "SVertexIterator";
+ }
+
+ virtual SVertex &operator*()
+ {
+ return *_vertex;
+ }
+
+ virtual SVertex *operator->()
+ {
+ return &(operator*());
+ }
+
+ virtual SVertexIterator &operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ virtual SVertexIterator operator++(int)
+ {
+ SVertexIterator ret(*this);
+ increment();
+ return ret;
+ }
+
+ virtual SVertexIterator &operator--()
+ {
+ decrement();
+ return *this;
+ }
+
+ virtual SVertexIterator operator--(int)
+ {
+ SVertexIterator ret(*this);
+ decrement();
+ return ret;
+ }
+
+ virtual int increment()
+ {
+ if (_vertex == _edge->vertexB()) {
+ _vertex = 0;
+ return 0;
+ }
+ _vertex = _edge->vertexB();
+ return 0;
+ }
+
+ virtual int decrement()
+ {
+ if (_vertex == _edge->vertexA()) {
+ _vertex = 0;
+ return 0;
+ }
+ _vertex = _edge->vertexA();
+ return 0;
+ }
+
+ virtual bool isBegin() const
+ {
+ return _vertex == _edge->vertexA();
+ }
+
+ virtual bool isEnd() const
+ {
+ return _vertex == _edge->vertexB();
+ }
+
+ virtual bool operator==(const Interface0DIteratorNested &it) const
+ {
+ const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator *>(&it);
+ if (!it_exact)
+ return false;
+ return ((_vertex == it_exact->_vertex) && (_edge == it_exact->_edge));
+ }
+
+ virtual float t() const
+ {
+ if (_vertex == _edge->vertexA()) {
+ return 0.0f;
+ }
+ return ((float)_edge->getLength2D());
+ }
+ virtual float u() const
+ {
+ if (_vertex == _edge->vertexA()) {
+ return 0.0f;
+ }
+ return 1.0f;
+ }
+
+ virtual SVertexIterator *copy() const
+ {
+ return new SVertexIterator(*this);
+ }
+
+ private:
+ SVertex *_vertex;
+ FEdge *_edge;
};
-} // end of namespace FEdgeInternal
+} // end of namespace FEdgeInternal
// Iterator access (implementation)
Interface0DIterator FEdge::verticesBegin()
{
- Interface0DIterator ret(new FEdgeInternal::SVertexIterator(_VertexA, this));
- return ret;
+ Interface0DIterator ret(new FEdgeInternal::SVertexIterator(_VertexA, this));
+ return ret;
}
Interface0DIterator FEdge::verticesEnd()
{
- Interface0DIterator ret(new FEdgeInternal::SVertexIterator(0, this));
- return ret;
+ Interface0DIterator ret(new FEdgeInternal::SVertexIterator(0, this));
+ return ret;
}
Interface0DIterator FEdge::pointsBegin(float /*t*/)
{
- return verticesBegin();
+ return verticesBegin();
}
Interface0DIterator FEdge::pointsEnd(float /*t*/)
{
- return verticesEnd();
+ return verticesEnd();
}
/*! Class defining a sharp FEdge. A Sharp FEdge corresponds to an initial edge of the input mesh.
@@ -1131,267 +1130,268 @@ Interface0DIterator FEdge::pointsEnd(float /*t*/)
* by two faces of the mesh. Face a lies on its right whereas Face b lies on its left.
* If it is a border edge, then it doesn't have any face on its right, and thus Face a = 0.
*/
-class FEdgeSharp : public FEdge
-{
-protected:
- Vec3r _aNormal; // When following the edge, normal of the right face
- Vec3r _bNormal; // When following the edge, normal of the left face
- unsigned _aFrsMaterialIndex;
- unsigned _bFrsMaterialIndex;
- bool _aFaceMark;
- bool _bFaceMark;
-
-public:
- /*! Returns the string "FEdgeSharp" . */
- virtual string getExactTypeName() const
- {
- return "FEdgeSharp";
- }
-
- /*! Default constructor. */
- inline FEdgeSharp() : FEdge()
- {
- _aFrsMaterialIndex = _bFrsMaterialIndex = 0;
- _aFaceMark = _bFaceMark = false;
- }
-
- /*! Builds an FEdgeSharp going from vA to vB. */
- inline FEdgeSharp(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
- {
- _aFrsMaterialIndex = _bFrsMaterialIndex = 0;
- _aFaceMark = _bFaceMark = false;
- }
-
- /*! Copy constructor. */
- inline FEdgeSharp(FEdgeSharp& iBrother) : FEdge(iBrother)
- {
- _aNormal = iBrother._aNormal;
- _bNormal = iBrother._bNormal;
- _aFrsMaterialIndex = iBrother._aFrsMaterialIndex;
- _bFrsMaterialIndex = iBrother._bFrsMaterialIndex;
- _aFaceMark = iBrother._aFaceMark;
- _bFaceMark = iBrother._bFaceMark;
- }
-
- /*! Destructor. */
- virtual ~FEdgeSharp() {}
-
- /*! Cloning method. */
- virtual FEdge *duplicate()
- {
- FEdge *clone = new FEdgeSharp(*this);
- return clone;
- }
-
- /*! Returns the normal to the face lying on the right of the FEdge. If this FEdge is a border,
- * it has no Face on its right and therefore, no normal.
- */
- inline const Vec3r& normalA()
- {
- return _aNormal;
- }
-
- /*! Returns the normal to the face lying on the left of the FEdge. */
- inline const Vec3r& normalB()
- {
- return _bNormal;
- }
-
- /*! Returns the index of the material of the face lying on the
- * right of the FEdge. If this FEdge is a border,
- * it has no Face on its right and therefore, no material.
- */
- inline unsigned aFrsMaterialIndex() const
- {
- return _aFrsMaterialIndex;
- }
-
- /*! Returns the material of the face lying on the right of the FEdge. If this FEdge is a border,
- * it has no Face on its right and therefore, no material.
- */
- const FrsMaterial& aFrsMaterial() const;
-
- /*! Returns the index of the material of the face lying on the left of the FEdge. */
- inline unsigned bFrsMaterialIndex() const
- {
- return _bFrsMaterialIndex;
- }
-
- /*! Returns the material of the face lying on the left of the FEdge. */
- const FrsMaterial& bFrsMaterial() const;
-
- /*! Returns the face mark of the face lying on the right of the FEdge.
- * If this FEdge is a border, it has no Face on its right and thus false is returned.
- */
- inline bool aFaceMark() const
- {
- return _aFaceMark;
- }
-
- /*! Returns the face mark of the face lying on the left of the FEdge. */
- inline bool bFaceMark() const
- {
- return _bFaceMark;
- }
-
- /*! Sets the normal to the face lying on the right of the FEdge. */
- inline void setNormalA(const Vec3r& iNormal)
- {
- _aNormal = iNormal;
- }
-
- /*! Sets the normal to the face lying on the left of the FEdge. */
- inline void setNormalB(const Vec3r& iNormal)
- {
- _bNormal = iNormal;
- }
-
- /*! Sets the index of the material lying on the right of the FEdge.*/
- inline void setaFrsMaterialIndex(unsigned i)
- {
- _aFrsMaterialIndex = i;
- }
-
- /*! Sets the index of the material lying on the left of the FEdge.*/
- inline void setbFrsMaterialIndex(unsigned i)
- {
- _bFrsMaterialIndex = i;
- }
-
- /*! Sets the face mark of the face lying on the right of the FEdge. */
- inline void setaFaceMark(bool iFaceMark)
- {
- _aFaceMark = iFaceMark;
- }
-
- /*! Sets the face mark of the face lying on the left of the FEdge. */
- inline void setbFaceMark(bool iFaceMark)
- {
- _bFaceMark = iFaceMark;
- }
+class FEdgeSharp : public FEdge {
+ protected:
+ Vec3r _aNormal; // When following the edge, normal of the right face
+ Vec3r _bNormal; // When following the edge, normal of the left face
+ unsigned _aFrsMaterialIndex;
+ unsigned _bFrsMaterialIndex;
+ bool _aFaceMark;
+ bool _bFaceMark;
+
+ public:
+ /*! Returns the string "FEdgeSharp" . */
+ virtual string getExactTypeName() const
+ {
+ return "FEdgeSharp";
+ }
+
+ /*! Default constructor. */
+ inline FEdgeSharp() : FEdge()
+ {
+ _aFrsMaterialIndex = _bFrsMaterialIndex = 0;
+ _aFaceMark = _bFaceMark = false;
+ }
+
+ /*! Builds an FEdgeSharp going from vA to vB. */
+ inline FEdgeSharp(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
+ {
+ _aFrsMaterialIndex = _bFrsMaterialIndex = 0;
+ _aFaceMark = _bFaceMark = false;
+ }
+
+ /*! Copy constructor. */
+ inline FEdgeSharp(FEdgeSharp &iBrother) : FEdge(iBrother)
+ {
+ _aNormal = iBrother._aNormal;
+ _bNormal = iBrother._bNormal;
+ _aFrsMaterialIndex = iBrother._aFrsMaterialIndex;
+ _bFrsMaterialIndex = iBrother._bFrsMaterialIndex;
+ _aFaceMark = iBrother._aFaceMark;
+ _bFaceMark = iBrother._bFaceMark;
+ }
+
+ /*! Destructor. */
+ virtual ~FEdgeSharp()
+ {
+ }
+
+ /*! Cloning method. */
+ virtual FEdge *duplicate()
+ {
+ FEdge *clone = new FEdgeSharp(*this);
+ return clone;
+ }
+
+ /*! Returns the normal to the face lying on the right of the FEdge. If this FEdge is a border,
+ * it has no Face on its right and therefore, no normal.
+ */
+ inline const Vec3r &normalA()
+ {
+ return _aNormal;
+ }
+
+ /*! Returns the normal to the face lying on the left of the FEdge. */
+ inline const Vec3r &normalB()
+ {
+ return _bNormal;
+ }
+
+ /*! Returns the index of the material of the face lying on the
+ * right of the FEdge. If this FEdge is a border,
+ * it has no Face on its right and therefore, no material.
+ */
+ inline unsigned aFrsMaterialIndex() const
+ {
+ return _aFrsMaterialIndex;
+ }
+
+ /*! Returns the material of the face lying on the right of the FEdge. If this FEdge is a border,
+ * it has no Face on its right and therefore, no material.
+ */
+ const FrsMaterial &aFrsMaterial() const;
+
+ /*! Returns the index of the material of the face lying on the left of the FEdge. */
+ inline unsigned bFrsMaterialIndex() const
+ {
+ return _bFrsMaterialIndex;
+ }
+
+ /*! Returns the material of the face lying on the left of the FEdge. */
+ const FrsMaterial &bFrsMaterial() const;
+
+ /*! Returns the face mark of the face lying on the right of the FEdge.
+ * If this FEdge is a border, it has no Face on its right and thus false is returned.
+ */
+ inline bool aFaceMark() const
+ {
+ return _aFaceMark;
+ }
+
+ /*! Returns the face mark of the face lying on the left of the FEdge. */
+ inline bool bFaceMark() const
+ {
+ return _bFaceMark;
+ }
+
+ /*! Sets the normal to the face lying on the right of the FEdge. */
+ inline void setNormalA(const Vec3r &iNormal)
+ {
+ _aNormal = iNormal;
+ }
+
+ /*! Sets the normal to the face lying on the left of the FEdge. */
+ inline void setNormalB(const Vec3r &iNormal)
+ {
+ _bNormal = iNormal;
+ }
+
+ /*! Sets the index of the material lying on the right of the FEdge.*/
+ inline void setaFrsMaterialIndex(unsigned i)
+ {
+ _aFrsMaterialIndex = i;
+ }
+
+ /*! Sets the index of the material lying on the left of the FEdge.*/
+ inline void setbFrsMaterialIndex(unsigned i)
+ {
+ _bFrsMaterialIndex = i;
+ }
+
+ /*! Sets the face mark of the face lying on the right of the FEdge. */
+ inline void setaFaceMark(bool iFaceMark)
+ {
+ _aFaceMark = iFaceMark;
+ }
+
+ /*! Sets the face mark of the face lying on the left of the FEdge. */
+ inline void setbFaceMark(bool iFaceMark)
+ {
+ _bFaceMark = iFaceMark;
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeSharp")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeSharp")
#endif
};
/*! Class defining a smooth edge. This kind of edge typically runs across a face of the input mesh. It can be
* a silhouette, a ridge or valley, a suggestive contour.
*/
-class FEdgeSmooth : public FEdge
-{
-protected:
- Vec3r _Normal;
- unsigned _FrsMaterialIndex;
+class FEdgeSmooth : public FEdge {
+ protected:
+ Vec3r _Normal;
+ unsigned _FrsMaterialIndex;
#if 0
- bool _hasVisibilityPoint;
- Vec3r _VisibilityPointA; // The edge on which the visibility will be computed represented
- Vec3r _VisibilityPointB; // using its 2 extremity points A and B
+ bool _hasVisibilityPoint;
+ Vec3r _VisibilityPointA; // The edge on which the visibility will be computed represented
+ Vec3r _VisibilityPointB; // using its 2 extremity points A and B
#endif
- void *_Face; // In case of exact silhouette, Face is the WFace crossed by Fedge
- // NOT HANDLED BY THE COPY CONSTRUCTEUR
- bool _FaceMark;
-
-public:
- /*! Returns the string "FEdgeSmooth" . */
- virtual string getExactTypeName() const
- {
- return "FEdgeSmooth";
- }
-
- /*! Default constructor. */
- inline FEdgeSmooth() : FEdge()
- {
- _Face = NULL;
- _FaceMark = false;
- _FrsMaterialIndex = 0;
- _isSmooth = true;
- }
-
- /*! Builds an FEdgeSmooth going from vA to vB. */
- inline FEdgeSmooth(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
- {
- _Face = NULL;
- _FaceMark = false;
- _FrsMaterialIndex = 0;
- _isSmooth = true;
- }
-
- /*! Copy constructor. */
- inline FEdgeSmooth(FEdgeSmooth& iBrother) : FEdge(iBrother)
- {
- _Normal = iBrother._Normal;
- _Face = iBrother._Face;
- _FaceMark = iBrother._FaceMark;
- _FrsMaterialIndex = iBrother._FrsMaterialIndex;
- _isSmooth = true;
- }
-
- /*! Destructor. */
- virtual ~FEdgeSmooth() {}
-
- /*! Cloning method. */
- virtual FEdge *duplicate()
- {
- FEdge *clone = new FEdgeSmooth(*this);
- return clone;
- }
-
- inline void *face() const
- {
- return _Face;
- }
-
- /*! Returns the face mark of the face it is running across. */
- inline bool faceMark() const
- {
- return _FaceMark;
- }
-
- /*! Returns the normal to the Face it is running accross. */
- inline const Vec3r& normal()
- {
- return _Normal;
- }
-
- /*! Returns the index of the material of the face it is running accross. */
- inline unsigned frs_materialIndex() const
- {
- return _FrsMaterialIndex;
- }
-
- /*! Returns the material of the face it is running accross. */
- const FrsMaterial& frs_material() const;
-
- inline void setFace(void *iFace)
- {
- _Face = iFace;
- }
-
- /*! Sets the face mark of the face it is running across. */
- inline void setFaceMark(bool iFaceMark)
- {
- _FaceMark = iFaceMark;
- }
-
- /*! Sets the normal to the Face it is running accross. */
- inline void setNormal(const Vec3r& iNormal)
- {
- _Normal = iNormal;
- }
-
- /*! Sets the index of the material of the face it is running accross. */
- inline void setFrsMaterialIndex(unsigned i)
- {
- _FrsMaterialIndex = i;
- }
+ void *_Face; // In case of exact silhouette, Face is the WFace crossed by Fedge
+ // NOT HANDLED BY THE COPY CONSTRUCTEUR
+ bool _FaceMark;
+
+ public:
+ /*! Returns the string "FEdgeSmooth" . */
+ virtual string getExactTypeName() const
+ {
+ return "FEdgeSmooth";
+ }
+
+ /*! Default constructor. */
+ inline FEdgeSmooth() : FEdge()
+ {
+ _Face = NULL;
+ _FaceMark = false;
+ _FrsMaterialIndex = 0;
+ _isSmooth = true;
+ }
+
+ /*! Builds an FEdgeSmooth going from vA to vB. */
+ inline FEdgeSmooth(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
+ {
+ _Face = NULL;
+ _FaceMark = false;
+ _FrsMaterialIndex = 0;
+ _isSmooth = true;
+ }
+
+ /*! Copy constructor. */
+ inline FEdgeSmooth(FEdgeSmooth &iBrother) : FEdge(iBrother)
+ {
+ _Normal = iBrother._Normal;
+ _Face = iBrother._Face;
+ _FaceMark = iBrother._FaceMark;
+ _FrsMaterialIndex = iBrother._FrsMaterialIndex;
+ _isSmooth = true;
+ }
+
+ /*! Destructor. */
+ virtual ~FEdgeSmooth()
+ {
+ }
+
+ /*! Cloning method. */
+ virtual FEdge *duplicate()
+ {
+ FEdge *clone = new FEdgeSmooth(*this);
+ return clone;
+ }
+
+ inline void *face() const
+ {
+ return _Face;
+ }
+
+ /*! Returns the face mark of the face it is running across. */
+ inline bool faceMark() const
+ {
+ return _FaceMark;
+ }
+
+ /*! Returns the normal to the Face it is running accross. */
+ inline const Vec3r &normal()
+ {
+ return _Normal;
+ }
+
+ /*! Returns the index of the material of the face it is running accross. */
+ inline unsigned frs_materialIndex() const
+ {
+ return _FrsMaterialIndex;
+ }
+
+ /*! Returns the material of the face it is running accross. */
+ const FrsMaterial &frs_material() const;
+
+ inline void setFace(void *iFace)
+ {
+ _Face = iFace;
+ }
+
+ /*! Sets the face mark of the face it is running across. */
+ inline void setFaceMark(bool iFaceMark)
+ {
+ _FaceMark = iFaceMark;
+ }
+
+ /*! Sets the normal to the Face it is running accross. */
+ inline void setNormal(const Vec3r &iNormal)
+ {
+ _Normal = iNormal;
+ }
+
+ /*! Sets the index of the material of the face it is running accross. */
+ inline void setFrsMaterialIndex(unsigned i)
+ {
+ _FrsMaterialIndex = i;
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeSmooth")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeSmooth")
#endif
};
-
/**********************************/
/* */
/* */
@@ -1400,540 +1400,544 @@ public:
/* */
/**********************************/
-
/*! Class to define a feature shape. It is the gathering of feature elements from an identified input shape */
-class SShape
-{
-private:
- vector<FEdge*> _chains; // list of fedges that are chains starting points.
- vector<SVertex*> _verticesList; // list of all vertices
- vector<FEdge*> _edgesList; // list of all edges
- Id _Id;
- string _Name;
- string _LibraryPath;
- BBox<Vec3r> _BBox;
- vector<FrsMaterial> _FrsMaterials;
-
- float _importance;
-
- ViewShape *_ViewShape;
-
-public:
- /*! A field that can be used by the user to store any data.
- * This field must be reseted afterwards using ResetUserData().
- */
- void *userdata; // added by E.T.
-
- /*! Default constructor */
- inline SShape()
- {
- userdata = NULL;
- _importance = 0.0f;
- _ViewShape = NULL;
- }
-
- /*! Copy constructor */
- inline SShape(SShape& iBrother)
- {
- userdata = NULL;
- _Id = iBrother._Id;
- _Name = iBrother._Name;
- _LibraryPath = iBrother._LibraryPath;
- _BBox = iBrother.bbox();
- _FrsMaterials = iBrother._FrsMaterials;
- _importance = iBrother._importance;
- _ViewShape = iBrother._ViewShape;
-
- //---------
- // vertices
- //---------
- vector<SVertex*>::iterator sv, svend;
- vector<SVertex*>& verticesList = iBrother.getVertexList();
- for (sv = verticesList.begin(), svend = verticesList.end(); sv != svend; sv++) {
- SVertex *newv = new SVertex(*(*sv));
- newv->setShape(this);
- _verticesList.push_back(newv);
- }
-
- //------
- // edges
- //------
- vector<FEdge*>::iterator e, eend;
- vector<FEdge*>& edgesList = iBrother.getEdgeList();
- for (e = edgesList.begin(), eend = edgesList.end(); e != eend; e++) {
- FEdge *newe = (*e)->duplicate();
- _edgesList.push_back(newe);
- }
-
- //-------------------------
- // starting chain edges
- //-------------------------
- vector<FEdge*>::iterator fe, fend;
- vector<FEdge*>& fedges = iBrother.getChains();
- for (fe = fedges.begin(), fend = fedges.end(); fe != fend; fe++) {
- _chains.push_back((FEdge *)((*fe)->userdata));
- }
-
- //-------------------------
- // remap edges in vertices:
- //-------------------------
- for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
- const vector<FEdge*>& fedgeList = (*sv)->fedges();
- vector<FEdge*> newfedgelist;
- for (vector<FEdge*>::const_iterator fed = fedgeList.begin(), fedend = fedgeList.end();
- fed != fedend;
- fed++)
- {
- FEdge *current = *fed;
- newfedgelist.push_back((FEdge *)current->userdata);
- }
- (*sv)->setFEdges(newfedgelist);
- }
-
- //-------------------------------------
- // remap vertices and nextedge in edges:
- //-------------------------------------
- for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
- (*e)->setVertexA((SVertex *)((*e)->vertexA()->userdata));
- (*e)->setVertexB((SVertex *)((*e)->vertexB()->userdata));
- (*e)->setNextEdge((FEdge *)((*e)->nextEdge()->userdata));
- (*e)->setPreviousEdge((FEdge *)((*e)->previousEdge()->userdata));
- }
-
- // reset all brothers userdata to NULL:
- //-------------------------------------
- //---------
- // vertices
- //---------
- for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
- (*sv)->userdata = NULL;
- }
-
- //------
- // edges
- //------
- for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
- (*e)->userdata = NULL;
- }
- }
-
- /*! Cloning method. */
- virtual SShape *duplicate()
- {
- SShape *clone = new SShape(*this);
- return clone;
- }
-
- /*! Destructor. */
- virtual inline ~SShape()
- {
- vector<SVertex*>::iterator sv, svend;
- vector<FEdge*>::iterator e, eend;
- if (0 != _verticesList.size()) {
- for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
- delete (*sv);
- }
- _verticesList.clear();
- }
-
- if (0 != _edgesList.size()) {
- for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
- delete (*e);
- }
- _edgesList.clear();
- }
-
- //! Clear the chains list
- //-----------------------
- if (0 != _chains.size()) {
- _chains.clear();
- }
- }
-
- /*! Adds a FEdge to the list of FEdges. */
- inline void AddEdge(FEdge *iEdge)
- {
- _edgesList.push_back(iEdge);
- }
-
- /*! Adds a SVertex to the list of SVertex of this Shape.
- * The SShape attribute of the SVertex is also set to 'this'.
- */
- inline void AddNewVertex(SVertex *iv)
- {
- iv->setShape(this);
- _verticesList.push_back(iv);
- }
-
- inline void AddChain(FEdge *iEdge)
- {
- _chains.push_back(iEdge);
- }
-
- inline SVertex *CreateSVertex(const Vec3r& P3D, const Vec3r& P2D, const Id& id)
- {
- SVertex *Ia = new SVertex(P3D, id);
- Ia->setPoint2D(P2D);
- AddNewVertex(Ia);
- return Ia;
- }
-
- /*! Splits an edge into several edges.
- * The edge's vertices are passed rather than the edge itself. This way, all feature edges (SILHOUETTE,
- * CREASE, BORDER) are splitted in the same time.
- * The processed edges are flagged as done (using the userdata flag).One single new vertex is created whereas
- * several splitted edges might created for the different kinds of edges. These new elements are added to the lists
- * maintained by the shape.
- * New chains are also created.
- * ioA
- * The first vertex for the edge that gets splitted
- * ioB
- * The second vertex for the edge that gets splitted
- * iParameters
- * A vector containing 2D real vectors indicating the parameters giving the intersections coordinates in
- * 3D and in 2D. These intersections points must be sorted from B to A.
- * Each parameter defines the intersection point I as I=A+T*AB. T<0 and T>1 are then incorrect insofar as
- * they give intersections points that lie outside the segment.
- * ioNewEdges
- * The edges that are newly created (the initial edges are not included) are added to this list.
- */
- inline void SplitEdge(FEdge *fe, const vector<Vec2r>& iParameters, vector<FEdge*>& ioNewEdges)
- {
- SVertex *ioA = fe->vertexA();
- SVertex *ioB = fe->vertexB();
- Vec3r A = ioA->point3D();
- Vec3r B = ioB->point3D();
- Vec3r a = ioA->point2D();
- Vec3r b = ioB->point2D();
-
- Vec3r newpoint3d, newpoint2d;
- vector<SVertex*> intersections;
- real t, T;
- for (vector<Vec2r>::const_iterator p = iParameters.begin(), pend = iParameters.end(); p != pend; p++) {
- T = (*p)[0];
- t = (*p)[1];
-
- if ((t < 0) || (t > 1))
- cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - " << ioB->getId() << endl;
-
- // compute the 3D and 2D coordinates for the intersections points:
- newpoint3d = Vec3r(A + T * (B - A));
- newpoint2d = Vec3r(a + t * (b - a));
-
- // create new SVertex:
- // (we keep B's id)
- SVertex *newVertex = new SVertex(newpoint3d, ioB->getId());
- newVertex->setPoint2D(newpoint2d);
-
- // Add this vertex to the intersections list:
- intersections.push_back(newVertex);
-
- // Add this vertex to this sshape:
- AddNewVertex(newVertex);
- }
-
- for (vector<SVertex*>::iterator sv = intersections.begin(), svend = intersections.end(); sv != svend; sv++) {
- //SVertex *svA = fe->vertexA();
- SVertex *svB = fe->vertexB();
-
- // We split edge AB into AA' and A'B. A' and A'B are created.
- // AB becomes (address speaking) AA'. B is updated.
- //--------------------------------------------------
- // The edge AB becomes edge AA'.
- (fe)->setVertexB((*sv));
- // a new edge, A'B is created.
- FEdge *newEdge;
- if (fe->isSmooth()) {
- newEdge = new FEdgeSmooth((*sv), svB);
- FEdgeSmooth *se = dynamic_cast<FEdgeSmooth*>(newEdge);
- FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(fe);
- se->setFrsMaterialIndex(fes->frs_materialIndex());
- }
- else {
- newEdge = new FEdgeSharp((*sv), svB);
- FEdgeSharp *se = dynamic_cast<FEdgeSharp*>(newEdge);
- FEdgeSharp *fes = dynamic_cast<FEdgeSharp*>(fe);
- se->setaFrsMaterialIndex(fes->aFrsMaterialIndex());
- se->setbFrsMaterialIndex(fes->bFrsMaterialIndex());
- }
-
- newEdge->setNature((fe)->getNature());
-
- // to build a new chain:
- AddChain(newEdge);
- // add the new edge to the sshape edges list.
- AddEdge(newEdge);
- // add new edge to the list of new edges passed as argument:
- ioNewEdges.push_back(newEdge);
-
- // update edge A'B for the next pointing edge
- newEdge->setNextEdge((fe)->nextEdge());
- fe->nextEdge()->setPreviousEdge(newEdge);
- Id id(fe->getId().getFirst(), fe->getId().getSecond() + 1);
- newEdge->setId(fe->getId());
- fe->setId(id);
-
- // update edge AA' for the next pointing edge
- //ioEdge->setNextEdge(newEdge);
- (fe)->setNextEdge(NULL);
-
- // update vertex pointing edges list:
- // -- vertex B --
- svB->Replace((fe), newEdge);
- // -- vertex A' --
- (*sv)->AddFEdge((fe));
- (*sv)->AddFEdge(newEdge);
- }
- }
-
- /* splits an edge into 2 edges. The new vertex and edge are added to the sshape list of vertices and edges
- * a new chain is also created.
- * returns the new edge.
- * ioEdge
- * The edge that gets splitted
- * newpoint
- * x,y,z coordinates of the new point.
- */
- inline FEdge *SplitEdgeIn2(FEdge *ioEdge, SVertex *ioNewVertex)
- {
- //soc unused - SVertex *A = ioEdge->vertexA();
- SVertex *B = ioEdge->vertexB();
-
- // We split edge AB into AA' and A'B. A' and A'B are created.
- // AB becomes (address speaking) AA'. B is updated.
- //--------------------------------------------------
- // a new edge, A'B is created.
- FEdge *newEdge;
- if (ioEdge->isSmooth()) {
- newEdge = new FEdgeSmooth(ioNewVertex, B);
- FEdgeSmooth *se = dynamic_cast<FEdgeSmooth*>(newEdge);
- FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(ioEdge);
- se->setNormal(fes->normal());
- se->setFrsMaterialIndex(fes->frs_materialIndex());
- se->setFaceMark(fes->faceMark());
- }
- else {
- newEdge = new FEdgeSharp(ioNewVertex, B);
- FEdgeSharp *se = dynamic_cast<FEdgeSharp*>(newEdge);
- FEdgeSharp *fes = dynamic_cast<FEdgeSharp*>(ioEdge);
- se->setNormalA(fes->normalA());
- se->setNormalB(fes->normalB());
- se->setaFrsMaterialIndex(fes->aFrsMaterialIndex());
- se->setbFrsMaterialIndex(fes->bFrsMaterialIndex());
- se->setaFaceMark(fes->aFaceMark());
- se->setbFaceMark(fes->bFaceMark());
- }
- newEdge->setNature(ioEdge->getNature());
-
- if (ioEdge->nextEdge() != 0)
- ioEdge->nextEdge()->setPreviousEdge(newEdge);
-
- // update edge A'B for the next pointing edge
- newEdge->setNextEdge(ioEdge->nextEdge());
- // update edge A'B for the previous pointing edge
- newEdge->setPreviousEdge(0); // because it is now a TVertex
- Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1);
- newEdge->setId(ioEdge->getId());
- ioEdge->setId(id);
-
- // update edge AA' for the next pointing edge
- ioEdge->setNextEdge(0); // because it is now a TVertex
-
- // update vertex pointing edges list:
- // -- vertex B --
- B->Replace(ioEdge, newEdge);
- // -- vertex A' --
- ioNewVertex->AddFEdge(ioEdge);
- ioNewVertex->AddFEdge(newEdge);
-
- // to build a new chain:
- AddChain(newEdge);
- AddEdge(newEdge); // FIXME ??
-
- // The edge AB becomes edge AA'.
- ioEdge->setVertexB(ioNewVertex);
-
- if (ioEdge->isSmooth()) {
- ((FEdgeSmooth *)newEdge)->setFace(((FEdgeSmooth *)ioEdge)->face());
- }
-
- return newEdge;
- }
-
- /*! Sets the Bounding Box of the Shape */
- inline void setBBox(const BBox<Vec3r>& iBBox)
- {
- _BBox = iBBox;
- }
-
- /*! Compute the bbox of the sshape */
- inline void ComputeBBox()
- {
- if (0 == _verticesList.size())
- return;
-
- Vec3r firstVertex = _verticesList[0]->point3D();
- real XMax = firstVertex[0];
- real YMax = firstVertex[1];
- real ZMax = firstVertex[2];
-
- real XMin = firstVertex[0];
- real YMin = firstVertex[1];
- real ZMin = firstVertex[2];
-
- vector<SVertex*>::iterator v, vend;
- // parse all the coordinates to find the Xmax, YMax, ZMax
- for (v = _verticesList.begin(), vend = _verticesList.end(); v != vend; v++) {
- Vec3r vertex = (*v)->point3D();
- // X
- real x = vertex[0];
- if (x > XMax)
- XMax = x;
- else if (x < XMin)
- XMin = x;
-
- // Y
- real y = vertex[1];
- if (y > YMax)
- YMax = y;
- else if (y < YMin)
- YMin = y;
-
- // Z
- real z = vertex[2];
- if (z > ZMax)
- ZMax = z;
- else if (z < ZMin)
- ZMin = z;
- }
-
- setBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax)));
- }
-
- inline void RemoveEdgeFromChain(FEdge *iEdge)
- {
- for (vector<FEdge*>::iterator fe = _chains.begin(), feend = _chains.end(); fe != feend; fe++) {
- if (iEdge == (*fe)) {
- _chains.erase(fe);
- break;
- }
- }
- }
-
- inline void RemoveEdge(FEdge *iEdge)
- {
- for (vector<FEdge*>::iterator fe = _edgesList.begin(), feend = _edgesList.end(); fe != feend; fe++) {
- if (iEdge == (*fe)) {
- _edgesList.erase(fe);
- break;
- }
- }
- }
-
- /* accessors */
- /*! Returns the list of SVertex of the Shape. */
- inline vector<SVertex*>& getVertexList()
- {
- return _verticesList;
- }
-
- /*! Returns the list of FEdges of the Shape. */
- inline vector<FEdge*>& getEdgeList()
- {
- return _edgesList;
- }
-
- inline vector<FEdge*>& getChains()
- {
- return _chains;
- }
-
- /*! Returns the bounding box of the shape. */
- inline const BBox<Vec3r>& bbox()
- {
- return _BBox;
- }
-
- /*! Returns the ith material of the shape. */
- inline const FrsMaterial& frs_material(unsigned i) const
- {
- return _FrsMaterials[i];
- }
-
- /*! Returns the list of materials of the Shape. */
- inline const vector<FrsMaterial>& frs_materials() const
- {
- return _FrsMaterials;
- }
-
- inline ViewShape *viewShape()
- {
- return _ViewShape;
- }
-
- inline float importance() const
- {
- return _importance;
- }
-
- /*! Returns the Id of the Shape. */
- inline Id getId() const
- {
- return _Id;
- }
-
- /*! Returns the name of the Shape. */
- inline const string& getName() const
- {
- return _Name;
- }
-
- /*! Returns the library path of the Shape. */
- inline const string& getLibraryPath() const
- {
- return _LibraryPath;
- }
-
- /* Modififers */
- /*! Sets the Id of the shape.*/
- inline void setId(Id id)
- {
- _Id = id;
- }
-
- /*! Sets the name of the shape.*/
- inline void setName(const string& name)
- {
- _Name = name;
- }
-
- /*! Sets the library path of the shape.*/
- inline void setLibraryPath(const string& path)
- {
- _LibraryPath = path;
- }
-
- /*! Sets the list of materials for the shape */
- inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials)
- {
- _FrsMaterials = iMaterials;
- }
-
- inline void setViewShape(ViewShape *iShape)
- {
- _ViewShape = iShape;
- }
-
- inline void setImportance(float importance)
- {
- _importance = importance;
- }
+class SShape {
+ private:
+ vector<FEdge *> _chains; // list of fedges that are chains starting points.
+ vector<SVertex *> _verticesList; // list of all vertices
+ vector<FEdge *> _edgesList; // list of all edges
+ Id _Id;
+ string _Name;
+ string _LibraryPath;
+ BBox<Vec3r> _BBox;
+ vector<FrsMaterial> _FrsMaterials;
+
+ float _importance;
+
+ ViewShape *_ViewShape;
+
+ public:
+ /*! A field that can be used by the user to store any data.
+ * This field must be reseted afterwards using ResetUserData().
+ */
+ void *userdata; // added by E.T.
+
+ /*! Default constructor */
+ inline SShape()
+ {
+ userdata = NULL;
+ _importance = 0.0f;
+ _ViewShape = NULL;
+ }
+
+ /*! Copy constructor */
+ inline SShape(SShape &iBrother)
+ {
+ userdata = NULL;
+ _Id = iBrother._Id;
+ _Name = iBrother._Name;
+ _LibraryPath = iBrother._LibraryPath;
+ _BBox = iBrother.bbox();
+ _FrsMaterials = iBrother._FrsMaterials;
+ _importance = iBrother._importance;
+ _ViewShape = iBrother._ViewShape;
+
+ //---------
+ // vertices
+ //---------
+ vector<SVertex *>::iterator sv, svend;
+ vector<SVertex *> &verticesList = iBrother.getVertexList();
+ for (sv = verticesList.begin(), svend = verticesList.end(); sv != svend; sv++) {
+ SVertex *newv = new SVertex(*(*sv));
+ newv->setShape(this);
+ _verticesList.push_back(newv);
+ }
+
+ //------
+ // edges
+ //------
+ vector<FEdge *>::iterator e, eend;
+ vector<FEdge *> &edgesList = iBrother.getEdgeList();
+ for (e = edgesList.begin(), eend = edgesList.end(); e != eend; e++) {
+ FEdge *newe = (*e)->duplicate();
+ _edgesList.push_back(newe);
+ }
+
+ //-------------------------
+ // starting chain edges
+ //-------------------------
+ vector<FEdge *>::iterator fe, fend;
+ vector<FEdge *> &fedges = iBrother.getChains();
+ for (fe = fedges.begin(), fend = fedges.end(); fe != fend; fe++) {
+ _chains.push_back((FEdge *)((*fe)->userdata));
+ }
+
+ //-------------------------
+ // remap edges in vertices:
+ //-------------------------
+ for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
+ const vector<FEdge *> &fedgeList = (*sv)->fedges();
+ vector<FEdge *> newfedgelist;
+ for (vector<FEdge *>::const_iterator fed = fedgeList.begin(), fedend = fedgeList.end();
+ fed != fedend;
+ fed++) {
+ FEdge *current = *fed;
+ newfedgelist.push_back((FEdge *)current->userdata);
+ }
+ (*sv)->setFEdges(newfedgelist);
+ }
+
+ //-------------------------------------
+ // remap vertices and nextedge in edges:
+ //-------------------------------------
+ for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
+ (*e)->setVertexA((SVertex *)((*e)->vertexA()->userdata));
+ (*e)->setVertexB((SVertex *)((*e)->vertexB()->userdata));
+ (*e)->setNextEdge((FEdge *)((*e)->nextEdge()->userdata));
+ (*e)->setPreviousEdge((FEdge *)((*e)->previousEdge()->userdata));
+ }
+
+ // reset all brothers userdata to NULL:
+ //-------------------------------------
+ //---------
+ // vertices
+ //---------
+ for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
+ (*sv)->userdata = NULL;
+ }
+
+ //------
+ // edges
+ //------
+ for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
+ (*e)->userdata = NULL;
+ }
+ }
+
+ /*! Cloning method. */
+ virtual SShape *duplicate()
+ {
+ SShape *clone = new SShape(*this);
+ return clone;
+ }
+
+ /*! Destructor. */
+ virtual inline ~SShape()
+ {
+ vector<SVertex *>::iterator sv, svend;
+ vector<FEdge *>::iterator e, eend;
+ if (0 != _verticesList.size()) {
+ for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
+ delete (*sv);
+ }
+ _verticesList.clear();
+ }
+
+ if (0 != _edgesList.size()) {
+ for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
+ delete (*e);
+ }
+ _edgesList.clear();
+ }
+
+ //! Clear the chains list
+ //-----------------------
+ if (0 != _chains.size()) {
+ _chains.clear();
+ }
+ }
+
+ /*! Adds a FEdge to the list of FEdges. */
+ inline void AddEdge(FEdge *iEdge)
+ {
+ _edgesList.push_back(iEdge);
+ }
+
+ /*! Adds a SVertex to the list of SVertex of this Shape.
+ * The SShape attribute of the SVertex is also set to 'this'.
+ */
+ inline void AddNewVertex(SVertex *iv)
+ {
+ iv->setShape(this);
+ _verticesList.push_back(iv);
+ }
+
+ inline void AddChain(FEdge *iEdge)
+ {
+ _chains.push_back(iEdge);
+ }
+
+ inline SVertex *CreateSVertex(const Vec3r &P3D, const Vec3r &P2D, const Id &id)
+ {
+ SVertex *Ia = new SVertex(P3D, id);
+ Ia->setPoint2D(P2D);
+ AddNewVertex(Ia);
+ return Ia;
+ }
+
+ /*! Splits an edge into several edges.
+ * The edge's vertices are passed rather than the edge itself. This way, all feature edges (SILHOUETTE,
+ * CREASE, BORDER) are splitted in the same time.
+ * The processed edges are flagged as done (using the userdata flag).One single new vertex is created whereas
+ * several splitted edges might created for the different kinds of edges. These new elements are added to the lists
+ * maintained by the shape.
+ * New chains are also created.
+ * ioA
+ * The first vertex for the edge that gets splitted
+ * ioB
+ * The second vertex for the edge that gets splitted
+ * iParameters
+ * A vector containing 2D real vectors indicating the parameters giving the intersections coordinates in
+ * 3D and in 2D. These intersections points must be sorted from B to A.
+ * Each parameter defines the intersection point I as I=A+T*AB. T<0 and T>1 are then incorrect insofar as
+ * they give intersections points that lie outside the segment.
+ * ioNewEdges
+ * The edges that are newly created (the initial edges are not included) are added to this list.
+ */
+ inline void SplitEdge(FEdge *fe, const vector<Vec2r> &iParameters, vector<FEdge *> &ioNewEdges)
+ {
+ SVertex *ioA = fe->vertexA();
+ SVertex *ioB = fe->vertexB();
+ Vec3r A = ioA->point3D();
+ Vec3r B = ioB->point3D();
+ Vec3r a = ioA->point2D();
+ Vec3r b = ioB->point2D();
+
+ Vec3r newpoint3d, newpoint2d;
+ vector<SVertex *> intersections;
+ real t, T;
+ for (vector<Vec2r>::const_iterator p = iParameters.begin(), pend = iParameters.end();
+ p != pend;
+ p++) {
+ T = (*p)[0];
+ t = (*p)[1];
+
+ if ((t < 0) || (t > 1))
+ cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - "
+ << ioB->getId() << endl;
+
+ // compute the 3D and 2D coordinates for the intersections points:
+ newpoint3d = Vec3r(A + T * (B - A));
+ newpoint2d = Vec3r(a + t * (b - a));
+
+ // create new SVertex:
+ // (we keep B's id)
+ SVertex *newVertex = new SVertex(newpoint3d, ioB->getId());
+ newVertex->setPoint2D(newpoint2d);
+
+ // Add this vertex to the intersections list:
+ intersections.push_back(newVertex);
+
+ // Add this vertex to this sshape:
+ AddNewVertex(newVertex);
+ }
+
+ for (vector<SVertex *>::iterator sv = intersections.begin(), svend = intersections.end();
+ sv != svend;
+ sv++) {
+ //SVertex *svA = fe->vertexA();
+ SVertex *svB = fe->vertexB();
+
+ // We split edge AB into AA' and A'B. A' and A'B are created.
+ // AB becomes (address speaking) AA'. B is updated.
+ //--------------------------------------------------
+ // The edge AB becomes edge AA'.
+ (fe)->setVertexB((*sv));
+ // a new edge, A'B is created.
+ FEdge *newEdge;
+ if (fe->isSmooth()) {
+ newEdge = new FEdgeSmooth((*sv), svB);
+ FEdgeSmooth *se = dynamic_cast<FEdgeSmooth *>(newEdge);
+ FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
+ se->setFrsMaterialIndex(fes->frs_materialIndex());
+ }
+ else {
+ newEdge = new FEdgeSharp((*sv), svB);
+ FEdgeSharp *se = dynamic_cast<FEdgeSharp *>(newEdge);
+ FEdgeSharp *fes = dynamic_cast<FEdgeSharp *>(fe);
+ se->setaFrsMaterialIndex(fes->aFrsMaterialIndex());
+ se->setbFrsMaterialIndex(fes->bFrsMaterialIndex());
+ }
+
+ newEdge->setNature((fe)->getNature());
+
+ // to build a new chain:
+ AddChain(newEdge);
+ // add the new edge to the sshape edges list.
+ AddEdge(newEdge);
+ // add new edge to the list of new edges passed as argument:
+ ioNewEdges.push_back(newEdge);
+
+ // update edge A'B for the next pointing edge
+ newEdge->setNextEdge((fe)->nextEdge());
+ fe->nextEdge()->setPreviousEdge(newEdge);
+ Id id(fe->getId().getFirst(), fe->getId().getSecond() + 1);
+ newEdge->setId(fe->getId());
+ fe->setId(id);
+
+ // update edge AA' for the next pointing edge
+ //ioEdge->setNextEdge(newEdge);
+ (fe)->setNextEdge(NULL);
+
+ // update vertex pointing edges list:
+ // -- vertex B --
+ svB->Replace((fe), newEdge);
+ // -- vertex A' --
+ (*sv)->AddFEdge((fe));
+ (*sv)->AddFEdge(newEdge);
+ }
+ }
+
+ /* splits an edge into 2 edges. The new vertex and edge are added to the sshape list of vertices and edges
+ * a new chain is also created.
+ * returns the new edge.
+ * ioEdge
+ * The edge that gets splitted
+ * newpoint
+ * x,y,z coordinates of the new point.
+ */
+ inline FEdge *SplitEdgeIn2(FEdge *ioEdge, SVertex *ioNewVertex)
+ {
+ //soc unused - SVertex *A = ioEdge->vertexA();
+ SVertex *B = ioEdge->vertexB();
+
+ // We split edge AB into AA' and A'B. A' and A'B are created.
+ // AB becomes (address speaking) AA'. B is updated.
+ //--------------------------------------------------
+ // a new edge, A'B is created.
+ FEdge *newEdge;
+ if (ioEdge->isSmooth()) {
+ newEdge = new FEdgeSmooth(ioNewVertex, B);
+ FEdgeSmooth *se = dynamic_cast<FEdgeSmooth *>(newEdge);
+ FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(ioEdge);
+ se->setNormal(fes->normal());
+ se->setFrsMaterialIndex(fes->frs_materialIndex());
+ se->setFaceMark(fes->faceMark());
+ }
+ else {
+ newEdge = new FEdgeSharp(ioNewVertex, B);
+ FEdgeSharp *se = dynamic_cast<FEdgeSharp *>(newEdge);
+ FEdgeSharp *fes = dynamic_cast<FEdgeSharp *>(ioEdge);
+ se->setNormalA(fes->normalA());
+ se->setNormalB(fes->normalB());
+ se->setaFrsMaterialIndex(fes->aFrsMaterialIndex());
+ se->setbFrsMaterialIndex(fes->bFrsMaterialIndex());
+ se->setaFaceMark(fes->aFaceMark());
+ se->setbFaceMark(fes->bFaceMark());
+ }
+ newEdge->setNature(ioEdge->getNature());
+
+ if (ioEdge->nextEdge() != 0)
+ ioEdge->nextEdge()->setPreviousEdge(newEdge);
+
+ // update edge A'B for the next pointing edge
+ newEdge->setNextEdge(ioEdge->nextEdge());
+ // update edge A'B for the previous pointing edge
+ newEdge->setPreviousEdge(0); // because it is now a TVertex
+ Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1);
+ newEdge->setId(ioEdge->getId());
+ ioEdge->setId(id);
+
+ // update edge AA' for the next pointing edge
+ ioEdge->setNextEdge(0); // because it is now a TVertex
+
+ // update vertex pointing edges list:
+ // -- vertex B --
+ B->Replace(ioEdge, newEdge);
+ // -- vertex A' --
+ ioNewVertex->AddFEdge(ioEdge);
+ ioNewVertex->AddFEdge(newEdge);
+
+ // to build a new chain:
+ AddChain(newEdge);
+ AddEdge(newEdge); // FIXME ??
+
+ // The edge AB becomes edge AA'.
+ ioEdge->setVertexB(ioNewVertex);
+
+ if (ioEdge->isSmooth()) {
+ ((FEdgeSmooth *)newEdge)->setFace(((FEdgeSmooth *)ioEdge)->face());
+ }
+
+ return newEdge;
+ }
+
+ /*! Sets the Bounding Box of the Shape */
+ inline void setBBox(const BBox<Vec3r> &iBBox)
+ {
+ _BBox = iBBox;
+ }
+
+ /*! Compute the bbox of the sshape */
+ inline void ComputeBBox()
+ {
+ if (0 == _verticesList.size())
+ return;
+
+ Vec3r firstVertex = _verticesList[0]->point3D();
+ real XMax = firstVertex[0];
+ real YMax = firstVertex[1];
+ real ZMax = firstVertex[2];
+
+ real XMin = firstVertex[0];
+ real YMin = firstVertex[1];
+ real ZMin = firstVertex[2];
+
+ vector<SVertex *>::iterator v, vend;
+ // parse all the coordinates to find the Xmax, YMax, ZMax
+ for (v = _verticesList.begin(), vend = _verticesList.end(); v != vend; v++) {
+ Vec3r vertex = (*v)->point3D();
+ // X
+ real x = vertex[0];
+ if (x > XMax)
+ XMax = x;
+ else if (x < XMin)
+ XMin = x;
+
+ // Y
+ real y = vertex[1];
+ if (y > YMax)
+ YMax = y;
+ else if (y < YMin)
+ YMin = y;
+
+ // Z
+ real z = vertex[2];
+ if (z > ZMax)
+ ZMax = z;
+ else if (z < ZMin)
+ ZMin = z;
+ }
+
+ setBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax)));
+ }
+
+ inline void RemoveEdgeFromChain(FEdge *iEdge)
+ {
+ for (vector<FEdge *>::iterator fe = _chains.begin(), feend = _chains.end(); fe != feend;
+ fe++) {
+ if (iEdge == (*fe)) {
+ _chains.erase(fe);
+ break;
+ }
+ }
+ }
+
+ inline void RemoveEdge(FEdge *iEdge)
+ {
+ for (vector<FEdge *>::iterator fe = _edgesList.begin(), feend = _edgesList.end(); fe != feend;
+ fe++) {
+ if (iEdge == (*fe)) {
+ _edgesList.erase(fe);
+ break;
+ }
+ }
+ }
+
+ /* accessors */
+ /*! Returns the list of SVertex of the Shape. */
+ inline vector<SVertex *> &getVertexList()
+ {
+ return _verticesList;
+ }
+
+ /*! Returns the list of FEdges of the Shape. */
+ inline vector<FEdge *> &getEdgeList()
+ {
+ return _edgesList;
+ }
+
+ inline vector<FEdge *> &getChains()
+ {
+ return _chains;
+ }
+
+ /*! Returns the bounding box of the shape. */
+ inline const BBox<Vec3r> &bbox()
+ {
+ return _BBox;
+ }
+
+ /*! Returns the ith material of the shape. */
+ inline const FrsMaterial &frs_material(unsigned i) const
+ {
+ return _FrsMaterials[i];
+ }
+
+ /*! Returns the list of materials of the Shape. */
+ inline const vector<FrsMaterial> &frs_materials() const
+ {
+ return _FrsMaterials;
+ }
+
+ inline ViewShape *viewShape()
+ {
+ return _ViewShape;
+ }
+
+ inline float importance() const
+ {
+ return _importance;
+ }
+
+ /*! Returns the Id of the Shape. */
+ inline Id getId() const
+ {
+ return _Id;
+ }
+
+ /*! Returns the name of the Shape. */
+ inline const string &getName() const
+ {
+ return _Name;
+ }
+
+ /*! Returns the library path of the Shape. */
+ inline const string &getLibraryPath() const
+ {
+ return _LibraryPath;
+ }
+
+ /* Modififers */
+ /*! Sets the Id of the shape.*/
+ inline void setId(Id id)
+ {
+ _Id = id;
+ }
+
+ /*! Sets the name of the shape.*/
+ inline void setName(const string &name)
+ {
+ _Name = name;
+ }
+
+ /*! Sets the library path of the shape.*/
+ inline void setLibraryPath(const string &path)
+ {
+ _LibraryPath = path;
+ }
+
+ /*! Sets the list of materials for the shape */
+ inline void setFrsMaterials(const vector<FrsMaterial> &iMaterials)
+ {
+ _FrsMaterials = iMaterials;
+ }
+
+ inline void setViewShape(ViewShape *iShape)
+ {
+ _ViewShape = iShape;
+ }
+
+ inline void setImportance(float importance)
+ {
+ _importance = importance;
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SShape")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SShape")
#endif
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_SILHOUETTE_H__
+#endif // __FREESTYLE_SILHOUETTE_H__
diff --git a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
index 39893e61dc5..7d105a662b8 100644
--- a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
+++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
@@ -37,37 +37,37 @@ namespace Freestyle {
Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0, 0, 0);
real SilhouetteGeomEngine::_translation[3] = {0, 0, 0};
real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {
- {1, 0, 0, 0},
- {0, 1, 0, 0},
- {0, 0, 1, 0},
- {0, 0, 0, 1},
+ {1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {0, 0, 0, 1},
};
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {
- {1, 0, 0, 0},
- {0, 1, 0, 0},
- {0, 0, 1, 0},
- {0, 0, 0, 1},
+ {1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {0, 0, 0, 1},
};
real SilhouetteGeomEngine::_transform[4][4] = {
- {1, 0, 0, 0},
- {0, 1, 0, 0},
- {0, 0, 1, 0},
- {0, 0, 0, 1},
+ {1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {0, 0, 0, 1},
};
int SilhouetteGeomEngine::_viewport[4] = {1, 1, 1, 1};
real SilhouetteGeomEngine::_Focal = 0.0;
real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {
- {1, 0, 0, 0},
- {0, 1, 0, 0},
- {0, 0, 1, 0},
- {0, 0, 0, 1},
+ {1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {0, 0, 0, 1},
};
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {
- {1, 0, 0, 0},
- {0, 1, 0, 0},
- {0, 0, 1, 0},
- {0, 0, 0, 1},
+ {1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {0, 0, 0, 1},
};
real SilhouetteGeomEngine::_znear = 0.0;
real SilhouetteGeomEngine::_zfar = 100.0;
@@ -75,214 +75,218 @@ bool SilhouetteGeomEngine::_isOrthographicProjection = false;
SilhouetteGeomEngine *SilhouetteGeomEngine::_pInstance = NULL;
-void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
- const int iViewport[4], real iFocal)
+void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4],
+ const real iProjectionMatrix[4][4],
+ const int iViewport[4],
+ real iFocal)
{
- unsigned int i, j;
- _translation[0] = iModelViewMatrix[3][0];
- _translation[1] = iModelViewMatrix[3][1];
- _translation[2] = iModelViewMatrix[3][2];
+ unsigned int i, j;
+ _translation[0] = iModelViewMatrix[3][0];
+ _translation[1] = iModelViewMatrix[3][1];
+ _translation[2] = iModelViewMatrix[3][2];
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- _modelViewMatrix[i][j] = iModelViewMatrix[j][i];
- _glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
- }
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ _modelViewMatrix[i][j] = iModelViewMatrix[j][i];
+ _glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
+ }
+ }
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- _projectionMatrix[i][j] = iProjectionMatrix[j][i];
- _glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
- }
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ _projectionMatrix[i][j] = iProjectionMatrix[j][i];
+ _glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
+ }
+ }
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- _transform[i][j] = 0;
- for (unsigned int k = 0; k < 4; k++)
- _transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
- }
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ _transform[i][j] = 0;
+ for (unsigned int k = 0; k < 4; k++)
+ _transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
+ }
+ }
- for (i = 0; i < 4; i++) {
- _viewport[i] = iViewport[i];
- }
- _Focal = iFocal;
+ for (i = 0; i < 4; i++) {
+ _viewport[i] = iViewport[i];
+ }
+ _Focal = iFocal;
- _isOrthographicProjection = (iProjectionMatrix[3][3] != 0.0);
+ _isOrthographicProjection = (iProjectionMatrix[3][3] != 0.0);
}
void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
{
- _znear = iZNear;
- _zfar = iZFar;
+ _znear = iZNear;
+ _zfar = iZFar;
}
void SilhouetteGeomEngine::retrieveViewport(int viewport[4])
{
- memcpy(viewport, _viewport, 4 * sizeof(int));
+ memcpy(viewport, _viewport, 4 * sizeof(int));
}
-void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices)
+void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex *> &ioVertices)
{
- Vec3r newPoint;
- vector<SVertex*>::iterator sv, svend;
- for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
- GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
- (*sv)->setPoint2D(newPoint);
- }
+ Vec3r newPoint;
+ vector<SVertex *>::iterator sv, svend;
+ for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
+ GeomUtils::fromWorldToImage(
+ (*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
+ (*sv)->setPoint2D(newPoint);
+ }
}
void SilhouetteGeomEngine::ProjectSilhouette(SVertex *ioVertex)
{
- Vec3r newPoint;
- GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
- ioVertex->setPoint2D(newPoint);
+ Vec3r newPoint;
+ GeomUtils::fromWorldToImage(
+ ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
+ ioVertex->setPoint2D(newPoint);
}
real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
{
- if (_isOrthographicProjection)
- return t;
+ if (_isOrthographicProjection)
+ return t;
- // we need to compute for each parameter t the corresponding parameter T which gives the intersection in 3D.
- real T;
+ // we need to compute for each parameter t the corresponding parameter T which gives the intersection in 3D.
+ real T;
- // suffix w for world, c for camera, r for retina, i for image
- Vec3r Aw = (fe)->vertexA()->point3D();
- Vec3r Bw = (fe)->vertexB()->point3D();
- Vec3r Ac, Bc;
- GeomUtils::fromWorldToCamera(Aw, Ac, _modelViewMatrix);
- GeomUtils::fromWorldToCamera(Bw, Bc, _modelViewMatrix);
- Vec3r ABc = Bc - Ac;
+ // suffix w for world, c for camera, r for retina, i for image
+ Vec3r Aw = (fe)->vertexA()->point3D();
+ Vec3r Bw = (fe)->vertexB()->point3D();
+ Vec3r Ac, Bc;
+ GeomUtils::fromWorldToCamera(Aw, Ac, _modelViewMatrix);
+ GeomUtils::fromWorldToCamera(Bw, Bc, _modelViewMatrix);
+ Vec3r ABc = Bc - Ac;
#if 0
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Ac " << Ac << endl;
- cout << "Bc " << Bc << endl;
- cout << "ABc " << ABc << endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Ac " << Ac << endl;
+ cout << "Bc " << Bc << endl;
+ cout << "ABc " << ABc << endl;
+ }
#endif
- Vec3r Ai = (fe)->vertexA()->point2D();
- Vec3r Bi = (fe)->vertexB()->point2D();
- Vec3r Ii = Ai + t * (Bi - Ai); // the intersection point in the 2D image space
- Vec3r Ir, Ic;
- GeomUtils::fromImageToRetina(Ii, Ir, _viewport);
+ Vec3r Ai = (fe)->vertexA()->point2D();
+ Vec3r Bi = (fe)->vertexB()->point2D();
+ Vec3r Ii = Ai + t * (Bi - Ai); // the intersection point in the 2D image space
+ Vec3r Ir, Ic;
+ GeomUtils::fromImageToRetina(Ii, Ir, _viewport);
- real alpha, beta, denom;
- real m11 = _projectionMatrix[0][0];
- real m13 = _projectionMatrix[0][2];
- real m22 = _projectionMatrix[1][1];
- real m23 = _projectionMatrix[1][2];
+ real alpha, beta, denom;
+ real m11 = _projectionMatrix[0][0];
+ real m13 = _projectionMatrix[0][2];
+ real m22 = _projectionMatrix[1][1];
+ real m23 = _projectionMatrix[1][2];
- if (fabs(ABc[0]) > 1.0e-6) {
- alpha = ABc[2] / ABc[0];
- beta = Ac[2] - alpha * Ac[0];
- denom = alpha * (Ir[0] + m13) + m11;
- if (fabs(denom) < 1.0e-6)
- goto iter;
- Ic[0] = -beta * (Ir[0] + m13) / denom;
+ if (fabs(ABc[0]) > 1.0e-6) {
+ alpha = ABc[2] / ABc[0];
+ beta = Ac[2] - alpha * Ac[0];
+ denom = alpha * (Ir[0] + m13) + m11;
+ if (fabs(denom) < 1.0e-6)
+ goto iter;
+ Ic[0] = -beta * (Ir[0] + m13) / denom;
#if 0
- Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
- Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
+ Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
+ Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
#endif
- T = (Ic[0] - Ac[0]) / ABc[0];
-
- }
- else if (fabs(ABc[1]) > 1.0e-6) {
- alpha = ABc[2] / ABc[1];
- beta = Ac[2] - alpha * Ac[1];
- denom = alpha * (Ir[1] + m23) + m22;
- if (fabs(denom) < 1.0e-6)
- goto iter;
- Ic[1] = -beta * (Ir[1] + m23) / denom;
+ T = (Ic[0] - Ac[0]) / ABc[0];
+ }
+ else if (fabs(ABc[1]) > 1.0e-6) {
+ alpha = ABc[2] / ABc[1];
+ beta = Ac[2] - alpha * Ac[1];
+ denom = alpha * (Ir[1] + m23) + m22;
+ if (fabs(denom) < 1.0e-6)
+ goto iter;
+ Ic[1] = -beta * (Ir[1] + m23) / denom;
#if 0
- Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
- Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
+ Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
+ Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
#endif
- T = (Ic[1] - Ac[1]) / ABc[1];
- }
- else {
-iter:
- bool x_coords, less_than;
- if (fabs(Bi[0] - Ai[0]) > 1.0e-6) {
- x_coords = true;
- less_than = Ai[0] < Bi[0];
- }
- else {
- x_coords = false;
- less_than = Ai[1] < Bi[1];
- }
- Vec3r Pc, Pr, Pi;
- real T_sta = 0.0;
- real T_end = 1.0;
- real delta_x, delta_y, dist, dist_threshold = 1.0e-6;
- int i, max_iters = 100;
- for (i = 0; i < max_iters; i++) {
- T = T_sta + 0.5 * (T_end - T_sta);
- Pc = Ac + T * ABc;
- GeomUtils::fromCameraToRetina(Pc, Pr, _projectionMatrix);
- GeomUtils::fromRetinaToImage(Pr, Pi, _viewport);
- delta_x = Ii[0] - Pi[0];
- delta_y = Ii[1] - Pi[1];
- dist = sqrt(delta_x * delta_x + delta_y * delta_y);
- if (dist < dist_threshold)
- break;
- if (x_coords) {
- if (less_than) {
- if (Pi[0] < Ii[0])
- T_sta = T;
- else
- T_end = T;
- }
- else {
- if (Pi[0] > Ii[0])
- T_sta = T;
- else
- T_end = T;
- }
- }
- else {
- if (less_than) {
- if (Pi[1] < Ii[1])
- T_sta = T;
- else
- T_end = T;
- }
- else {
- if (Pi[1] > Ii[1])
- T_sta = T;
- else
- T_end = T;
- }
- }
- }
+ T = (Ic[1] - Ac[1]) / ABc[1];
+ }
+ else {
+ iter:
+ bool x_coords, less_than;
+ if (fabs(Bi[0] - Ai[0]) > 1.0e-6) {
+ x_coords = true;
+ less_than = Ai[0] < Bi[0];
+ }
+ else {
+ x_coords = false;
+ less_than = Ai[1] < Bi[1];
+ }
+ Vec3r Pc, Pr, Pi;
+ real T_sta = 0.0;
+ real T_end = 1.0;
+ real delta_x, delta_y, dist, dist_threshold = 1.0e-6;
+ int i, max_iters = 100;
+ for (i = 0; i < max_iters; i++) {
+ T = T_sta + 0.5 * (T_end - T_sta);
+ Pc = Ac + T * ABc;
+ GeomUtils::fromCameraToRetina(Pc, Pr, _projectionMatrix);
+ GeomUtils::fromRetinaToImage(Pr, Pi, _viewport);
+ delta_x = Ii[0] - Pi[0];
+ delta_y = Ii[1] - Pi[1];
+ dist = sqrt(delta_x * delta_x + delta_y * delta_y);
+ if (dist < dist_threshold)
+ break;
+ if (x_coords) {
+ if (less_than) {
+ if (Pi[0] < Ii[0])
+ T_sta = T;
+ else
+ T_end = T;
+ }
+ else {
+ if (Pi[0] > Ii[0])
+ T_sta = T;
+ else
+ T_end = T;
+ }
+ }
+ else {
+ if (less_than) {
+ if (Pi[1] < Ii[1])
+ T_sta = T;
+ else
+ T_end = T;
+ }
+ else {
+ if (Pi[1] > Ii[1])
+ T_sta = T;
+ else
+ T_end = T;
+ }
+ }
+ }
#if 0
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "SilhouetteGeomEngine::ImageToWorldParameter(): #iters = " << i << ", dist = " << dist << "\n";
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "SilhouetteGeomEngine::ImageToWorldParameter(): #iters = " << i << ", dist = " << dist << "\n";
+ }
#endif
- if (i == max_iters && G.debug & G_DEBUG_FREESTYLE) {
- cout << "SilhouetteGeomEngine::ImageToWorldParameter(): reached to max_iters (dist = " << dist << ")\n";
- }
- }
+ if (i == max_iters && G.debug & G_DEBUG_FREESTYLE) {
+ cout << "SilhouetteGeomEngine::ImageToWorldParameter(): reached to max_iters (dist = "
+ << dist << ")\n";
+ }
+ }
- return T;
+ return T;
}
-Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r& M)
+Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r &M)
{
- Vec3r newPoint;
- GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
- return newPoint;
+ Vec3r newPoint;
+ GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
+ return newPoint;
}
-Vec3r SilhouetteGeomEngine::CameraToImage(const Vec3r& M)
+Vec3r SilhouetteGeomEngine::CameraToImage(const Vec3r &M)
{
- Vec3r newPoint, p;
- GeomUtils::fromCameraToRetina(M, p, _projectionMatrix);
- GeomUtils::fromRetinaToImage(p, newPoint, _viewport);
- return newPoint;
+ Vec3r newPoint, p;
+ GeomUtils::fromCameraToRetina(M, p, _projectionMatrix);
+ GeomUtils::fromRetinaToImage(p, newPoint, _viewport);
+ return newPoint;
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
index 6e46979026a..306eb3a55be 100644
--- a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
+++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
@@ -30,7 +30,7 @@
#include "../system/FreestyleConfig.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
@@ -40,99 +40,100 @@ using namespace Geometry;
class SVertex;
class FEdge;
-class SilhouetteGeomEngine
-{
-private:
- // The viewpoint under which the silhouette has to be computed
- static Vec3r _Viewpoint;
- static real _translation[3];
- // the model view matrix (_modelViewMatrix[i][j] means element of line i and column j)
- static real _modelViewMatrix[4][4];
- // the projection matrix (_projectionMatrix[i][j] means element of line i and column j)
- static real _projectionMatrix[4][4];
- // the global transformation from world to screen (projection included)
- // (_transform[i][j] means element of line i and column j)
- static real _transform[4][4];
- // the viewport
- static int _viewport[4];
- static real _Focal;
-
- static real _znear;
- static real _zfar;
-
- // GL style (column major) projection matrix
- static real _glProjectionMatrix[4][4];
- // GL style (column major) model view matrix
- static real _glModelViewMatrix[4][4];
-
- static bool _isOrthographicProjection;
-
- static SilhouetteGeomEngine *_pInstance;
-
-public:
- /*! retrieves an instance on the singleton */
- static SilhouetteGeomEngine *getInstance()
- {
- if (_pInstance == NULL) {
- _pInstance = new SilhouetteGeomEngine;
- }
- return _pInstance;
- }
-
- /*! Sets the current viewpoint */
- static inline void setViewpoint(const Vec3r& ivp)
- {
- _Viewpoint = ivp;
- }
-
- /*! Sets the current transformation
- * iModelViewMatrix
- * The 4x4 model view matrix, in column major order (openGL like).
- * iProjection matrix
- * The 4x4 projection matrix, in column major order (openGL like).
- * iViewport
- * The viewport. 4 real array: origin.x, origin.y, width, length
- * iFocal
- * The focal length
- */
- static void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
- const int iViewport[4], real iFocal);
-
- /*! Sets the current znear and zfar */
- static void setFrustum(real iZNear, real iZFar);
-
- /* accessors */
- static void retrieveViewport(int viewport[4]);
-
- /*! Projects the silhouette in camera coordinates
- * This method modifies the ioEdges passed as argument.
- * ioVertices
- * The vertices to project. It is modified during the operation.
- */
- static void ProjectSilhouette(std::vector<SVertex*>& ioVertices);
- static void ProjectSilhouette(SVertex *ioVertex);
-
- /*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain
- * the parameter giving the corresponding 3D intersection.
- * Returns the 3D parameter
- * fe
- * The edge
- * t
- * The parameter for the 2D intersection.
- */
- static real ImageToWorldParameter(FEdge *fe, real t);
-
- /*! From world to image */
- static Vec3r WorldToImage(const Vec3r& M);
-
- /*! From camera to image */
- static Vec3r CameraToImage(const Vec3r& M);
+class SilhouetteGeomEngine {
+ private:
+ // The viewpoint under which the silhouette has to be computed
+ static Vec3r _Viewpoint;
+ static real _translation[3];
+ // the model view matrix (_modelViewMatrix[i][j] means element of line i and column j)
+ static real _modelViewMatrix[4][4];
+ // the projection matrix (_projectionMatrix[i][j] means element of line i and column j)
+ static real _projectionMatrix[4][4];
+ // the global transformation from world to screen (projection included)
+ // (_transform[i][j] means element of line i and column j)
+ static real _transform[4][4];
+ // the viewport
+ static int _viewport[4];
+ static real _Focal;
+
+ static real _znear;
+ static real _zfar;
+
+ // GL style (column major) projection matrix
+ static real _glProjectionMatrix[4][4];
+ // GL style (column major) model view matrix
+ static real _glModelViewMatrix[4][4];
+
+ static bool _isOrthographicProjection;
+
+ static SilhouetteGeomEngine *_pInstance;
+
+ public:
+ /*! retrieves an instance on the singleton */
+ static SilhouetteGeomEngine *getInstance()
+ {
+ if (_pInstance == NULL) {
+ _pInstance = new SilhouetteGeomEngine;
+ }
+ return _pInstance;
+ }
+
+ /*! Sets the current viewpoint */
+ static inline void setViewpoint(const Vec3r &ivp)
+ {
+ _Viewpoint = ivp;
+ }
+
+ /*! Sets the current transformation
+ * iModelViewMatrix
+ * The 4x4 model view matrix, in column major order (openGL like).
+ * iProjection matrix
+ * The 4x4 projection matrix, in column major order (openGL like).
+ * iViewport
+ * The viewport. 4 real array: origin.x, origin.y, width, length
+ * iFocal
+ * The focal length
+ */
+ static void setTransform(const real iModelViewMatrix[4][4],
+ const real iProjectionMatrix[4][4],
+ const int iViewport[4],
+ real iFocal);
+
+ /*! Sets the current znear and zfar */
+ static void setFrustum(real iZNear, real iZFar);
+
+ /* accessors */
+ static void retrieveViewport(int viewport[4]);
+
+ /*! Projects the silhouette in camera coordinates
+ * This method modifies the ioEdges passed as argument.
+ * ioVertices
+ * The vertices to project. It is modified during the operation.
+ */
+ static void ProjectSilhouette(std::vector<SVertex *> &ioVertices);
+ static void ProjectSilhouette(SVertex *ioVertex);
+
+ /*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain
+ * the parameter giving the corresponding 3D intersection.
+ * Returns the 3D parameter
+ * fe
+ * The edge
+ * t
+ * The parameter for the 2D intersection.
+ */
+ static real ImageToWorldParameter(FEdge *fe, real t);
+
+ /*! From world to image */
+ static Vec3r WorldToImage(const Vec3r &M);
+
+ /*! From camera to image */
+ static Vec3r CameraToImage(const Vec3r &M);
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SilhouetteGeomEngine")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SilhouetteGeomEngine")
#endif
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
+#endif // __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp
index 03a50331dc9..1a7f01d288f 100644
--- a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp
+++ b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp
@@ -38,207 +38,224 @@ namespace Freestyle {
// Cell
/////////
-SphericalGrid::Cell::Cell() {}
+SphericalGrid::Cell::Cell()
+{
+}
-SphericalGrid::Cell::~Cell() {}
+SphericalGrid::Cell::~Cell()
+{
+}
void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
{
- const real epsilon = 1.0e-06;
- boundary[0] = x - epsilon;
- boundary[1] = x + sizeX + epsilon;
- boundary[2] = y - epsilon;
- boundary[3] = y + sizeY + epsilon;
+ const real epsilon = 1.0e-06;
+ boundary[0] = x - epsilon;
+ boundary[1] = x + sizeX + epsilon;
+ boundary[2] = y - epsilon;
+ boundary[3] = y + sizeY + epsilon;
}
bool SphericalGrid::Cell::compareOccludersByShallowestPoint(const SphericalGrid::OccluderData *a,
const SphericalGrid::OccluderData *b)
{
- return a->shallowest < b->shallowest;
+ return a->shallowest < b->shallowest;
}
void SphericalGrid::Cell::indexPolygons()
{
- // Sort occluders by their shallowest points.
- sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
+ // Sort occluders by their shallowest points.
+ sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
}
// Iterator
//////////////////
-SphericalGrid::Iterator::Iterator(SphericalGrid& grid, Vec3r& center, real /*epsilon*/)
-: _target(SphericalGrid::Transform::sphericalProjection(center)), _foundOccludee(false)
+SphericalGrid::Iterator::Iterator(SphericalGrid &grid, Vec3r &center, real /*epsilon*/)
+ : _target(SphericalGrid::Transform::sphericalProjection(center)), _foundOccludee(false)
{
- // Find target cell
- _cell = grid.findCell(_target);
+ // Find target cell
+ _cell = grid.findCell(_target);
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Searching for occluders of edge centered at " << _target << " in cell [" <<
- _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2] <<
- ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Searching for occluders of edge centered at " << _target << " in cell ["
+ << _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2] << ", "
+ << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
+ }
#endif
- // Set iterator
- _current = _cell->faces.begin();
+ // Set iterator
+ _current = _cell->faces.begin();
}
-SphericalGrid::Iterator::~Iterator() {}
+SphericalGrid::Iterator::~Iterator()
+{
+}
// SphericalGrid
/////////////////
-SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
- Vec3r& viewpoint, bool enableQI)
-: _viewpoint(viewpoint), _enableQI(enableQI)
-{
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Generate Cell structure" << endl;
- }
- // Generate Cell structure
- assignCells(source, density, viewMap);
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Distribute occluders" << endl;
- }
- // Fill Cells
- distributePolygons(source);
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Reorganize cells" << endl;
- }
- // Reorganize Cells
- reorganizeCells();
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Ready to use SphericalGrid" << endl;
- }
-}
-
-SphericalGrid::~SphericalGrid() {}
-
-void SphericalGrid::assignCells(OccluderSource& /*source*/, GridDensityProvider& density, ViewMap *viewMap)
-{
- _cellSize = density.cellSize();
- _cellsX = density.cellsX();
- _cellsY = density.cellsY();
- _cellOrigin[0] = density.cellOrigin(0);
- _cellOrigin[1] = density.cellOrigin(1);
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
- cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
- }
-
- // Now allocate the cell table and fill it with default (empty) cells
- _cells.resize(_cellsX * _cellsY);
- for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
- (*i) = NULL;
- }
-
- // Identify cells that will be used, and set the dimensions for each
- ViewMap::fedges_container& fedges = viewMap->FEdges();
- for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
- if ((*f)->isInImage()) {
- Vec3r point = SphericalGrid::Transform::sphericalProjection((*f)->center3d());
- unsigned i, j;
- getCellCoordinates(point, i, j);
- if (_cells[i * _cellsY + j] == NULL) {
- // This is an uninitialized cell
- real x, y, width, height;
-
- x = _cellOrigin[0] + _cellSize * i;
- width = _cellSize;
-
- y = _cellOrigin[1] + _cellSize * j;
- height = _cellSize;
-
- // Initialize cell
- Cell *b = _cells[i * _cellsY + j] = new Cell();
- b->setDimensions(x, y, width, height);
- }
- }
- }
-}
-
-void SphericalGrid::distributePolygons(OccluderSource& source)
-{
- unsigned long nFaces = 0;
- unsigned long nKeptFaces = 0;
-
- for (source.begin(); source.isValid(); source.next()) {
- OccluderData *occluder = NULL;
-
- try {
- if (insertOccluder(source, occluder)) {
- _faces.push_back(occluder);
- ++nKeptFaces;
- }
- }
- catch (...) {
- // If an exception was thrown, _faces.push_back() cannot have succeeded. Occluder is not owned by anyone,
- // and must be deleted. If the exception was thrown before or during new OccluderData(), then
- // occluder is NULL, and this delete is harmless.
- delete occluder;
- throw;
- }
- ++nFaces;
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
- }
+SphericalGrid::SphericalGrid(OccluderSource &source,
+ GridDensityProvider &density,
+ ViewMap *viewMap,
+ Vec3r &viewpoint,
+ bool enableQI)
+ : _viewpoint(viewpoint), _enableQI(enableQI)
+{
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Generate Cell structure" << endl;
+ }
+ // Generate Cell structure
+ assignCells(source, density, viewMap);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Distribute occluders" << endl;
+ }
+ // Fill Cells
+ distributePolygons(source);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Reorganize cells" << endl;
+ }
+ // Reorganize Cells
+ reorganizeCells();
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Ready to use SphericalGrid" << endl;
+ }
+}
+
+SphericalGrid::~SphericalGrid()
+{
+}
+
+void SphericalGrid::assignCells(OccluderSource & /*source*/,
+ GridDensityProvider &density,
+ ViewMap *viewMap)
+{
+ _cellSize = density.cellSize();
+ _cellsX = density.cellsX();
+ _cellsY = density.cellsY();
+ _cellOrigin[0] = density.cellOrigin(0);
+ _cellOrigin[1] = density.cellOrigin(1);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square."
+ << endl;
+ cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
+ }
+
+ // Now allocate the cell table and fill it with default (empty) cells
+ _cells.resize(_cellsX * _cellsY);
+ for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
+ (*i) = NULL;
+ }
+
+ // Identify cells that will be used, and set the dimensions for each
+ ViewMap::fedges_container &fedges = viewMap->FEdges();
+ for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend;
+ ++f) {
+ if ((*f)->isInImage()) {
+ Vec3r point = SphericalGrid::Transform::sphericalProjection((*f)->center3d());
+ unsigned i, j;
+ getCellCoordinates(point, i, j);
+ if (_cells[i * _cellsY + j] == NULL) {
+ // This is an uninitialized cell
+ real x, y, width, height;
+
+ x = _cellOrigin[0] + _cellSize * i;
+ width = _cellSize;
+
+ y = _cellOrigin[1] + _cellSize * j;
+ height = _cellSize;
+
+ // Initialize cell
+ Cell *b = _cells[i * _cellsY + j] = new Cell();
+ b->setDimensions(x, y, width, height);
+ }
+ }
+ }
+}
+
+void SphericalGrid::distributePolygons(OccluderSource &source)
+{
+ unsigned long nFaces = 0;
+ unsigned long nKeptFaces = 0;
+
+ for (source.begin(); source.isValid(); source.next()) {
+ OccluderData *occluder = NULL;
+
+ try {
+ if (insertOccluder(source, occluder)) {
+ _faces.push_back(occluder);
+ ++nKeptFaces;
+ }
+ }
+ catch (...) {
+ // If an exception was thrown, _faces.push_back() cannot have succeeded. Occluder is not owned by anyone,
+ // and must be deleted. If the exception was thrown before or during new OccluderData(), then
+ // occluder is NULL, and this delete is harmless.
+ delete occluder;
+ throw;
+ }
+ ++nFaces;
+ }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
+ }
}
void SphericalGrid::reorganizeCells()
{
- // Sort the occluders by shallowest point
- for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
- if (*i != NULL) {
- (*i)->indexPolygons();
- }
- }
+ // Sort the occluders by shallowest point
+ for (vector<Cell *>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
+ if (*i != NULL) {
+ (*i)->indexPolygons();
+ }
+ }
}
-void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
+void SphericalGrid::getCellCoordinates(const Vec3r &point, unsigned &x, unsigned &y)
{
- x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
- y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
+ x = min(_cellsX - 1, (unsigned)floor(max((double)0.0f, point[0] - _cellOrigin[0]) / _cellSize));
+ y = min(_cellsY - 1, (unsigned)floor(max((double)0.0f, point[1] - _cellOrigin[1]) / _cellSize));
}
-SphericalGrid::Cell *SphericalGrid::findCell(const Vec3r& point)
+SphericalGrid::Cell *SphericalGrid::findCell(const Vec3r &point)
{
- unsigned x, y;
- getCellCoordinates(point, x, y);
- return _cells[x * _cellsY + y];
+ unsigned x, y;
+ getCellCoordinates(point, x, y);
+ return _cells[x * _cellsY + y];
}
bool SphericalGrid::orthographicProjection() const
{
- return false;
+ return false;
}
-const Vec3r& SphericalGrid::viewpoint() const
+const Vec3r &SphericalGrid::viewpoint() const
{
- return _viewpoint;
+ return _viewpoint;
}
bool SphericalGrid::enableQI() const
{
- return _enableQI;
+ return _enableQI;
}
-SphericalGrid::Transform::Transform () : GridHelpers::Transform() {}
+SphericalGrid::Transform::Transform() : GridHelpers::Transform()
+{
+}
-Vec3r SphericalGrid::Transform::operator()(const Vec3r& point) const
+Vec3r SphericalGrid::Transform::operator()(const Vec3r &point) const
{
- return sphericalProjection(point);
+ return sphericalProjection(point);
}
-Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M)
+Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r &M)
{
- Vec3r newPoint;
+ Vec3r newPoint;
- newPoint[0] = ::atan(M[0] / M[2]);
- newPoint[1] = ::atan(M[1] / M[2]);
- newPoint[2] = ::sqrt(M[0] * M[0] + M[1] * M[1] + M[2] * M[2]);
+ newPoint[0] = ::atan(M[0] / M[2]);
+ newPoint[1] = ::atan(M[1] / M[2]);
+ newPoint[2] = ::sqrt(M[0] * M[0] + M[1] * M[1] + M[2] * M[2]);
- return newPoint;
+ return newPoint;
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.h b/source/blender/freestyle/intern/view_map/SphericalGrid.h
index 19c2461ce01..ae00c270c1d 100644
--- a/source/blender/freestyle/intern/view_map/SphericalGrid.h
+++ b/source/blender/freestyle/intern/view_map/SphericalGrid.h
@@ -44,388 +44,389 @@
#include "BKE_global.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
-class SphericalGrid
-{
-public:
- // Helper classes
- struct OccluderData
- {
- explicit OccluderData (OccluderSource& source, Polygon3r& p);
- Polygon3r poly;
- Polygon3r cameraSpacePolygon;
- real shallowest, deepest;
- // N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
- // However, code comments make it clear that userdata is deprecated, so we avoid the temptation to save
- // 4 or 8 bytes.
- WFace *face;
+class SphericalGrid {
+ public:
+ // Helper classes
+ struct OccluderData {
+ explicit OccluderData(OccluderSource &source, Polygon3r &p);
+ Polygon3r poly;
+ Polygon3r cameraSpacePolygon;
+ real shallowest, deepest;
+ // N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
+ // However, code comments make it clear that userdata is deprecated, so we avoid the temptation to save
+ // 4 or 8 bytes.
+ WFace *face;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:OccluderData")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:OccluderData")
#endif
- };
-
-private:
- struct Cell
- {
- // Can't store Cell in a vector without copy and assign
- //Cell(const Cell& other);
- //Cell& operator=(const Cell& other);
-
- explicit Cell();
- ~Cell();
-
- static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
-
- void setDimensions(real x, real y, real sizeX, real sizeY);
- void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
- void indexPolygons();
-
- real boundary[4];
- //deque<OccluderData*> faces;
- vector<OccluderData*> faces;
- };
-
-public:
- /*! Iterator needs to allow the user to avoid full 3D comparison in two cases:
- *
- * (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
- *
- * (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
- *
- * In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an occludee
- * candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder could
- * possibly be a better occludee.
- */
-
- class Iterator
- {
- public:
- // epsilon is not used in this class, but other grids with the same interface may need an epsilon
- explicit Iterator(SphericalGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
- ~Iterator();
- void initBeforeTarget();
- void initAfterTarget();
- void nextOccluder();
- void nextOccludee();
- bool validBeforeTarget();
- bool validAfterTarget();
- WFace *getWFace() const;
- Polygon3r *getCameraSpacePolygon();
- void reportDepth(Vec3r origin, Vec3r u, real t);
- private:
- bool testOccluder(bool wantOccludee);
- void markCurrentOccludeeCandidate(real depth);
-
- Cell *_cell;
- Vec3r _target;
- bool _foundOccludee;
- real _occludeeDepth;
- //deque<OccluderData*>::iterator _current, _occludeeCandidate;
- vector<OccluderData*>::iterator _current, _occludeeCandidate;
+ };
+
+ private:
+ struct Cell {
+ // Can't store Cell in a vector without copy and assign
+ //Cell(const Cell& other);
+ //Cell& operator=(const Cell& other);
+
+ explicit Cell();
+ ~Cell();
+
+ static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
+
+ void setDimensions(real x, real y, real sizeX, real sizeY);
+ void checkAndInsert(OccluderSource &source, Polygon3r &poly, OccluderData *&occluder);
+ void indexPolygons();
+
+ real boundary[4];
+ //deque<OccluderData*> faces;
+ vector<OccluderData *> faces;
+ };
+
+ public:
+ /*! Iterator needs to allow the user to avoid full 3D comparison in two cases:
+ *
+ * (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
+ *
+ * (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
+ *
+ * In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an occludee
+ * candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder could
+ * possibly be a better occludee.
+ */
+
+ class Iterator {
+ public:
+ // epsilon is not used in this class, but other grids with the same interface may need an epsilon
+ explicit Iterator(SphericalGrid &grid, Vec3r &center, real epsilon = 1.0e-06);
+ ~Iterator();
+ void initBeforeTarget();
+ void initAfterTarget();
+ void nextOccluder();
+ void nextOccludee();
+ bool validBeforeTarget();
+ bool validAfterTarget();
+ WFace *getWFace() const;
+ Polygon3r *getCameraSpacePolygon();
+ void reportDepth(Vec3r origin, Vec3r u, real t);
+
+ private:
+ bool testOccluder(bool wantOccludee);
+ void markCurrentOccludeeCandidate(real depth);
+
+ Cell *_cell;
+ Vec3r _target;
+ bool _foundOccludee;
+ real _occludeeDepth;
+ //deque<OccluderData*>::iterator _current, _occludeeCandidate;
+ vector<OccluderData *>::iterator _current, _occludeeCandidate;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:Iterator")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:Iterator")
#endif
-
- };
-
- class Transform : public GridHelpers::Transform
- {
- public:
- explicit Transform();
- explicit Transform(Transform& other);
- Vec3r operator()(const Vec3r& point) const;
- static Vec3r sphericalProjection(const Vec3r& M);
- };
-
-private:
- // Prevent implicit copies and assignments.
- SphericalGrid(const SphericalGrid& other);
- SphericalGrid& operator=(const SphericalGrid& other);
-
-public:
- explicit SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
- Vec3r& viewpoint, bool enableQI);
- virtual ~SphericalGrid();
-
- // Generate Cell structure
- void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
- // Fill Cells
- void distributePolygons(OccluderSource& source);
- // Insert one polygon into each matching cell, return true if any cell consumes the polygon
- bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
- // Sort occluders in each cell
- void reorganizeCells();
-
- Cell *findCell(const Vec3r& point);
-
- // Accessors:
- bool orthographicProjection() const;
- const Vec3r& viewpoint() const;
- bool enableQI() const;
-
-private:
- void getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y);
-
- typedef PointerSequence<vector<Cell*>, Cell*> cellContainer;
- //typedef PointerSequence<deque<OccluderData*>, OccluderData*> occluderContainer;
- typedef PointerSequence<vector<OccluderData*>, OccluderData*> occluderContainer;
- unsigned _cellsX, _cellsY;
- float _cellSize;
- float _cellOrigin[2];
- cellContainer _cells;
- occluderContainer _faces;
- Vec3r _viewpoint;
- bool _enableQI;
+ };
+
+ class Transform : public GridHelpers::Transform {
+ public:
+ explicit Transform();
+ explicit Transform(Transform &other);
+ Vec3r operator()(const Vec3r &point) const;
+ static Vec3r sphericalProjection(const Vec3r &M);
+ };
+
+ private:
+ // Prevent implicit copies and assignments.
+ SphericalGrid(const SphericalGrid &other);
+ SphericalGrid &operator=(const SphericalGrid &other);
+
+ public:
+ explicit SphericalGrid(OccluderSource &source,
+ GridDensityProvider &density,
+ ViewMap *viewMap,
+ Vec3r &viewpoint,
+ bool enableQI);
+ virtual ~SphericalGrid();
+
+ // Generate Cell structure
+ void assignCells(OccluderSource &source, GridDensityProvider &density, ViewMap *viewMap);
+ // Fill Cells
+ void distributePolygons(OccluderSource &source);
+ // Insert one polygon into each matching cell, return true if any cell consumes the polygon
+ bool insertOccluder(OccluderSource &source, OccluderData *&occluder);
+ // Sort occluders in each cell
+ void reorganizeCells();
+
+ Cell *findCell(const Vec3r &point);
+
+ // Accessors:
+ bool orthographicProjection() const;
+ const Vec3r &viewpoint() const;
+ bool enableQI() const;
+
+ private:
+ void getCellCoordinates(const Vec3r &point, unsigned &x, unsigned &y);
+
+ typedef PointerSequence<vector<Cell *>, Cell *> cellContainer;
+ //typedef PointerSequence<deque<OccluderData*>, OccluderData*> occluderContainer;
+ typedef PointerSequence<vector<OccluderData *>, OccluderData *> occluderContainer;
+ unsigned _cellsX, _cellsY;
+ float _cellSize;
+ float _cellOrigin[2];
+ cellContainer _cells;
+ occluderContainer _faces;
+ Vec3r _viewpoint;
+ bool _enableQI;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid")
#endif
};
inline void SphericalGrid::Iterator::initBeforeTarget()
{
- _current = _cell->faces.begin();
- while (_current != _cell->faces.end() && !testOccluder(false)) {
- ++_current;
- }
+ _current = _cell->faces.begin();
+ while (_current != _cell->faces.end() && !testOccluder(false)) {
+ ++_current;
+ }
}
inline void SphericalGrid::Iterator::initAfterTarget()
{
- if (_foundOccludee) {
+ if (_foundOccludee) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\tStarting occludee search from occludeeCandidate at depth " <<
- _occludeeDepth << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth
+ << std::endl;
+ }
#endif
- _current = _occludeeCandidate;
- return;
- }
+ _current = _occludeeCandidate;
+ return;
+ }
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\tStarting occludee search from current position" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\tStarting occludee search from current position" << std::endl;
+ }
#endif
- while (_current != _cell->faces.end() && !testOccluder(true)) {
- ++_current;
- }
+ while (_current != _cell->faces.end() && !testOccluder(true)) {
+ ++_current;
+ }
}
inline bool SphericalGrid::Iterator::testOccluder(bool wantOccludee)
{
- // End-of-list is not even a valid iterator position
- if (_current == _cell->faces.end()) {
- // Returning true seems strange, but it will break us out of whatever loop is calling testOccluder, and
- // _current=_cell->face.end() will make the calling routine give up.
- return true;
- }
+ // End-of-list is not even a valid iterator position
+ if (_current == _cell->faces.end()) {
+ // Returning true seems strange, but it will break us out of whatever loop is calling testOccluder, and
+ // _current=_cell->face.end() will make the calling routine give up.
+ return true;
+ }
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
- for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
- std::cout << ", " << (*_current)->poly.getVertices()[i];
- }
- std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
+ for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
+ std::cout << ", " << (*_current)->poly.getVertices()[i];
+ }
+ std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
+ }
#endif
- // If we have an occluder candidate and we are unambiguously after it, abort
- if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
+ // If we have an occluder candidate and we are unambiguously after it, abort
+ if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
+ }
#endif
- _current = _cell->faces.end();
+ _current = _cell->faces.end();
- // See note above
- return true;
- }
+ // See note above
+ return true;
+ }
- // Specific continue or stop conditions when searching for each type
- if (wantOccludee) {
- if ((*_current)->deepest < _target[2]) {
+ // Specific continue or stop conditions when searching for each type
+ if (wantOccludee) {
+ if ((*_current)->deepest < _target[2]) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
+ }
#endif
- return false;
- }
- }
- else {
- if ((*_current)->shallowest > _target[2]) {
+ return false;
+ }
+ }
+ else {
+ if ((*_current)->shallowest > _target[2]) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
+ }
#endif
- return true;
- }
- }
+ return true;
+ }
+ }
- // Depthwise, this is a valid occluder.
+ // Depthwise, this is a valid occluder.
- // Check to see if target is in the 2D bounding box
- Vec3r bbMin, bbMax;
- (*_current)->poly.getBBox(bbMin, bbMax);
- if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
+ // Check to see if target is in the 2D bounding box
+ Vec3r bbMin, bbMax;
+ (*_current)->poly.getBBox(bbMin, bbMax);
+ if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] ||
+ _target[1] > bbMax[1]) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tSkipping: bounding box violation" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tSkipping: bounding box violation" << std::endl;
+ }
#endif
- return false;
- }
+ return false;
+ }
- // We've done all the corner cutting we can. Let the caller work out whether or not the geometry is correct.
- return true;
+ // We've done all the corner cutting we can. Let the caller work out whether or not the geometry is correct.
+ return true;
}
inline void SphericalGrid::Iterator::reportDepth(Vec3r origin, Vec3r u, real t)
{
- // The reported depth is the length of a ray in camera space. We need to convert it into the distance from viewpoint
- // If origin is the viewpoint, depth == t. A future optimization could allow the caller to tell us if origin is
- // viewponit or target, at the cost of changing the OptimizedGrid API.
- real depth = (origin + u * t).norm();
+ // The reported depth is the length of a ray in camera space. We need to convert it into the distance from viewpoint
+ // If origin is the viewpoint, depth == t. A future optimization could allow the caller to tell us if origin is
+ // viewponit or target, at the cost of changing the OptimizedGrid API.
+ real depth = (origin + u * t).norm();
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tReporting depth of occluder/ee: " << depth;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tReporting depth of occluder/ee: " << depth;
+ }
#endif
- if (depth > _target[2]) {
+ if (depth > _target[2]) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << " is deeper than target" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << " is deeper than target" << std::endl;
+ }
#endif
- // If the current occluder is the best occludee so far, save it.
- if (! _foundOccludee || _occludeeDepth > depth) {
- markCurrentOccludeeCandidate(depth);
- }
- }
- else {
+ // If the current occluder is the best occludee so far, save it.
+ if (!_foundOccludee || _occludeeDepth > depth) {
+ markCurrentOccludeeCandidate(depth);
+ }
+ }
+ else {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << std::endl;
+ }
#endif
- }
+ }
}
inline void SphericalGrid::Iterator::nextOccluder()
{
- if (_current != _cell->faces.end()) {
- do {
- ++_current;
- } while (_current != _cell->faces.end() && !testOccluder(false));
- }
+ if (_current != _cell->faces.end()) {
+ do {
+ ++_current;
+ } while (_current != _cell->faces.end() && !testOccluder(false));
+ }
}
inline void SphericalGrid::Iterator::nextOccludee()
{
- if (_current != _cell->faces.end()) {
- do {
- ++_current;
- } while (_current != _cell->faces.end() && !testOccluder(true));
- }
+ if (_current != _cell->faces.end()) {
+ do {
+ ++_current;
+ } while (_current != _cell->faces.end() && !testOccluder(true));
+ }
}
inline bool SphericalGrid::Iterator::validBeforeTarget()
{
- return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
+ return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
}
inline bool SphericalGrid::Iterator::validAfterTarget()
{
- return _current != _cell->faces.end();
+ return _current != _cell->faces.end();
}
inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth)
{
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
+ }
#endif
- _occludeeCandidate = _current;
- _occludeeDepth = depth;
- _foundOccludee = true;
+ _occludeeCandidate = _current;
+ _occludeeDepth = depth;
+ _foundOccludee = true;
}
inline WFace *SphericalGrid::Iterator::getWFace() const
{
- return (*_current)->face;
+ return (*_current)->face;
}
inline Polygon3r *SphericalGrid::Iterator::getCameraSpacePolygon()
{
- return &((*_current)->cameraSpacePolygon);
+ return &((*_current)->cameraSpacePolygon);
}
-inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
-: poly(p), cameraSpacePolygon(source.getCameraSpacePolygon()), face(source.getWFace())
+inline SphericalGrid::OccluderData::OccluderData(OccluderSource &source, Polygon3r &p)
+ : poly(p), cameraSpacePolygon(source.getCameraSpacePolygon()), face(source.getWFace())
{
- const Vec3r viewpoint(0, 0, 0);
- // Get the point on the camera-space polygon that is closest to the viewpoint
- // shallowest is the distance from the viewpoint to that point
- shallowest = GridHelpers::distancePointToPolygon(viewpoint, cameraSpacePolygon);
-
- // Get the point on the camera-space polygon that is furthest from the viewpoint
- // deepest is the distance from the viewpoint to that point
- deepest = cameraSpacePolygon.getVertices()[2].norm();
- for (unsigned int i = 0; i < 2; ++i) {
- real t = cameraSpacePolygon.getVertices()[i].norm();
- if (t > deepest) {
- deepest = t;
- }
- }
+ const Vec3r viewpoint(0, 0, 0);
+ // Get the point on the camera-space polygon that is closest to the viewpoint
+ // shallowest is the distance from the viewpoint to that point
+ shallowest = GridHelpers::distancePointToPolygon(viewpoint, cameraSpacePolygon);
+
+ // Get the point on the camera-space polygon that is furthest from the viewpoint
+ // deepest is the distance from the viewpoint to that point
+ deepest = cameraSpacePolygon.getVertices()[2].norm();
+ for (unsigned int i = 0; i < 2; ++i) {
+ real t = cameraSpacePolygon.getVertices()[i].norm();
+ if (t > deepest) {
+ deepest = t;
+ }
+ }
}
-inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
+inline void SphericalGrid::Cell::checkAndInsert(OccluderSource &source,
+ Polygon3r &poly,
+ OccluderData *&occluder)
{
- if (GridHelpers::insideProscenium (boundary, poly)) {
- if (occluder == NULL) {
- // Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
- // or automatically by SphericalGrid::_faces;
- occluder = new OccluderData(source, poly);
- }
- faces.push_back(occluder);
- }
+ if (GridHelpers::insideProscenium(boundary, poly)) {
+ if (occluder == NULL) {
+ // Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
+ // or automatically by SphericalGrid::_faces;
+ occluder = new OccluderData(source, poly);
+ }
+ faces.push_back(occluder);
+ }
}
-inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
+inline bool SphericalGrid::insertOccluder(OccluderSource &source, OccluderData *&occluder)
{
- Polygon3r& poly(source.getGridSpacePolygon());
- occluder = NULL;
-
- Vec3r bbMin, bbMax;
- poly.getBBox(bbMin, bbMax);
- // Check overlapping cells
- unsigned startX, startY, endX, endY;
- getCellCoordinates(bbMin, startX, startY);
- getCellCoordinates(bbMax, endX, endY);
-
- for (unsigned int i = startX; i <= endX; ++i) {
- for (unsigned int j = startY; j <= endY; ++j) {
- if (_cells[i * _cellsY + j] != NULL) {
- _cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
- }
- }
- }
-
- return occluder != NULL;
+ Polygon3r &poly(source.getGridSpacePolygon());
+ occluder = NULL;
+
+ Vec3r bbMin, bbMax;
+ poly.getBBox(bbMin, bbMax);
+ // Check overlapping cells
+ unsigned startX, startY, endX, endY;
+ getCellCoordinates(bbMin, startX, startY);
+ getCellCoordinates(bbMax, endX, endY);
+
+ for (unsigned int i = startX; i <= endX; ++i) {
+ for (unsigned int j = startY; j <= endY; ++j) {
+ if (_cells[i * _cellsY + j] != NULL) {
+ _cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
+ }
+ }
+ }
+
+ return occluder != NULL;
}
} /* namespace Freestyle */
-#endif // __FREESTYLE_SPHERICAL_GRID_H__
+#endif // __FREESTYLE_SPHERICAL_GRID_H__
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
index bb9f8069610..94541b2c312 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
@@ -43,249 +43,257 @@ using namespace Geometry;
SteerableViewMap::SteerableViewMap(unsigned int nbOrientations)
{
- _nbOrientations = nbOrientations;
- _bound = cos(M_PI / (float)_nbOrientations);
- for (unsigned int i = 0; i < _nbOrientations; ++i) {
- _directions.push_back(Vec2d(cos((float)i * M_PI / (float)_nbOrientations),
- sin((float)i * M_PI / (float)_nbOrientations)));
- }
- Build();
+ _nbOrientations = nbOrientations;
+ _bound = cos(M_PI / (float)_nbOrientations);
+ for (unsigned int i = 0; i < _nbOrientations; ++i) {
+ _directions.push_back(Vec2d(cos((float)i * M_PI / (float)_nbOrientations),
+ sin((float)i * M_PI / (float)_nbOrientations)));
+ }
+ Build();
}
void SteerableViewMap::Build()
{
- _imagesPyramids = new ImagePyramid *[_nbOrientations + 1]; // one more map to store the complete visible VM
- memset((_imagesPyramids), 0, (_nbOrientations + 1) * sizeof(ImagePyramid *));
+ _imagesPyramids =
+ new ImagePyramid *[_nbOrientations + 1]; // one more map to store the complete visible VM
+ memset((_imagesPyramids), 0, (_nbOrientations + 1) * sizeof(ImagePyramid *));
}
-SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother)
+SteerableViewMap::SteerableViewMap(const SteerableViewMap &iBrother)
{
- _nbOrientations = iBrother._nbOrientations;
- unsigned int i;
- _bound = iBrother._bound;
- _directions = iBrother._directions;
- _mapping = iBrother._mapping;
- _imagesPyramids = new ImagePyramid *[_nbOrientations + 1]; // one more map to store the complete visible VM
- for (i = 0; i <= _nbOrientations; ++i)
- _imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
+ _nbOrientations = iBrother._nbOrientations;
+ unsigned int i;
+ _bound = iBrother._bound;
+ _directions = iBrother._directions;
+ _mapping = iBrother._mapping;
+ _imagesPyramids =
+ new ImagePyramid *[_nbOrientations + 1]; // one more map to store the complete visible VM
+ for (i = 0; i <= _nbOrientations; ++i)
+ _imagesPyramids[i] = new GaussianPyramid(
+ *(dynamic_cast<GaussianPyramid *>(iBrother._imagesPyramids[i])));
}
SteerableViewMap::~SteerableViewMap()
{
- Clear();
+ Clear();
}
void SteerableViewMap::Clear()
{
- unsigned int i;
- if (_imagesPyramids) {
- for (i = 0; i <= _nbOrientations; ++i) {
- if (_imagesPyramids[i])
- delete (_imagesPyramids)[i];
- }
- delete[] _imagesPyramids;
- _imagesPyramids = 0;
- }
- if (!_mapping.empty()) {
- for (map<unsigned int, double*>::iterator m = _mapping.begin(), mend = _mapping.end(); m != mend; ++m) {
- delete[] (*m).second;
- }
- _mapping.clear();
- }
+ unsigned int i;
+ if (_imagesPyramids) {
+ for (i = 0; i <= _nbOrientations; ++i) {
+ if (_imagesPyramids[i])
+ delete (_imagesPyramids)[i];
+ }
+ delete[] _imagesPyramids;
+ _imagesPyramids = 0;
+ }
+ if (!_mapping.empty()) {
+ for (map<unsigned int, double *>::iterator m = _mapping.begin(), mend = _mapping.end();
+ m != mend;
+ ++m) {
+ delete[](*m).second;
+ }
+ _mapping.clear();
+ }
}
void SteerableViewMap::Reset()
{
- Clear();
- Build();
+ Clear();
+ Build();
}
-double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i)
+double SteerableViewMap::ComputeWeight(const Vec2d &dir, unsigned i)
{
- double dotp = fabs(dir * _directions[i]);
- if (dotp < _bound)
- return 0.0;
- if (dotp > 1.0)
- dotp = 1.0;
+ double dotp = fabs(dir * _directions[i]);
+ if (dotp < _bound)
+ return 0.0;
+ if (dotp > 1.0)
+ dotp = 1.0;
- return cos((float)_nbOrientations / 2.0 * acos(dotp));
+ return cos((float)_nbOrientations / 2.0 * acos(dotp));
}
double *SteerableViewMap::AddFEdge(FEdge *iFEdge)
{
- unsigned i;
- unsigned id = iFEdge->getId().getFirst();
- map<unsigned int, double *>::iterator o = _mapping.find(id);
- if (o != _mapping.end()) {
- return (*o).second;
- }
- double *res = new double[_nbOrientations];
- for (i = 0; i < _nbOrientations; ++i) {
- res[i] = 0.0;
- }
- Vec3r o2d3 = iFEdge->orientation2d();
- Vec2r o2d2(o2d3.x(), o2d3.y());
- real norm = o2d2.norm();
- if (norm < 1.0e-6) {
- return res;
- }
- o2d2 /= norm;
-
- for (i = 0; i < _nbOrientations; ++i) {
- res[i] = ComputeWeight(o2d2, i);
- }
- _mapping[id] = res;
- return res;
+ unsigned i;
+ unsigned id = iFEdge->getId().getFirst();
+ map<unsigned int, double *>::iterator o = _mapping.find(id);
+ if (o != _mapping.end()) {
+ return (*o).second;
+ }
+ double *res = new double[_nbOrientations];
+ for (i = 0; i < _nbOrientations; ++i) {
+ res[i] = 0.0;
+ }
+ Vec3r o2d3 = iFEdge->orientation2d();
+ Vec2r o2d2(o2d3.x(), o2d3.y());
+ real norm = o2d2.norm();
+ if (norm < 1.0e-6) {
+ return res;
+ }
+ o2d2 /= norm;
+
+ for (i = 0; i < _nbOrientations; ++i) {
+ res[i] = ComputeWeight(o2d2, i);
+ }
+ _mapping[id] = res;
+ return res;
}
-unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient)
+unsigned SteerableViewMap::getSVMNumber(const Vec2f &orient)
{
- Vec2f dir(orient);
- //soc unsigned res = 0;
- real norm = dir.norm();
- if (norm < 1.0e-6) {
- return _nbOrientations + 1;
- }
- dir /= norm;
- double maxw = 0.0f;
- unsigned winner = _nbOrientations + 1;
- for (unsigned int i = 0; i < _nbOrientations; ++i) {
- double w = ComputeWeight(dir, i);
- if (w > maxw) {
- maxw = w;
- winner = i;
- }
- }
- return winner;
+ Vec2f dir(orient);
+ //soc unsigned res = 0;
+ real norm = dir.norm();
+ if (norm < 1.0e-6) {
+ return _nbOrientations + 1;
+ }
+ dir /= norm;
+ double maxw = 0.0f;
+ unsigned winner = _nbOrientations + 1;
+ for (unsigned int i = 0; i < _nbOrientations; ++i) {
+ double w = ComputeWeight(dir, i);
+ if (w > maxw) {
+ maxw = w;
+ winner = i;
+ }
+ }
+ return winner;
}
unsigned SteerableViewMap::getSVMNumber(unsigned id)
{
- map<unsigned int, double *>::iterator o = _mapping.find(id);
- if (o != _mapping.end()) {
- double *wvalues = (*o).second;
- double maxw = 0.0;
- unsigned winner = _nbOrientations + 1;
- for (unsigned i = 0; i < _nbOrientations; ++i) {
- double w = wvalues[i];
- if (w > maxw) {
- maxw = w;
- winner = i;
- }
- }
- return winner;
- }
- return _nbOrientations + 1;
+ map<unsigned int, double *>::iterator o = _mapping.find(id);
+ if (o != _mapping.end()) {
+ double *wvalues = (*o).second;
+ double maxw = 0.0;
+ unsigned winner = _nbOrientations + 1;
+ for (unsigned i = 0; i < _nbOrientations; ++i) {
+ double w = wvalues[i];
+ if (w > maxw) {
+ maxw = w;
+ winner = i;
+ }
+ }
+ return winner;
+ }
+ return _nbOrientations + 1;
}
-void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma)
+void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases,
+ bool copy,
+ unsigned iNbLevels,
+ float iSigma)
{
- for (unsigned int i = 0; i <= _nbOrientations; ++i) {
- ImagePyramid *svm = (_imagesPyramids)[i];
- if (svm)
- delete svm;
- if (copy)
- svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma);
- else
- svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma);
- _imagesPyramids[i] = svm;
- }
+ for (unsigned int i = 0; i <= _nbOrientations; ++i) {
+ ImagePyramid *svm = (_imagesPyramids)[i];
+ if (svm)
+ delete svm;
+ if (copy)
+ svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma);
+ else
+ svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma);
+ _imagesPyramids[i] = svm;
+ }
}
float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y)
{
- ImagePyramid *pyramid = _imagesPyramids[iOrientation];
- if (!pyramid) {
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
- }
- return 0.0f;
- }
- if ((x < 0) || (x >= pyramid->width()) || (y < 0) || (y >= pyramid->height()))
- return 0;
- //float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) * 255.0f;
- // We encode both the directionality and the lines counting on 8 bits (because of frame buffer). Thus, we allow
- // until 8 lines to pass through the same pixel, so that we can discretize the Pi/_nbOrientations angle into
- // 32 slices. Therefore, for example, in the vertical direction, a vertical line will have the value 32 on
- // each pixel it passes through.
- float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) / 32.0f;
- return v;
+ ImagePyramid *pyramid = _imagesPyramids[iOrientation];
+ if (!pyramid) {
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
+ }
+ return 0.0f;
+ }
+ if ((x < 0) || (x >= pyramid->width()) || (y < 0) || (y >= pyramid->height()))
+ return 0;
+ //float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) * 255.0f;
+ // We encode both the directionality and the lines counting on 8 bits (because of frame buffer). Thus, we allow
+ // until 8 lines to pass through the same pixel, so that we can discretize the Pi/_nbOrientations angle into
+ // 32 slices. Therefore, for example, in the vertical direction, a vertical line will have the value 32 on
+ // each pixel it passes through.
+ float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) / 32.0f;
+ return v;
}
float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y)
{
- return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y);
+ return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y);
}
unsigned int SteerableViewMap::getNumberOfPyramidLevels() const
{
- if (_imagesPyramids[0])
- return _imagesPyramids[0]->getNumberOfLevels();
- return 0;
+ if (_imagesPyramids[0])
+ return _imagesPyramids[0]->getNumberOfLevels();
+ return 0;
}
void SteerableViewMap::saveSteerableViewMap() const
{
- for (unsigned int i = 0; i <= _nbOrientations; ++i) {
- if (_imagesPyramids[i] == 0) {
- cerr << "SteerableViewMap warning: orientation " << i <<
- " of steerable View Map whas not been computed yet" << endl;
- continue;
- }
- int ow = _imagesPyramids[i]->width(0);
- int oh = _imagesPyramids[i]->height(0);
-
- //soc QString base("SteerableViewMap");
- string base("SteerableViewMap");
- stringstream filename;
-
- for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc
- float coeff = 1.0f; // 1 / 255.0f; // 100 * 255; // * pow(2, j);
- //soc QImage qtmp(ow, oh, QImage::Format_RGB32);
- ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
- int rowbytes = ow * 4;
- char *pix;
-
- for (int y = 0; y < oh; ++y) { //soc
- for (int x = 0; x < ow; ++x) { //soc
- int c = (int)(coeff * _imagesPyramids[i]->pixel(x, y, j));
- if (c > 255)
- c = 255;
- //int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
-
- //soc qtmp.setPixel(x, y, qRgb(c, c, c));
- pix = (char *)ibuf->rect + y * rowbytes + x * 4;
- pix[0] = pix[1] = pix[2] = c;
- }
- }
-
- //soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
- filename << base;
- filename << i << "-" << j << ".png";
- ibuf->ftype = IMB_FTYPE_PNG;
- IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0);
- }
+ for (unsigned int i = 0; i <= _nbOrientations; ++i) {
+ if (_imagesPyramids[i] == 0) {
+ cerr << "SteerableViewMap warning: orientation " << i
+ << " of steerable View Map whas not been computed yet" << endl;
+ continue;
+ }
+ int ow = _imagesPyramids[i]->width(0);
+ int oh = _imagesPyramids[i]->height(0);
+
+ //soc QString base("SteerableViewMap");
+ string base("SteerableViewMap");
+ stringstream filename;
+
+ for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc
+ float coeff = 1.0f; // 1 / 255.0f; // 100 * 255; // * pow(2, j);
+ //soc QImage qtmp(ow, oh, QImage::Format_RGB32);
+ ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
+ int rowbytes = ow * 4;
+ char *pix;
+
+ for (int y = 0; y < oh; ++y) { //soc
+ for (int x = 0; x < ow; ++x) { //soc
+ int c = (int)(coeff * _imagesPyramids[i]->pixel(x, y, j));
+ if (c > 255)
+ c = 255;
+ //int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
+
+ //soc qtmp.setPixel(x, y, qRgb(c, c, c));
+ pix = (char *)ibuf->rect + y * rowbytes + x * 4;
+ pix[0] = pix[1] = pix[2] = c;
+ }
+ }
+
+ //soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
+ filename << base;
+ filename << i << "-" << j << ".png";
+ ibuf->ftype = IMB_FTYPE_PNG;
+ IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0);
+ }
#if 0
- QString base("SteerableViewMap");
- for (unsigned j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) {
- GrayImage *img = _imagesPyramids[i]->getLevel(j);
- int ow = img->width();
- int oh = img->height();
- float coeff = 1.0f; // 100 * 255; // * pow(2, j);
- QImage qtmp(ow, oh, 32);
- for (unsigned int y = 0; y < oh; ++y) {
- for (unsigned int x = 0; x < ow; ++x) {
- int c = (int)(coeff * img->pixel(x, y));
- if (c > 255)
- c = 255;
- //int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
- qtmp.setPixel(x, y, qRgb(c, c, c));
- }
- }
- qtmp.save(base + QString::number(i) + "-" + QString::number(j) + ".png", "PNG");
- }
+ QString base("SteerableViewMap");
+ for (unsigned j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) {
+ GrayImage *img = _imagesPyramids[i]->getLevel(j);
+ int ow = img->width();
+ int oh = img->height();
+ float coeff = 1.0f; // 100 * 255; // * pow(2, j);
+ QImage qtmp(ow, oh, 32);
+ for (unsigned int y = 0; y < oh; ++y) {
+ for (unsigned int x = 0; x < ow; ++x) {
+ int c = (int)(coeff * img->pixel(x, y));
+ if (c > 255)
+ c = 255;
+ //int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
+ qtmp.setPixel(x, y, qRgb(c, c, c));
+ }
+ }
+ qtmp.save(base + QString::number(i) + "-" + QString::number(j) + ".png", "PNG");
+ }
#endif
- }
+ }
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.h b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
index 608d64703f4..16f57f39737 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.h
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
@@ -29,7 +29,7 @@
#include "../system/FreestyleConfig.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
using namespace std;
@@ -45,109 +45,110 @@ class GrayImage;
/*! This class checks for every FEdge in which steerable it belongs and stores the mapping allowing to retrieve
* this information from the FEdge Id.
*/
-class SteerableViewMap
-{
-protected:
- // for each vector the list of nbOrientations weights corresponding to its contributions
- // to the nbOrientations directional maps
- map<unsigned int, double*> _mapping;
- unsigned _nbOrientations;
- ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM
-
- // internal
- double _bound; // cos(Pi/N)
- vector<Vec2d> _directions;
-
-public:
- SteerableViewMap(unsigned int nbOrientations = 4);
- SteerableViewMap(const SteerableViewMap& iBrother);
- virtual ~SteerableViewMap();
-
- /*! Resets everything */
- virtual void Reset();
-
- /*! Adds a FEdge to steerable VM.
- * Returns the nbOrientations weights corresponding to the FEdge contributions to the nbOrientations
- * directional maps.
- */
- double *AddFEdge(FEdge *iFEdge);
-
- /*! Compute the weight of direction dir for orientation iNOrientation */
- double ComputeWeight(const Vec2d& dir, unsigned iNOrientation);
-
- /*! Returns the number of the SVM to which a direction belongs to.
- * \param dir:
- * The direction
- */
- unsigned getSVMNumber(const Vec2f& dir);
-
- /*! Returns the number of the SVM to which a FEdge belongs most.
- * \param id:
- * The First element of the Id struct of the FEdge we're interested in.
- */
- unsigned getSVMNumber(unsigned id);
-
- /*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images of the steerable viewmap.
- * \param steerableBases:
- * The _nbOrientations+1 images constituting the basis for the steerable pyramid.
- * \param copy:
- * If false, the data is not duplicated, and Canvas deals with the memory management of these
- * _nbOrientations+1 images. If true, data is copied, and it's up to the caller to delete the images.
- * \param iNbLevels:
- * The number of levels desired for each pyramid.
- * If iNbLevels == 0, the complete pyramid is built.
- * \param iSigma:
- * The sigma that will be used for the gaussian blur
- */
- void buildImagesPyramids(GrayImage **steerableBases, bool copy = false, unsigned iNbLevels = 4,
- float iSigma = 1.0f);
-
- /*! Reads a pixel value in one of the VewMap density steerable pyramids.
- * Returns a value between 0 and 1.
- * \param iOrientation:
- * the number telling which orientation we need to check.
- * There are _nbOrientations+1 oriented ViewMaps:
- * 0 -> the ViewMap containing every horizontal lines
- * 1 -> the ViewMap containing every lines whose orientation is around PI/4
- * 2 -> the ViewMap containing every vertical lines
- * 3 -> the ViewMap containing every lines whose orientation is around 3PI/4
- * 4 -> the complete ViewMap
- * \param iLevel:
- * The level of the pyramid we want to read
- * \param x:
- * The abscissa of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
- * \param y:
- * The ordinate of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
- */
- float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y);
-
- /*! Reads a pixel in the one of the level of the pyramid containing the images of the complete ViewMap.
- * Returns a value between 0 and 1.
- * Equivalent to : readSteerableViewMapPixel(nbOrientations, x, y)
- */
- float readCompleteViewMapPixel(int iLevel, int x, int y);
-
- /*! Returns the number of levels in the pyramids */
- unsigned int getNumberOfPyramidLevels() const;
-
- /*! Returns the number of orientations */
- unsigned int getNumberOfOrientations() const
- {
- return _nbOrientations;
- }
-
- /*! for debug purposes */
- void saveSteerableViewMap() const;
-
-protected:
- void Clear();
- void Build();
+class SteerableViewMap {
+ protected:
+ // for each vector the list of nbOrientations weights corresponding to its contributions
+ // to the nbOrientations directional maps
+ map<unsigned int, double *> _mapping;
+ unsigned _nbOrientations;
+ ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM
+
+ // internal
+ double _bound; // cos(Pi/N)
+ vector<Vec2d> _directions;
+
+ public:
+ SteerableViewMap(unsigned int nbOrientations = 4);
+ SteerableViewMap(const SteerableViewMap &iBrother);
+ virtual ~SteerableViewMap();
+
+ /*! Resets everything */
+ virtual void Reset();
+
+ /*! Adds a FEdge to steerable VM.
+ * Returns the nbOrientations weights corresponding to the FEdge contributions to the nbOrientations
+ * directional maps.
+ */
+ double *AddFEdge(FEdge *iFEdge);
+
+ /*! Compute the weight of direction dir for orientation iNOrientation */
+ double ComputeWeight(const Vec2d &dir, unsigned iNOrientation);
+
+ /*! Returns the number of the SVM to which a direction belongs to.
+ * \param dir:
+ * The direction
+ */
+ unsigned getSVMNumber(const Vec2f &dir);
+
+ /*! Returns the number of the SVM to which a FEdge belongs most.
+ * \param id:
+ * The First element of the Id struct of the FEdge we're interested in.
+ */
+ unsigned getSVMNumber(unsigned id);
+
+ /*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images of the steerable viewmap.
+ * \param steerableBases:
+ * The _nbOrientations+1 images constituting the basis for the steerable pyramid.
+ * \param copy:
+ * If false, the data is not duplicated, and Canvas deals with the memory management of these
+ * _nbOrientations+1 images. If true, data is copied, and it's up to the caller to delete the images.
+ * \param iNbLevels:
+ * The number of levels desired for each pyramid.
+ * If iNbLevels == 0, the complete pyramid is built.
+ * \param iSigma:
+ * The sigma that will be used for the gaussian blur
+ */
+ void buildImagesPyramids(GrayImage **steerableBases,
+ bool copy = false,
+ unsigned iNbLevels = 4,
+ float iSigma = 1.0f);
+
+ /*! Reads a pixel value in one of the VewMap density steerable pyramids.
+ * Returns a value between 0 and 1.
+ * \param iOrientation:
+ * the number telling which orientation we need to check.
+ * There are _nbOrientations+1 oriented ViewMaps:
+ * 0 -> the ViewMap containing every horizontal lines
+ * 1 -> the ViewMap containing every lines whose orientation is around PI/4
+ * 2 -> the ViewMap containing every vertical lines
+ * 3 -> the ViewMap containing every lines whose orientation is around 3PI/4
+ * 4 -> the complete ViewMap
+ * \param iLevel:
+ * The level of the pyramid we want to read
+ * \param x:
+ * The abscissa of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
+ * \param y:
+ * The ordinate of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
+ */
+ float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y);
+
+ /*! Reads a pixel in the one of the level of the pyramid containing the images of the complete ViewMap.
+ * Returns a value between 0 and 1.
+ * Equivalent to : readSteerableViewMapPixel(nbOrientations, x, y)
+ */
+ float readCompleteViewMapPixel(int iLevel, int x, int y);
+
+ /*! Returns the number of levels in the pyramids */
+ unsigned int getNumberOfPyramidLevels() const;
+
+ /*! Returns the number of orientations */
+ unsigned int getNumberOfOrientations() const
+ {
+ return _nbOrientations;
+ }
+
+ /*! for debug purposes */
+ void saveSteerableViewMap() const;
+
+ protected:
+ void Clear();
+ void Build();
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SteerableViewMap")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SteerableViewMap")
#endif
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_STEERABLE_VIEW_MAP_H__
+#endif // __FREESTYLE_STEERABLE_VIEW_MAP_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
index 0ec008ebf2b..8896918e60d 100644
--- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
@@ -33,712 +33,721 @@ namespace Freestyle {
void ViewEdgeXBuilder::Init(ViewShape *oVShape)
{
- if (NULL == oVShape)
- return;
+ if (NULL == oVShape)
+ return;
- // for design conveniance, we store the current SShape.
- _pCurrentSShape = oVShape->sshape();
- if (0 == _pCurrentSShape)
- return;
+ // for design conveniance, we store the current SShape.
+ _pCurrentSShape = oVShape->sshape();
+ if (0 == _pCurrentSShape)
+ return;
- _pCurrentVShape = oVShape;
+ _pCurrentVShape = oVShape;
- // Reset previous data
- //--------------------
- if (!_SVertexMap.empty())
- _SVertexMap.clear();
+ // Reset previous data
+ //--------------------
+ if (!_SVertexMap.empty())
+ _SVertexMap.clear();
}
-void ViewEdgeXBuilder::BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, vector<ViewEdge*>& ioVEdges,
- vector<ViewVertex*>& ioVVertices, vector<FEdge*>& ioFEdges,
- vector<SVertex*>& ioSVertices)
+void ViewEdgeXBuilder::BuildViewEdges(WXShape *iWShape,
+ ViewShape *oVShape,
+ vector<ViewEdge *> &ioVEdges,
+ vector<ViewVertex *> &ioVVertices,
+ vector<FEdge *> &ioFEdges,
+ vector<SVertex *> &ioSVertices)
{
- // Reinit structures
- Init(oVShape);
-
- /* ViewEdge *vedge; */ /* UNUSED */
- // Let us build the smooth stuff
- //----------------------------------------
- // We parse all faces to find the ones that contain smooth edges
- vector<WFace*>& wfaces = iWShape->GetFaceList();
- vector<WFace*>::iterator wf, wfend;
- WXFace *wxf;
- for (wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; wf++) {
- wxf = dynamic_cast<WXFace*>(*wf);
- if (false == ((wxf))->hasSmoothEdges()) // does it contain at least one smooth edge ?
- continue;
- // parse all smooth layers:
- vector<WXFaceLayer*>& smoothLayers = wxf->getSmoothLayers();
- for (vector<WXFaceLayer*>::iterator sl = smoothLayers.begin(), slend = smoothLayers.end(); sl != slend; ++sl) {
- if (!(*sl)->hasSmoothEdge())
- continue;
- if (stopSmoothViewEdge((*sl))) // has it been parsed already ?
- continue;
- // here we know that we're dealing with a face layer that has not been processed yet and that contains
- // a smooth edge.
- /* vedge =*/ /* UNUSED */ BuildSmoothViewEdge(OWXFaceLayer(*sl, true));
- }
- }
-
- // Now let's build sharp view edges:
- //----------------------------------
- // Reset all userdata for WXEdge structure
- //----------------------------------------
- //iWShape->ResetUserData();
-
- WXEdge *wxe;
- vector<WEdge*>& wedges = iWShape->getEdgeList();
- //------------------------------
- for (vector<WEdge*>::iterator we = wedges.begin(), weend = wedges.end(); we != weend; we++) {
- wxe = dynamic_cast<WXEdge*>(*we);
- if (Nature::NO_FEATURE == wxe->nature())
- continue;
-
- if (!stopSharpViewEdge(wxe)) {
- bool b = true;
- if (wxe->order() == -1)
- b = false;
- BuildSharpViewEdge(OWXEdge(wxe, b));
- }
- }
-
- // Reset all userdata for WXEdge structure
- //----------------------------------------
- iWShape->ResetUserData();
-
- // Add all these new edges to the scene's feature edges list:
- //-----------------------------------------------------------
- vector<FEdge*>& newedges = _pCurrentSShape->getEdgeList();
- vector<SVertex*>& newVertices = _pCurrentSShape->getVertexList();
- vector<ViewVertex*>& newVVertices = _pCurrentVShape->vertices();
- vector<ViewEdge*>& newVEdges = _pCurrentVShape->edges();
-
- // inserts in ioFEdges, at its end, all the edges of newedges
- ioFEdges.insert(ioFEdges.end(), newedges.begin(), newedges.end());
- ioSVertices.insert(ioSVertices.end(), newVertices.begin(), newVertices.end());
- ioVVertices.insert(ioVVertices.end(), newVVertices.begin(), newVVertices.end());
- ioVEdges.insert(ioVEdges.end(), newVEdges.begin(), newVEdges.end());
+ // Reinit structures
+ Init(oVShape);
+
+ /* ViewEdge *vedge; */ /* UNUSED */
+ // Let us build the smooth stuff
+ //----------------------------------------
+ // We parse all faces to find the ones that contain smooth edges
+ vector<WFace *> &wfaces = iWShape->GetFaceList();
+ vector<WFace *>::iterator wf, wfend;
+ WXFace *wxf;
+ for (wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; wf++) {
+ wxf = dynamic_cast<WXFace *>(*wf);
+ if (false == ((wxf))->hasSmoothEdges()) // does it contain at least one smooth edge ?
+ continue;
+ // parse all smooth layers:
+ vector<WXFaceLayer *> &smoothLayers = wxf->getSmoothLayers();
+ for (vector<WXFaceLayer *>::iterator sl = smoothLayers.begin(), slend = smoothLayers.end();
+ sl != slend;
+ ++sl) {
+ if (!(*sl)->hasSmoothEdge())
+ continue;
+ if (stopSmoothViewEdge((*sl))) // has it been parsed already ?
+ continue;
+ // here we know that we're dealing with a face layer that has not been processed yet and that contains
+ // a smooth edge.
+ /* vedge =*//* UNUSED */ BuildSmoothViewEdge(OWXFaceLayer(*sl, true));
+ }
+ }
+
+ // Now let's build sharp view edges:
+ //----------------------------------
+ // Reset all userdata for WXEdge structure
+ //----------------------------------------
+ //iWShape->ResetUserData();
+
+ WXEdge *wxe;
+ vector<WEdge *> &wedges = iWShape->getEdgeList();
+ //------------------------------
+ for (vector<WEdge *>::iterator we = wedges.begin(), weend = wedges.end(); we != weend; we++) {
+ wxe = dynamic_cast<WXEdge *>(*we);
+ if (Nature::NO_FEATURE == wxe->nature())
+ continue;
+
+ if (!stopSharpViewEdge(wxe)) {
+ bool b = true;
+ if (wxe->order() == -1)
+ b = false;
+ BuildSharpViewEdge(OWXEdge(wxe, b));
+ }
+ }
+
+ // Reset all userdata for WXEdge structure
+ //----------------------------------------
+ iWShape->ResetUserData();
+
+ // Add all these new edges to the scene's feature edges list:
+ //-----------------------------------------------------------
+ vector<FEdge *> &newedges = _pCurrentSShape->getEdgeList();
+ vector<SVertex *> &newVertices = _pCurrentSShape->getVertexList();
+ vector<ViewVertex *> &newVVertices = _pCurrentVShape->vertices();
+ vector<ViewEdge *> &newVEdges = _pCurrentVShape->edges();
+
+ // inserts in ioFEdges, at its end, all the edges of newedges
+ ioFEdges.insert(ioFEdges.end(), newedges.begin(), newedges.end());
+ ioSVertices.insert(ioSVertices.end(), newVertices.begin(), newVertices.end());
+ ioVVertices.insert(ioVVertices.end(), newVVertices.begin(), newVVertices.end());
+ ioVEdges.insert(ioVEdges.end(), newVEdges.begin(), newVEdges.end());
}
-ViewEdge *ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
+ViewEdge *ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer &iFaceLayer)
{
- // Find first edge:
- OWXFaceLayer first = iFaceLayer;
- OWXFaceLayer currentFace = first;
-
- // bidirectional chaining.
- // first direction
- list<OWXFaceLayer> facesChain;
- unsigned size = 0;
- while (!stopSmoothViewEdge(currentFace.fl)) {
- facesChain.push_back(currentFace);
- ++size;
- currentFace.fl->userdata = (void *)1; // processed
- // Find the next edge!
- currentFace = FindNextFaceLayer(currentFace);
- }
- OWXFaceLayer end = facesChain.back();
- // second direction
- currentFace = FindPreviousFaceLayer(first);
- while (!stopSmoothViewEdge(currentFace.fl)) {
- facesChain.push_front(currentFace);
- ++size;
- currentFace.fl->userdata = (void *)1; // processed
- // Find the previous edge!
- currentFace = FindPreviousFaceLayer(currentFace);
- }
- first = facesChain.front();
-
- if (iFaceLayer.fl->nature() & Nature::RIDGE) {
- if (size < 4) {
- return 0;
- }
- }
-
- // Start a new chain edges
- ViewEdge *newVEdge = new ViewEdge;
- newVEdge->setId(_currentViewId);
- ++_currentViewId;
-
- _pCurrentVShape->AddEdge(newVEdge);
-
- // build FEdges
- FEdge *feprevious = NULL;
- FEdge *fefirst = NULL;
- FEdge *fe = NULL;
- for (list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend = facesChain.end(); fl != flend; ++fl) {
- fe = BuildSmoothFEdge(feprevious, (*fl));
- if (feprevious && fe == feprevious)
- continue;
- fe->setViewEdge(newVEdge);
- if (!fefirst)
- fefirst = fe;
- feprevious = fe;
- }
- // Store the chain starting edge:
- _pCurrentSShape->AddChain(fefirst);
- newVEdge->setNature(iFaceLayer.fl->nature());
- newVEdge->setFEdgeA(fefirst);
- newVEdge->setFEdgeB(fe);
-
- // is it a closed loop ?
- if ((first == end) && (size != 1)) {
- fefirst->setPreviousEdge(fe);
- fe->setNextEdge(fefirst);
- newVEdge->setA(0);
- newVEdge->setB(0);
- }
- else {
- ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
- ViewVertex *vvb = MakeViewVertex(fe->vertexB());
-
- ((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge);
- ((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge);
-
- newVEdge->setA(vva);
- newVEdge->setB(vvb);
- }
-
- return newVEdge;
+ // Find first edge:
+ OWXFaceLayer first = iFaceLayer;
+ OWXFaceLayer currentFace = first;
+
+ // bidirectional chaining.
+ // first direction
+ list<OWXFaceLayer> facesChain;
+ unsigned size = 0;
+ while (!stopSmoothViewEdge(currentFace.fl)) {
+ facesChain.push_back(currentFace);
+ ++size;
+ currentFace.fl->userdata = (void *)1; // processed
+ // Find the next edge!
+ currentFace = FindNextFaceLayer(currentFace);
+ }
+ OWXFaceLayer end = facesChain.back();
+ // second direction
+ currentFace = FindPreviousFaceLayer(first);
+ while (!stopSmoothViewEdge(currentFace.fl)) {
+ facesChain.push_front(currentFace);
+ ++size;
+ currentFace.fl->userdata = (void *)1; // processed
+ // Find the previous edge!
+ currentFace = FindPreviousFaceLayer(currentFace);
+ }
+ first = facesChain.front();
+
+ if (iFaceLayer.fl->nature() & Nature::RIDGE) {
+ if (size < 4) {
+ return 0;
+ }
+ }
+
+ // Start a new chain edges
+ ViewEdge *newVEdge = new ViewEdge;
+ newVEdge->setId(_currentViewId);
+ ++_currentViewId;
+
+ _pCurrentVShape->AddEdge(newVEdge);
+
+ // build FEdges
+ FEdge *feprevious = NULL;
+ FEdge *fefirst = NULL;
+ FEdge *fe = NULL;
+ for (list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend = facesChain.end(); fl != flend;
+ ++fl) {
+ fe = BuildSmoothFEdge(feprevious, (*fl));
+ if (feprevious && fe == feprevious)
+ continue;
+ fe->setViewEdge(newVEdge);
+ if (!fefirst)
+ fefirst = fe;
+ feprevious = fe;
+ }
+ // Store the chain starting edge:
+ _pCurrentSShape->AddChain(fefirst);
+ newVEdge->setNature(iFaceLayer.fl->nature());
+ newVEdge->setFEdgeA(fefirst);
+ newVEdge->setFEdgeB(fe);
+
+ // is it a closed loop ?
+ if ((first == end) && (size != 1)) {
+ fefirst->setPreviousEdge(fe);
+ fe->setNextEdge(fefirst);
+ newVEdge->setA(0);
+ newVEdge->setB(0);
+ }
+ else {
+ ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
+ ViewVertex *vvb = MakeViewVertex(fe->vertexB());
+
+ ((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge);
+ ((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge);
+
+ newVEdge->setA(vva);
+ newVEdge->setB(vvb);
+ }
+
+ return newVEdge;
}
-ViewEdge *ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge)
+ViewEdge *ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge &iWEdge)
{
- // Start a new sharp chain edges
- ViewEdge *newVEdge = new ViewEdge;
- newVEdge->setId(_currentViewId);
- ++_currentViewId;
- unsigned size = 0;
-
- _pCurrentVShape->AddEdge(newVEdge);
-
- // Find first edge:
- OWXEdge firstWEdge = iWEdge;
- /* OWXEdge previousWEdge = firstWEdge; */ /* UNUSED */
- OWXEdge currentWEdge = firstWEdge;
- list<OWXEdge> edgesChain;
+ // Start a new sharp chain edges
+ ViewEdge *newVEdge = new ViewEdge;
+ newVEdge->setId(_currentViewId);
+ ++_currentViewId;
+ unsigned size = 0;
+
+ _pCurrentVShape->AddEdge(newVEdge);
+
+ // Find first edge:
+ OWXEdge firstWEdge = iWEdge;
+ /* OWXEdge previousWEdge = firstWEdge; */ /* UNUSED */
+ OWXEdge currentWEdge = firstWEdge;
+ list<OWXEdge> edgesChain;
#if 0 /* TK 02-Sep-2012 Experimental fix for incorrect view edge visibility. */
- // bidirectional chaining
- // first direction:
- while (!stopSharpViewEdge(currentWEdge.e)) {
- edgesChain.push_back(currentWEdge);
- ++size;
- currentWEdge.e->userdata = (void *)1; // processed
- // Find the next edge!
- currentWEdge = FindNextWEdge(currentWEdge);
- }
- OWXEdge endWEdge = edgesChain.back();
- // second direction
- currentWEdge = FindPreviousWEdge(firstWEdge);
- while (!stopSharpViewEdge(currentWEdge.e)) {
- edgesChain.push_front(currentWEdge);
- ++size;
- currentWEdge.e->userdata = (void *)1; // processed
- // Find the previous edge!
- currentWEdge = FindPreviousWEdge(currentWEdge);
- }
+ // bidirectional chaining
+ // first direction:
+ while (!stopSharpViewEdge(currentWEdge.e)) {
+ edgesChain.push_back(currentWEdge);
+ ++size;
+ currentWEdge.e->userdata = (void *)1; // processed
+ // Find the next edge!
+ currentWEdge = FindNextWEdge(currentWEdge);
+ }
+ OWXEdge endWEdge = edgesChain.back();
+ // second direction
+ currentWEdge = FindPreviousWEdge(firstWEdge);
+ while (!stopSharpViewEdge(currentWEdge.e)) {
+ edgesChain.push_front(currentWEdge);
+ ++size;
+ currentWEdge.e->userdata = (void *)1; // processed
+ // Find the previous edge!
+ currentWEdge = FindPreviousWEdge(currentWEdge);
+ }
#else
- edgesChain.push_back(currentWEdge);
- ++size;
- currentWEdge.e->userdata = (void *)1; // processed
- OWXEdge endWEdge = edgesChain.back();
+ edgesChain.push_back(currentWEdge);
+ ++size;
+ currentWEdge.e->userdata = (void *)1; // processed
+ OWXEdge endWEdge = edgesChain.back();
#endif
- firstWEdge = edgesChain.front();
-
- // build FEdges
- FEdge *feprevious = NULL;
- FEdge *fefirst = NULL;
- FEdge *fe = NULL;
- for (list<OWXEdge>::iterator we = edgesChain.begin(), weend = edgesChain.end(); we != weend; ++we) {
- fe = BuildSharpFEdge(feprevious, (*we));
- fe->setViewEdge(newVEdge);
- if (!fefirst)
- fefirst = fe;
- feprevious = fe;
- }
- // Store the chain starting edge:
- _pCurrentSShape->AddChain(fefirst);
- newVEdge->setNature(iWEdge.e->nature());
- newVEdge->setFEdgeA(fefirst);
- newVEdge->setFEdgeB(fe);
-
- // is it a closed loop ?
- if ((firstWEdge == endWEdge) && (size != 1)) {
- fefirst->setPreviousEdge(fe);
- fe->setNextEdge(fefirst);
- newVEdge->setA(0);
- newVEdge->setB(0);
- }
- else {
- ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
- ViewVertex *vvb = MakeViewVertex(fe->vertexB());
-
- ((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge);
- ((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge);
-
- newVEdge->setA(vva);
- newVEdge->setB(vvb);
- }
-
- return newVEdge;
+ firstWEdge = edgesChain.front();
+
+ // build FEdges
+ FEdge *feprevious = NULL;
+ FEdge *fefirst = NULL;
+ FEdge *fe = NULL;
+ for (list<OWXEdge>::iterator we = edgesChain.begin(), weend = edgesChain.end(); we != weend;
+ ++we) {
+ fe = BuildSharpFEdge(feprevious, (*we));
+ fe->setViewEdge(newVEdge);
+ if (!fefirst)
+ fefirst = fe;
+ feprevious = fe;
+ }
+ // Store the chain starting edge:
+ _pCurrentSShape->AddChain(fefirst);
+ newVEdge->setNature(iWEdge.e->nature());
+ newVEdge->setFEdgeA(fefirst);
+ newVEdge->setFEdgeB(fe);
+
+ // is it a closed loop ?
+ if ((firstWEdge == endWEdge) && (size != 1)) {
+ fefirst->setPreviousEdge(fe);
+ fe->setNextEdge(fefirst);
+ newVEdge->setA(0);
+ newVEdge->setB(0);
+ }
+ else {
+ ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
+ ViewVertex *vvb = MakeViewVertex(fe->vertexB());
+
+ ((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge);
+ ((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge);
+
+ newVEdge->setA(vva);
+ newVEdge->setB(vvb);
+ }
+
+ return newVEdge;
}
-OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer)
+OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer &iFaceLayer)
{
- WXFace *nextFace = NULL;
- WOEdge *woeend;
- real tend;
- if (iFaceLayer.order) {
- woeend = iFaceLayer.fl->getSmoothEdge()->woeb();
- tend = iFaceLayer.fl->getSmoothEdge()->tb();
- }
- else {
- woeend = iFaceLayer.fl->getSmoothEdge()->woea();
- tend = iFaceLayer.fl->getSmoothEdge()->ta();
- }
- // special case of EDGE_VERTEX config:
- if ((tend == 0.0) || (tend == 1.0)) {
- WVertex *nextVertex;
- if (tend == 0.0)
- nextVertex = woeend->GetaVertex();
- else
- nextVertex = woeend->GetbVertex();
- if (nextVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
- return OWXFaceLayer(0, true);
- bool found = false;
- WVertex::face_iterator f = nextVertex->faces_begin();
- WVertex::face_iterator fend = nextVertex->faces_end();
- while ((!found) && (f != fend)) {
- nextFace = dynamic_cast<WXFace*>(*f);
- if ((0 != nextFace) && (nextFace != iFaceLayer.fl->getFace())) {
- vector<WXFaceLayer*> sameNatureLayers;
- nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
- // don't know... Maybe should test whether this face has also a vertex_edge configuration.
- if (sameNatureLayers.size() == 1) {
- WXFaceLayer *winner = sameNatureLayers[0];
- // check face mark continuity
- if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
- return OWXFaceLayer(NULL, true);
- if (woeend == winner->getSmoothEdge()->woea()->twin())
- return OWXFaceLayer(winner, true);
- else
- return OWXFaceLayer(winner, false);
- }
- }
- ++f;
- }
- }
- else {
- nextFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woeend));
- if (!nextFace)
- return OWXFaceLayer(NULL, true);
- // if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
- if (!nextFace->hasSmoothEdges())
- return OWXFaceLayer(NULL, true);
- vector<WXFaceLayer*> sameNatureLayers;
- nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
- // don't know how to deal with several edges of same nature on a single face
- if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
- return OWXFaceLayer(NULL, true);
- }
- else {
- WXFaceLayer *winner = sameNatureLayers[0];
- // check face mark continuity
- if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
- return OWXFaceLayer(NULL, true);
- if (woeend == winner->getSmoothEdge()->woea()->twin())
- return OWXFaceLayer(winner, true);
- else
- return OWXFaceLayer(winner, false);
- }
- }
- return OWXFaceLayer(NULL, true);
+ WXFace *nextFace = NULL;
+ WOEdge *woeend;
+ real tend;
+ if (iFaceLayer.order) {
+ woeend = iFaceLayer.fl->getSmoothEdge()->woeb();
+ tend = iFaceLayer.fl->getSmoothEdge()->tb();
+ }
+ else {
+ woeend = iFaceLayer.fl->getSmoothEdge()->woea();
+ tend = iFaceLayer.fl->getSmoothEdge()->ta();
+ }
+ // special case of EDGE_VERTEX config:
+ if ((tend == 0.0) || (tend == 1.0)) {
+ WVertex *nextVertex;
+ if (tend == 0.0)
+ nextVertex = woeend->GetaVertex();
+ else
+ nextVertex = woeend->GetbVertex();
+ if (nextVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
+ return OWXFaceLayer(0, true);
+ bool found = false;
+ WVertex::face_iterator f = nextVertex->faces_begin();
+ WVertex::face_iterator fend = nextVertex->faces_end();
+ while ((!found) && (f != fend)) {
+ nextFace = dynamic_cast<WXFace *>(*f);
+ if ((0 != nextFace) && (nextFace != iFaceLayer.fl->getFace())) {
+ vector<WXFaceLayer *> sameNatureLayers;
+ nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
+ // don't know... Maybe should test whether this face has also a vertex_edge configuration.
+ if (sameNatureLayers.size() == 1) {
+ WXFaceLayer *winner = sameNatureLayers[0];
+ // check face mark continuity
+ if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
+ return OWXFaceLayer(NULL, true);
+ if (woeend == winner->getSmoothEdge()->woea()->twin())
+ return OWXFaceLayer(winner, true);
+ else
+ return OWXFaceLayer(winner, false);
+ }
+ }
+ ++f;
+ }
+ }
+ else {
+ nextFace = dynamic_cast<WXFace *>(iFaceLayer.fl->getFace()->GetBordingFace(woeend));
+ if (!nextFace)
+ return OWXFaceLayer(NULL, true);
+ // if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
+ if (!nextFace->hasSmoothEdges())
+ return OWXFaceLayer(NULL, true);
+ vector<WXFaceLayer *> sameNatureLayers;
+ nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
+ // don't know how to deal with several edges of same nature on a single face
+ if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
+ return OWXFaceLayer(NULL, true);
+ }
+ else {
+ WXFaceLayer *winner = sameNatureLayers[0];
+ // check face mark continuity
+ if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
+ return OWXFaceLayer(NULL, true);
+ if (woeend == winner->getSmoothEdge()->woea()->twin())
+ return OWXFaceLayer(winner, true);
+ else
+ return OWXFaceLayer(winner, false);
+ }
+ }
+ return OWXFaceLayer(NULL, true);
}
-OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer)
+OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer &iFaceLayer)
{
- WXFace *previousFace = NULL;
- WOEdge *woebegin;
- real tend;
- if (iFaceLayer.order) {
- woebegin = iFaceLayer.fl->getSmoothEdge()->woea();
- tend = iFaceLayer.fl->getSmoothEdge()->ta();
- }
- else {
- woebegin = iFaceLayer.fl->getSmoothEdge()->woeb();
- tend = iFaceLayer.fl->getSmoothEdge()->tb();
- }
-
- // special case of EDGE_VERTEX config:
- if ((tend == 0.0) || (tend == 1.0)) {
- WVertex *previousVertex;
- if (tend == 0.0)
- previousVertex = woebegin->GetaVertex();
- else
- previousVertex = woebegin->GetbVertex();
- if (previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
- return OWXFaceLayer(NULL, true);
- bool found = false;
- WVertex::face_iterator f = previousVertex->faces_begin();
- WVertex::face_iterator fend = previousVertex->faces_end();
- for (; (!found) && (f != fend); ++f) {
- previousFace = dynamic_cast<WXFace*>(*f);
- if ((0 != previousFace) && (previousFace != iFaceLayer.fl->getFace())) {
- vector<WXFaceLayer*> sameNatureLayers;
- previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
- // don't know... Maybe should test whether this face has also a vertex_edge configuration
- if (sameNatureLayers.size() == 1) {
- WXFaceLayer *winner = sameNatureLayers[0];
- // check face mark continuity
- if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
- return OWXFaceLayer(NULL, true);
- if (woebegin == winner->getSmoothEdge()->woeb()->twin())
- return OWXFaceLayer(winner, true);
- else
- return OWXFaceLayer(winner, false);
- }
- }
- }
- }
- else {
- previousFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin));
- if (0 == previousFace)
- return OWXFaceLayer(NULL, true);
- // if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
- if (!previousFace->hasSmoothEdges())
- return OWXFaceLayer(NULL, true);
- vector<WXFaceLayer*> sameNatureLayers;
- previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
- // don't know how to deal with several edges of same nature on a single face
- if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
- return OWXFaceLayer(NULL, true);
- }
- else {
- WXFaceLayer *winner = sameNatureLayers[0];
- // check face mark continuity
- if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
- return OWXFaceLayer(NULL, true);
- if (woebegin == winner->getSmoothEdge()->woeb()->twin())
- return OWXFaceLayer(winner, true);
- else
- return OWXFaceLayer(winner, false);
- }
- }
- return OWXFaceLayer(NULL, true);
+ WXFace *previousFace = NULL;
+ WOEdge *woebegin;
+ real tend;
+ if (iFaceLayer.order) {
+ woebegin = iFaceLayer.fl->getSmoothEdge()->woea();
+ tend = iFaceLayer.fl->getSmoothEdge()->ta();
+ }
+ else {
+ woebegin = iFaceLayer.fl->getSmoothEdge()->woeb();
+ tend = iFaceLayer.fl->getSmoothEdge()->tb();
+ }
+
+ // special case of EDGE_VERTEX config:
+ if ((tend == 0.0) || (tend == 1.0)) {
+ WVertex *previousVertex;
+ if (tend == 0.0)
+ previousVertex = woebegin->GetaVertex();
+ else
+ previousVertex = woebegin->GetbVertex();
+ if (previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
+ return OWXFaceLayer(NULL, true);
+ bool found = false;
+ WVertex::face_iterator f = previousVertex->faces_begin();
+ WVertex::face_iterator fend = previousVertex->faces_end();
+ for (; (!found) && (f != fend); ++f) {
+ previousFace = dynamic_cast<WXFace *>(*f);
+ if ((0 != previousFace) && (previousFace != iFaceLayer.fl->getFace())) {
+ vector<WXFaceLayer *> sameNatureLayers;
+ previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
+ // don't know... Maybe should test whether this face has also a vertex_edge configuration
+ if (sameNatureLayers.size() == 1) {
+ WXFaceLayer *winner = sameNatureLayers[0];
+ // check face mark continuity
+ if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
+ return OWXFaceLayer(NULL, true);
+ if (woebegin == winner->getSmoothEdge()->woeb()->twin())
+ return OWXFaceLayer(winner, true);
+ else
+ return OWXFaceLayer(winner, false);
+ }
+ }
+ }
+ }
+ else {
+ previousFace = dynamic_cast<WXFace *>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin));
+ if (0 == previousFace)
+ return OWXFaceLayer(NULL, true);
+ // if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
+ if (!previousFace->hasSmoothEdges())
+ return OWXFaceLayer(NULL, true);
+ vector<WXFaceLayer *> sameNatureLayers;
+ previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
+ // don't know how to deal with several edges of same nature on a single face
+ if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
+ return OWXFaceLayer(NULL, true);
+ }
+ else {
+ WXFaceLayer *winner = sameNatureLayers[0];
+ // check face mark continuity
+ if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
+ return OWXFaceLayer(NULL, true);
+ if (woebegin == winner->getSmoothEdge()->woeb()->twin())
+ return OWXFaceLayer(winner, true);
+ else
+ return OWXFaceLayer(winner, false);
+ }
+ }
+ return OWXFaceLayer(NULL, true);
}
-FEdge *ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl)
+FEdge *ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer &ifl)
{
- WOEdge *woea, *woeb;
- real ta, tb;
- SVertex *va, *vb;
- FEdgeSmooth *fe;
- // retrieve exact silhouette data
- WXSmoothEdge *se = ifl.fl->getSmoothEdge();
-
- if (ifl.order) {
- woea = se->woea();
- woeb = se->woeb();
- ta = se->ta();
- tb = se->tb();
- }
- else {
- woea = se->woeb();
- woeb = se->woea();
- ta = se->tb();
- tb = se->ta();
- }
-
- Vec3r normal;
- // Make the 2 Svertices
- if (feprevious == 0) { // that means that we don't have any vertex already built for that face
- Vec3r A1(woea->GetaVertex()->GetVertex());
- Vec3r A2(woea->GetbVertex()->GetVertex());
- Vec3r A(A1 + ta * (A2 - A1));
-
- va = MakeSVertex(A, false);
- // Set normal:
- Vec3r NA1(ifl.fl->getFace()->GetVertexNormal(woea->GetaVertex()));
- Vec3r NA2(ifl.fl->getFace()->GetVertexNormal(woea->GetbVertex()));
- Vec3r na((1 - ta) * NA1 + ta * NA2);
- na.normalize();
- va->AddNormal(na);
- normal = na;
-
- // Set CurvatureInfo
- CurvatureInfo *curvature_info_a =
- new CurvatureInfo(*(dynamic_cast<WXVertex*>(woea->GetaVertex())->curvatures()),
- *(dynamic_cast<WXVertex*>(woea->GetbVertex())->curvatures()), ta);
- va->setCurvatureInfo(curvature_info_a);
- }
- else {
- va = feprevious->vertexB();
- }
-
- Vec3r B1(woeb->GetaVertex()->GetVertex());
- Vec3r B2(woeb->GetbVertex()->GetVertex());
- Vec3r B(B1 + tb * (B2 - B1));
-
- if (feprevious && (B - va->point3D()).norm() < 1.0e-6)
- return feprevious;
-
- vb = MakeSVertex(B, false);
- // Set normal:
- Vec3r NB1(ifl.fl->getFace()->GetVertexNormal(woeb->GetaVertex()));
- Vec3r NB2(ifl.fl->getFace()->GetVertexNormal(woeb->GetbVertex()));
- Vec3r nb((1 - tb) * NB1 + tb * NB2);
- nb.normalize();
- normal += nb;
- vb->AddNormal(nb);
-
- // Set CurvatureInfo
- CurvatureInfo *curvature_info_b =
- new CurvatureInfo(*(dynamic_cast<WXVertex*>(woeb->GetaVertex())->curvatures()),
- *(dynamic_cast<WXVertex*>(woeb->GetbVertex())->curvatures()), tb);
- vb->setCurvatureInfo(curvature_info_b);
-
- // Creates the corresponding feature edge
- fe = new FEdgeSmooth(va, vb);
- fe->setNature(ifl.fl->nature());
- fe->setId(_currentFId);
- fe->setFrsMaterialIndex(ifl.fl->getFace()->frs_materialIndex());
- fe->setFace(ifl.fl->getFace());
- fe->setFaceMark(ifl.fl->getFace()->GetMark());
- if (feprevious == 0)
- normal.normalize();
- fe->setNormal(normal);
- fe->setPreviousEdge(feprevious);
- if (feprevious)
- feprevious->setNextEdge(fe);
- _pCurrentSShape->AddEdge(fe);
- va->AddFEdge(fe);
- vb->AddFEdge(fe);
-
- ++_currentFId;
- ifl.fl->userdata = fe;
- return fe;
+ WOEdge *woea, *woeb;
+ real ta, tb;
+ SVertex *va, *vb;
+ FEdgeSmooth *fe;
+ // retrieve exact silhouette data
+ WXSmoothEdge *se = ifl.fl->getSmoothEdge();
+
+ if (ifl.order) {
+ woea = se->woea();
+ woeb = se->woeb();
+ ta = se->ta();
+ tb = se->tb();
+ }
+ else {
+ woea = se->woeb();
+ woeb = se->woea();
+ ta = se->tb();
+ tb = se->ta();
+ }
+
+ Vec3r normal;
+ // Make the 2 Svertices
+ if (feprevious == 0) { // that means that we don't have any vertex already built for that face
+ Vec3r A1(woea->GetaVertex()->GetVertex());
+ Vec3r A2(woea->GetbVertex()->GetVertex());
+ Vec3r A(A1 + ta * (A2 - A1));
+
+ va = MakeSVertex(A, false);
+ // Set normal:
+ Vec3r NA1(ifl.fl->getFace()->GetVertexNormal(woea->GetaVertex()));
+ Vec3r NA2(ifl.fl->getFace()->GetVertexNormal(woea->GetbVertex()));
+ Vec3r na((1 - ta) * NA1 + ta * NA2);
+ na.normalize();
+ va->AddNormal(na);
+ normal = na;
+
+ // Set CurvatureInfo
+ CurvatureInfo *curvature_info_a = new CurvatureInfo(
+ *(dynamic_cast<WXVertex *>(woea->GetaVertex())->curvatures()),
+ *(dynamic_cast<WXVertex *>(woea->GetbVertex())->curvatures()),
+ ta);
+ va->setCurvatureInfo(curvature_info_a);
+ }
+ else {
+ va = feprevious->vertexB();
+ }
+
+ Vec3r B1(woeb->GetaVertex()->GetVertex());
+ Vec3r B2(woeb->GetbVertex()->GetVertex());
+ Vec3r B(B1 + tb * (B2 - B1));
+
+ if (feprevious && (B - va->point3D()).norm() < 1.0e-6)
+ return feprevious;
+
+ vb = MakeSVertex(B, false);
+ // Set normal:
+ Vec3r NB1(ifl.fl->getFace()->GetVertexNormal(woeb->GetaVertex()));
+ Vec3r NB2(ifl.fl->getFace()->GetVertexNormal(woeb->GetbVertex()));
+ Vec3r nb((1 - tb) * NB1 + tb * NB2);
+ nb.normalize();
+ normal += nb;
+ vb->AddNormal(nb);
+
+ // Set CurvatureInfo
+ CurvatureInfo *curvature_info_b = new CurvatureInfo(
+ *(dynamic_cast<WXVertex *>(woeb->GetaVertex())->curvatures()),
+ *(dynamic_cast<WXVertex *>(woeb->GetbVertex())->curvatures()),
+ tb);
+ vb->setCurvatureInfo(curvature_info_b);
+
+ // Creates the corresponding feature edge
+ fe = new FEdgeSmooth(va, vb);
+ fe->setNature(ifl.fl->nature());
+ fe->setId(_currentFId);
+ fe->setFrsMaterialIndex(ifl.fl->getFace()->frs_materialIndex());
+ fe->setFace(ifl.fl->getFace());
+ fe->setFaceMark(ifl.fl->getFace()->GetMark());
+ if (feprevious == 0)
+ normal.normalize();
+ fe->setNormal(normal);
+ fe->setPreviousEdge(feprevious);
+ if (feprevious)
+ feprevious->setNextEdge(fe);
+ _pCurrentSShape->AddEdge(fe);
+ va->AddFEdge(fe);
+ vb->AddFEdge(fe);
+
+ ++_currentFId;
+ ifl.fl->userdata = fe;
+ return fe;
}
bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer)
{
- if (NULL == iFaceLayer)
- return true;
- if (iFaceLayer->userdata == 0)
- return false;
- return true;
+ if (NULL == iFaceLayer)
+ return true;
+ if (iFaceLayer->userdata == 0)
+ return false;
+ return true;
}
int ViewEdgeXBuilder::retrieveFaceMarks(WXEdge *iEdge)
{
- WFace *aFace = iEdge->GetaFace();
- WFace *bFace = iEdge->GetbFace();
- int result = 0;
- if (aFace && aFace->GetMark())
- result += 1;
- if (bFace && bFace->GetMark())
- result += 2;
- return result;
+ WFace *aFace = iEdge->GetaFace();
+ WFace *bFace = iEdge->GetbFace();
+ int result = 0;
+ if (aFace && aFace->GetMark())
+ result += 1;
+ if (bFace && bFace->GetMark())
+ result += 2;
+ return result;
}
-OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge)
+OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge &iEdge)
{
- if (Nature::NO_FEATURE == iEdge.e->nature())
- return OWXEdge(NULL, true);
-
- WVertex *v;
- if (true == iEdge.order)
- v = iEdge.e->GetbVertex();
- else
- v = iEdge.e->GetaVertex();
-
- if (((WXVertex *)v)->isFeature())
- return 0; /* XXX eeek? NULL? OWXEdge(NULL, true/false)?*/
-
- int faceMarks = retrieveFaceMarks(iEdge.e);
- vector<WEdge*>& vEdges = (v)->GetEdges();
- for (vector<WEdge*>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
- WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
- if (wxe == iEdge.e)
- continue; // same edge as the one processed
-
- if (wxe->nature() != iEdge.e->nature())
- continue;
-
- // check face mark continuity
- if (retrieveFaceMarks(wxe) != faceMarks)
- continue;
-
- if (wxe->GetaVertex() == v) {
- // That means that the face necesarily lies on the edge left.
- // So the vertex order is OK.
- return OWXEdge(wxe, true);
- }
- else {
- // That means that the face necesarily lies on the edge left.
- // So the vertex order is OK.
- return OWXEdge(wxe, false);
- }
- }
- // we did not find:
- return OWXEdge(NULL, true);
+ if (Nature::NO_FEATURE == iEdge.e->nature())
+ return OWXEdge(NULL, true);
+
+ WVertex *v;
+ if (true == iEdge.order)
+ v = iEdge.e->GetbVertex();
+ else
+ v = iEdge.e->GetaVertex();
+
+ if (((WXVertex *)v)->isFeature())
+ return 0; /* XXX eeek? NULL? OWXEdge(NULL, true/false)?*/
+
+ int faceMarks = retrieveFaceMarks(iEdge.e);
+ vector<WEdge *> &vEdges = (v)->GetEdges();
+ for (vector<WEdge *>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
+ WXEdge *wxe = dynamic_cast<WXEdge *>(*ve);
+ if (wxe == iEdge.e)
+ continue; // same edge as the one processed
+
+ if (wxe->nature() != iEdge.e->nature())
+ continue;
+
+ // check face mark continuity
+ if (retrieveFaceMarks(wxe) != faceMarks)
+ continue;
+
+ if (wxe->GetaVertex() == v) {
+ // That means that the face necesarily lies on the edge left.
+ // So the vertex order is OK.
+ return OWXEdge(wxe, true);
+ }
+ else {
+ // That means that the face necesarily lies on the edge left.
+ // So the vertex order is OK.
+ return OWXEdge(wxe, false);
+ }
+ }
+ // we did not find:
+ return OWXEdge(NULL, true);
}
-OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge)
+OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge &iEdge)
{
- if (Nature::NO_FEATURE == iEdge.e->nature())
- return OWXEdge(NULL, true);
-
- WVertex *v;
- if (true == iEdge.order)
- v = iEdge.e->GetaVertex();
- else
- v = iEdge.e->GetbVertex();
-
- if (((WXVertex *)v)->isFeature())
- return 0;
-
- int faceMarks = retrieveFaceMarks(iEdge.e);
- vector<WEdge *>& vEdges = (v)->GetEdges();
- for (vector<WEdge *>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
- WXEdge *wxe = dynamic_cast<WXEdge *>(*ve);
- if (wxe == iEdge.e)
- continue; // same edge as the one processed
-
- if (wxe->nature() != iEdge.e->nature())
- continue;
-
- // check face mark continuity
- if (retrieveFaceMarks(wxe) != faceMarks)
- continue;
-
- if (wxe->GetbVertex() == v) {
- return OWXEdge(wxe, true);
- }
- else {
- return OWXEdge(wxe, false);
- }
- }
- // we did not find:
- return OWXEdge(NULL, true);
+ if (Nature::NO_FEATURE == iEdge.e->nature())
+ return OWXEdge(NULL, true);
+
+ WVertex *v;
+ if (true == iEdge.order)
+ v = iEdge.e->GetaVertex();
+ else
+ v = iEdge.e->GetbVertex();
+
+ if (((WXVertex *)v)->isFeature())
+ return 0;
+
+ int faceMarks = retrieveFaceMarks(iEdge.e);
+ vector<WEdge *> &vEdges = (v)->GetEdges();
+ for (vector<WEdge *>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
+ WXEdge *wxe = dynamic_cast<WXEdge *>(*ve);
+ if (wxe == iEdge.e)
+ continue; // same edge as the one processed
+
+ if (wxe->nature() != iEdge.e->nature())
+ continue;
+
+ // check face mark continuity
+ if (retrieveFaceMarks(wxe) != faceMarks)
+ continue;
+
+ if (wxe->GetbVertex() == v) {
+ return OWXEdge(wxe, true);
+ }
+ else {
+ return OWXEdge(wxe, false);
+ }
+ }
+ // we did not find:
+ return OWXEdge(NULL, true);
}
-FEdge *ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
+FEdge *ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge &iwe)
{
- SVertex *va, *vb;
- FEdgeSharp *fe;
- Vec3r vA, vB;
- if (iwe.order) {
- vA = iwe.e->GetaVertex()->GetVertex();
- vB = iwe.e->GetbVertex()->GetVertex();
- }
- else {
- vA = iwe.e->GetbVertex()->GetVertex();
- vB = iwe.e->GetaVertex()->GetVertex();
- }
- // Make the 2 SVertex
- va = MakeSVertex(vA, true);
- vb = MakeSVertex(vB, true);
-
- // get the faces normals and the material indices
- Vec3r normalA, normalB;
- unsigned matA(0), matB(0);
- bool faceMarkA = false, faceMarkB = false;
- if (iwe.order) {
- normalB = (iwe.e->GetbFace()->GetNormal());
- matB = (iwe.e->GetbFace()->frs_materialIndex());
- faceMarkB = (iwe.e->GetbFace()->GetMark());
- if (!(iwe.e->nature() & Nature::BORDER)) {
- normalA = (iwe.e->GetaFace()->GetNormal());
- matA = (iwe.e->GetaFace()->frs_materialIndex());
- faceMarkA = (iwe.e->GetaFace()->GetMark());
- }
- }
- else {
- normalA = (iwe.e->GetbFace()->GetNormal());
- matA = (iwe.e->GetbFace()->frs_materialIndex());
- faceMarkA = (iwe.e->GetbFace()->GetMark());
- if (!(iwe.e->nature() & Nature::BORDER)) {
- normalB = (iwe.e->GetaFace()->GetNormal());
- matB = (iwe.e->GetaFace()->frs_materialIndex());
- faceMarkB = (iwe.e->GetaFace()->GetMark());
- }
- }
- // Creates the corresponding feature edge
- fe = new FEdgeSharp(va, vb);
- fe->setNature(iwe.e->nature());
- fe->setId(_currentFId);
- fe->setaFrsMaterialIndex(matA);
- fe->setbFrsMaterialIndex(matB);
- fe->setaFaceMark(faceMarkA);
- fe->setbFaceMark(faceMarkB);
- fe->setNormalA(normalA);
- fe->setNormalB(normalB);
- fe->setPreviousEdge(feprevious);
- if (feprevious)
- feprevious->setNextEdge(fe);
- _pCurrentSShape->AddEdge(fe);
- va->AddFEdge(fe);
- vb->AddFEdge(fe);
- //Add normals:
- va->AddNormal(normalA);
- va->AddNormal(normalB);
- vb->AddNormal(normalA);
- vb->AddNormal(normalB);
-
- ++_currentFId;
- iwe.e->userdata = fe;
- return fe;
+ SVertex *va, *vb;
+ FEdgeSharp *fe;
+ Vec3r vA, vB;
+ if (iwe.order) {
+ vA = iwe.e->GetaVertex()->GetVertex();
+ vB = iwe.e->GetbVertex()->GetVertex();
+ }
+ else {
+ vA = iwe.e->GetbVertex()->GetVertex();
+ vB = iwe.e->GetaVertex()->GetVertex();
+ }
+ // Make the 2 SVertex
+ va = MakeSVertex(vA, true);
+ vb = MakeSVertex(vB, true);
+
+ // get the faces normals and the material indices
+ Vec3r normalA, normalB;
+ unsigned matA(0), matB(0);
+ bool faceMarkA = false, faceMarkB = false;
+ if (iwe.order) {
+ normalB = (iwe.e->GetbFace()->GetNormal());
+ matB = (iwe.e->GetbFace()->frs_materialIndex());
+ faceMarkB = (iwe.e->GetbFace()->GetMark());
+ if (!(iwe.e->nature() & Nature::BORDER)) {
+ normalA = (iwe.e->GetaFace()->GetNormal());
+ matA = (iwe.e->GetaFace()->frs_materialIndex());
+ faceMarkA = (iwe.e->GetaFace()->GetMark());
+ }
+ }
+ else {
+ normalA = (iwe.e->GetbFace()->GetNormal());
+ matA = (iwe.e->GetbFace()->frs_materialIndex());
+ faceMarkA = (iwe.e->GetbFace()->GetMark());
+ if (!(iwe.e->nature() & Nature::BORDER)) {
+ normalB = (iwe.e->GetaFace()->GetNormal());
+ matB = (iwe.e->GetaFace()->frs_materialIndex());
+ faceMarkB = (iwe.e->GetaFace()->GetMark());
+ }
+ }
+ // Creates the corresponding feature edge
+ fe = new FEdgeSharp(va, vb);
+ fe->setNature(iwe.e->nature());
+ fe->setId(_currentFId);
+ fe->setaFrsMaterialIndex(matA);
+ fe->setbFrsMaterialIndex(matB);
+ fe->setaFaceMark(faceMarkA);
+ fe->setbFaceMark(faceMarkB);
+ fe->setNormalA(normalA);
+ fe->setNormalB(normalB);
+ fe->setPreviousEdge(feprevious);
+ if (feprevious)
+ feprevious->setNextEdge(fe);
+ _pCurrentSShape->AddEdge(fe);
+ va->AddFEdge(fe);
+ vb->AddFEdge(fe);
+ //Add normals:
+ va->AddNormal(normalA);
+ va->AddNormal(normalB);
+ vb->AddNormal(normalA);
+ vb->AddNormal(normalB);
+
+ ++_currentFId;
+ iwe.e->userdata = fe;
+ return fe;
}
bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge)
{
- if (NULL == iEdge)
- return true;
- if (iEdge->userdata == 0)
- return false;
- return true;
+ if (NULL == iEdge)
+ return true;
+ if (iEdge->userdata == 0)
+ return false;
+ return true;
}
-SVertex *ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint)
+SVertex *ViewEdgeXBuilder::MakeSVertex(Vec3r &iPoint)
{
- SVertex *va = new SVertex(iPoint, _currentSVertexId);
- SilhouetteGeomEngine::ProjectSilhouette(va);
- ++_currentSVertexId;
- // Add the svertex to the SShape svertex list:
- _pCurrentSShape->AddNewVertex(va);
- return va;
+ SVertex *va = new SVertex(iPoint, _currentSVertexId);
+ SilhouetteGeomEngine::ProjectSilhouette(va);
+ ++_currentSVertexId;
+ // Add the svertex to the SShape svertex list:
+ _pCurrentSShape->AddNewVertex(va);
+ return va;
}
-SVertex *ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint, bool shared)
+SVertex *ViewEdgeXBuilder::MakeSVertex(Vec3r &iPoint, bool shared)
{
- SVertex *va;
- if (!shared) {
- va = MakeSVertex(iPoint);
- }
- else {
- // Check whether the iPoint is already in the table
- SVertexMap::const_iterator found = _SVertexMap.find(iPoint);
- if (shared && found != _SVertexMap.end()) {
- va = (*found).second;
- }
- else {
- va = MakeSVertex(iPoint);
- // Add the svertex into the table using iPoint as the key
- _SVertexMap[iPoint] = va;
- }
- }
- return va;
+ SVertex *va;
+ if (!shared) {
+ va = MakeSVertex(iPoint);
+ }
+ else {
+ // Check whether the iPoint is already in the table
+ SVertexMap::const_iterator found = _SVertexMap.find(iPoint);
+ if (shared && found != _SVertexMap.end()) {
+ va = (*found).second;
+ }
+ else {
+ va = MakeSVertex(iPoint);
+ // Add the svertex into the table using iPoint as the key
+ _SVertexMap[iPoint] = va;
+ }
+ }
+ return va;
}
ViewVertex *ViewEdgeXBuilder::MakeViewVertex(SVertex *iSVertex)
{
- ViewVertex *vva = iSVertex->viewvertex();
- if (vva)
- return vva;
- vva = new NonTVertex(iSVertex);
- // Add the view vertex to the ViewShape svertex list:
- _pCurrentVShape->AddVertex(vva);
- return vva;
+ ViewVertex *vva = iSVertex->viewvertex();
+ if (vva)
+ return vva;
+ vva = new NonTVertex(iSVertex);
+ // Add the view vertex to the ViewShape svertex list:
+ _pCurrentVShape->AddVertex(vva);
+ return vva;
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
index fbe0ee8be0f..6f3604a1029 100644
--- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
@@ -26,13 +26,13 @@
#include <utility>
#include <vector>
-#if 0 // soc
-#if defined(__GNUC__) && (__GNUC__ >= 3)
+#if 0 // soc
+# if defined(__GNUC__) && (__GNUC__ >= 3)
//hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
-# include <hash_map.h>
-#else
-# include <hash_map>
-#endif
+# include <hash_map.h>
+# else
+# include <hash_map>
+# endif
#endif
#include "Interface1D.h"
@@ -42,7 +42,7 @@
#include "../system/FreestyleConfig.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
using namespace std;
@@ -54,117 +54,112 @@ using namespace Geometry;
class SVertex;
/*! Defines a hash table used for searching the SVertex */
-struct SVertexHasher
-{
+struct SVertexHasher {
#define _MUL 950706376UL
#define _MOD 2147483647UL
- inline size_t operator()(const Vec3r& p) const
- {
- size_t res = ((unsigned long)(p[0] * _MUL)) % _MOD;
- res = ((res + (unsigned long)(p[1]) * _MUL)) % _MOD;
- return ((res +(unsigned long)(p[2]) * _MUL)) % _MOD;
- }
+ inline size_t operator()(const Vec3r &p) const
+ {
+ size_t res = ((unsigned long)(p[0] * _MUL)) % _MOD;
+ res = ((res + (unsigned long)(p[1]) * _MUL)) % _MOD;
+ return ((res + (unsigned long)(p[2]) * _MUL)) % _MOD;
+ }
#undef _MUL
#undef _MOD
};
// Key_compare predicate for hash_map. In particular, return false if equal.
-struct epsilonEquals
-{
- bool operator()(const Vec3r& v1, const Vec3r& v2) const
- {
- real norm = (v1 - v2).norm();
- return (norm < 1.0e-06);
- }
+struct epsilonEquals {
+ bool operator()(const Vec3r &v1, const Vec3r &v2) const
+ {
+ real norm = (v1 - v2).norm();
+ return (norm < 1.0e-06);
+ }
};
-
// typedef hash_map<Vec3r, SVertex*, SVertexHasher, epsilonEquals> SVertexMap;
typedef map<Vec3r, SVertex *> SVertexMap;
class WXFaceLayer;
/*! class to describe an oriented smooth edge */
-class OWXFaceLayer
-{
-public:
- WXFaceLayer *fl;
- bool order;
-
- OWXFaceLayer()
- {
- fl = NULL;
- order = true;
- }
-
- OWXFaceLayer(WXFaceLayer *ifl, bool iOrder = true)
- {
- fl = ifl;
- order = iOrder;
- }
-
- OWXFaceLayer& operator=(const OWXFaceLayer& iBrother)
- {
- fl = iBrother.fl;
- order = iBrother.order;
- return *this;
- }
-
- bool operator==(const OWXFaceLayer& b)
- {
- return ((fl == b.fl) && (order == b.order));
- }
-
- bool operator!=(const OWXFaceLayer& b)
- {
- return !(*this == b);
- }
+class OWXFaceLayer {
+ public:
+ WXFaceLayer *fl;
+ bool order;
+
+ OWXFaceLayer()
+ {
+ fl = NULL;
+ order = true;
+ }
+
+ OWXFaceLayer(WXFaceLayer *ifl, bool iOrder = true)
+ {
+ fl = ifl;
+ order = iOrder;
+ }
+
+ OWXFaceLayer &operator=(const OWXFaceLayer &iBrother)
+ {
+ fl = iBrother.fl;
+ order = iBrother.order;
+ return *this;
+ }
+
+ bool operator==(const OWXFaceLayer &b)
+ {
+ return ((fl == b.fl) && (order == b.order));
+ }
+
+ bool operator!=(const OWXFaceLayer &b)
+ {
+ return !(*this == b);
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OWXFaceLayer")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OWXFaceLayer")
#endif
};
class WXEdge;
/*! class to describe an oriented sharp edge */
-class OWXEdge
-{
-public:
- WXEdge *e;
- bool order;
-
- OWXEdge()
- {
- e = NULL;
- order = true;
- }
-
- OWXEdge(WXEdge *ie, bool iOrder = true)
- {
- e = ie;
- order = iOrder;
- }
-
- OWXEdge& operator=(const OWXEdge& iBrother)
- {
- e = iBrother.e;
- order = iBrother.order;
- return *this;
- }
-
- bool operator==(const OWXEdge& b)
- {
- return ((e == b.e) && (order == b.order));
- }
-
- bool operator!=(const OWXEdge& b)
- {
- return !(*this == b);
- }
+class OWXEdge {
+ public:
+ WXEdge *e;
+ bool order;
+
+ OWXEdge()
+ {
+ e = NULL;
+ order = true;
+ }
+
+ OWXEdge(WXEdge *ie, bool iOrder = true)
+ {
+ e = ie;
+ order = iOrder;
+ }
+
+ OWXEdge &operator=(const OWXEdge &iBrother)
+ {
+ e = iBrother.e;
+ order = iBrother.order;
+ return *this;
+ }
+
+ bool operator==(const OWXEdge &b)
+ {
+ return ((e == b.e) && (order == b.order));
+ }
+
+ bool operator!=(const OWXEdge &b)
+ {
+ return !(*this == b);
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OWXEdge")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OWXEdge")
#endif
};
@@ -177,117 +172,121 @@ class ViewVertex;
class ViewEdge;
class ViewShape;
-class ViewEdgeXBuilder
-{
-protected:
- int _currentViewId; // Id for view edges
- int _currentFId; // Id for FEdges
- int _currentSVertexId; // Id for SVertex
-
-public:
- inline ViewEdgeXBuilder()
- {
- _currentViewId = 1;
- _currentFId = 0;
- _currentSVertexId = 0;
- }
-
- virtual ~ViewEdgeXBuilder() {}
-
- /*! Builds a view shape from a WXShape in which the feature edges are flagged
- * Builds chains of feature edges (so ViewEdges) from a WXShape
- * iWShape
- * The Winged Edge structure in which all silhouette edges and vertices are flagged.
- * oViewShape
- * The Silhouette Shape in which the chains must be added.
- * ioVEdges
- * The list of new ViewEdges.
- * ioVVertices
- * THe new ViewVertices
- * ioFEdges
- * A list in which all new FEdges are added
- * ioSVertices
- * A list of SVertex where all created SVertex are added.
- */
- virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, std::vector<ViewEdge*>& ioVEdges,
- std::vector<ViewVertex*>& ioVVertices, std::vector<FEdge*>& ioFEdges,
- std::vector<SVertex*>& ioSVertices);
-
- /*! Builds a smooth view edge, starting the face iFace. */
- ViewEdge *BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer);
-
- /*! Makes a sharp viewedge */
- ViewEdge *BuildSharpViewEdge(const OWXEdge& iWEdge);
-
-public:
- /*! accessors */
- inline int currentViewId() const
- {
- return _currentViewId;
- }
-
- inline int currentFId() const
- {
- return _currentFId;
- }
-
- inline int currentSVertexId() const
- {
- return _currentSVertexId;
- }
-
- /*! modifiers */
- inline void setCurrentViewId(int id)
- {
- _currentViewId = id;
- }
-
- inline void setCurrentFId(int id)
- {
- _currentFId = id;
- }
-
- inline void setCurrentSVertexId(int id)
- {
- _currentSVertexId = id;
- }
-
-protected:
- /*! Init the view edges building */
- virtual void Init(ViewShape *oVShape);
-
- // SMOOTH //
- /*! checks whether a face has already been processed or not */
- bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer);
- OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer& iFaceLayer);
- OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer);
- FEdge *BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl);
-
- // SHARP //
- /*! checks whether a WEdge has already been processed or not */
- bool stopSharpViewEdge(WXEdge *iFace);
- int retrieveFaceMarks(WXEdge *iEdge);
- OWXEdge FindNextWEdge(const OWXEdge& iEdge);
- OWXEdge FindPreviousWEdge(const OWXEdge& iEdge);
- FEdge *BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe);
-
- // GENERAL //
- /*! Instanciate a SVertex */
- SVertex *MakeSVertex(Vec3r& iPoint);
- /*! Instanciate a SVertex if it hasn't been already created */
- SVertex *MakeSVertex(Vec3r& iPoint, bool shared);
- /*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */
- ViewVertex *MakeViewVertex(SVertex *iSVertex);
-
- //oldtmp values
- //IdHashTable _hashtable;
- //VVIdHashTable _multivertexHashTable;
- SVertexMap _SVertexMap;
- SShape *_pCurrentSShape;
- ViewShape *_pCurrentVShape;
+class ViewEdgeXBuilder {
+ protected:
+ int _currentViewId; // Id for view edges
+ int _currentFId; // Id for FEdges
+ int _currentSVertexId; // Id for SVertex
+
+ public:
+ inline ViewEdgeXBuilder()
+ {
+ _currentViewId = 1;
+ _currentFId = 0;
+ _currentSVertexId = 0;
+ }
+
+ virtual ~ViewEdgeXBuilder()
+ {
+ }
+
+ /*! Builds a view shape from a WXShape in which the feature edges are flagged
+ * Builds chains of feature edges (so ViewEdges) from a WXShape
+ * iWShape
+ * The Winged Edge structure in which all silhouette edges and vertices are flagged.
+ * oViewShape
+ * The Silhouette Shape in which the chains must be added.
+ * ioVEdges
+ * The list of new ViewEdges.
+ * ioVVertices
+ * THe new ViewVertices
+ * ioFEdges
+ * A list in which all new FEdges are added
+ * ioSVertices
+ * A list of SVertex where all created SVertex are added.
+ */
+ virtual void BuildViewEdges(WXShape *iWShape,
+ ViewShape *oVShape,
+ std::vector<ViewEdge *> &ioVEdges,
+ std::vector<ViewVertex *> &ioVVertices,
+ std::vector<FEdge *> &ioFEdges,
+ std::vector<SVertex *> &ioSVertices);
+
+ /*! Builds a smooth view edge, starting the face iFace. */
+ ViewEdge *BuildSmoothViewEdge(const OWXFaceLayer &iFaceLayer);
+
+ /*! Makes a sharp viewedge */
+ ViewEdge *BuildSharpViewEdge(const OWXEdge &iWEdge);
+
+ public:
+ /*! accessors */
+ inline int currentViewId() const
+ {
+ return _currentViewId;
+ }
+
+ inline int currentFId() const
+ {
+ return _currentFId;
+ }
+
+ inline int currentSVertexId() const
+ {
+ return _currentSVertexId;
+ }
+
+ /*! modifiers */
+ inline void setCurrentViewId(int id)
+ {
+ _currentViewId = id;
+ }
+
+ inline void setCurrentFId(int id)
+ {
+ _currentFId = id;
+ }
+
+ inline void setCurrentSVertexId(int id)
+ {
+ _currentSVertexId = id;
+ }
+
+ protected:
+ /*! Init the view edges building */
+ virtual void Init(ViewShape *oVShape);
+
+ // SMOOTH //
+ /*! checks whether a face has already been processed or not */
+ bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer);
+ OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer &iFaceLayer);
+ OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer &iFaceLayer);
+ FEdge *BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer &ifl);
+
+ // SHARP //
+ /*! checks whether a WEdge has already been processed or not */
+ bool stopSharpViewEdge(WXEdge *iFace);
+ int retrieveFaceMarks(WXEdge *iEdge);
+ OWXEdge FindNextWEdge(const OWXEdge &iEdge);
+ OWXEdge FindPreviousWEdge(const OWXEdge &iEdge);
+ FEdge *BuildSharpFEdge(FEdge *feprevious, const OWXEdge &iwe);
+
+ // GENERAL //
+ /*! Instanciate a SVertex */
+ SVertex *MakeSVertex(Vec3r &iPoint);
+ /*! Instanciate a SVertex if it hasn't been already created */
+ SVertex *MakeSVertex(Vec3r &iPoint, bool shared);
+ /*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */
+ ViewVertex *MakeViewVertex(SVertex *iSVertex);
+
+ //oldtmp values
+ //IdHashTable _hashtable;
+ //VVIdHashTable _multivertexHashTable;
+ SVertexMap _SVertexMap;
+ SShape *_pCurrentSShape;
+ ViewShape *_pCurrentVShape;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdgeXBuilder")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdgeXBuilder")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp
index d23a87d7159..7c72e44fc10 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp
@@ -41,230 +41,243 @@ ViewMap *ViewMap::_pInstance = NULL;
ViewMap::~ViewMap()
{
- // The view vertices must be deleted here as some of them are shared between two shapes:
- for (vector<ViewVertex*>::iterator vv = _VVertices.begin(), vvend = _VVertices.end(); vv != vvend; vv++) {
- delete (*vv);
- }
- _VVertices.clear();
+ // The view vertices must be deleted here as some of them are shared between two shapes:
+ for (vector<ViewVertex *>::iterator vv = _VVertices.begin(), vvend = _VVertices.end();
+ vv != vvend;
+ vv++) {
+ delete (*vv);
+ }
+ _VVertices.clear();
- for (vector<ViewShape*>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend; vs++) {
- delete (*vs);
- }
- _VShapes.clear();
+ for (vector<ViewShape *>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend;
+ vs++) {
+ delete (*vs);
+ }
+ _VShapes.clear();
- _FEdges.clear();
- _SVertices.clear();
- _VEdges.clear();
+ _FEdges.clear();
+ _SVertices.clear();
+ _VEdges.clear();
}
void ViewMap::Clean()
{
- vector<FEdge*> tmpEdges;
-
- for (vector<ViewShape*>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend; vs++) {
- vector<FEdge*>& edges = (*vs)->sshape()->getEdgeList();
- for (vector<FEdge*>::iterator it = edges.begin(), itend = edges.end(); it != itend; it++) {
- if ((*it)->isTemporary()) {
- (*it)->setTemporary(false); // avoid being counted multiple times
- tmpEdges.push_back(*it);
- }
- }
- }
-
- for (vector<FEdge*>::iterator it = tmpEdges.begin(), itend = tmpEdges.end(); it != itend; it++) {
- for (vector<ViewShape*>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend; vs++) {
- (*vs)->sshape()->RemoveEdge(*it);
- }
- (*it)->vertexA()->RemoveFEdge(*it);
- (*it)->vertexB()->RemoveFEdge(*it);
- delete (*it);
- }
+ vector<FEdge *> tmpEdges;
+
+ for (vector<ViewShape *>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend;
+ vs++) {
+ vector<FEdge *> &edges = (*vs)->sshape()->getEdgeList();
+ for (vector<FEdge *>::iterator it = edges.begin(), itend = edges.end(); it != itend; it++) {
+ if ((*it)->isTemporary()) {
+ (*it)->setTemporary(false); // avoid being counted multiple times
+ tmpEdges.push_back(*it);
+ }
+ }
+ }
+
+ for (vector<FEdge *>::iterator it = tmpEdges.begin(), itend = tmpEdges.end(); it != itend;
+ it++) {
+ for (vector<ViewShape *>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend;
+ vs++) {
+ (*vs)->sshape()->RemoveEdge(*it);
+ }
+ (*it)->vertexA()->RemoveFEdge(*it);
+ (*it)->vertexB()->RemoveFEdge(*it);
+ delete (*it);
+ }
}
ViewShape *ViewMap::viewShape(unsigned id)
{
- int index = _shapeIdToIndex[id];
- return _VShapes[ index ];
+ int index = _shapeIdToIndex[id];
+ return _VShapes[index];
}
void ViewMap::AddViewShape(ViewShape *iVShape)
{
- _shapeIdToIndex[iVShape->getId().getFirst()] = _VShapes.size();
- _VShapes.push_back(iVShape);
+ _shapeIdToIndex[iVShape->getId().getFirst()] = _VShapes.size();
+ _VShapes.push_back(iVShape);
}
const FEdge *ViewMap::getClosestFEdge(real x, real y) const
{
- // find the closest of this candidates:
- real minDist = DBL_MAX;
- FEdge *winner = NULL;
- for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; fe++) {
- Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
- Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
- real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
- if (dist < minDist) {
- minDist = dist;
- winner = (*fe);
- }
- }
+ // find the closest of this candidates:
+ real minDist = DBL_MAX;
+ FEdge *winner = NULL;
+ for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend;
+ fe++) {
+ Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
+ Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
+ real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
+ if (dist < minDist) {
+ minDist = dist;
+ winner = (*fe);
+ }
+ }
- return winner;
+ return winner;
}
const ViewEdge *ViewMap::getClosestViewEdge(real x, real y) const
{
- // find the closest of this candidates:
- real minDist = DBL_MAX;
- FEdge *winner = NULL;
- for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; fe++) {
- Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
- Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
- real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
- if (dist < minDist) {
- minDist = dist;
- winner = (*fe);
- }
- }
- if (!winner)
- return NULL;
-
- return winner->viewedge();
-}
-
-
-TVertex *ViewMap::CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFEdgeA,
- const Vec3r& iB3D, const Vec3r& iB2D, FEdge *iFEdgeB, const Id& id)
-{
- ViewShape *vshapeA = iFEdgeA->viewedge()->viewShape();
- SShape *shapeA = iFEdgeA->shape();
- ViewShape *vshapeB = iFEdgeB->viewedge()->viewShape();
- SShape *shapeB = iFEdgeB->shape();
-
- SVertex *Ia = shapeA->CreateSVertex(iA3D, iA2D, iFEdgeA->vertexA()->getId());
- SVertex *Ib = shapeB->CreateSVertex(iB3D, iB2D, iFEdgeB->vertexA()->getId());
-
- // depending on which of these 2 svertices is the nearest from the viewpoint, we're going to build the TVertex
- // by giving them in an order or another (the first one must be the nearest)
- real dista = Ia->point2D()[2];
- real distb = Ib->point2D()[2];
-
- TVertex *tvertex;
- if (dista < distb)
- tvertex = new TVertex(Ia, Ib);
- else
- tvertex = new TVertex(Ib, Ia);
-
- tvertex->setId(id);
-
- // add these vertices to the view map
- AddViewVertex(tvertex);
- AddSVertex(Ia);
- AddSVertex(Ib);
-
- // and this T Vertex to the view shapes:
- vshapeA->AddVertex(tvertex);
- vshapeB->AddVertex(tvertex);
-
- return tvertex;
-}
-
-ViewVertex *ViewMap::InsertViewVertex(SVertex *iVertex, vector<ViewEdge*>& newViewEdges)
-{
- NonTVertex *vva = dynamic_cast<NonTVertex*>(iVertex->viewvertex());
- if (vva)
- return vva;
- // because it is not already a ViewVertex, this SVertex must have only 2 FEdges. The incoming one still belongs
- // to ioEdge, the outgoing one now belongs to newVEdge
- const vector<FEdge *>& fedges = iVertex->fedges();
- if (fedges.size() != 2) {
- cerr << "ViewMap warning: Can't split the ViewEdge" << endl;
- return NULL;
- }
- FEdge *fend(NULL), *fbegin(NULL);
- for (vector<FEdge *>::const_iterator fe = fedges.begin(), feend = fedges.end(); fe != feend; ++fe) {
- if ((*fe)->vertexB() == iVertex) {
- fend = (*fe);
- }
- if ((*fe)->vertexA() == iVertex) {
- fbegin = (*fe);
- }
- if ((fbegin != NULL) && (fend != NULL))
- break;
- }
- ViewEdge *ioEdge = fbegin->viewedge();
- ViewShape *vshape = ioEdge->viewShape();
- vva = new NonTVertex(iVertex);
- // if the ViewEdge is a closed loop, we don't create a new VEdge
- if (ioEdge->A() == 0) {
- // closed loop
- ioEdge->setA(vva);
- ioEdge->setB(vva);
- // update sshape
- vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeA());
- vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeB());
-
- ioEdge->setFEdgeA(fbegin);
- ioEdge->setFEdgeB(fend);
-
- // Update FEdges
- fend->setNextEdge(NULL);
- fbegin->setPreviousEdge(NULL);
-
- // update new View Vertex:
- vva->AddOutgoingViewEdge(ioEdge);
- vva->AddIncomingViewEdge(ioEdge);
-
- vshape->sshape()->AddChain(ioEdge->fedgeA());
- vshape->sshape()->AddChain(ioEdge->fedgeB());
- }
- else {
- // Create new ViewEdge
- ViewEdge *newVEdge = new ViewEdge(vva, ioEdge->B(), fbegin, ioEdge->fedgeB(), vshape);
- newVEdge->setId(Id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1));
- newVEdge->setNature(ioEdge->getNature());
- //newVEdge->UpdateFEdges(); // done in the ViewEdge constructor
- // Update old ViewEdge
- ioEdge->setB(vva);
- ioEdge->setFEdgeB(fend);
-
- // Update FEdges
- fend->setNextEdge(NULL);
- fbegin->setPreviousEdge(NULL);
-
- // update new View Vertex:
- vva->AddOutgoingViewEdge(newVEdge);
- vva->AddIncomingViewEdge(ioEdge);
-
- NonTVertex *vvb = dynamic_cast<NonTVertex*>(newVEdge->B());
- if (vvb)
- vvb->Replace(ioEdge, newVEdge);
-
- // update ViewShape
- //vshape->AddEdge(newVEdge);
- // update SShape
- vshape->sshape()->AddChain(fbegin);
- // update ViewMap
- //_VEdges.push_back(newVEdge);
- newViewEdges.push_back(newVEdge);
- }
-
- // update ViewShape
- vshape->AddVertex(vva);
-
- // update ViewMap
- _VVertices.push_back(vva);
-
- return vva;
+ // find the closest of this candidates:
+ real minDist = DBL_MAX;
+ FEdge *winner = NULL;
+ for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend;
+ fe++) {
+ Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
+ Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
+ real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
+ if (dist < minDist) {
+ minDist = dist;
+ winner = (*fe);
+ }
+ }
+ if (!winner)
+ return NULL;
+
+ return winner->viewedge();
+}
+
+TVertex *ViewMap::CreateTVertex(const Vec3r &iA3D,
+ const Vec3r &iA2D,
+ FEdge *iFEdgeA,
+ const Vec3r &iB3D,
+ const Vec3r &iB2D,
+ FEdge *iFEdgeB,
+ const Id &id)
+{
+ ViewShape *vshapeA = iFEdgeA->viewedge()->viewShape();
+ SShape *shapeA = iFEdgeA->shape();
+ ViewShape *vshapeB = iFEdgeB->viewedge()->viewShape();
+ SShape *shapeB = iFEdgeB->shape();
+
+ SVertex *Ia = shapeA->CreateSVertex(iA3D, iA2D, iFEdgeA->vertexA()->getId());
+ SVertex *Ib = shapeB->CreateSVertex(iB3D, iB2D, iFEdgeB->vertexA()->getId());
+
+ // depending on which of these 2 svertices is the nearest from the viewpoint, we're going to build the TVertex
+ // by giving them in an order or another (the first one must be the nearest)
+ real dista = Ia->point2D()[2];
+ real distb = Ib->point2D()[2];
+
+ TVertex *tvertex;
+ if (dista < distb)
+ tvertex = new TVertex(Ia, Ib);
+ else
+ tvertex = new TVertex(Ib, Ia);
+
+ tvertex->setId(id);
+
+ // add these vertices to the view map
+ AddViewVertex(tvertex);
+ AddSVertex(Ia);
+ AddSVertex(Ib);
+
+ // and this T Vertex to the view shapes:
+ vshapeA->AddVertex(tvertex);
+ vshapeB->AddVertex(tvertex);
+
+ return tvertex;
+}
+
+ViewVertex *ViewMap::InsertViewVertex(SVertex *iVertex, vector<ViewEdge *> &newViewEdges)
+{
+ NonTVertex *vva = dynamic_cast<NonTVertex *>(iVertex->viewvertex());
+ if (vva)
+ return vva;
+ // because it is not already a ViewVertex, this SVertex must have only 2 FEdges. The incoming one still belongs
+ // to ioEdge, the outgoing one now belongs to newVEdge
+ const vector<FEdge *> &fedges = iVertex->fedges();
+ if (fedges.size() != 2) {
+ cerr << "ViewMap warning: Can't split the ViewEdge" << endl;
+ return NULL;
+ }
+ FEdge *fend(NULL), *fbegin(NULL);
+ for (vector<FEdge *>::const_iterator fe = fedges.begin(), feend = fedges.end(); fe != feend;
+ ++fe) {
+ if ((*fe)->vertexB() == iVertex) {
+ fend = (*fe);
+ }
+ if ((*fe)->vertexA() == iVertex) {
+ fbegin = (*fe);
+ }
+ if ((fbegin != NULL) && (fend != NULL))
+ break;
+ }
+ ViewEdge *ioEdge = fbegin->viewedge();
+ ViewShape *vshape = ioEdge->viewShape();
+ vva = new NonTVertex(iVertex);
+ // if the ViewEdge is a closed loop, we don't create a new VEdge
+ if (ioEdge->A() == 0) {
+ // closed loop
+ ioEdge->setA(vva);
+ ioEdge->setB(vva);
+ // update sshape
+ vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeA());
+ vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeB());
+
+ ioEdge->setFEdgeA(fbegin);
+ ioEdge->setFEdgeB(fend);
+
+ // Update FEdges
+ fend->setNextEdge(NULL);
+ fbegin->setPreviousEdge(NULL);
+
+ // update new View Vertex:
+ vva->AddOutgoingViewEdge(ioEdge);
+ vva->AddIncomingViewEdge(ioEdge);
+
+ vshape->sshape()->AddChain(ioEdge->fedgeA());
+ vshape->sshape()->AddChain(ioEdge->fedgeB());
+ }
+ else {
+ // Create new ViewEdge
+ ViewEdge *newVEdge = new ViewEdge(vva, ioEdge->B(), fbegin, ioEdge->fedgeB(), vshape);
+ newVEdge->setId(Id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1));
+ newVEdge->setNature(ioEdge->getNature());
+ //newVEdge->UpdateFEdges(); // done in the ViewEdge constructor
+ // Update old ViewEdge
+ ioEdge->setB(vva);
+ ioEdge->setFEdgeB(fend);
+
+ // Update FEdges
+ fend->setNextEdge(NULL);
+ fbegin->setPreviousEdge(NULL);
+
+ // update new View Vertex:
+ vva->AddOutgoingViewEdge(newVEdge);
+ vva->AddIncomingViewEdge(ioEdge);
+
+ NonTVertex *vvb = dynamic_cast<NonTVertex *>(newVEdge->B());
+ if (vvb)
+ vvb->Replace(ioEdge, newVEdge);
+
+ // update ViewShape
+ //vshape->AddEdge(newVEdge);
+ // update SShape
+ vshape->sshape()->AddChain(fbegin);
+ // update ViewMap
+ //_VEdges.push_back(newVEdge);
+ newViewEdges.push_back(newVEdge);
+ }
+
+ // update ViewShape
+ vshape->AddVertex(vva);
+
+ // update ViewMap
+ _VVertices.push_back(vva);
+
+ return vva;
}
#if 0
FEdge *ViewMap::Connect(FEdge *ioEdge, SVertex *ioVertex, vector<ViewEdge*>& oNewVEdges)
{
- SShape *sshape = ioEdge->shape();
- FEdge *newFEdge = sshape->SplitEdgeIn2(ioEdge, ioVertex);
- AddFEdge(newFEdge);
- InsertViewVertex(ioVertex, oNewVEdges);
- return newFEdge;
+ SShape *sshape = ioEdge->shape();
+ FEdge *newFEdge = sshape->SplitEdgeIn2(ioEdge, ioVertex);
+ AddFEdge(newFEdge);
+ InsertViewVertex(ioVertex, oNewVEdges);
+ return newFEdge;
}
#endif
@@ -277,219 +290,231 @@ FEdge *ViewMap::Connect(FEdge *ioEdge, SVertex *ioVertex, vector<ViewEdge*>& oNe
/**********************************/
// is dve1 before dve2 ? (does it have a smaller angle ?)
-static bool ViewEdgeComp(ViewVertex::directedViewEdge& dve1, ViewVertex::directedViewEdge& dve2)
-{
- FEdge *fe1;
- if (dve1.second)
- fe1 = dve1.first->fedgeB();
- else
- fe1 = dve1.first->fedgeA();
- FEdge *fe2;
- if (dve2.second)
- fe2 = dve2.first->fedgeB();
- else
- fe2 = dve2.first->fedgeA();
-
- Vec3r V1 = fe1->orientation2d();
- Vec2r v1(V1.x(), V1.y());
- v1.normalize();
- Vec3r V2 = fe2->orientation2d();
- Vec2r v2(V2.x(), V2.y());
- v2.normalize();
- if (v1.y() > 0) {
- if (v2.y() < 0)
- return true;
- else
- return (v1.x() > v2.x());
- }
- else {
- if (v2.y() > 0)
- return false;
- else
- return (v1.x() < v2.x());
- }
- return false;
+static bool ViewEdgeComp(ViewVertex::directedViewEdge &dve1, ViewVertex::directedViewEdge &dve2)
+{
+ FEdge *fe1;
+ if (dve1.second)
+ fe1 = dve1.first->fedgeB();
+ else
+ fe1 = dve1.first->fedgeA();
+ FEdge *fe2;
+ if (dve2.second)
+ fe2 = dve2.first->fedgeB();
+ else
+ fe2 = dve2.first->fedgeA();
+
+ Vec3r V1 = fe1->orientation2d();
+ Vec2r v1(V1.x(), V1.y());
+ v1.normalize();
+ Vec3r V2 = fe2->orientation2d();
+ Vec2r v2(V2.x(), V2.y());
+ v2.normalize();
+ if (v1.y() > 0) {
+ if (v2.y() < 0)
+ return true;
+ else
+ return (v1.x() > v2.x());
+ }
+ else {
+ if (v2.y() > 0)
+ return false;
+ else
+ return (v1.x() < v2.x());
+ }
+ return false;
}
void TVertex::setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming)
{
- if (!iFrontEdgeA) {
- cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeA()" << endl;
- return;
- }
- _FrontEdgeA = directedViewEdge(iFrontEdgeA, incoming);
- if (!_sortedEdges.empty()) {
- edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
- for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeA); ++dve);
- _sortedEdges.insert( dve, &_FrontEdgeA);
- }
- else {
- _sortedEdges.push_back(&_FrontEdgeA);
- }
+ if (!iFrontEdgeA) {
+ cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeA()" << endl;
+ return;
+ }
+ _FrontEdgeA = directedViewEdge(iFrontEdgeA, incoming);
+ if (!_sortedEdges.empty()) {
+ edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
+ for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeA); ++dve)
+ ;
+ _sortedEdges.insert(dve, &_FrontEdgeA);
+ }
+ else {
+ _sortedEdges.push_back(&_FrontEdgeA);
+ }
}
void TVertex::setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming)
{
- if (!iFrontEdgeB) {
- cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeB()" << endl;
- return;
- }
- _FrontEdgeB = directedViewEdge(iFrontEdgeB, incoming);
- if (!_sortedEdges.empty()) {
- edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
- for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeB); ++dve);
- _sortedEdges.insert(dve, &_FrontEdgeB);
- }
- else {
- _sortedEdges.push_back(&_FrontEdgeB);
- }
+ if (!iFrontEdgeB) {
+ cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeB()" << endl;
+ return;
+ }
+ _FrontEdgeB = directedViewEdge(iFrontEdgeB, incoming);
+ if (!_sortedEdges.empty()) {
+ edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
+ for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeB); ++dve)
+ ;
+ _sortedEdges.insert(dve, &_FrontEdgeB);
+ }
+ else {
+ _sortedEdges.push_back(&_FrontEdgeB);
+ }
}
void TVertex::setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming)
{
- if (!iBackEdgeA) {
- cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeA()" << endl;
- return;
- }
- _BackEdgeA = directedViewEdge(iBackEdgeA, incoming);
- if (!_sortedEdges.empty()) {
- edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
- for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeA); ++dve);
- _sortedEdges.insert(dve, &_BackEdgeA);
- }
- else {
- _sortedEdges.push_back(&_BackEdgeA);
- }
+ if (!iBackEdgeA) {
+ cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeA()" << endl;
+ return;
+ }
+ _BackEdgeA = directedViewEdge(iBackEdgeA, incoming);
+ if (!_sortedEdges.empty()) {
+ edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
+ for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeA); ++dve)
+ ;
+ _sortedEdges.insert(dve, &_BackEdgeA);
+ }
+ else {
+ _sortedEdges.push_back(&_BackEdgeA);
+ }
}
void TVertex::setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming)
{
- if (!iBackEdgeB) {
- cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeB()" << endl;
- return;
- }
- _BackEdgeB = directedViewEdge(iBackEdgeB, incoming);
- if (!_sortedEdges.empty()) {
- edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
- for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeB); ++dve);
- _sortedEdges.insert(dve, &_BackEdgeB);
- }
- else {
- _sortedEdges.push_back(&_BackEdgeB);
- }
+ if (!iBackEdgeB) {
+ cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeB()" << endl;
+ return;
+ }
+ _BackEdgeB = directedViewEdge(iBackEdgeB, incoming);
+ if (!_sortedEdges.empty()) {
+ edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
+ for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeB); ++dve)
+ ;
+ _sortedEdges.insert(dve, &_BackEdgeB);
+ }
+ else {
+ _sortedEdges.push_back(&_BackEdgeB);
+ }
}
void TVertex::Replace(ViewEdge *iOld, ViewEdge *iNew)
{
- // theoritically, we only replace edges for which this
- // view vertex is the B vertex
- if ((iOld == _FrontEdgeA.first) && (_FrontEdgeA.first->B() == this)) {
- _FrontEdgeA.first = iNew;
- return;
- }
- if ((iOld == _FrontEdgeB.first) && (_FrontEdgeB.first->B() == this)) {
- _FrontEdgeB.first = iNew;
- return;
- }
- if ((iOld == _BackEdgeA.first) && (_BackEdgeA.first->B() == this)) {
- _BackEdgeA.first = iNew;
- return;
- }
- if ((iOld == _BackEdgeB.first) && (_BackEdgeB.first->B() == this)) {
- _BackEdgeB.first = iNew;
- return;
- }
+ // theoritically, we only replace edges for which this
+ // view vertex is the B vertex
+ if ((iOld == _FrontEdgeA.first) && (_FrontEdgeA.first->B() == this)) {
+ _FrontEdgeA.first = iNew;
+ return;
+ }
+ if ((iOld == _FrontEdgeB.first) && (_FrontEdgeB.first->B() == this)) {
+ _FrontEdgeB.first = iNew;
+ return;
+ }
+ if ((iOld == _BackEdgeA.first) && (_BackEdgeA.first->B() == this)) {
+ _BackEdgeA.first = iNew;
+ return;
+ }
+ if ((iOld == _BackEdgeB.first) && (_BackEdgeB.first->B() == this)) {
+ _BackEdgeB.first = iNew;
+ return;
+ }
}
/*! iterators access */
ViewVertex::edge_iterator TVertex::edges_begin()
{
- //return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
- return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
+ //return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
+ return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
}
ViewVertex::const_edge_iterator TVertex::edges_begin() const
{
- //return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
- return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
+ //return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
+ return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
}
ViewVertex::edge_iterator TVertex::edges_end()
{
- //return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, directedViewEdge(0,true));
- return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
+ //return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, directedViewEdge(0,true));
+ return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
}
ViewVertex::const_edge_iterator TVertex::edges_end() const
{
- //return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, directedViewEdge(0, true));
- return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
+ //return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, directedViewEdge(0, true));
+ return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
}
ViewVertex::edge_iterator TVertex::edges_iterator(ViewEdge *iEdge)
{
- for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end(); it != itend; it++) {
- if ((*it)->first == iEdge)
- return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it);
- }
- return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
+ for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end();
+ it != itend;
+ it++) {
+ if ((*it)->first == iEdge)
+ return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it);
+ }
+ return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
#if 0
- directedViewEdge dEdge;
- if (_FrontEdgeA.first == iEdge)
- dEdge = _FrontEdgeA;
- else if (_FrontEdgeB.first == iEdge)
- dEdge = _FrontEdgeB;
- else if (_BackEdgeA.first == iEdge)
- dEdge = _BackEdgeA;
- else if (_BackEdgeB.first == iEdge)
- dEdge = _BackEdgeB;
- return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
+ directedViewEdge dEdge;
+ if (_FrontEdgeA.first == iEdge)
+ dEdge = _FrontEdgeA;
+ else if (_FrontEdgeB.first == iEdge)
+ dEdge = _FrontEdgeB;
+ else if (_BackEdgeA.first == iEdge)
+ dEdge = _BackEdgeA;
+ else if (_BackEdgeB.first == iEdge)
+ dEdge = _BackEdgeB;
+ return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
#endif
}
ViewVertex::const_edge_iterator TVertex::edges_iterator(ViewEdge *iEdge) const
{
- for (edge_pointers_container::const_iterator it = _sortedEdges.begin(), itend = _sortedEdges.end();
- it != itend;
- it++)
- {
- if ((*it)->first == iEdge)
- return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it);
- }
- return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
+ for (edge_pointers_container::const_iterator it = _sortedEdges.begin(),
+ itend = _sortedEdges.end();
+ it != itend;
+ it++) {
+ if ((*it)->first == iEdge)
+ return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it);
+ }
+ return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
#if 0
- directedViewEdge dEdge;
- if (_FrontEdgeA.first == iEdge)
- dEdge = _FrontEdgeA;
- else if (_FrontEdgeB.first == iEdge)
- dEdge = _FrontEdgeB;
- else if (_BackEdgeA.first == iEdge)
- dEdge = _BackEdgeA;
- else if (_BackEdgeB.first == iEdge)
- dEdge = _BackEdgeB;
- return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
+ directedViewEdge dEdge;
+ if (_FrontEdgeA.first == iEdge)
+ dEdge = _FrontEdgeA;
+ else if (_FrontEdgeB.first == iEdge)
+ dEdge = _FrontEdgeB;
+ else if (_BackEdgeA.first == iEdge)
+ dEdge = _BackEdgeA;
+ else if (_BackEdgeB.first == iEdge)
+ dEdge = _BackEdgeB;
+ return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
#endif
}
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesBegin()
{
- return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
+ return ViewVertexInternal::orientedViewEdgeIterator(
+ _sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
}
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesEnd()
{
- return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
+ return ViewVertexInternal::orientedViewEdgeIterator(
+ _sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
}
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesIterator(ViewEdge *iEdge)
{
- for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end(); it != itend; it++) {
- if ((*it)->first == iEdge)
- return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), it);
- }
- return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
+ for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end();
+ it != itend;
+ it++) {
+ if ((*it)->first == iEdge)
+ return ViewVertexInternal::orientedViewEdgeIterator(
+ _sortedEdges.begin(), _sortedEdges.end(), it);
+ }
+ return ViewVertexInternal::orientedViewEdgeIterator(
+ _sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
}
/**********************************/
@@ -502,88 +527,98 @@ ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesIterator(ViewEdge *iE
void NonTVertex::AddOutgoingViewEdge(ViewEdge *iVEdge)
{
- // let's keep the viewedges ordered in CCW order in the 2D image plan
- directedViewEdge idve(iVEdge, false);
- if (!_ViewEdges.empty()) {
- edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
- for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve);
- _ViewEdges.insert(dve, idve);
- }
- else {
- _ViewEdges.push_back(idve);
- }
+ // let's keep the viewedges ordered in CCW order in the 2D image plan
+ directedViewEdge idve(iVEdge, false);
+ if (!_ViewEdges.empty()) {
+ edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
+ for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve)
+ ;
+ _ViewEdges.insert(dve, idve);
+ }
+ else {
+ _ViewEdges.push_back(idve);
+ }
}
void NonTVertex::AddIncomingViewEdge(ViewEdge *iVEdge)
{
- // let's keep the viewedges ordered in CCW order in the 2D image plan
- directedViewEdge idve(iVEdge, true);
- if (!_ViewEdges.empty()) {
- edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
- for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve);
- _ViewEdges.insert(dve, idve);
- }
- else {
- _ViewEdges.push_back(idve);
- }
+ // let's keep the viewedges ordered in CCW order in the 2D image plan
+ directedViewEdge idve(iVEdge, true);
+ if (!_ViewEdges.empty()) {
+ edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
+ for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve)
+ ;
+ _ViewEdges.insert(dve, idve);
+ }
+ else {
+ _ViewEdges.push_back(idve);
+ }
}
/*! iterators access */
ViewVertex::edge_iterator NonTVertex::edges_begin()
{
- return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
+ return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertex::const_edge_iterator NonTVertex::edges_begin() const
{
- return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
+ return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertex::edge_iterator NonTVertex::edges_end()
{
- return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
+ return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
}
ViewVertex::const_edge_iterator NonTVertex::edges_end() const
{
- return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
+ return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
}
ViewVertex::edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge)
{
- for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend; it++) {
- if ((it)->first == iEdge)
- return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
- }
- return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
+ for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend;
+ it++) {
+ if ((it)->first == iEdge)
+ return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
+ }
+ return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertex::const_edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge) const
{
- for (edges_container::const_iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend; it++) {
- if ((it)->first == iEdge)
- return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
- }
- return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
+ for (edges_container::const_iterator it = _ViewEdges.begin(), itend = _ViewEdges.end();
+ it != itend;
+ it++) {
+ if ((it)->first == iEdge)
+ return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
+ }
+ return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesBegin()
{
- return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
+ return ViewVertexInternal::orientedViewEdgeIterator(
+ _ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesEnd()
{
- return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
+ return ViewVertexInternal::orientedViewEdgeIterator(
+ _ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
}
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesIterator(ViewEdge *iEdge)
{
- for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend; it++) {
- if ((it)->first == iEdge)
- return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), it);
- }
- return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
+ for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend;
+ it++) {
+ if ((it)->first == iEdge)
+ return ViewVertexInternal::orientedViewEdgeIterator(
+ _ViewEdges.begin(), _ViewEdges.end(), it);
+ }
+ return ViewVertexInternal::orientedViewEdgeIterator(
+ _ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
/**********************************/
@@ -596,160 +631,161 @@ ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesIterator(ViewEdge
real ViewEdge::getLength2D() const
{
- float length = 0.0f;
- ViewEdge::const_fedge_iterator itlast = fedge_iterator_last();
- ViewEdge::const_fedge_iterator it = fedge_iterator_begin(), itend = fedge_iterator_end();
- Vec2r seg;
- do {
- seg = Vec2r((*it)->orientation2d()[0], (*it)->orientation2d()[1]);
- length += seg.norm();
- ++it;
- } while ((it != itend) && (it != itlast));
- return length;
+ float length = 0.0f;
+ ViewEdge::const_fedge_iterator itlast = fedge_iterator_last();
+ ViewEdge::const_fedge_iterator it = fedge_iterator_begin(), itend = fedge_iterator_end();
+ Vec2r seg;
+ do {
+ seg = Vec2r((*it)->orientation2d()[0], (*it)->orientation2d()[1]);
+ length += seg.norm();
+ ++it;
+ } while ((it != itend) && (it != itlast));
+ return length;
}
//! view edge iterator
ViewEdge::edge_iterator ViewEdge::ViewEdge_iterator()
{
- return edge_iterator(this);
+ return edge_iterator(this);
}
ViewEdge::const_edge_iterator ViewEdge::ViewEdge_iterator() const
{
- return const_edge_iterator((ViewEdge *)this);
+ return const_edge_iterator((ViewEdge *)this);
}
//! feature edge iterator
ViewEdge::fedge_iterator ViewEdge::fedge_iterator_begin()
{
- return fedge_iterator(this->_FEdgeA, this->_FEdgeB);
+ return fedge_iterator(this->_FEdgeA, this->_FEdgeB);
}
ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_begin() const
{
- return const_fedge_iterator(this->_FEdgeA, this->_FEdgeB);
+ return const_fedge_iterator(this->_FEdgeA, this->_FEdgeB);
}
ViewEdge::fedge_iterator ViewEdge::fedge_iterator_last()
{
- return fedge_iterator(this->_FEdgeB, this->_FEdgeB);
+ return fedge_iterator(this->_FEdgeB, this->_FEdgeB);
}
ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_last() const
{
- return const_fedge_iterator(this->_FEdgeB, this->_FEdgeB);
+ return const_fedge_iterator(this->_FEdgeB, this->_FEdgeB);
}
ViewEdge::fedge_iterator ViewEdge::fedge_iterator_end()
{
- return fedge_iterator(0, this->_FEdgeB);
+ return fedge_iterator(0, this->_FEdgeB);
}
ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_end() const
{
- return const_fedge_iterator(0, this->_FEdgeB);
+ return const_fedge_iterator(0, this->_FEdgeB);
}
//! embedding vertex iterator
ViewEdge::const_vertex_iterator ViewEdge::vertices_begin() const
{
- return const_vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
+ return const_vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
}
ViewEdge::vertex_iterator ViewEdge::vertices_begin()
{
- return vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
+ return vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
}
ViewEdge::const_vertex_iterator ViewEdge::vertices_last() const
{
- return const_vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);
+ return const_vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);
}
ViewEdge::vertex_iterator ViewEdge::vertices_last()
{
- return vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);
+ return vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);
}
ViewEdge::const_vertex_iterator ViewEdge::vertices_end() const
{
- return const_vertex_iterator(0, _FEdgeB, 0);
+ return const_vertex_iterator(0, _FEdgeB, 0);
}
ViewEdge::vertex_iterator ViewEdge::vertices_end()
{
- return vertex_iterator(0, _FEdgeB, 0);
+ return vertex_iterator(0, _FEdgeB, 0);
}
Interface0DIterator ViewEdge::verticesBegin()
{
- Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(this->_FEdgeA->vertexA(),
- this->_FEdgeA->vertexA(), NULL, _FEdgeA, 0.0f));
- return ret;
+ Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(
+ this->_FEdgeA->vertexA(), this->_FEdgeA->vertexA(), NULL, _FEdgeA, 0.0f));
+ return ret;
}
Interface0DIterator ViewEdge::verticesEnd()
{
- Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(NULL, this->_FEdgeA->vertexA(),
- _FEdgeB, NULL, getLength2D()));
- return ret;
+ Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(
+ NULL, this->_FEdgeA->vertexA(), _FEdgeB, NULL, getLength2D()));
+ return ret;
}
Interface0DIterator ViewEdge::pointsBegin(float /*t*/)
{
- return verticesBegin();
+ return verticesBegin();
}
Interface0DIterator ViewEdge::pointsEnd(float /*t*/)
{
- return verticesEnd();
+ return verticesEnd();
}
- /**********************************/
- /* */
- /* */
- /* ViewShape */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* ViewShape */
+/* */
+/* */
+/**********************************/
ViewShape::~ViewShape()
{
- _Vertices.clear();
+ _Vertices.clear();
- if (!(_Edges.empty())) {
- for (vector<ViewEdge*>::iterator e = _Edges.begin(), eend = _Edges.end(); e != eend; e++) {
- delete (*e);
- }
- _Edges.clear();
- }
+ if (!(_Edges.empty())) {
+ for (vector<ViewEdge *>::iterator e = _Edges.begin(), eend = _Edges.end(); e != eend; e++) {
+ delete (*e);
+ }
+ _Edges.clear();
+ }
- if (_SShape) {
- delete _SShape;
- _SShape = NULL;
- }
+ if (_SShape) {
+ delete _SShape;
+ _SShape = NULL;
+ }
}
void ViewShape::RemoveEdge(ViewEdge *iViewEdge)
{
- FEdge *fedge = iViewEdge->fedgeA();
- for (vector<ViewEdge*>::iterator ve = _Edges.begin(), veend = _Edges.end(); ve != veend; ve++) {
- if (iViewEdge == (*ve)) {
- _Edges.erase(ve);
- _SShape->RemoveEdge(fedge);
- break;
- }
- }
+ FEdge *fedge = iViewEdge->fedgeA();
+ for (vector<ViewEdge *>::iterator ve = _Edges.begin(), veend = _Edges.end(); ve != veend; ve++) {
+ if (iViewEdge == (*ve)) {
+ _Edges.erase(ve);
+ _SShape->RemoveEdge(fedge);
+ break;
+ }
+ }
}
void ViewShape::RemoveVertex(ViewVertex *iViewVertex)
{
- for (vector<ViewVertex*>::iterator vv = _Vertices.begin(), vvend = _Vertices.end(); vv != vvend; vv++) {
- if (iViewVertex == (*vv)) {
- _Vertices.erase(vv);
- break;
- }
- }
+ for (vector<ViewVertex *>::iterator vv = _Vertices.begin(), vvend = _Vertices.end(); vv != vvend;
+ vv++) {
+ if (iViewVertex == (*vv)) {
+ _Vertices.erase(vv);
+ break;
+ }
+ }
}
/**********************************/
@@ -762,13 +798,13 @@ void ViewShape::RemoveVertex(ViewVertex *iViewVertex)
void ViewEdge::UpdateFEdges()
{
- FEdge *currentEdge = _FEdgeA;
- do {
- currentEdge->setViewEdge(this);
- currentEdge = currentEdge->nextEdge();
- } while ((currentEdge != NULL) && (currentEdge != _FEdgeB));
- // last one
- _FEdgeB->setViewEdge(this);
+ FEdge *currentEdge = _FEdgeA;
+ do {
+ currentEdge->setViewEdge(this);
+ currentEdge = currentEdge->nextEdge();
+ } while ((currentEdge != NULL) && (currentEdge != _FEdgeB));
+ // last one
+ _FEdgeB->setViewEdge(this);
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h
index 4f0f50fbee2..b25e13d990f 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.h
+++ b/source/blender/freestyle/intern/view_map/ViewMap.h
@@ -26,7 +26,7 @@
#include "Interface0D.h"
#include "Interface1D.h"
-#include "Silhouette.h" // defines the embedding
+#include "Silhouette.h" // defines the embedding
#include "../geometry/GeomUtils.h"
@@ -34,7 +34,7 @@
#include "../system/FreestyleConfig.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
@@ -47,7 +47,6 @@ namespace Freestyle {
/* */
/**********************************/
-
/* Density
* Mean area depth value
* distance to a point
@@ -59,182 +58,186 @@ class ViewShape;
class TVertex;
/*! Class defining the ViewMap.*/
-class ViewMap
-{
-public:
- typedef vector<ViewEdge*> viewedges_container;
- typedef vector<ViewVertex*> viewvertices_container;
- typedef vector<ViewShape*> viewshapes_container;
- typedef vector<SVertex*> svertices_container;
- typedef vector<FEdge*> fedges_container;
- typedef map<int, int> id_to_index_map;
-
-private:
- static ViewMap *_pInstance;
- viewshapes_container _VShapes; // view shapes
- viewedges_container _VEdges; // view edges
- viewvertices_container _VVertices; // view vertices
- fedges_container _FEdges; // feature edges (embedded edges)
- svertices_container _SVertices; // embedded vertices
- BBox<Vec3r> _scene3DBBox;
- // Mapping between the WShape or VShape id to the VShape index in the _VShapes vector. Used in the method
- // viewShape(int id) to access a shape from its id.
- id_to_index_map _shapeIdToIndex;
-
-public:
- /*! A field that can be used by the user to store any data.
- * This field must be reseted afterwards using ResetUserData().
- */
- void *userdata;
-
- /*! Default constructor. */
- ViewMap()
- {
- _pInstance = this;
- userdata = NULL;
- }
-
- /*! Destructor. */
- virtual ~ViewMap();
-
- /*! Gets the viewedge the nearest to the 2D position specified as argument */
- const ViewEdge *getClosestViewEdge(real x, real y) const;
-
- /*! Gets the Fedge the nearest to the 2D position specified as argument */
- const FEdge *getClosestFEdge(real x, real y) const;
-
- /* accessors */
- /*! The ViewMap is a singleton class. This static method returns the instance of the ViewMap. */
- static inline ViewMap *getInstance()
- {
- return _pInstance;
- }
-
- /* Returns the list of ViewShapes of the scene. */
- inline viewshapes_container& ViewShapes()
- {
- return _VShapes;
- }
-
- /* Returns the list of ViewEdges of the scene. */
- inline viewedges_container& ViewEdges()
- {
- return _VEdges;
- }
-
- /* Returns the list of ViewVertices of the scene. */
- inline viewvertices_container& ViewVertices()
- {
- return _VVertices;
- }
-
- /* Returns the list of FEdges of the scene. */
- inline fedges_container& FEdges()
- {
- return _FEdges;
- }
-
- /* Returns the list of SVertices of the scene. */
- inline svertices_container& SVertices()
- {
- return _SVertices;
- }
-
- /* Returns an iterator pointing onto the first ViewEdge of the list. */
- inline viewedges_container::iterator viewedges_begin()
- {
- return _VEdges.begin();
- }
-
- inline viewedges_container::iterator viewedges_end()
- {
- return _VEdges.end();
- }
-
- inline int viewedges_size()
- {
- return _VEdges.size();
- }
-
- ViewShape *viewShape(unsigned index);
-
- id_to_index_map& shapeIdToIndexMap()
- {
- return _shapeIdToIndex;
- }
-
- /*! Returns the scene 3D bounding box. */
- inline BBox<Vec3r> getScene3dBBox() const
- {
- return _scene3DBBox;
- }
-
- /* modifiers */
- void AddViewShape(ViewShape *iVShape);
-
- inline void AddViewEdge(ViewEdge *iVEdge)
- {
- _VEdges.push_back(iVEdge);
- }
-
- inline void AddViewVertex(ViewVertex *iVVertex)
- {
- _VVertices.push_back(iVVertex);
- }
-
- inline void AddFEdge(FEdge *iFEdge)
- {
- _FEdges.push_back(iFEdge);
- }
-
- inline void AddSVertex(SVertex *iSVertex)
- {
- _SVertices.push_back(iSVertex);
- }
-
- /*! Sets the scene 3D bounding box. */
- inline void setScene3dBBox(const BBox<Vec3r>& bbox)
- {
- _scene3DBBox = bbox;
- }
-
- /* Creates a T vertex in the view map.
- * A T vertex is the intersection between 2 FEdges (before these ones are splitted).
- * The TVertex is a 2D intersection but it corresponds to a 3D point on each of the 2 FEdges.
- * iA3D
- * The 3D coordinates of the point corresponding to the intersection on the first edge.
- * iA2D
- * The x,y,z 2D coordinates of the projection of iA3D
- * iFEdgeA
- * The first FEdge
- * iB3D
- * The 3D coordinates of the point corresponding to the intersection on the second edge.
- * iB2D
- * The x,y,z 2D coordinates of the projection of iB3D
- * iFEdgeB
- * The second FEdge
- * id
- * The id that must be given to that TVertex
- */
- TVertex *CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFEdgeA, const Vec3r& iB3D, const Vec3r& iB2D,
- FEdge *iFEdgeB, const Id& id);
-
- /* Updates the structures to take into account the fact that a SVertex must now be considered as a ViewVertex
- * iVertex
- * The SVertex on top of which the ViewVertex is built (it is necessarily a NonTVertex because it is a SVertex)
- * newViewEdges
- * The new ViewEdges that must be add to the ViewMap
- */
- ViewVertex *InsertViewVertex(SVertex *iVertex, vector<ViewEdge*>& newViewEdges);
-
- /* connects a FEdge to the graph trough a SVertex */
- //FEdge *Connect(FEdge *ioEdge, SVertex *ioVertex);
-
- /* Clean temporary FEdges created by chaining */
- virtual void Clean();
+class ViewMap {
+ public:
+ typedef vector<ViewEdge *> viewedges_container;
+ typedef vector<ViewVertex *> viewvertices_container;
+ typedef vector<ViewShape *> viewshapes_container;
+ typedef vector<SVertex *> svertices_container;
+ typedef vector<FEdge *> fedges_container;
+ typedef map<int, int> id_to_index_map;
+
+ private:
+ static ViewMap *_pInstance;
+ viewshapes_container _VShapes; // view shapes
+ viewedges_container _VEdges; // view edges
+ viewvertices_container _VVertices; // view vertices
+ fedges_container _FEdges; // feature edges (embedded edges)
+ svertices_container _SVertices; // embedded vertices
+ BBox<Vec3r> _scene3DBBox;
+ // Mapping between the WShape or VShape id to the VShape index in the _VShapes vector. Used in the method
+ // viewShape(int id) to access a shape from its id.
+ id_to_index_map _shapeIdToIndex;
+
+ public:
+ /*! A field that can be used by the user to store any data.
+ * This field must be reseted afterwards using ResetUserData().
+ */
+ void *userdata;
+
+ /*! Default constructor. */
+ ViewMap()
+ {
+ _pInstance = this;
+ userdata = NULL;
+ }
+
+ /*! Destructor. */
+ virtual ~ViewMap();
+
+ /*! Gets the viewedge the nearest to the 2D position specified as argument */
+ const ViewEdge *getClosestViewEdge(real x, real y) const;
+
+ /*! Gets the Fedge the nearest to the 2D position specified as argument */
+ const FEdge *getClosestFEdge(real x, real y) const;
+
+ /* accessors */
+ /*! The ViewMap is a singleton class. This static method returns the instance of the ViewMap. */
+ static inline ViewMap *getInstance()
+ {
+ return _pInstance;
+ }
+
+ /* Returns the list of ViewShapes of the scene. */
+ inline viewshapes_container &ViewShapes()
+ {
+ return _VShapes;
+ }
+
+ /* Returns the list of ViewEdges of the scene. */
+ inline viewedges_container &ViewEdges()
+ {
+ return _VEdges;
+ }
+
+ /* Returns the list of ViewVertices of the scene. */
+ inline viewvertices_container &ViewVertices()
+ {
+ return _VVertices;
+ }
+
+ /* Returns the list of FEdges of the scene. */
+ inline fedges_container &FEdges()
+ {
+ return _FEdges;
+ }
+
+ /* Returns the list of SVertices of the scene. */
+ inline svertices_container &SVertices()
+ {
+ return _SVertices;
+ }
+
+ /* Returns an iterator pointing onto the first ViewEdge of the list. */
+ inline viewedges_container::iterator viewedges_begin()
+ {
+ return _VEdges.begin();
+ }
+
+ inline viewedges_container::iterator viewedges_end()
+ {
+ return _VEdges.end();
+ }
+
+ inline int viewedges_size()
+ {
+ return _VEdges.size();
+ }
+
+ ViewShape *viewShape(unsigned index);
+
+ id_to_index_map &shapeIdToIndexMap()
+ {
+ return _shapeIdToIndex;
+ }
+
+ /*! Returns the scene 3D bounding box. */
+ inline BBox<Vec3r> getScene3dBBox() const
+ {
+ return _scene3DBBox;
+ }
+
+ /* modifiers */
+ void AddViewShape(ViewShape *iVShape);
+
+ inline void AddViewEdge(ViewEdge *iVEdge)
+ {
+ _VEdges.push_back(iVEdge);
+ }
+
+ inline void AddViewVertex(ViewVertex *iVVertex)
+ {
+ _VVertices.push_back(iVVertex);
+ }
+
+ inline void AddFEdge(FEdge *iFEdge)
+ {
+ _FEdges.push_back(iFEdge);
+ }
+
+ inline void AddSVertex(SVertex *iSVertex)
+ {
+ _SVertices.push_back(iSVertex);
+ }
+
+ /*! Sets the scene 3D bounding box. */
+ inline void setScene3dBBox(const BBox<Vec3r> &bbox)
+ {
+ _scene3DBBox = bbox;
+ }
+
+ /* Creates a T vertex in the view map.
+ * A T vertex is the intersection between 2 FEdges (before these ones are splitted).
+ * The TVertex is a 2D intersection but it corresponds to a 3D point on each of the 2 FEdges.
+ * iA3D
+ * The 3D coordinates of the point corresponding to the intersection on the first edge.
+ * iA2D
+ * The x,y,z 2D coordinates of the projection of iA3D
+ * iFEdgeA
+ * The first FEdge
+ * iB3D
+ * The 3D coordinates of the point corresponding to the intersection on the second edge.
+ * iB2D
+ * The x,y,z 2D coordinates of the projection of iB3D
+ * iFEdgeB
+ * The second FEdge
+ * id
+ * The id that must be given to that TVertex
+ */
+ TVertex *CreateTVertex(const Vec3r &iA3D,
+ const Vec3r &iA2D,
+ FEdge *iFEdgeA,
+ const Vec3r &iB3D,
+ const Vec3r &iB2D,
+ FEdge *iFEdgeB,
+ const Id &id);
+
+ /* Updates the structures to take into account the fact that a SVertex must now be considered as a ViewVertex
+ * iVertex
+ * The SVertex on top of which the ViewVertex is built (it is necessarily a NonTVertex because it is a SVertex)
+ * newViewEdges
+ * The new ViewEdges that must be add to the ViewMap
+ */
+ ViewVertex *InsertViewVertex(SVertex *iVertex, vector<ViewEdge *> &newViewEdges);
+
+ /* connects a FEdge to the graph trough a SVertex */
+ //FEdge *Connect(FEdge *ioEdge, SVertex *ioVertex);
+
+ /* Clean temporary FEdges created by chaining */
+ virtual void Clean();
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMap")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMap")
#endif
};
@@ -256,7 +259,7 @@ class edge_nonconst_traits;
template<class Traits> class edge_iterator_base;
class orientedViewEdgeIterator;
-} // end of namespace ViewEdgeInternal
+} // namespace ViewVertexInternal
/*! Class to define a view vertex.
* A view vertex is a feature vertex corresponding to a point of the image graph, where the characteristics of an
@@ -265,106 +268,111 @@ class orientedViewEdgeIterator;
* NonTVertex when it corresponds to a vertex of the initial input mesh (it is the case for vertices such as corners
* for example). Thus, this class can be specialized into two classes, the TVertex class and the NonTVertex class.
*/
-class ViewVertex : public Interface0D
-{
-public: // Implementation of Interface0D
- /*! Returns the string "ViewVertex". */
- virtual string getExactTypeName() const
- {
- return "ViewVertex";
- }
-
-public:
- friend class ViewShape;
- typedef pair<ViewEdge *, bool> directedViewEdge; // if bool = true, the ViewEdge is incoming
-
- typedef vector<directedViewEdge> edges_container;
-
- typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_nonconst_traits> edge_iterator;
- typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_const_traits> const_edge_iterator;
-
-private:
- Nature::VertexNature _Nature;
-
-public:
- /*! A field that can be used by the user to store any data.
- * This field must be reseted afterwards using ResetUserData().
- */
- void *userdata;
-
- /*! Default constructor.*/
- inline ViewVertex()
- {
- userdata = NULL;
- _Nature = Nature::VIEW_VERTEX;
- }
-
- inline ViewVertex(Nature::VertexNature nature)
- {
- userdata = NULL;
- _Nature = Nature::VIEW_VERTEX | nature;
- }
-
-protected:
- /*! Copy constructor. */
- inline ViewVertex(ViewVertex& iBrother)
- {
- _Nature = iBrother._Nature;
- iBrother.userdata = this;
- userdata = NULL;
- }
-
- /*! Cloning method. */
- virtual ViewVertex *duplicate() = 0;
-
-public:
- /*! Destructor. */
- virtual ~ViewVertex() {}
-
- /* accessors */
- /*! Returns the nature of the vertex .*/
- virtual Nature::VertexNature getNature() const
- {
- return _Nature;
- }
-
- /* modifiers */
- /*! Sets the nature of the vertex. */
- inline void setNature(Nature::VertexNature iNature)
- {
- _Nature = iNature;
- }
-
- /* Replaces old edge by new edge */
- virtual void Replace(ViewEdge *, ViewEdge *) {}
-
-public:
- /* iterators access */
- // allows iteration on the edges that comes from/goes to this vertex in CCW order (order defined in 2D in the
- // image plan)
- virtual edge_iterator edges_begin() = 0;
- virtual const_edge_iterator edges_begin() const = 0;
- virtual edge_iterator edges_end() = 0;
- virtual const_edge_iterator edges_end() const = 0;
- virtual edge_iterator edges_iterator(ViewEdge *iEdge) = 0;
- virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const = 0;
-
- // Iterator access
- /*! Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to the first
- * ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges
- * and to get the orientation for each ViewEdge (incoming/outgoing).
- */
- virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() = 0;
-
- /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after the last ViewEdge.
- */
- virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() = 0;
-
- /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
- virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) = 0;
+class ViewVertex : public Interface0D {
+ public: // Implementation of Interface0D
+ /*! Returns the string "ViewVertex". */
+ virtual string getExactTypeName() const
+ {
+ return "ViewVertex";
+ }
+
+ public:
+ friend class ViewShape;
+ typedef pair<ViewEdge *, bool> directedViewEdge; // if bool = true, the ViewEdge is incoming
+
+ typedef vector<directedViewEdge> edges_container;
+
+ typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_nonconst_traits>
+ edge_iterator;
+ typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_const_traits>
+ const_edge_iterator;
+
+ private:
+ Nature::VertexNature _Nature;
+
+ public:
+ /*! A field that can be used by the user to store any data.
+ * This field must be reseted afterwards using ResetUserData().
+ */
+ void *userdata;
+
+ /*! Default constructor.*/
+ inline ViewVertex()
+ {
+ userdata = NULL;
+ _Nature = Nature::VIEW_VERTEX;
+ }
+
+ inline ViewVertex(Nature::VertexNature nature)
+ {
+ userdata = NULL;
+ _Nature = Nature::VIEW_VERTEX | nature;
+ }
+
+ protected:
+ /*! Copy constructor. */
+ inline ViewVertex(ViewVertex &iBrother)
+ {
+ _Nature = iBrother._Nature;
+ iBrother.userdata = this;
+ userdata = NULL;
+ }
+
+ /*! Cloning method. */
+ virtual ViewVertex *duplicate() = 0;
+
+ public:
+ /*! Destructor. */
+ virtual ~ViewVertex()
+ {
+ }
+
+ /* accessors */
+ /*! Returns the nature of the vertex .*/
+ virtual Nature::VertexNature getNature() const
+ {
+ return _Nature;
+ }
+
+ /* modifiers */
+ /*! Sets the nature of the vertex. */
+ inline void setNature(Nature::VertexNature iNature)
+ {
+ _Nature = iNature;
+ }
+
+ /* Replaces old edge by new edge */
+ virtual void Replace(ViewEdge *, ViewEdge *)
+ {
+ }
+
+ public:
+ /* iterators access */
+ // allows iteration on the edges that comes from/goes to this vertex in CCW order (order defined in 2D in the
+ // image plan)
+ virtual edge_iterator edges_begin() = 0;
+ virtual const_edge_iterator edges_begin() const = 0;
+ virtual edge_iterator edges_end() = 0;
+ virtual const_edge_iterator edges_end() const = 0;
+ virtual edge_iterator edges_iterator(ViewEdge *iEdge) = 0;
+ virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const = 0;
+
+ // Iterator access
+ /*! Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to the first
+ * ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges
+ * and to get the orientation for each ViewEdge (incoming/outgoing).
+ */
+ virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() = 0;
+
+ /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after the last ViewEdge.
+ */
+ virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() = 0;
+
+ /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
+ virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) = 0;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewVertex")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewVertex")
#endif
};
@@ -382,265 +390,264 @@ public:
* Basically the front edge hides part of the back edge.
* So, among the back edges, 1 is of invisibility n and the other of visibility n+1
*/
-class TVertex : public ViewVertex
-{
-public:
- typedef vector<directedViewEdge*> edge_pointers_container;
-
-public: // Implementation of Interface0D
- /*! Returns the string "TVertex". */
- virtual string getExactTypeName() const
- {
- return "TVertex";
- }
-
- // Data access methods
- /* Returns the 3D x coordinate of the vertex. Ambiguous in this case. */
- virtual real getX() const
- {
- cerr << "Warning: getX() undefined for this point" << endl;
- return _FrontSVertex->point3D().x();
- }
-
- virtual real getY() const
- {
- cerr << "Warning: getX() undefined for this point" << endl;
- return _FrontSVertex->point3D().y();
- }
-
- virtual real getZ() const
- {
- cerr << "Warning: getX() undefined for this point" << endl;
- return _FrontSVertex->point3D().z();
- }
-
- /*! Returns the 3D point. */
- virtual Vec3r getPoint3D() const
- {
- cerr << "Warning: getPoint3D() undefined for this point" << endl;
- return _FrontSVertex->getPoint3D();
- }
-
- /*! Returns the projected 3D x coordinate of the vertex. */
- virtual real getProjectedX() const
- {
- return _FrontSVertex->point2D().x();
- }
-
- /*! Returns the projected 3D y coordinate of the vertex. */
- virtual real getProjectedY() const
- {
- return _FrontSVertex->point2D().y();
- }
-
- virtual real getProjectedZ() const
- {
- return _FrontSVertex->point2D().z();
- }
-
- /*! Returns the 2D point. */
- virtual Vec2r getPoint2D() const
- {
- return _FrontSVertex->getPoint2D();
- }
-
- /*! Returns the Id of the TVertex. */
- virtual Id getId() const
- {
- return _Id;
- }
-
- /*! Cast the Interface0D in SVertex if it can be. */
- // it can't
- virtual ViewVertex *castToViewVertex()
- {
- return this;
- }
-
- /*! Cast the Interface0D in TVertex if it can be. */
- virtual TVertex *castToTVertex()
- {
- return this;
- }
-
-private:
- SVertex *_FrontSVertex;
- SVertex *_BackSVertex;
- directedViewEdge _FrontEdgeA;
- directedViewEdge _FrontEdgeB;
- directedViewEdge _BackEdgeA;
- directedViewEdge _BackEdgeB;
- Id _Id; // id to identify t vertices . these id will be negative in order not to be mixed with NonTVertex ids.
- edge_pointers_container _sortedEdges; // the list of the four ViewEdges, ordered in CCW order (in the image plan)
-
-public:
- /*! Default constructor.*/
- inline TVertex() : ViewVertex(Nature::T_VERTEX)
- {
- _FrontSVertex = NULL;
- _BackSVertex = NULL;
- _FrontEdgeA.first = 0;
- _FrontEdgeB.first = 0;
- _BackEdgeA.first = 0;
- _BackEdgeB.first = 0;
- }
-
- inline TVertex(SVertex *svFront, SVertex *svBack) : ViewVertex(Nature::T_VERTEX)
- {
- _FrontSVertex = svFront;
- _BackSVertex = svBack;
- _FrontEdgeA.first = 0;
- _FrontEdgeB.first = 0;
- _BackEdgeA.first = 0;
- _BackEdgeB.first = 0;
- svFront->setViewVertex(this);
- svBack->setViewVertex(this);
- }
-
-protected:
- /*! Copy constructor. */
- inline TVertex(TVertex& iBrother) : ViewVertex(iBrother)
- {
- _FrontSVertex = iBrother._FrontSVertex;
- _BackSVertex = iBrother._BackSVertex;
- _FrontEdgeA = iBrother._FrontEdgeA;
- _FrontEdgeB = iBrother._FrontEdgeB;
- _BackEdgeA = iBrother._BackEdgeA;
- _BackEdgeB = iBrother._BackEdgeB;
- _sortedEdges = iBrother._sortedEdges;
- }
-
- /*! Cloning method. */
- virtual ViewVertex *duplicate()
- {
- TVertex *clone = new TVertex(*this);
- return clone;
- }
-
-public:
- /* accessors */
- /*! Returns the SVertex that is closer to the viewpoint. */
- inline SVertex *frontSVertex()
- {
- return _FrontSVertex;
- }
-
- /*! Returns the SVertex that is further away from the viewpoint. */
- inline SVertex *backSVertex()
- {
- return _BackSVertex;
- }
-
- inline directedViewEdge& frontEdgeA()
- {
- return _FrontEdgeA;
- }
-
- inline directedViewEdge& frontEdgeB()
- {
- return _FrontEdgeB;
- }
-
- inline directedViewEdge& backEdgeA()
- {
- return _BackEdgeA;
- }
-
- inline directedViewEdge& backEdgeB()
- {
- return _BackEdgeB;
- }
-
- /* modifiers */
- /*! Sets the SVertex that is closer to the viewpoint. */
- inline void setFrontSVertex(SVertex *iFrontSVertex)
- {
- _FrontSVertex = iFrontSVertex;
- _FrontSVertex->setViewVertex(this);
- }
-
- /*! Sets the SVertex that is further away from the viewpoint. */
- inline void setBackSVertex(SVertex *iBackSVertex)
- {
- _BackSVertex = iBackSVertex;
- _BackSVertex->setViewVertex(this);
- }
-
- void setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming = true);
- void setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming = true);
- void setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming = true);
- void setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming = true);
-
- /*! Sets the Id. */
- inline void setId(const Id& iId)
- {
- _Id = iId;
- }
-
- /*! Returns the SVertex (among the 2) belonging to the FEdge iFEdge */
- inline SVertex *getSVertex(FEdge *iFEdge)
- {
- const vector<FEdge*>& vfEdges = _FrontSVertex->fedges();
- vector<FEdge*>::const_iterator fe, fend;
- for (fe = vfEdges.begin(), fend = vfEdges.end(); fe != fend; fe++) {
- if ((*fe) == iFEdge)
- return _FrontSVertex;
- }
-
- const vector<FEdge*>& vbEdges = _BackSVertex->fedges();
- for (fe = vbEdges.begin(), fend = vbEdges.end(); fe != fend; fe++) {
- if ((*fe) == iFEdge)
- return _BackSVertex;
- }
- return NULL;
- }
-
- virtual void Replace(ViewEdge *iOld, ViewEdge *iNew);
-
- /*! returns the mate edge of iEdgeA.
- * For example, if iEdgeA is frontEdgeA, then frontEdgeB is returned. If iEdgeA is frontEdgeB then frontEdgeA
- * is returned. Same for back edges
- */
- virtual ViewEdge *mate(ViewEdge *iEdgeA)
- {
- if (iEdgeA == _FrontEdgeA.first)
- return _FrontEdgeB.first;
- if (iEdgeA == _FrontEdgeB.first)
- return _FrontEdgeA.first;
- if (iEdgeA == _BackEdgeA.first)
- return _BackEdgeB.first;
- if (iEdgeA == _BackEdgeB.first)
- return _BackEdgeA.first;
- return NULL;
- }
-
- /* iterators access */
- virtual edge_iterator edges_begin();
- virtual const_edge_iterator edges_begin() const;
- virtual edge_iterator edges_end();
- virtual const_edge_iterator edges_end() const;
- virtual edge_iterator edges_iterator(ViewEdge *iEdge);
- virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const;
-
- /*! Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to the first
- * ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges
- * and to get the orientation for each ViewEdge (incoming/outgoing).
- */
- virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin();
-
- /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after the last ViewEdge.
- */
- virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd();
-
- /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
- virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge);
+class TVertex : public ViewVertex {
+ public:
+ typedef vector<directedViewEdge *> edge_pointers_container;
+
+ public: // Implementation of Interface0D
+ /*! Returns the string "TVertex". */
+ virtual string getExactTypeName() const
+ {
+ return "TVertex";
+ }
+
+ // Data access methods
+ /* Returns the 3D x coordinate of the vertex. Ambiguous in this case. */
+ virtual real getX() const
+ {
+ cerr << "Warning: getX() undefined for this point" << endl;
+ return _FrontSVertex->point3D().x();
+ }
+
+ virtual real getY() const
+ {
+ cerr << "Warning: getX() undefined for this point" << endl;
+ return _FrontSVertex->point3D().y();
+ }
+
+ virtual real getZ() const
+ {
+ cerr << "Warning: getX() undefined for this point" << endl;
+ return _FrontSVertex->point3D().z();
+ }
+
+ /*! Returns the 3D point. */
+ virtual Vec3r getPoint3D() const
+ {
+ cerr << "Warning: getPoint3D() undefined for this point" << endl;
+ return _FrontSVertex->getPoint3D();
+ }
+
+ /*! Returns the projected 3D x coordinate of the vertex. */
+ virtual real getProjectedX() const
+ {
+ return _FrontSVertex->point2D().x();
+ }
+
+ /*! Returns the projected 3D y coordinate of the vertex. */
+ virtual real getProjectedY() const
+ {
+ return _FrontSVertex->point2D().y();
+ }
+
+ virtual real getProjectedZ() const
+ {
+ return _FrontSVertex->point2D().z();
+ }
+
+ /*! Returns the 2D point. */
+ virtual Vec2r getPoint2D() const
+ {
+ return _FrontSVertex->getPoint2D();
+ }
+
+ /*! Returns the Id of the TVertex. */
+ virtual Id getId() const
+ {
+ return _Id;
+ }
+
+ /*! Cast the Interface0D in SVertex if it can be. */
+ // it can't
+ virtual ViewVertex *castToViewVertex()
+ {
+ return this;
+ }
+
+ /*! Cast the Interface0D in TVertex if it can be. */
+ virtual TVertex *castToTVertex()
+ {
+ return this;
+ }
+
+ private:
+ SVertex *_FrontSVertex;
+ SVertex *_BackSVertex;
+ directedViewEdge _FrontEdgeA;
+ directedViewEdge _FrontEdgeB;
+ directedViewEdge _BackEdgeA;
+ directedViewEdge _BackEdgeB;
+ Id _Id; // id to identify t vertices . these id will be negative in order not to be mixed with NonTVertex ids.
+ edge_pointers_container
+ _sortedEdges; // the list of the four ViewEdges, ordered in CCW order (in the image plan)
+
+ public:
+ /*! Default constructor.*/
+ inline TVertex() : ViewVertex(Nature::T_VERTEX)
+ {
+ _FrontSVertex = NULL;
+ _BackSVertex = NULL;
+ _FrontEdgeA.first = 0;
+ _FrontEdgeB.first = 0;
+ _BackEdgeA.first = 0;
+ _BackEdgeB.first = 0;
+ }
+
+ inline TVertex(SVertex *svFront, SVertex *svBack) : ViewVertex(Nature::T_VERTEX)
+ {
+ _FrontSVertex = svFront;
+ _BackSVertex = svBack;
+ _FrontEdgeA.first = 0;
+ _FrontEdgeB.first = 0;
+ _BackEdgeA.first = 0;
+ _BackEdgeB.first = 0;
+ svFront->setViewVertex(this);
+ svBack->setViewVertex(this);
+ }
+
+ protected:
+ /*! Copy constructor. */
+ inline TVertex(TVertex &iBrother) : ViewVertex(iBrother)
+ {
+ _FrontSVertex = iBrother._FrontSVertex;
+ _BackSVertex = iBrother._BackSVertex;
+ _FrontEdgeA = iBrother._FrontEdgeA;
+ _FrontEdgeB = iBrother._FrontEdgeB;
+ _BackEdgeA = iBrother._BackEdgeA;
+ _BackEdgeB = iBrother._BackEdgeB;
+ _sortedEdges = iBrother._sortedEdges;
+ }
+
+ /*! Cloning method. */
+ virtual ViewVertex *duplicate()
+ {
+ TVertex *clone = new TVertex(*this);
+ return clone;
+ }
+
+ public:
+ /* accessors */
+ /*! Returns the SVertex that is closer to the viewpoint. */
+ inline SVertex *frontSVertex()
+ {
+ return _FrontSVertex;
+ }
+
+ /*! Returns the SVertex that is further away from the viewpoint. */
+ inline SVertex *backSVertex()
+ {
+ return _BackSVertex;
+ }
+
+ inline directedViewEdge &frontEdgeA()
+ {
+ return _FrontEdgeA;
+ }
+
+ inline directedViewEdge &frontEdgeB()
+ {
+ return _FrontEdgeB;
+ }
+
+ inline directedViewEdge &backEdgeA()
+ {
+ return _BackEdgeA;
+ }
+
+ inline directedViewEdge &backEdgeB()
+ {
+ return _BackEdgeB;
+ }
+
+ /* modifiers */
+ /*! Sets the SVertex that is closer to the viewpoint. */
+ inline void setFrontSVertex(SVertex *iFrontSVertex)
+ {
+ _FrontSVertex = iFrontSVertex;
+ _FrontSVertex->setViewVertex(this);
+ }
+
+ /*! Sets the SVertex that is further away from the viewpoint. */
+ inline void setBackSVertex(SVertex *iBackSVertex)
+ {
+ _BackSVertex = iBackSVertex;
+ _BackSVertex->setViewVertex(this);
+ }
+
+ void setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming = true);
+ void setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming = true);
+ void setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming = true);
+ void setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming = true);
+
+ /*! Sets the Id. */
+ inline void setId(const Id &iId)
+ {
+ _Id = iId;
+ }
+
+ /*! Returns the SVertex (among the 2) belonging to the FEdge iFEdge */
+ inline SVertex *getSVertex(FEdge *iFEdge)
+ {
+ const vector<FEdge *> &vfEdges = _FrontSVertex->fedges();
+ vector<FEdge *>::const_iterator fe, fend;
+ for (fe = vfEdges.begin(), fend = vfEdges.end(); fe != fend; fe++) {
+ if ((*fe) == iFEdge)
+ return _FrontSVertex;
+ }
+
+ const vector<FEdge *> &vbEdges = _BackSVertex->fedges();
+ for (fe = vbEdges.begin(), fend = vbEdges.end(); fe != fend; fe++) {
+ if ((*fe) == iFEdge)
+ return _BackSVertex;
+ }
+ return NULL;
+ }
+
+ virtual void Replace(ViewEdge *iOld, ViewEdge *iNew);
+
+ /*! returns the mate edge of iEdgeA.
+ * For example, if iEdgeA is frontEdgeA, then frontEdgeB is returned. If iEdgeA is frontEdgeB then frontEdgeA
+ * is returned. Same for back edges
+ */
+ virtual ViewEdge *mate(ViewEdge *iEdgeA)
+ {
+ if (iEdgeA == _FrontEdgeA.first)
+ return _FrontEdgeB.first;
+ if (iEdgeA == _FrontEdgeB.first)
+ return _FrontEdgeA.first;
+ if (iEdgeA == _BackEdgeA.first)
+ return _BackEdgeB.first;
+ if (iEdgeA == _BackEdgeB.first)
+ return _BackEdgeA.first;
+ return NULL;
+ }
+
+ /* iterators access */
+ virtual edge_iterator edges_begin();
+ virtual const_edge_iterator edges_begin() const;
+ virtual edge_iterator edges_end();
+ virtual const_edge_iterator edges_end() const;
+ virtual edge_iterator edges_iterator(ViewEdge *iEdge);
+ virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const;
+
+ /*! Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to the first
+ * ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges
+ * and to get the orientation for each ViewEdge (incoming/outgoing).
+ */
+ virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin();
+
+ /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after the last ViewEdge.
+ */
+ virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd();
+
+ /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
+ virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge);
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TVertex")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TVertex")
#endif
};
-
/**********************************/
/* */
/* */
@@ -649,210 +656,212 @@ public:
/* */
/**********************************/
-
// (non T vertex)
/*! View vertex for corners, cusps, etc...
* Associated to a single SVertex.
* Can be associated to 2 or several view edges
*/
-class NonTVertex : public ViewVertex
-{
-public:
- typedef vector<directedViewEdge> edges_container;
-
-public: // Implementation of Interface0D
- /*! Returns the string "ViewVertex". */
- virtual string getExactTypeName() const
- {
- return "NonTVertex";
- }
-
- // Data access methods
- /*! Returns the 3D x coordinate of the vertex. */
- virtual real getX() const
- {
- return _SVertex->point3D().x();
- }
-
- /*! Returns the 3D y coordinate of the vertex. */
- virtual real getY() const
- {
- return _SVertex->point3D().y();
- }
-
- /*! Returns the 3D z coordinate of the vertex. */
- virtual real getZ() const
- {
- return _SVertex->point3D().z();
- }
-
- /*! Returns the 3D point. */
- virtual Vec3r getPoint3D() const
- {
- return _SVertex->getPoint3D();
- }
-
- /*! Returns the projected 3D x coordinate of the vertex. */
- virtual real getProjectedX() const
- {
- return _SVertex->point2D().x();
- }
-
- /*! Returns the projected 3D y coordinate of the vertex. */
- virtual real getProjectedY() const
- {
- return _SVertex->point2D().y();
- }
-
- /*! Returns the projected 3D z coordinate of the vertex. */
- virtual real getProjectedZ() const
- {
- return _SVertex->point2D().z();
- }
-
- /*! Returns the 2D point. */
- virtual Vec2r getPoint2D() const
- {
- return _SVertex->getPoint2D();
- }
-
- /*! Returns the Id of the vertex. */
- virtual Id getId() const
- {
- return _SVertex->getId();
- }
-
- /*! Cast the Interface0D in SVertex if it can be. */
- virtual SVertex *castToSVertex()
- {
- return _SVertex;
- }
-
- /*! Cast the Interface0D in ViewVertex if it can be. */
- virtual ViewVertex *castToViewVertex()
- {
- return this;
- }
-
- /*! Cast the Interface0D in NonTVertex if it can be. */
- virtual NonTVertex *castToNonTVertex()
- {
- return this;
- }
-
-private:
- SVertex *_SVertex;
- edges_container _ViewEdges;
-
-public:
- /*! Default constructor.*/
- inline NonTVertex() : ViewVertex(Nature::NON_T_VERTEX)
- {
- _SVertex = NULL;
- }
-
- /*! Builds a NonTVertex from a SVertex. */
- inline NonTVertex(SVertex *iSVertex) : ViewVertex(Nature::NON_T_VERTEX)
- {
- _SVertex = iSVertex;
- _SVertex->setViewVertex(this);
- }
-
-protected:
- /*! Copy constructor. */
- inline NonTVertex(NonTVertex& iBrother) : ViewVertex(iBrother)
- {
- _SVertex = iBrother._SVertex;
- _SVertex->setViewVertex(this);
- _ViewEdges = iBrother._ViewEdges;
- }
-
- /*! Cloning method. */
- virtual ViewVertex *duplicate()
- {
- NonTVertex *clone = new NonTVertex(*this);
- return clone;
- }
-
-public:
- /*! destructor. */
- virtual ~NonTVertex() {}
-
- /* accessors */
- /*! Returns the SVertex on top of which this NonTVertex is built. */
- inline SVertex *svertex()
- {
- return _SVertex;
- }
-
- inline edges_container& viewedges()
- {
- return _ViewEdges;
- }
-
- /* modifiers */
- /*! Sets the SVertex on top of which this NonTVertex is built. */
- inline void setSVertex(SVertex *iSVertex)
- {
- _SVertex = iSVertex;
- _SVertex->setViewVertex(this);
- }
-
- inline void setViewEdges(const vector<directedViewEdge>& iViewEdges)
- {
- _ViewEdges = iViewEdges;
- }
-
- void AddIncomingViewEdge(ViewEdge *iVEdge);
- void AddOutgoingViewEdge(ViewEdge *iVEdge);
-
- inline void AddViewEdge(ViewEdge *iVEdge, bool incoming = true)
- {
- if (incoming)
- AddIncomingViewEdge(iVEdge);
- else
- AddOutgoingViewEdge(iVEdge);
- }
-
- /* Replaces old edge by new edge */
- virtual void Replace(ViewEdge *iOld, ViewEdge *iNew)
- {
- edges_container::iterator insertedve;
- for (edges_container::iterator ve = _ViewEdges.begin(), vend = _ViewEdges.end(); ve != vend; ve++) {
- if ((ve)->first == iOld) {
- insertedve = _ViewEdges.insert(ve, directedViewEdge(iNew, ve->second));// inserts e2 before ve.
- // returns an iterator pointing toward e2. ve is invalidated.
- // we want to remove e1, but we can't use ve anymore:
- insertedve++; // insertedve points now to e1
- _ViewEdges.erase(insertedve);
- return;
- }
- }
- }
-
- /* iterators access */
- virtual edge_iterator edges_begin();
- virtual const_edge_iterator edges_begin() const;
- virtual edge_iterator edges_end();
- virtual const_edge_iterator edges_end() const;
- virtual edge_iterator edges_iterator(ViewEdge *iEdge);
- virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const;
-
- /*! Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to the first
- * ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges
- * and to get the orientation for each ViewEdge (incoming/outgoing).
- */
- virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin();
-
- /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after the last ViewEdge.
- */
- virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd();
-
- /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
- virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge);
+class NonTVertex : public ViewVertex {
+ public:
+ typedef vector<directedViewEdge> edges_container;
+
+ public: // Implementation of Interface0D
+ /*! Returns the string "ViewVertex". */
+ virtual string getExactTypeName() const
+ {
+ return "NonTVertex";
+ }
+
+ // Data access methods
+ /*! Returns the 3D x coordinate of the vertex. */
+ virtual real getX() const
+ {
+ return _SVertex->point3D().x();
+ }
+
+ /*! Returns the 3D y coordinate of the vertex. */
+ virtual real getY() const
+ {
+ return _SVertex->point3D().y();
+ }
+
+ /*! Returns the 3D z coordinate of the vertex. */
+ virtual real getZ() const
+ {
+ return _SVertex->point3D().z();
+ }
+
+ /*! Returns the 3D point. */
+ virtual Vec3r getPoint3D() const
+ {
+ return _SVertex->getPoint3D();
+ }
+
+ /*! Returns the projected 3D x coordinate of the vertex. */
+ virtual real getProjectedX() const
+ {
+ return _SVertex->point2D().x();
+ }
+
+ /*! Returns the projected 3D y coordinate of the vertex. */
+ virtual real getProjectedY() const
+ {
+ return _SVertex->point2D().y();
+ }
+
+ /*! Returns the projected 3D z coordinate of the vertex. */
+ virtual real getProjectedZ() const
+ {
+ return _SVertex->point2D().z();
+ }
+
+ /*! Returns the 2D point. */
+ virtual Vec2r getPoint2D() const
+ {
+ return _SVertex->getPoint2D();
+ }
+
+ /*! Returns the Id of the vertex. */
+ virtual Id getId() const
+ {
+ return _SVertex->getId();
+ }
+
+ /*! Cast the Interface0D in SVertex if it can be. */
+ virtual SVertex *castToSVertex()
+ {
+ return _SVertex;
+ }
+
+ /*! Cast the Interface0D in ViewVertex if it can be. */
+ virtual ViewVertex *castToViewVertex()
+ {
+ return this;
+ }
+
+ /*! Cast the Interface0D in NonTVertex if it can be. */
+ virtual NonTVertex *castToNonTVertex()
+ {
+ return this;
+ }
+
+ private:
+ SVertex *_SVertex;
+ edges_container _ViewEdges;
+
+ public:
+ /*! Default constructor.*/
+ inline NonTVertex() : ViewVertex(Nature::NON_T_VERTEX)
+ {
+ _SVertex = NULL;
+ }
+
+ /*! Builds a NonTVertex from a SVertex. */
+ inline NonTVertex(SVertex *iSVertex) : ViewVertex(Nature::NON_T_VERTEX)
+ {
+ _SVertex = iSVertex;
+ _SVertex->setViewVertex(this);
+ }
+
+ protected:
+ /*! Copy constructor. */
+ inline NonTVertex(NonTVertex &iBrother) : ViewVertex(iBrother)
+ {
+ _SVertex = iBrother._SVertex;
+ _SVertex->setViewVertex(this);
+ _ViewEdges = iBrother._ViewEdges;
+ }
+
+ /*! Cloning method. */
+ virtual ViewVertex *duplicate()
+ {
+ NonTVertex *clone = new NonTVertex(*this);
+ return clone;
+ }
+
+ public:
+ /*! destructor. */
+ virtual ~NonTVertex()
+ {
+ }
+
+ /* accessors */
+ /*! Returns the SVertex on top of which this NonTVertex is built. */
+ inline SVertex *svertex()
+ {
+ return _SVertex;
+ }
+
+ inline edges_container &viewedges()
+ {
+ return _ViewEdges;
+ }
+
+ /* modifiers */
+ /*! Sets the SVertex on top of which this NonTVertex is built. */
+ inline void setSVertex(SVertex *iSVertex)
+ {
+ _SVertex = iSVertex;
+ _SVertex->setViewVertex(this);
+ }
+
+ inline void setViewEdges(const vector<directedViewEdge> &iViewEdges)
+ {
+ _ViewEdges = iViewEdges;
+ }
+
+ void AddIncomingViewEdge(ViewEdge *iVEdge);
+ void AddOutgoingViewEdge(ViewEdge *iVEdge);
+
+ inline void AddViewEdge(ViewEdge *iVEdge, bool incoming = true)
+ {
+ if (incoming)
+ AddIncomingViewEdge(iVEdge);
+ else
+ AddOutgoingViewEdge(iVEdge);
+ }
+
+ /* Replaces old edge by new edge */
+ virtual void Replace(ViewEdge *iOld, ViewEdge *iNew)
+ {
+ edges_container::iterator insertedve;
+ for (edges_container::iterator ve = _ViewEdges.begin(), vend = _ViewEdges.end(); ve != vend;
+ ve++) {
+ if ((ve)->first == iOld) {
+ insertedve = _ViewEdges.insert(
+ ve, directedViewEdge(iNew, ve->second)); // inserts e2 before ve.
+ // returns an iterator pointing toward e2. ve is invalidated.
+ // we want to remove e1, but we can't use ve anymore:
+ insertedve++; // insertedve points now to e1
+ _ViewEdges.erase(insertedve);
+ return;
+ }
+ }
+ }
+
+ /* iterators access */
+ virtual edge_iterator edges_begin();
+ virtual const_edge_iterator edges_begin() const;
+ virtual edge_iterator edges_end();
+ virtual const_edge_iterator edges_end() const;
+ virtual edge_iterator edges_iterator(ViewEdge *iEdge);
+ virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const;
+
+ /*! Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to the first
+ * ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges
+ * and to get the orientation for each ViewEdge (incoming/outgoing).
+ */
+ virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin();
+
+ /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after the last ViewEdge.
+ */
+ virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd();
+
+ /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
+ virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge);
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NonTVertex")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NonTVertex")
#endif
};
@@ -880,502 +889,499 @@ template<class Traits> class edge_iterator_base;
template<class Traits> class fedge_iterator_base;
template<class Traits> class vertex_iterator_base;
-} // end of namespace ViewEdgeInternal
+} // end of namespace ViewEdgeInternal
/*! Class defining a ViewEdge. A ViewEdge in an edge of the image graph. it connects two ViewVertex.
* It is made by connecting a set of FEdges.
*/
-class ViewEdge : public Interface1D
-{
-public: // Implementation of Interface0D
- /*! Returns the string "ViewEdge". */
- virtual string getExactTypeName() const
- {
- return "ViewEdge";
- }
-
- // Data access methods
- /*! Returns the Id of the vertex. */
- virtual Id getId() const
- {
- return _Id;
- }
-
- /*! Returns the nature of the ViewEdge. */
- virtual Nature::EdgeNature getNature() const
- {
- return _Nature;
- }
-
-public:
- typedef SVertex vertex_type;
- friend class ViewShape;
- // for ViewEdge iterator
- typedef ViewEdgeInternal::edge_iterator_base<Nonconst_traits<ViewEdge*> > edge_iterator;
- typedef ViewEdgeInternal::edge_iterator_base<Const_traits<ViewEdge*> > const_edge_iterator;
- // for fedge iterator
- typedef ViewEdgeInternal::fedge_iterator_base<Nonconst_traits<FEdge*> > fedge_iterator;
- typedef ViewEdgeInternal::fedge_iterator_base<Const_traits<FEdge*> > const_fedge_iterator;
- // for svertex iterator
- typedef ViewEdgeInternal::vertex_iterator_base<Nonconst_traits<SVertex*> > vertex_iterator;
- typedef ViewEdgeInternal::vertex_iterator_base<Const_traits<SVertex*> > const_vertex_iterator;
-
-private:
- ViewVertex *__A; // edge starting vertex
- ViewVertex *__B; // edge ending vertex
- Nature::EdgeNature _Nature; // nature of view edge
- ViewShape *_Shape; // shape to which the view edge belongs
- FEdge *_FEdgeA; // first edge of the embedded fedges chain
- FEdge *_FEdgeB; // last edge of the embedded fedges chain
- Id _Id;
- unsigned _ChainingTimeStamp;
- // The silhouette view edge separates 2 2D spaces. The one on the left is necessarly the Shape _Shape (the one to
- // which this edge belongs to) and _aShape is the one on its right
- // NOT HANDLED BY THE COPY CONSTRUCTOR
- ViewShape *_aShape;
- int _qi;
- vector<ViewShape*> _Occluders;
- bool _isInImage;
-
- // tmp
- Id *_splittingId;
-
-public:
- /*! A field that can be used by the user to store any data.
- * This field must be reseted afterwards using ResetUserData().
- */
- void *userdata;
-
- /*! Default constructor. */
- inline ViewEdge()
- {
- __A = NULL;
- __B = NULL;
- _FEdgeA = NULL;
- _FEdgeB = NULL;
- _ChainingTimeStamp = 0;
- _qi = 0;
- _aShape = NULL;
- userdata = NULL;
- _splittingId = NULL;
- _isInImage = true;
- }
-
- inline ViewEdge(ViewVertex *iA, ViewVertex *iB)
- {
- __A = iA;
- __B = iB;
- _FEdgeA = NULL;
- _FEdgeB = NULL;
- _Shape = 0;
- _ChainingTimeStamp = 0;
- _qi = 0;
- _aShape = NULL;
- userdata = NULL;
- _splittingId = NULL;
- _isInImage = true;
- }
-
- inline ViewEdge(ViewVertex *iA, ViewVertex *iB, FEdge *iFEdgeA)
- {
- __A = iA;
- __B = iB;
- _FEdgeA = iFEdgeA;
- _FEdgeB = NULL;
- _Shape = NULL;
- _ChainingTimeStamp = 0;
- _qi = 0;
- _aShape = NULL;
- userdata = NULL;
- _splittingId = NULL;
- _isInImage = true;
- }
-
- inline ViewEdge(ViewVertex *iA, ViewVertex *iB, FEdge *iFEdgeA, FEdge *iFEdgeB, ViewShape *iShape)
- {
- __A = iA;
- __B = iB;
- _FEdgeA = iFEdgeA;
- _FEdgeB = iFEdgeB;
- _Shape = iShape;
- _ChainingTimeStamp = 0;
- _qi = 0;
- _aShape = NULL;
- userdata = NULL;
- _splittingId = NULL;
- _isInImage = true;
- UpdateFEdges(); // tells every FEdge between iFEdgeA and iFEdgeB that this is theit ViewEdge
- }
-
-//soc protected:
- /*! Copy constructor. */
- inline ViewEdge(ViewEdge& iBrother)
- {
- __A = iBrother.__A;
- __B = iBrother.__B;
- _FEdgeA = iBrother._FEdgeA;
- _FEdgeB = iBrother._FEdgeB;
- _Nature = iBrother._Nature;
- _Shape = NULL;
- _Id = iBrother._Id;
- _ChainingTimeStamp = iBrother._ChainingTimeStamp;
- _aShape = iBrother._aShape;
- _qi = iBrother._qi;
- _splittingId = NULL;
- _isInImage = iBrother._isInImage;
- iBrother.userdata = this;
- userdata = NULL;
- }
-
- /*! Cloning method. */
- virtual ViewEdge *duplicate()
- {
- ViewEdge *clone = new ViewEdge(*this);
- return clone;
- }
-
-public:
- /*! Destructor. */
- virtual ~ViewEdge()
- {
+class ViewEdge : public Interface1D {
+ public: // Implementation of Interface0D
+ /*! Returns the string "ViewEdge". */
+ virtual string getExactTypeName() const
+ {
+ return "ViewEdge";
+ }
+
+ // Data access methods
+ /*! Returns the Id of the vertex. */
+ virtual Id getId() const
+ {
+ return _Id;
+ }
+
+ /*! Returns the nature of the ViewEdge. */
+ virtual Nature::EdgeNature getNature() const
+ {
+ return _Nature;
+ }
+
+ public:
+ typedef SVertex vertex_type;
+ friend class ViewShape;
+ // for ViewEdge iterator
+ typedef ViewEdgeInternal::edge_iterator_base<Nonconst_traits<ViewEdge *>> edge_iterator;
+ typedef ViewEdgeInternal::edge_iterator_base<Const_traits<ViewEdge *>> const_edge_iterator;
+ // for fedge iterator
+ typedef ViewEdgeInternal::fedge_iterator_base<Nonconst_traits<FEdge *>> fedge_iterator;
+ typedef ViewEdgeInternal::fedge_iterator_base<Const_traits<FEdge *>> const_fedge_iterator;
+ // for svertex iterator
+ typedef ViewEdgeInternal::vertex_iterator_base<Nonconst_traits<SVertex *>> vertex_iterator;
+ typedef ViewEdgeInternal::vertex_iterator_base<Const_traits<SVertex *>> const_vertex_iterator;
+
+ private:
+ ViewVertex *__A; // edge starting vertex
+ ViewVertex *__B; // edge ending vertex
+ Nature::EdgeNature _Nature; // nature of view edge
+ ViewShape *_Shape; // shape to which the view edge belongs
+ FEdge *_FEdgeA; // first edge of the embedded fedges chain
+ FEdge *_FEdgeB; // last edge of the embedded fedges chain
+ Id _Id;
+ unsigned _ChainingTimeStamp;
+ // The silhouette view edge separates 2 2D spaces. The one on the left is necessarly the Shape _Shape (the one to
+ // which this edge belongs to) and _aShape is the one on its right
+ // NOT HANDLED BY THE COPY CONSTRUCTOR
+ ViewShape *_aShape;
+ int _qi;
+ vector<ViewShape *> _Occluders;
+ bool _isInImage;
+
+ // tmp
+ Id *_splittingId;
+
+ public:
+ /*! A field that can be used by the user to store any data.
+ * This field must be reseted afterwards using ResetUserData().
+ */
+ void *userdata;
+
+ /*! Default constructor. */
+ inline ViewEdge()
+ {
+ __A = NULL;
+ __B = NULL;
+ _FEdgeA = NULL;
+ _FEdgeB = NULL;
+ _ChainingTimeStamp = 0;
+ _qi = 0;
+ _aShape = NULL;
+ userdata = NULL;
+ _splittingId = NULL;
+ _isInImage = true;
+ }
+
+ inline ViewEdge(ViewVertex *iA, ViewVertex *iB)
+ {
+ __A = iA;
+ __B = iB;
+ _FEdgeA = NULL;
+ _FEdgeB = NULL;
+ _Shape = 0;
+ _ChainingTimeStamp = 0;
+ _qi = 0;
+ _aShape = NULL;
+ userdata = NULL;
+ _splittingId = NULL;
+ _isInImage = true;
+ }
+
+ inline ViewEdge(ViewVertex *iA, ViewVertex *iB, FEdge *iFEdgeA)
+ {
+ __A = iA;
+ __B = iB;
+ _FEdgeA = iFEdgeA;
+ _FEdgeB = NULL;
+ _Shape = NULL;
+ _ChainingTimeStamp = 0;
+ _qi = 0;
+ _aShape = NULL;
+ userdata = NULL;
+ _splittingId = NULL;
+ _isInImage = true;
+ }
+
+ inline ViewEdge(
+ ViewVertex *iA, ViewVertex *iB, FEdge *iFEdgeA, FEdge *iFEdgeB, ViewShape *iShape)
+ {
+ __A = iA;
+ __B = iB;
+ _FEdgeA = iFEdgeA;
+ _FEdgeB = iFEdgeB;
+ _Shape = iShape;
+ _ChainingTimeStamp = 0;
+ _qi = 0;
+ _aShape = NULL;
+ userdata = NULL;
+ _splittingId = NULL;
+ _isInImage = true;
+ UpdateFEdges(); // tells every FEdge between iFEdgeA and iFEdgeB that this is theit ViewEdge
+ }
+
+ //soc protected:
+ /*! Copy constructor. */
+ inline ViewEdge(ViewEdge &iBrother)
+ {
+ __A = iBrother.__A;
+ __B = iBrother.__B;
+ _FEdgeA = iBrother._FEdgeA;
+ _FEdgeB = iBrother._FEdgeB;
+ _Nature = iBrother._Nature;
+ _Shape = NULL;
+ _Id = iBrother._Id;
+ _ChainingTimeStamp = iBrother._ChainingTimeStamp;
+ _aShape = iBrother._aShape;
+ _qi = iBrother._qi;
+ _splittingId = NULL;
+ _isInImage = iBrother._isInImage;
+ iBrother.userdata = this;
+ userdata = NULL;
+ }
+
+ /*! Cloning method. */
+ virtual ViewEdge *duplicate()
+ {
+ ViewEdge *clone = new ViewEdge(*this);
+ return clone;
+ }
+
+ public:
+ /*! Destructor. */
+ virtual ~ViewEdge()
+ {
#if 0
- if (_aFace) {
- delete _aFace;
- _aFace = NULL;
- }
+ if (_aFace) {
+ delete _aFace;
+ _aFace = NULL;
+ }
#endif
- // only the last splitted deletes this id
- if (_splittingId) {
- if (*_splittingId == _Id)
- delete _splittingId;
- }
- }
-
- /* accessors */
- /*! Returns the first ViewVertex. */
- inline ViewVertex *A()
- {
- return __A;
- }
-
- /*! Returns the second ViewVertex. */
- inline ViewVertex *B()
- {
- return __B;
- }
-
- /*! Returns the first FEdge that constitues this ViewEdge. */
- inline FEdge *fedgeA()
- {
- return _FEdgeA;
- }
-
- /*! Returns the last FEdge that constitues this ViewEdge. */
- inline FEdge *fedgeB()
- {
- return _FEdgeB;
- }
-
- /*! Returns the ViewShape to which this ViewEdge belongs to .*/
- inline ViewShape *viewShape()
- {
- return _Shape;
- }
-
- /*! Returns the shape that is occluded by the ViewShape to which this ViewEdge belongs to. If no object is occluded,
- * NULL is returned.
- * \return The occluded ViewShape.
- */
- inline ViewShape *aShape()
- {
- return _aShape;
- }
-
- /*! Tells whether this ViewEdge forms a closed loop or not. */
- inline bool isClosed()
- {
- if (!__B)
- return true;
- return false;
- }
-
- /*! Returns the time stamp of this ViewEdge. */
- inline unsigned getChainingTimeStamp()
- {
- return _ChainingTimeStamp;
- }
-
- inline const ViewShape *aShape() const
- {
- return _aShape;
- }
-
- inline const ViewShape *bShape() const
- {
- return _Shape;
- }
-
- inline vector<ViewShape*>& occluders()
- {
- return _Occluders;
- }
-
- inline Id *splittingId()
- {
- return _splittingId;
- }
-
- inline bool isInImage() const
- {
- return _isInImage;
- }
-
- /* modifiers */
- /*! Sets the first ViewVertex of the ViewEdge. */
- inline void setA(ViewVertex *iA)
- {
- __A = iA;
- }
-
- /*! Sets the last ViewVertex of the ViewEdge. */
- inline void setB(ViewVertex *iB)
- {
- __B = iB;
- }
-
- /*! Sets the nature of the ViewEdge. */
- inline void setNature(Nature::EdgeNature iNature)
- {
- _Nature = iNature;
- }
-
- /*! Sets the first FEdge of the ViewEdge. */
- inline void setFEdgeA(FEdge *iFEdge)
- {
- _FEdgeA = iFEdge;
- }
-
- /*! Sets the last FEdge of the ViewEdge. */
- inline void setFEdgeB(FEdge *iFEdge)
- {
- _FEdgeB = iFEdge;
- }
-
- /*! Sets the ViewShape to which this ViewEdge belongs to.*/
- inline void setShape(ViewShape *iVShape)
- {
- _Shape = iVShape;
- }
-
- /*! Sets the ViewEdge id. */
- inline void setId(const Id& id)
- {
- _Id = id;
- }
-
- /*! Sets Viewedge to this for all embedded fedges */
- void UpdateFEdges();
-
- /*! Sets the occluded ViewShape */
- inline void setaShape(ViewShape *iShape)
- {
- _aShape = iShape;
- }
-
- /*! Sets the quantitative invisibility value. */
- inline void setQI(int qi)
- {
- _qi = qi;
- }
-
- /*! Sets the time stamp value. */
- inline void setChainingTimeStamp(unsigned ts)
- {
- _ChainingTimeStamp = ts;
- }
-
- inline void AddOccluder(ViewShape *iShape)
- {
- _Occluders.push_back(iShape);
- }
-
- inline void setSplittingId(Id *id)
- {
- _splittingId = id;
- }
-
- inline void setIsInImage(bool iFlag)
- {
- _isInImage = iFlag;
- }
-
- /* stroke interface definition */
- inline bool intersect_2d_area(const Vec2r& iMin, const Vec2r& iMax) const
- {
- // parse edges to check if one of them is intersection the region:
- FEdge *current = _FEdgeA;
- do {
- if (GeomUtils::intersect2dSeg2dArea(iMin, iMax,
- Vec2r(current->vertexA()->point2D()[0],
- current->vertexA()->point2D()[1]),
- Vec2r(current->vertexB()->point2D()[0],
- current->vertexB()->point2D()[1])))
- {
- return true;
- }
- current = current->nextEdge();
- } while ((current != 0) && (current != _FEdgeA));
-
- return false;
- }
-
- inline bool include_in_2d_area(const Vec2r& iMin, const Vec2r& iMax) const
- {
- // parse edges to check if all of them are intersection the region:
- FEdge *current = _FEdgeA;
-
- do {
- if (!GeomUtils::include2dSeg2dArea(iMin, iMax,
- Vec2r(current->vertexA()->point2D()[0],
- current->vertexA()->point2D()[1]),
- Vec2r(current->vertexB()->point2D()[0],
- current->vertexB()->point2D()[1])))
- {
- return false;
- }
- current = current->nextEdge();
- } while ((current != 0) && (current != _FEdgeA));
-
- return true;
- }
-
- /* Information access interface */
+ // only the last splitted deletes this id
+ if (_splittingId) {
+ if (*_splittingId == _Id)
+ delete _splittingId;
+ }
+ }
+
+ /* accessors */
+ /*! Returns the first ViewVertex. */
+ inline ViewVertex *A()
+ {
+ return __A;
+ }
+
+ /*! Returns the second ViewVertex. */
+ inline ViewVertex *B()
+ {
+ return __B;
+ }
+
+ /*! Returns the first FEdge that constitues this ViewEdge. */
+ inline FEdge *fedgeA()
+ {
+ return _FEdgeA;
+ }
+
+ /*! Returns the last FEdge that constitues this ViewEdge. */
+ inline FEdge *fedgeB()
+ {
+ return _FEdgeB;
+ }
+
+ /*! Returns the ViewShape to which this ViewEdge belongs to .*/
+ inline ViewShape *viewShape()
+ {
+ return _Shape;
+ }
+
+ /*! Returns the shape that is occluded by the ViewShape to which this ViewEdge belongs to. If no object is occluded,
+ * NULL is returned.
+ * \return The occluded ViewShape.
+ */
+ inline ViewShape *aShape()
+ {
+ return _aShape;
+ }
+
+ /*! Tells whether this ViewEdge forms a closed loop or not. */
+ inline bool isClosed()
+ {
+ if (!__B)
+ return true;
+ return false;
+ }
+
+ /*! Returns the time stamp of this ViewEdge. */
+ inline unsigned getChainingTimeStamp()
+ {
+ return _ChainingTimeStamp;
+ }
+
+ inline const ViewShape *aShape() const
+ {
+ return _aShape;
+ }
+
+ inline const ViewShape *bShape() const
+ {
+ return _Shape;
+ }
+
+ inline vector<ViewShape *> &occluders()
+ {
+ return _Occluders;
+ }
+
+ inline Id *splittingId()
+ {
+ return _splittingId;
+ }
+
+ inline bool isInImage() const
+ {
+ return _isInImage;
+ }
+
+ /* modifiers */
+ /*! Sets the first ViewVertex of the ViewEdge. */
+ inline void setA(ViewVertex *iA)
+ {
+ __A = iA;
+ }
+
+ /*! Sets the last ViewVertex of the ViewEdge. */
+ inline void setB(ViewVertex *iB)
+ {
+ __B = iB;
+ }
+
+ /*! Sets the nature of the ViewEdge. */
+ inline void setNature(Nature::EdgeNature iNature)
+ {
+ _Nature = iNature;
+ }
+
+ /*! Sets the first FEdge of the ViewEdge. */
+ inline void setFEdgeA(FEdge *iFEdge)
+ {
+ _FEdgeA = iFEdge;
+ }
+
+ /*! Sets the last FEdge of the ViewEdge. */
+ inline void setFEdgeB(FEdge *iFEdge)
+ {
+ _FEdgeB = iFEdge;
+ }
+
+ /*! Sets the ViewShape to which this ViewEdge belongs to.*/
+ inline void setShape(ViewShape *iVShape)
+ {
+ _Shape = iVShape;
+ }
+
+ /*! Sets the ViewEdge id. */
+ inline void setId(const Id &id)
+ {
+ _Id = id;
+ }
+
+ /*! Sets Viewedge to this for all embedded fedges */
+ void UpdateFEdges();
+
+ /*! Sets the occluded ViewShape */
+ inline void setaShape(ViewShape *iShape)
+ {
+ _aShape = iShape;
+ }
+
+ /*! Sets the quantitative invisibility value. */
+ inline void setQI(int qi)
+ {
+ _qi = qi;
+ }
+
+ /*! Sets the time stamp value. */
+ inline void setChainingTimeStamp(unsigned ts)
+ {
+ _ChainingTimeStamp = ts;
+ }
+
+ inline void AddOccluder(ViewShape *iShape)
+ {
+ _Occluders.push_back(iShape);
+ }
+
+ inline void setSplittingId(Id *id)
+ {
+ _splittingId = id;
+ }
+
+ inline void setIsInImage(bool iFlag)
+ {
+ _isInImage = iFlag;
+ }
+
+ /* stroke interface definition */
+ inline bool intersect_2d_area(const Vec2r &iMin, const Vec2r &iMax) const
+ {
+ // parse edges to check if one of them is intersection the region:
+ FEdge *current = _FEdgeA;
+ do {
+ if (GeomUtils::intersect2dSeg2dArea(
+ iMin,
+ iMax,
+ Vec2r(current->vertexA()->point2D()[0], current->vertexA()->point2D()[1]),
+ Vec2r(current->vertexB()->point2D()[0], current->vertexB()->point2D()[1]))) {
+ return true;
+ }
+ current = current->nextEdge();
+ } while ((current != 0) && (current != _FEdgeA));
+
+ return false;
+ }
+
+ inline bool include_in_2d_area(const Vec2r &iMin, const Vec2r &iMax) const
+ {
+ // parse edges to check if all of them are intersection the region:
+ FEdge *current = _FEdgeA;
+
+ do {
+ if (!GeomUtils::include2dSeg2dArea(
+ iMin,
+ iMax,
+ Vec2r(current->vertexA()->point2D()[0], current->vertexA()->point2D()[1]),
+ Vec2r(current->vertexB()->point2D()[0], current->vertexB()->point2D()[1]))) {
+ return false;
+ }
+ current = current->nextEdge();
+ } while ((current != 0) && (current != _FEdgeA));
+
+ return true;
+ }
+
+ /* Information access interface */
#if 0
- inline Nature::EdgeNature viewedge_nature() const
- {
- return getNature();
- }
+ inline Nature::EdgeNature viewedge_nature() const
+ {
+ return getNature();
+ }
- float viewedge_length() const;
+ float viewedge_length() const;
#endif
- /*! Returns the 2D length of the Viewedge. */
- real getLength2D() const;
+ /*! Returns the 2D length of the Viewedge. */
+ real getLength2D() const;
#if 0
- inline Material material() const
- {
- return _FEdgeA->vertexA()->shape()->material();
- }
+ inline Material material() const
+ {
+ return _FEdgeA->vertexA()->shape()->material();
+ }
#endif
- inline int qi() const
- {
- return _qi;
- }
-
- inline occluder_container::const_iterator occluders_begin() const
- {
- return _Occluders.begin();
- }
-
- inline occluder_container::const_iterator occluders_end() const
- {
- return _Occluders.end();
- }
-
- inline int occluders_size() const
- {
- return _Occluders.size();
- }
-
- inline bool occluders_empty() const
- {
- return _Occluders.empty();
- }
-
- inline const Polygon3r& occludee() const
- {
- return (_FEdgeA->aFace());
- }
-
- inline const SShape *occluded_shape() const;
-
- inline const bool occludee_empty() const
- {
- if (_aShape == 0)
- return true;
- return false;
- }
-
- //inline real z_discontinuity(int iCombination = 0) const;
-
- inline Id shape_id() const
- {
- return _FEdgeA->vertexA()->shape()->getId();
- }
-
- inline const SShape *shape() const
- {
- return _FEdgeA->vertexA()->shape();
- }
-
- inline float shape_importance() const
- {
- return _FEdgeA->shape_importance();
- }
-
- /* iterators access */
- // view edge iterator
- edge_iterator ViewEdge_iterator();
- const_edge_iterator ViewEdge_iterator() const;
- // feature edge iterator
- fedge_iterator fedge_iterator_begin();
- const_fedge_iterator fedge_iterator_begin() const;
- fedge_iterator fedge_iterator_last();
- const_fedge_iterator fedge_iterator_last() const;
- fedge_iterator fedge_iterator_end();
- const_fedge_iterator fedge_iterator_end() const;
- // embedding vertex iterator
- const_vertex_iterator vertices_begin() const;
- vertex_iterator vertices_begin();
- const_vertex_iterator vertices_last() const;
- vertex_iterator vertices_last();
- const_vertex_iterator vertices_end() const;
- vertex_iterator vertices_end();
-
- // Iterator access (Interface1D)
- /*! Returns an Interface0DIterator to iterate over the SVertex constituting the embedding of this ViewEdge.
- * The returned Interface0DIterator points to the first SVertex of the ViewEdge.
- */
- virtual Interface0DIterator verticesBegin();
-
- /*! Returns an Interface0DIterator to iterate over the SVertex constituting the embedding of this ViewEdge.
- * The returned Interface0DIterator points after the last SVertex of the ViewEdge.
- */
- virtual Interface0DIterator verticesEnd();
-
- /*! Returns an Interface0DIterator to iterate over the points of this ViewEdge at a given resolution.
- * The returned Interface0DIterator points on the first Point of the ViewEdge.
- * \param t:
- * the sampling value.
- */
- virtual Interface0DIterator pointsBegin(float t = 0.0f);
-
- /*! Returns an Interface0DIterator to iterate over the points of this ViewEdge at a given resolution.
- * The returned Interface0DIterator points after the last Point of the ViewEdge.
- * \param t:
- * the sampling value.
- */
- virtual Interface0DIterator pointsEnd(float t = 0.0f);
+ inline int qi() const
+ {
+ return _qi;
+ }
+
+ inline occluder_container::const_iterator occluders_begin() const
+ {
+ return _Occluders.begin();
+ }
+
+ inline occluder_container::const_iterator occluders_end() const
+ {
+ return _Occluders.end();
+ }
+
+ inline int occluders_size() const
+ {
+ return _Occluders.size();
+ }
+
+ inline bool occluders_empty() const
+ {
+ return _Occluders.empty();
+ }
+
+ inline const Polygon3r &occludee() const
+ {
+ return (_FEdgeA->aFace());
+ }
+
+ inline const SShape *occluded_shape() const;
+
+ inline const bool occludee_empty() const
+ {
+ if (_aShape == 0)
+ return true;
+ return false;
+ }
+
+ //inline real z_discontinuity(int iCombination = 0) const;
+
+ inline Id shape_id() const
+ {
+ return _FEdgeA->vertexA()->shape()->getId();
+ }
+
+ inline const SShape *shape() const
+ {
+ return _FEdgeA->vertexA()->shape();
+ }
+
+ inline float shape_importance() const
+ {
+ return _FEdgeA->shape_importance();
+ }
+
+ /* iterators access */
+ // view edge iterator
+ edge_iterator ViewEdge_iterator();
+ const_edge_iterator ViewEdge_iterator() const;
+ // feature edge iterator
+ fedge_iterator fedge_iterator_begin();
+ const_fedge_iterator fedge_iterator_begin() const;
+ fedge_iterator fedge_iterator_last();
+ const_fedge_iterator fedge_iterator_last() const;
+ fedge_iterator fedge_iterator_end();
+ const_fedge_iterator fedge_iterator_end() const;
+ // embedding vertex iterator
+ const_vertex_iterator vertices_begin() const;
+ vertex_iterator vertices_begin();
+ const_vertex_iterator vertices_last() const;
+ vertex_iterator vertices_last();
+ const_vertex_iterator vertices_end() const;
+ vertex_iterator vertices_end();
+
+ // Iterator access (Interface1D)
+ /*! Returns an Interface0DIterator to iterate over the SVertex constituting the embedding of this ViewEdge.
+ * The returned Interface0DIterator points to the first SVertex of the ViewEdge.
+ */
+ virtual Interface0DIterator verticesBegin();
+
+ /*! Returns an Interface0DIterator to iterate over the SVertex constituting the embedding of this ViewEdge.
+ * The returned Interface0DIterator points after the last SVertex of the ViewEdge.
+ */
+ virtual Interface0DIterator verticesEnd();
+
+ /*! Returns an Interface0DIterator to iterate over the points of this ViewEdge at a given resolution.
+ * The returned Interface0DIterator points on the first Point of the ViewEdge.
+ * \param t:
+ * the sampling value.
+ */
+ virtual Interface0DIterator pointsBegin(float t = 0.0f);
+
+ /*! Returns an Interface0DIterator to iterate over the points of this ViewEdge at a given resolution.
+ * The returned Interface0DIterator points after the last Point of the ViewEdge.
+ * \param t:
+ * the sampling value.
+ */
+ virtual Interface0DIterator pointsEnd(float t = 0.0f);
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdge")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdge")
#endif
};
-
/**********************************/
/* */
/* */
@@ -1385,239 +1391,235 @@ public:
/**********************************/
/*! Class gathering the elements of the ViewMap (ViewVertex, ViewEdge) that are issued from the same input shape. */
-class ViewShape
-{
-private:
- vector<ViewVertex*> _Vertices;
- vector<ViewEdge*> _Edges;
- SShape *_SShape;
-
-public:
- /*! A field that can be used by the user to store any data.
- * This field must be reseted afterwards using ResetUserData().
- */
- void *userdata;
-
- /*! Default constructor.*/
- inline ViewShape()
- {
- userdata = NULL;
- _SShape = NULL;
- }
-
- /*! Builds a ViewShape from a SShape. */
- inline ViewShape(SShape *iSShape)
- {
- userdata = NULL;
- _SShape = iSShape;
- //_SShape->setViewShape(this);
- }
-
- /*! Copy constructor. */
- inline ViewShape(ViewShape& iBrother)
- {
- userdata = NULL;
- vector<ViewVertex *>::iterator vv, vvend;
- vector<ViewEdge *>::iterator ve, veend;
-
- _SShape = iBrother._SShape;
-
- vector<ViewVertex*>& vvertices = iBrother.vertices();
- // duplicate vertices
- for (vv = vvertices.begin(), vvend = vvertices.end(); vv != vvend; vv++) {
- ViewVertex *newVertex = (*vv)->duplicate();
- AddVertex(newVertex);
- }
-
- vector<ViewEdge*>& vvedges = iBrother.edges();
- // duplicate edges
- for (ve = vvedges.begin(), veend = vvedges.end(); ve != veend; ve++) {
- ViewEdge *newEdge = (*ve)->duplicate();
- AddEdge(newEdge); // here the shape is set as the edge's shape
- }
-
- //-------------------------
- // remap edges in vertices:
- //-------------------------
- for (vv = _Vertices.begin(), vvend = _Vertices.end(); vv != vvend; vv++) {
- switch ((*vv)->getNature()) {
- case Nature::T_VERTEX:
- {
- TVertex *v = (TVertex *)(*vv);
- ViewEdge *veFrontA = (ViewEdge *)(v)->frontEdgeA().first->userdata;
- ViewEdge *veFrontB = (ViewEdge *)(v)->frontEdgeB().first->userdata;
- ViewEdge *veBackA = (ViewEdge *)(v)->backEdgeA().first->userdata;
- ViewEdge *veBackB = (ViewEdge *)(v)->backEdgeB().first->userdata;
-
- v->setFrontEdgeA(veFrontA, v->frontEdgeA().second);
- v->setFrontEdgeB(veFrontB, v->frontEdgeB().second);
- v->setBackEdgeA(veBackA, v->backEdgeA().second);
- v->setBackEdgeB(veBackB, v->backEdgeB().second);
- }
- break;
- case Nature::NON_T_VERTEX:
- {
- NonTVertex *v = (NonTVertex *)(*vv);
- vector<ViewVertex::directedViewEdge>& vedges = (v)->viewedges();
- vector<ViewVertex::directedViewEdge> newEdges;
- for (vector<ViewVertex::directedViewEdge>::iterator ve = vedges.begin(), veend = vedges.end();
- ve != veend;
- ve++)
- {
- ViewEdge *current = (ViewEdge *)((ve)->first)->userdata;
- newEdges.push_back(ViewVertex::directedViewEdge(current, ve->second));
- }
- (v)->setViewEdges(newEdges);
- }
- break;
- default:
- break;
- }
- }
-
- //-------------------------------------
- // remap vertices in edges:
- //-------------------------------------
- for (ve = _Edges.begin(), veend = _Edges.end(); ve != veend; ve++) {
- (*ve)->setA((ViewVertex *)((*ve)->A()->userdata));
- (*ve)->setB((ViewVertex *)((*ve)->B()->userdata));
- //---------------------------------------
- // Update all embedded FEdges
- //---------------------------------------
- (*ve)->UpdateFEdges();
- }
-
- // reset all brothers userdata to NULL:
- //-------------------------------------
- //---------
- // vertices
- //---------
- for (vv = vvertices.begin(), vvend = vvertices.end(); vv != vvend; vv++) {
- (*vv)->userdata = NULL;
- }
-
- //------
- // edges
- //------
- for (ve = vvedges.begin(), veend = vvedges.end(); ve != veend; ve++) {
- (*ve)->userdata = NULL;
- }
- }
-
- /*! Cloning method. */
- virtual ViewShape *duplicate()
- {
- ViewShape *clone = new ViewShape(*this);
- return clone;
- }
-
- /*! Destructor. */
- virtual ~ViewShape();
-
- /* splits a view edge into several view edges.
- * fe
- * The FEdge that gets splitted
- * iViewVertices
- * The view vertices corresponding to the different intersections for the edge fe.
- * This list need to be sorted such as the first view vertex is the farther away from fe->vertexA.
- * ioNewEdges
- * The feature edges that are newly created (the initial edges are not included) are added to this list.
- * ioNewViewEdges
- * The view edges that are newly created (the initial edges are not included) are added to this list.
- */
- inline void SplitEdge(FEdge *fe, const vector<TVertex*>& iViewVertices, vector<FEdge*>& ioNewEdges,
- vector<ViewEdge*>& ioNewViewEdges);
-
- /* accessors */
- /*! Returns the SShape on top of which this ViewShape is built. */
- inline SShape *sshape()
- {
- return _SShape;
- }
-
- /*! Returns the SShape on top of which this ViewShape is built. */
- inline const SShape *sshape() const
- {
- return _SShape;
- }
-
- /*! Returns the list of ViewVertex contained in this ViewShape. */
- inline vector<ViewVertex*>& vertices()
- {
- return _Vertices;
- }
-
- /*! Returns the list of ViewEdge contained in this ViewShape. */
- inline vector<ViewEdge*>& edges()
- {
- return _Edges;
- }
-
- /*! Returns the ViewShape id. */
- inline Id getId() const
- {
- return _SShape->getId();
- }
-
- /*! Returns the ViewShape name. */
- inline const string& getName() const
- {
- return _SShape->getName();
- }
-
- /*! Returns the ViewShape library path. */
- inline const string& getLibraryPath() const
- {
- return _SShape->getLibraryPath();
- }
-
- /* modifiers */
- /*! Sets the SShape on top of which the ViewShape is built. */
- inline void setSShape(SShape *iSShape)
- {
- _SShape = iSShape;
- }
-
- /*! Sets the list of ViewVertex contained in this ViewShape. */
- inline void setVertices(const vector<ViewVertex*>& iVertices)
- {
- _Vertices = iVertices;
- }
-
- /*! Sets the list of ViewEdge contained in this ViewShape. */
- inline void setEdges(const vector<ViewEdge*>& iEdges)
- {
- _Edges = iEdges;
- }
-
- /*! Adds a ViewVertex to the list. */
- inline void AddVertex(ViewVertex *iVertex)
- {
- _Vertices.push_back(iVertex);
- //_SShape->AddNewVertex(iVertex->svertex());
- }
-
- /*! Adds a ViewEdge to the list */
- inline void AddEdge(ViewEdge *iEdge)
- {
- _Edges.push_back(iEdge);
- iEdge->setShape(this);
- //_SShape->AddNewEdge(iEdge->fedge());
- }
-
- /* removes the view edge iViewEdge in the View Shape and the associated FEdge chain entry in the underlying SShape
- */
- void RemoveEdge(ViewEdge *iViewEdge);
-
- /* removes the view vertex iViewVertex in the View Shape. */
- void RemoveVertex(ViewVertex *iViewVertex);
+class ViewShape {
+ private:
+ vector<ViewVertex *> _Vertices;
+ vector<ViewEdge *> _Edges;
+ SShape *_SShape;
+
+ public:
+ /*! A field that can be used by the user to store any data.
+ * This field must be reseted afterwards using ResetUserData().
+ */
+ void *userdata;
+
+ /*! Default constructor.*/
+ inline ViewShape()
+ {
+ userdata = NULL;
+ _SShape = NULL;
+ }
+
+ /*! Builds a ViewShape from a SShape. */
+ inline ViewShape(SShape *iSShape)
+ {
+ userdata = NULL;
+ _SShape = iSShape;
+ //_SShape->setViewShape(this);
+ }
+
+ /*! Copy constructor. */
+ inline ViewShape(ViewShape &iBrother)
+ {
+ userdata = NULL;
+ vector<ViewVertex *>::iterator vv, vvend;
+ vector<ViewEdge *>::iterator ve, veend;
+
+ _SShape = iBrother._SShape;
+
+ vector<ViewVertex *> &vvertices = iBrother.vertices();
+ // duplicate vertices
+ for (vv = vvertices.begin(), vvend = vvertices.end(); vv != vvend; vv++) {
+ ViewVertex *newVertex = (*vv)->duplicate();
+ AddVertex(newVertex);
+ }
+
+ vector<ViewEdge *> &vvedges = iBrother.edges();
+ // duplicate edges
+ for (ve = vvedges.begin(), veend = vvedges.end(); ve != veend; ve++) {
+ ViewEdge *newEdge = (*ve)->duplicate();
+ AddEdge(newEdge); // here the shape is set as the edge's shape
+ }
+
+ //-------------------------
+ // remap edges in vertices:
+ //-------------------------
+ for (vv = _Vertices.begin(), vvend = _Vertices.end(); vv != vvend; vv++) {
+ switch ((*vv)->getNature()) {
+ case Nature::T_VERTEX: {
+ TVertex *v = (TVertex *)(*vv);
+ ViewEdge *veFrontA = (ViewEdge *)(v)->frontEdgeA().first->userdata;
+ ViewEdge *veFrontB = (ViewEdge *)(v)->frontEdgeB().first->userdata;
+ ViewEdge *veBackA = (ViewEdge *)(v)->backEdgeA().first->userdata;
+ ViewEdge *veBackB = (ViewEdge *)(v)->backEdgeB().first->userdata;
+
+ v->setFrontEdgeA(veFrontA, v->frontEdgeA().second);
+ v->setFrontEdgeB(veFrontB, v->frontEdgeB().second);
+ v->setBackEdgeA(veBackA, v->backEdgeA().second);
+ v->setBackEdgeB(veBackB, v->backEdgeB().second);
+ } break;
+ case Nature::NON_T_VERTEX: {
+ NonTVertex *v = (NonTVertex *)(*vv);
+ vector<ViewVertex::directedViewEdge> &vedges = (v)->viewedges();
+ vector<ViewVertex::directedViewEdge> newEdges;
+ for (vector<ViewVertex::directedViewEdge>::iterator ve = vedges.begin(),
+ veend = vedges.end();
+ ve != veend;
+ ve++) {
+ ViewEdge *current = (ViewEdge *)((ve)->first)->userdata;
+ newEdges.push_back(ViewVertex::directedViewEdge(current, ve->second));
+ }
+ (v)->setViewEdges(newEdges);
+ } break;
+ default:
+ break;
+ }
+ }
+
+ //-------------------------------------
+ // remap vertices in edges:
+ //-------------------------------------
+ for (ve = _Edges.begin(), veend = _Edges.end(); ve != veend; ve++) {
+ (*ve)->setA((ViewVertex *)((*ve)->A()->userdata));
+ (*ve)->setB((ViewVertex *)((*ve)->B()->userdata));
+ //---------------------------------------
+ // Update all embedded FEdges
+ //---------------------------------------
+ (*ve)->UpdateFEdges();
+ }
+
+ // reset all brothers userdata to NULL:
+ //-------------------------------------
+ //---------
+ // vertices
+ //---------
+ for (vv = vvertices.begin(), vvend = vvertices.end(); vv != vvend; vv++) {
+ (*vv)->userdata = NULL;
+ }
+
+ //------
+ // edges
+ //------
+ for (ve = vvedges.begin(), veend = vvedges.end(); ve != veend; ve++) {
+ (*ve)->userdata = NULL;
+ }
+ }
+
+ /*! Cloning method. */
+ virtual ViewShape *duplicate()
+ {
+ ViewShape *clone = new ViewShape(*this);
+ return clone;
+ }
+
+ /*! Destructor. */
+ virtual ~ViewShape();
+
+ /* splits a view edge into several view edges.
+ * fe
+ * The FEdge that gets splitted
+ * iViewVertices
+ * The view vertices corresponding to the different intersections for the edge fe.
+ * This list need to be sorted such as the first view vertex is the farther away from fe->vertexA.
+ * ioNewEdges
+ * The feature edges that are newly created (the initial edges are not included) are added to this list.
+ * ioNewViewEdges
+ * The view edges that are newly created (the initial edges are not included) are added to this list.
+ */
+ inline void SplitEdge(FEdge *fe,
+ const vector<TVertex *> &iViewVertices,
+ vector<FEdge *> &ioNewEdges,
+ vector<ViewEdge *> &ioNewViewEdges);
+
+ /* accessors */
+ /*! Returns the SShape on top of which this ViewShape is built. */
+ inline SShape *sshape()
+ {
+ return _SShape;
+ }
+
+ /*! Returns the SShape on top of which this ViewShape is built. */
+ inline const SShape *sshape() const
+ {
+ return _SShape;
+ }
+
+ /*! Returns the list of ViewVertex contained in this ViewShape. */
+ inline vector<ViewVertex *> &vertices()
+ {
+ return _Vertices;
+ }
+
+ /*! Returns the list of ViewEdge contained in this ViewShape. */
+ inline vector<ViewEdge *> &edges()
+ {
+ return _Edges;
+ }
+
+ /*! Returns the ViewShape id. */
+ inline Id getId() const
+ {
+ return _SShape->getId();
+ }
+
+ /*! Returns the ViewShape name. */
+ inline const string &getName() const
+ {
+ return _SShape->getName();
+ }
+
+ /*! Returns the ViewShape library path. */
+ inline const string &getLibraryPath() const
+ {
+ return _SShape->getLibraryPath();
+ }
+
+ /* modifiers */
+ /*! Sets the SShape on top of which the ViewShape is built. */
+ inline void setSShape(SShape *iSShape)
+ {
+ _SShape = iSShape;
+ }
+
+ /*! Sets the list of ViewVertex contained in this ViewShape. */
+ inline void setVertices(const vector<ViewVertex *> &iVertices)
+ {
+ _Vertices = iVertices;
+ }
+
+ /*! Sets the list of ViewEdge contained in this ViewShape. */
+ inline void setEdges(const vector<ViewEdge *> &iEdges)
+ {
+ _Edges = iEdges;
+ }
+
+ /*! Adds a ViewVertex to the list. */
+ inline void AddVertex(ViewVertex *iVertex)
+ {
+ _Vertices.push_back(iVertex);
+ //_SShape->AddNewVertex(iVertex->svertex());
+ }
+
+ /*! Adds a ViewEdge to the list */
+ inline void AddEdge(ViewEdge *iEdge)
+ {
+ _Edges.push_back(iEdge);
+ iEdge->setShape(this);
+ //_SShape->AddNewEdge(iEdge->fedge());
+ }
+
+ /* removes the view edge iViewEdge in the View Shape and the associated FEdge chain entry in the underlying SShape
+ */
+ void RemoveEdge(ViewEdge *iViewEdge);
+
+ /* removes the view vertex iViewVertex in the View Shape. */
+ void RemoveVertex(ViewVertex *iViewVertex);
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewShape")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewShape")
#endif
};
-
/*
* #############################################
* #############################################
@@ -1631,116 +1633,118 @@ public:
*/
/* for inline functions */
-void ViewShape::SplitEdge(FEdge *fe, const vector<TVertex*>& iViewVertices, vector<FEdge*>& ioNewEdges,
- vector<ViewEdge*>& ioNewViewEdges)
+void ViewShape::SplitEdge(FEdge *fe,
+ const vector<TVertex *> &iViewVertices,
+ vector<FEdge *> &ioNewEdges,
+ vector<ViewEdge *> &ioNewViewEdges)
{
- ViewEdge *vEdge = fe->viewedge();
-
- // We first need to sort the view vertices from farther to closer to fe->vertexA
- SVertex *sv, *sv2;
- ViewVertex *vva, *vvb;
- vector<TVertex*>::const_iterator vv, vvend;
- for (vv = iViewVertices.begin(), vvend = iViewVertices.end(); vv != vvend; vv++) {
- // Add the viewvertices to the ViewShape
- AddVertex((*vv));
-
- // retrieve the correct SVertex from the view vertex
- //--------------------------------------------------
- sv = (*vv)->frontSVertex();
- sv2 = (*vv)->backSVertex();
-
- if (sv->shape() != sv2->shape()) {
- if (sv->shape() != _SShape)
- sv = sv2;
- }
- else {
- // if the shape is the same we can safely differ the two vertices using their ids:
- if (sv->getId() != fe->vertexA()->getId())
- sv = sv2;
- }
-
- vva = vEdge->A();
- vvb = vEdge->B();
-
- // We split Fedge AB into AA' and A'B. A' and A'B are created.
- // AB becomes (address speaking) AA'. B is updated.
- //--------------------------------------------------
- SShape *shape = fe->shape();
-
- // a new edge, A'B is created.
- FEdge *newEdge = shape->SplitEdgeIn2(fe, sv);
- /* One of the two FEdges (fe and newEdge) may have a 2D length less than M_EPSILON.
- * (22 Feb 2011, T.K.)
- */
-
- ioNewEdges.push_back(newEdge);
- ViewEdge *newVEdge;
-
- if ((vva == 0) || (vvb == 0)) { // that means we're dealing with a closed viewedge (loop)
- // remove the chain that was starting by the fedge A of vEdge (which is different from fe !!!!)
- shape->RemoveEdgeFromChain(vEdge->fedgeA());
- // we set
- vEdge->setA(*vv);
- vEdge->setB(*vv);
- vEdge->setFEdgeA(newEdge);
- //FEdge *previousEdge = newEdge->previousEdge();
- vEdge->setFEdgeB(fe);
- newVEdge = vEdge;
- vEdge->fedgeA()->setViewEdge(newVEdge);
- }
- else {
- // while we create the view edge, it updates the "ViewEdge" pointer of every underlying FEdges to this.
- newVEdge = new ViewEdge((*vv), vvb); //, newEdge, vEdge->fedgeB());
- newVEdge->setNature((fe)->getNature());
- newVEdge->setFEdgeA(newEdge);
- //newVEdge->setFEdgeB(fe);
- // If our original viewedge is made of one FEdge, then
- if ((vEdge->fedgeA() == vEdge->fedgeB()) || (fe == vEdge->fedgeB()))
- newVEdge->setFEdgeB(newEdge);
- else
- newVEdge->setFEdgeB(vEdge->fedgeB()); //MODIF
-
- Id *newId = vEdge->splittingId();
- if (newId == 0) {
- newId = new Id(vEdge->getId());
- vEdge->setSplittingId(newId);
- }
- newId->setSecond(newId->getSecond() + 1);
- newVEdge->setId(*newId);
- newVEdge->setSplittingId(newId);
+ ViewEdge *vEdge = fe->viewedge();
+
+ // We first need to sort the view vertices from farther to closer to fe->vertexA
+ SVertex *sv, *sv2;
+ ViewVertex *vva, *vvb;
+ vector<TVertex *>::const_iterator vv, vvend;
+ for (vv = iViewVertices.begin(), vvend = iViewVertices.end(); vv != vvend; vv++) {
+ // Add the viewvertices to the ViewShape
+ AddVertex((*vv));
+
+ // retrieve the correct SVertex from the view vertex
+ //--------------------------------------------------
+ sv = (*vv)->frontSVertex();
+ sv2 = (*vv)->backSVertex();
+
+ if (sv->shape() != sv2->shape()) {
+ if (sv->shape() != _SShape)
+ sv = sv2;
+ }
+ else {
+ // if the shape is the same we can safely differ the two vertices using their ids:
+ if (sv->getId() != fe->vertexA()->getId())
+ sv = sv2;
+ }
+
+ vva = vEdge->A();
+ vvb = vEdge->B();
+
+ // We split Fedge AB into AA' and A'B. A' and A'B are created.
+ // AB becomes (address speaking) AA'. B is updated.
+ //--------------------------------------------------
+ SShape *shape = fe->shape();
+
+ // a new edge, A'B is created.
+ FEdge *newEdge = shape->SplitEdgeIn2(fe, sv);
+ /* One of the two FEdges (fe and newEdge) may have a 2D length less than M_EPSILON.
+ * (22 Feb 2011, T.K.)
+ */
+
+ ioNewEdges.push_back(newEdge);
+ ViewEdge *newVEdge;
+
+ if ((vva == 0) || (vvb == 0)) { // that means we're dealing with a closed viewedge (loop)
+ // remove the chain that was starting by the fedge A of vEdge (which is different from fe !!!!)
+ shape->RemoveEdgeFromChain(vEdge->fedgeA());
+ // we set
+ vEdge->setA(*vv);
+ vEdge->setB(*vv);
+ vEdge->setFEdgeA(newEdge);
+ //FEdge *previousEdge = newEdge->previousEdge();
+ vEdge->setFEdgeB(fe);
+ newVEdge = vEdge;
+ vEdge->fedgeA()->setViewEdge(newVEdge);
+ }
+ else {
+ // while we create the view edge, it updates the "ViewEdge" pointer of every underlying FEdges to this.
+ newVEdge = new ViewEdge((*vv), vvb); //, newEdge, vEdge->fedgeB());
+ newVEdge->setNature((fe)->getNature());
+ newVEdge->setFEdgeA(newEdge);
+ //newVEdge->setFEdgeB(fe);
+ // If our original viewedge is made of one FEdge, then
+ if ((vEdge->fedgeA() == vEdge->fedgeB()) || (fe == vEdge->fedgeB()))
+ newVEdge->setFEdgeB(newEdge);
+ else
+ newVEdge->setFEdgeB(vEdge->fedgeB()); //MODIF
+
+ Id *newId = vEdge->splittingId();
+ if (newId == 0) {
+ newId = new Id(vEdge->getId());
+ vEdge->setSplittingId(newId);
+ }
+ newId->setSecond(newId->getSecond() + 1);
+ newVEdge->setId(*newId);
+ newVEdge->setSplittingId(newId);
#if 0
- Id id(vEdge->getId().getFirst(), vEdge->getId().getSecond() + 1);
- newVEdge->setId(vEdge->getId());
- vEdge->setId(id);
+ Id id(vEdge->getId().getFirst(), vEdge->getId().getSecond() + 1);
+ newVEdge->setId(vEdge->getId());
+ vEdge->setId(id);
#endif
- AddEdge(newVEdge); // here this shape is set as the edge's shape
-
- // add new edge to the list of new edges passed as argument:
- ioNewViewEdges.push_back(newVEdge);
-
- if (0 != vvb)
- vvb->Replace((vEdge), newVEdge);
-
- // we split the view edge:
- vEdge->setB((*vv));
- vEdge->setFEdgeB(fe); //MODIF
-
- // Update fedges so that they point to the new viewedge:
- newVEdge->UpdateFEdges();
- }
- // check whether this vertex is a front vertex or a back one
- if (sv == (*vv)->frontSVertex()) {
- // -- View Vertex A' --
- (*vv)->setFrontEdgeA(vEdge, true);
- (*vv)->setFrontEdgeB(newVEdge, false);
- }
- else {
- // -- View Vertex A' --
- (*vv)->setBackEdgeA(vEdge, true);
- (*vv)->setBackEdgeB(newVEdge, false);
- }
- }
+ AddEdge(newVEdge); // here this shape is set as the edge's shape
+
+ // add new edge to the list of new edges passed as argument:
+ ioNewViewEdges.push_back(newVEdge);
+
+ if (0 != vvb)
+ vvb->Replace((vEdge), newVEdge);
+
+ // we split the view edge:
+ vEdge->setB((*vv));
+ vEdge->setFEdgeB(fe); //MODIF
+
+ // Update fedges so that they point to the new viewedge:
+ newVEdge->UpdateFEdges();
+ }
+ // check whether this vertex is a front vertex or a back one
+ if (sv == (*vv)->frontSVertex()) {
+ // -- View Vertex A' --
+ (*vv)->setFrontEdgeA(vEdge, true);
+ (*vv)->setFrontEdgeB(newVEdge, false);
+ }
+ else {
+ // -- View Vertex A' --
+ (*vv)->setBackEdgeA(vEdge, true);
+ (*vv)->setBackEdgeB(newVEdge, false);
+ }
+ }
}
/**********************************/
@@ -1754,54 +1758,54 @@ void ViewShape::SplitEdge(FEdge *fe, const vector<TVertex*>& iViewVertices, vect
#if 0
inline Vec3r ViewEdge::orientation2d(int iCombination) const
{
- return edge_orientation2d_function<ViewEdge>(*this, iCombination);
+ return edge_orientation2d_function<ViewEdge>(*this, iCombination);
}
inline Vec3r ViewEdge::orientation3d(int iCombination) const
{
- return edge_orientation3d_function<ViewEdge>(*this, iCombination);
+ return edge_orientation3d_function<ViewEdge>(*this, iCombination);
}
inline real ViewEdge::z_discontinuity(int iCombination) const
{
- return z_discontinuity_edge_function<ViewEdge>(*this, iCombination);
+ return z_discontinuity_edge_function<ViewEdge>(*this, iCombination);
}
inline float ViewEdge::local_average_depth(int iCombination ) const
{
- return local_average_depth_edge_function<ViewEdge>(*this, iCombination);
+ return local_average_depth_edge_function<ViewEdge>(*this, iCombination);
}
inline float ViewEdge::local_depth_variance(int iCombination) const
{
- return local_depth_variance_edge_function<ViewEdge>(*this, iCombination);
+ return local_depth_variance_edge_function<ViewEdge>(*this, iCombination);
}
inline real ViewEdge::local_average_density(float sigma, int iCombination) const
{
- return density_edge_function<ViewEdge>(*this, iCombination);
+ return density_edge_function<ViewEdge>(*this, iCombination);
}
#endif
inline const SShape *ViewEdge::occluded_shape() const
{
- if (0 == _aShape)
- return 0;
- return _aShape->sshape();
+ if (0 == _aShape)
+ return 0;
+ return _aShape->sshape();
}
#if 0
inline Vec3r ViewEdge::curvature2d_as_vector(int iCombination) const
{
- return curvature2d_as_vector_edge_function<ViewEdge>(*this, iCombination);
+ return curvature2d_as_vector_edge_function<ViewEdge>(*this, iCombination);
}
inline real ViewEdge::curvature2d_as_angle(int iCombination) const
{
- return curvature2d_as_angle_edge_function<ViewEdge>(*this, iCombination);
+ return curvature2d_as_angle_edge_function<ViewEdge>(*this, iCombination);
}
#endif
} /* namespace Freestyle */
-#endif // __FREESTYLE_VIEW_MAP_H__
+#endif // __FREESTYLE_VIEW_MAP_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h b/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
index 1b4a98498dd..2c09bde487b 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
@@ -25,7 +25,7 @@
#include "ViewMap.h"
-#include "../system/Iterator.h" //soc
+#include "../system/Iterator.h" //soc
namespace Freestyle {
@@ -47,290 +47,295 @@ namespace Freestyle {
namespace ViewVertexInternal {
-class edge_const_traits : public Const_traits<ViewVertex::directedViewEdge>
-{
-public:
- typedef vector<ViewVertex::directedViewEdge> edges_container;
- typedef edges_container::const_iterator edges_container_iterator;
- typedef vector<ViewVertex::directedViewEdge*> edge_pointers_container;
- typedef edge_pointers_container::const_iterator edge_pointers_container_iterator;
+class edge_const_traits : public Const_traits<ViewVertex::directedViewEdge> {
+ public:
+ typedef vector<ViewVertex::directedViewEdge> edges_container;
+ typedef edges_container::const_iterator edges_container_iterator;
+ typedef vector<ViewVertex::directedViewEdge *> edge_pointers_container;
+ typedef edge_pointers_container::const_iterator edge_pointers_container_iterator;
};
-class edge_nonconst_traits : public Nonconst_traits<ViewVertex::directedViewEdge>
-{
-public:
- typedef vector<ViewVertex::directedViewEdge> edges_container;
- typedef edges_container::iterator edges_container_iterator;
- typedef vector<ViewVertex::directedViewEdge*> edge_pointers_container;
- typedef edge_pointers_container::iterator edge_pointers_container_iterator;
+class edge_nonconst_traits : public Nonconst_traits<ViewVertex::directedViewEdge> {
+ public:
+ typedef vector<ViewVertex::directedViewEdge> edges_container;
+ typedef edges_container::iterator edges_container_iterator;
+ typedef vector<ViewVertex::directedViewEdge *> edge_pointers_container;
+ typedef edge_pointers_container::iterator edge_pointers_container_iterator;
};
template<class Traits>
-class edge_iterator_base : public IteratorBase<Traits, InputIteratorTag_Traits>
-{
-public:
- typedef typename Traits::value_type value_type;
- typedef typename Traits::difference_type difference_type;
- typedef typename Traits::pointer pointer;
- typedef typename Traits::reference reference;
- typedef edge_iterator_base<Traits> Self;
- typedef typename Traits::edges_container_iterator edges_container_iterator;
- typedef typename Traits::edge_pointers_container_iterator edge_pointers_container_iterator;
- typedef edge_iterator_base<edge_nonconst_traits> iterator;
- typedef edge_iterator_base<edge_const_traits> const_iterator;
-
-public:
- friend class ViewVertex;
- friend class TVertex;
- friend class NonTVertex;
- friend class ViewEdge;
- friend class edge_iterator;
-
-protected:
- Nature::VertexNature _Nature; // the nature of the underlying vertex
- // T vertex attributes
- edge_pointers_container_iterator _tbegin;
- edge_pointers_container_iterator _tend;
- edge_pointers_container_iterator _tvertex_iter;
+class edge_iterator_base : public IteratorBase<Traits, InputIteratorTag_Traits> {
+ public:
+ typedef typename Traits::value_type value_type;
+ typedef typename Traits::difference_type difference_type;
+ typedef typename Traits::pointer pointer;
+ typedef typename Traits::reference reference;
+ typedef edge_iterator_base<Traits> Self;
+ typedef typename Traits::edges_container_iterator edges_container_iterator;
+ typedef typename Traits::edge_pointers_container_iterator edge_pointers_container_iterator;
+ typedef edge_iterator_base<edge_nonconst_traits> iterator;
+ typedef edge_iterator_base<edge_const_traits> const_iterator;
+
+ public:
+ friend class ViewVertex;
+ friend class TVertex;
+ friend class NonTVertex;
+ friend class ViewEdge;
+ friend class edge_iterator;
+
+ protected:
+ Nature::VertexNature _Nature; // the nature of the underlying vertex
+ // T vertex attributes
+ edge_pointers_container_iterator _tbegin;
+ edge_pointers_container_iterator _tend;
+ edge_pointers_container_iterator _tvertex_iter;
#if 0
- mutable value_type _tvertex_iter;
- value_type _feA;
- value_type _feB;
- value_type _beA;
- value_type _beB;
+ mutable value_type _tvertex_iter;
+ value_type _feA;
+ value_type _feB;
+ value_type _beA;
+ value_type _beB;
#endif
- // Non TVertex attributes
- edges_container_iterator _begin;
- edges_container_iterator _end;
- edges_container_iterator _nontvertex_iter;
+ // Non TVertex attributes
+ edges_container_iterator _begin;
+ edges_container_iterator _end;
+ edges_container_iterator _nontvertex_iter;
- typedef IteratorBase<Traits, InputIteratorTag_Traits> parent_class;
+ typedef IteratorBase<Traits, InputIteratorTag_Traits> parent_class;
-public:
- inline edge_iterator_base() : parent_class() {}
+ public:
+ inline edge_iterator_base() : parent_class()
+ {
+ }
- inline edge_iterator_base(Nature::VertexNature iNature) : parent_class()
- {
- _Nature = iNature;
- }
+ inline edge_iterator_base(Nature::VertexNature iNature) : parent_class()
+ {
+ _Nature = iNature;
+ }
- edge_iterator_base(const edge_iterator_base<edge_nonconst_traits>& iBrother) : parent_class(iBrother)
- {
- _Nature = iBrother._Nature;
- if (_Nature & Nature::T_VERTEX) {
+ edge_iterator_base(const edge_iterator_base<edge_nonconst_traits> &iBrother)
+ : parent_class(iBrother)
+ {
+ _Nature = iBrother._Nature;
+ if (_Nature & Nature::T_VERTEX) {
#if 0
- _feA = iBrother._feA;
- _feB = iBrother._feB;
- _beA = iBrother._beA;
- _beB = iBrother._beB;
- _tvertex_iter = iBrother._tvertex_iter;
+ _feA = iBrother._feA;
+ _feB = iBrother._feB;
+ _beA = iBrother._beA;
+ _beB = iBrother._beB;
+ _tvertex_iter = iBrother._tvertex_iter;
#endif
- _tbegin = iBrother._tbegin;
- _tend = iBrother._tend;
- _tvertex_iter = iBrother._tvertex_iter;
- }
- else {
- _begin = iBrother._begin;
- _end = iBrother._end;
- _nontvertex_iter = iBrother._nontvertex_iter;
- }
- }
-
- edge_iterator_base(const edge_iterator_base<edge_const_traits>& iBrother) : parent_class(iBrother)
- {
- _Nature = iBrother._Nature;
- if (_Nature & Nature::T_VERTEX) {
+ _tbegin = iBrother._tbegin;
+ _tend = iBrother._tend;
+ _tvertex_iter = iBrother._tvertex_iter;
+ }
+ else {
+ _begin = iBrother._begin;
+ _end = iBrother._end;
+ _nontvertex_iter = iBrother._nontvertex_iter;
+ }
+ }
+
+ edge_iterator_base(const edge_iterator_base<edge_const_traits> &iBrother)
+ : parent_class(iBrother)
+ {
+ _Nature = iBrother._Nature;
+ if (_Nature & Nature::T_VERTEX) {
#if 0
- _feA = iBrother._feA;
- _feB = iBrother._feB;
- _beA = iBrother._beA;
- _beB = iBrother._beB;
- _tvertex_iter = iBrother._tvertex_iter;
+ _feA = iBrother._feA;
+ _feB = iBrother._feB;
+ _beA = iBrother._beA;
+ _beB = iBrother._beB;
+ _tvertex_iter = iBrother._tvertex_iter;
#endif
- _tbegin = iBrother._tbegin;
- _tend = iBrother._tend;
- _tvertex_iter = iBrother._tvertex_iter;
- }
- else {
- _begin = iBrother._begin;
- _end = iBrother._end;
- _nontvertex_iter = iBrother._nontvertex_iter;
- }
- }
-
- virtual ~edge_iterator_base() {}
-
-//protected://FIXME
-public:
+ _tbegin = iBrother._tbegin;
+ _tend = iBrother._tend;
+ _tvertex_iter = iBrother._tvertex_iter;
+ }
+ else {
+ _begin = iBrother._begin;
+ _end = iBrother._end;
+ _nontvertex_iter = iBrother._nontvertex_iter;
+ }
+ }
+
+ virtual ~edge_iterator_base()
+ {
+ }
+
+ //protected://FIXME
+ public:
#if 0
- inline edge_iterator_base(value_type ifeA, value_type ifeB, value_type ibeA, value_type ibeB, value_type iter)
- : parent_class()
- {
- _Nature = Nature::T_VERTEX;
- _feA = ifeA;
- _feB = ifeB;
- _beA = ibeA;
- _beB = ibeB;
- _tvertex_iter = iter;
- }
+ inline edge_iterator_base(value_type ifeA, value_type ifeB, value_type ibeA, value_type ibeB, value_type iter)
+ : parent_class()
+ {
+ _Nature = Nature::T_VERTEX;
+ _feA = ifeA;
+ _feB = ifeB;
+ _beA = ibeA;
+ _beB = ibeB;
+ _tvertex_iter = iter;
+ }
#endif
- inline edge_iterator_base(edge_pointers_container_iterator begin, edge_pointers_container_iterator end,
- edge_pointers_container_iterator iter)
- : parent_class()
- {
- _Nature = Nature::T_VERTEX;
- _tbegin = begin;
- _tend = end;
- _tvertex_iter = iter;
- }
-
- inline edge_iterator_base(edges_container_iterator begin, edges_container_iterator end,
- edges_container_iterator iter)
- : parent_class()
- {
- _Nature = Nature::NON_T_VERTEX;
- _begin = begin;
- _end = end;
- _nontvertex_iter = iter;
- }
-
-public:
- virtual bool begin() const
- {
- if (_Nature & Nature::T_VERTEX)
- return (_tvertex_iter == _tbegin);
- //return (_tvertex_iter == _feA);
- else
- return (_nontvertex_iter == _begin);
- }
-
- virtual bool end() const
- {
- if (_Nature & Nature::T_VERTEX)
- //return (_tvertex_iter.first == 0);
- return (_tvertex_iter == _tend);
- else
- return (_nontvertex_iter == _end);
- }
-
- // operators
- // operator corresponding to ++i
- virtual Self& operator++()
- {
- increment();
- return *this;
- }
-
- // operator corresponding to i++, i.e. which returns the value *and then* increments it.
- // That's why we store the value in a temp.
- virtual Self operator++(int)
- {
- Self tmp = *this;
- increment();
- return tmp;
- }
-
- // comparibility
- virtual bool operator!=(const Self& b) const
- {
- if (_Nature & Nature::T_VERTEX)
- return (_tvertex_iter != b._tvertex_iter);
- else
- return (_nontvertex_iter != b._nontvertex_iter);
- }
-
- virtual bool operator==(const Self& b) const
- {
- return !(*this != b);
- }
-
- // dereferencing
- virtual reference operator*() const
- {
- if (_Nature & Nature::T_VERTEX)
- //return _tvertex_iter;
- return **_tvertex_iter;
- else
- return (*_nontvertex_iter);
- }
-
- virtual pointer operator->() const
- {
- return &(operator*());
- }
-
-protected:
- inline void increment()
- {
- if (_Nature & Nature::T_VERTEX) {
- value_type tmp = (**_tvertex_iter);
- ++_tvertex_iter;
- value_type tmp2 = (**_tvertex_iter);
- if (tmp2.first == tmp.first)
- ++_tvertex_iter;
+ inline edge_iterator_base(edge_pointers_container_iterator begin,
+ edge_pointers_container_iterator end,
+ edge_pointers_container_iterator iter)
+ : parent_class()
+ {
+ _Nature = Nature::T_VERTEX;
+ _tbegin = begin;
+ _tend = end;
+ _tvertex_iter = iter;
+ }
+
+ inline edge_iterator_base(edges_container_iterator begin,
+ edges_container_iterator end,
+ edges_container_iterator iter)
+ : parent_class()
+ {
+ _Nature = Nature::NON_T_VERTEX;
+ _begin = begin;
+ _end = end;
+ _nontvertex_iter = iter;
+ }
+
+ public:
+ virtual bool begin() const
+ {
+ if (_Nature & Nature::T_VERTEX)
+ return (_tvertex_iter == _tbegin);
+ //return (_tvertex_iter == _feA);
+ else
+ return (_nontvertex_iter == _begin);
+ }
+
+ virtual bool end() const
+ {
+ if (_Nature & Nature::T_VERTEX)
+ //return (_tvertex_iter.first == 0);
+ return (_tvertex_iter == _tend);
+ else
+ return (_nontvertex_iter == _end);
+ }
+
+ // operators
+ // operator corresponding to ++i
+ virtual Self &operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ // operator corresponding to i++, i.e. which returns the value *and then* increments it.
+ // That's why we store the value in a temp.
+ virtual Self operator++(int)
+ {
+ Self tmp = *this;
+ increment();
+ return tmp;
+ }
+
+ // comparibility
+ virtual bool operator!=(const Self &b) const
+ {
+ if (_Nature & Nature::T_VERTEX)
+ return (_tvertex_iter != b._tvertex_iter);
+ else
+ return (_nontvertex_iter != b._nontvertex_iter);
+ }
+
+ virtual bool operator==(const Self &b) const
+ {
+ return !(*this != b);
+ }
+
+ // dereferencing
+ virtual reference operator*() const
+ {
+ if (_Nature & Nature::T_VERTEX)
+ //return _tvertex_iter;
+ return **_tvertex_iter;
+ else
+ return (*_nontvertex_iter);
+ }
+
+ virtual pointer operator->() const
+ {
+ return &(operator*());
+ }
+
+ protected:
+ inline void increment()
+ {
+ if (_Nature & Nature::T_VERTEX) {
+ value_type tmp = (**_tvertex_iter);
+ ++_tvertex_iter;
+ value_type tmp2 = (**_tvertex_iter);
+ if (tmp2.first == tmp.first)
+ ++_tvertex_iter;
#if 0
- // Hack to deal with cusp. the result of a cusp is a TVertex having two identical viewedges.
- // In order to iterate properly, we chose to skip these last ones.
- if (_feB.first == _beA.first) {
- if (_feA.first == _beB.first) {
- _tvertex_iter.first = 0;
- return;
- }
-
- if (_tvertex_iter.first == _feA.first)
- _tvertex_iter.first = _beB.first;
- else if (_tvertex_iter.first == _beB.first)
- _tvertex_iter.first = 0;
- else
- _tvertex_iter.first = _feA.first;
- return;
- }
- if (_feA.first == _beB.first) {
- if (_feB.first == _beA.first) {
- _tvertex_iter.first = 0;
- return;
- }
-
- if (_tvertex_iter.first == _feB.first)
- _tvertex_iter.first = _beA.first;
- else if (_tvertex_iter.first == _beA.first)
- _tvertex_iter.first = 0;
- else
- _tvertex_iter.first = _feB.first;
- return;
- }
- // End of hack
-
- if (_tvertex_iter.first == _feA.first) {
- // we return bea or beb
- // choose one of them
- _tvertex_iter.first = _feB.first;
- return;
- }
- if (_tvertex_iter.first == _feB.first) {
- _tvertex_iter.first = _beA.first;
- return;
- }
- if (_tvertex_iter.first == _beA.first) {
- _tvertex_iter.first = _beB.first;
- return;
- }
- if (_tvertex_iter.first == _beB.first) {
- _tvertex_iter.first = 0;
- return;
- }
+ // Hack to deal with cusp. the result of a cusp is a TVertex having two identical viewedges.
+ // In order to iterate properly, we chose to skip these last ones.
+ if (_feB.first == _beA.first) {
+ if (_feA.first == _beB.first) {
+ _tvertex_iter.first = 0;
+ return;
+ }
+
+ if (_tvertex_iter.first == _feA.first)
+ _tvertex_iter.first = _beB.first;
+ else if (_tvertex_iter.first == _beB.first)
+ _tvertex_iter.first = 0;
+ else
+ _tvertex_iter.first = _feA.first;
+ return;
+ }
+ if (_feA.first == _beB.first) {
+ if (_feB.first == _beA.first) {
+ _tvertex_iter.first = 0;
+ return;
+ }
+
+ if (_tvertex_iter.first == _feB.first)
+ _tvertex_iter.first = _beA.first;
+ else if (_tvertex_iter.first == _beA.first)
+ _tvertex_iter.first = 0;
+ else
+ _tvertex_iter.first = _feB.first;
+ return;
+ }
+ // End of hack
+
+ if (_tvertex_iter.first == _feA.first) {
+ // we return bea or beb
+ // choose one of them
+ _tvertex_iter.first = _feB.first;
+ return;
+ }
+ if (_tvertex_iter.first == _feB.first) {
+ _tvertex_iter.first = _beA.first;
+ return;
+ }
+ if (_tvertex_iter.first == _beA.first) {
+ _tvertex_iter.first = _beB.first;
+ return;
+ }
+ if (_tvertex_iter.first == _beB.first) {
+ _tvertex_iter.first = 0;
+ return;
+ }
#endif
- }
- else {
- ++_nontvertex_iter;
- }
- }
+ }
+ else {
+ ++_nontvertex_iter;
+ }
+ }
};
-} // ViewVertexInternal namespace
+} // namespace ViewVertexInternal
/**********************************/
/* */
@@ -346,435 +351,453 @@ namespace ViewEdgeInternal {
/*! Iterators definition */
/*!----------------------*/
template<class Traits>
-class edge_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTag_Traits>
-{
-public:
- typedef typename Traits::value_type value_type;
- typedef typename Traits::difference_type difference_type;
- typedef typename Traits::pointer pointer;
- typedef typename Traits::reference reference;
- typedef edge_iterator_base<Traits> Self;
-
-public:
- mutable value_type _ViewEdge;
- //friend class edge_iterator_base<Nonconst_traits<ViewEdge*> >;
- //friend class edge_iterator_base<Const_traits<ViewEdge*> >;
- value_type _first;
- bool _orientation;
- typedef IteratorBase<Traits, BidirectionalIteratorTag_Traits> parent_class;
-
-public:
- friend class ViewEdge;
- inline edge_iterator_base() : parent_class()
- {
- _orientation = true;
- _first = 0;
- }
-
- inline edge_iterator_base(const edge_iterator_base<Nonconst_traits<ViewEdge*> >& iBrother) : parent_class()
- {
- _ViewEdge = iBrother._ViewEdge;
- _first = iBrother._first;
- _orientation = iBrother._orientation;
- }
-
- inline edge_iterator_base(const edge_iterator_base<Const_traits<ViewEdge*> >& iBrother) : parent_class()
- {
- _ViewEdge = iBrother._ViewEdge;
- _first = iBrother._first;
- _orientation = iBrother._orientation;
- }
-
-//protected://FIXME
-public:
- inline edge_iterator_base(value_type iEdge, bool orientation = true) : parent_class()
- {
- _ViewEdge = iEdge;
- _first = iEdge;
- _orientation = orientation;
- }
-
-public:
- virtual Self *clone() const
- {
- return new edge_iterator_base(*this);
- }
-
- virtual ~edge_iterator_base() {}
-
-public:
- virtual bool orientation()
- {
- return _orientation;
- }
-
- virtual void set_edge(value_type iVE)
- {
- _ViewEdge = iVE;
- }
-
- virtual void set_orientation(bool iOrientation)
- {
- _orientation = iOrientation;
- }
-
- virtual void change_orientation()
- {
- _orientation = !_orientation;
- }
-
- // operators
- // operator corresponding to ++i
- inline Self& operator++()
- {
- //++_ViewEdge->getTimeStamp();
- increment();
- return *this;
- }
-
- // operator corresponding to i++, i.e. which returns the value *and then* increments it.
- // That's why we store the value in a temp.
- inline Self operator++(int)
- {
- //++_ViewEdge->getTimeStamp();
- Self tmp = *this;
- increment();
- return tmp;
- }
-
- // operator corresponding to --i
- inline Self& operator--()
- {
- //++_ViewEdge->getTimeStamp();
- decrement();
- return *this;
- }
-
- // operator corresponding to i--, i.e. which returns the value *and then* increments it.
- // That's why we store the value in a temp.
- inline Self operator--(int)
- {
- //++_ViewEdge->getTimeStamp();
- Self tmp = *this;
- decrement();
- return tmp;
- }
-
- // comparibility
- virtual bool operator!=(const Self& b) const
- {
- return (_ViewEdge != b._ViewEdge);
- }
-
- virtual bool operator==(const Self& b) const
- {
- return !(*this != b);
- }
-
- // dereferencing
- virtual reference operator*() const
- {
- return (_ViewEdge);
- }
-
- virtual pointer operator->() const
- {
- return &(operator*());
- }
-
-public:
- virtual bool begin() const
- {
- return (_ViewEdge == _first) ? true : false;
- }
-
- virtual bool end() const
- {
- return (_ViewEdge == 0) ? true : false;
- }
-
-protected:
- virtual void increment() {}
- virtual void decrement() {}
+class edge_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTag_Traits> {
+ public:
+ typedef typename Traits::value_type value_type;
+ typedef typename Traits::difference_type difference_type;
+ typedef typename Traits::pointer pointer;
+ typedef typename Traits::reference reference;
+ typedef edge_iterator_base<Traits> Self;
+
+ public:
+ mutable value_type _ViewEdge;
+ //friend class edge_iterator_base<Nonconst_traits<ViewEdge*> >;
+ //friend class edge_iterator_base<Const_traits<ViewEdge*> >;
+ value_type _first;
+ bool _orientation;
+ typedef IteratorBase<Traits, BidirectionalIteratorTag_Traits> parent_class;
+
+ public:
+ friend class ViewEdge;
+ inline edge_iterator_base() : parent_class()
+ {
+ _orientation = true;
+ _first = 0;
+ }
+
+ inline edge_iterator_base(const edge_iterator_base<Nonconst_traits<ViewEdge *>> &iBrother)
+ : parent_class()
+ {
+ _ViewEdge = iBrother._ViewEdge;
+ _first = iBrother._first;
+ _orientation = iBrother._orientation;
+ }
+
+ inline edge_iterator_base(const edge_iterator_base<Const_traits<ViewEdge *>> &iBrother)
+ : parent_class()
+ {
+ _ViewEdge = iBrother._ViewEdge;
+ _first = iBrother._first;
+ _orientation = iBrother._orientation;
+ }
+
+ //protected://FIXME
+ public:
+ inline edge_iterator_base(value_type iEdge, bool orientation = true) : parent_class()
+ {
+ _ViewEdge = iEdge;
+ _first = iEdge;
+ _orientation = orientation;
+ }
+
+ public:
+ virtual Self *clone() const
+ {
+ return new edge_iterator_base(*this);
+ }
+
+ virtual ~edge_iterator_base()
+ {
+ }
+
+ public:
+ virtual bool orientation()
+ {
+ return _orientation;
+ }
+
+ virtual void set_edge(value_type iVE)
+ {
+ _ViewEdge = iVE;
+ }
+
+ virtual void set_orientation(bool iOrientation)
+ {
+ _orientation = iOrientation;
+ }
+
+ virtual void change_orientation()
+ {
+ _orientation = !_orientation;
+ }
+
+ // operators
+ // operator corresponding to ++i
+ inline Self &operator++()
+ {
+ //++_ViewEdge->getTimeStamp();
+ increment();
+ return *this;
+ }
+
+ // operator corresponding to i++, i.e. which returns the value *and then* increments it.
+ // That's why we store the value in a temp.
+ inline Self operator++(int)
+ {
+ //++_ViewEdge->getTimeStamp();
+ Self tmp = *this;
+ increment();
+ return tmp;
+ }
+
+ // operator corresponding to --i
+ inline Self &operator--()
+ {
+ //++_ViewEdge->getTimeStamp();
+ decrement();
+ return *this;
+ }
+
+ // operator corresponding to i--, i.e. which returns the value *and then* increments it.
+ // That's why we store the value in a temp.
+ inline Self operator--(int)
+ {
+ //++_ViewEdge->getTimeStamp();
+ Self tmp = *this;
+ decrement();
+ return tmp;
+ }
+
+ // comparibility
+ virtual bool operator!=(const Self &b) const
+ {
+ return (_ViewEdge != b._ViewEdge);
+ }
+
+ virtual bool operator==(const Self &b) const
+ {
+ return !(*this != b);
+ }
+
+ // dereferencing
+ virtual reference operator*() const
+ {
+ return (_ViewEdge);
+ }
+
+ virtual pointer operator->() const
+ {
+ return &(operator*());
+ }
+
+ public:
+ virtual bool begin() const
+ {
+ return (_ViewEdge == _first) ? true : false;
+ }
+
+ virtual bool end() const
+ {
+ return (_ViewEdge == 0) ? true : false;
+ }
+
+ protected:
+ virtual void increment()
+ {
+ }
+ virtual void decrement()
+ {
+ }
};
template<class Traits>
-class fedge_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTag_Traits>
-{
-public:
- typedef typename Traits::value_type value_type;
- typedef typename Traits::difference_type difference_type;
- typedef typename Traits::pointer pointer;
- typedef typename Traits::reference reference;
- typedef fedge_iterator_base<Traits> Self;
-
-public:
- typedef IteratorBase<Traits, BidirectionalIteratorTag_Traits> parent_class;
- mutable value_type _FEdge;
- value_type _first;
- value_type _FEdgeB; // last fedge of the view edge
-
-public:
- friend class ViewEdge;
- friend class fedge_iterator;
-
- inline fedge_iterator_base() : parent_class() {}
-
- inline fedge_iterator_base(const fedge_iterator_base<Nonconst_traits<FEdge*> >& iBrother) : parent_class()
- {
- _FEdge = iBrother._FEdge;
- _first = iBrother._first;
- _FEdgeB = iBrother._FEdgeB;
- }
-
- inline fedge_iterator_base(const fedge_iterator_base<Const_traits<FEdge*> >& iBrother) : parent_class()
- {
- _FEdge = iBrother._FEdge;
- _first = iBrother._first;
- _FEdgeB = iBrother._FEdgeB;
- }
-
-//protected://FIXME
-public:
- inline fedge_iterator_base(value_type iEdge, value_type iFEdgeB) : parent_class()
- {
- _FEdge = iEdge;
- _first = iEdge;
- _FEdgeB = iFEdgeB;
- }
-
-public:
- virtual ~fedge_iterator_base() {}
-
- // operators
- // operator corresponding to ++i.
- inline Self& operator++()
- {
- increment();
- return *this;
- }
-
- // operator corresponding to i++, i.e. which returns the value *and then* increments it.
- // That's why we store the value in a temp.
- inline Self operator++(int)
- {
- Self tmp = *this;
- increment();
- return tmp;
- }
-
- // operator corresponding to --i
- inline Self& operator--()
- {
- decrement();
- return *this;
- }
-
- // operator corresponding to i--, i.e. which returns the value *and then* increments it.
- // That's why we store the value in a temp.
- inline Self operator--(int)
- {
- Self tmp = *this;
- decrement();
- return tmp;
- }
-
- // comparibility
- virtual bool operator!=(const Self& b) const
- {
- return (_FEdge != b._FEdge);
- }
-
- virtual bool operator==(const Self& b) const
- {
- return !(*this != b);
- }
-
- // dereferencing
- virtual reference operator*() const
- {
- return (_FEdge);
- }
-
- virtual pointer operator->() const
- {
- return &(operator*());
- }
-
-public:
- virtual bool begin() const
- {
- return (_FEdge == _first) ? true : false;
- }
-
- virtual bool end() const
- {
- return (_FEdge == 0) ? true : false;
- }
-
-protected:
- virtual void increment()
- {
- _FEdge = _FEdge->nextEdge(); // we don't change or
- }
-
- virtual void decrement()
- {
- if (0 == _FEdge) {
- _FEdge = _FEdgeB;
- return;
- }
- _FEdge = _FEdge->previousEdge(); // we don't change or
- }
+class fedge_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTag_Traits> {
+ public:
+ typedef typename Traits::value_type value_type;
+ typedef typename Traits::difference_type difference_type;
+ typedef typename Traits::pointer pointer;
+ typedef typename Traits::reference reference;
+ typedef fedge_iterator_base<Traits> Self;
+
+ public:
+ typedef IteratorBase<Traits, BidirectionalIteratorTag_Traits> parent_class;
+ mutable value_type _FEdge;
+ value_type _first;
+ value_type _FEdgeB; // last fedge of the view edge
+
+ public:
+ friend class ViewEdge;
+ friend class fedge_iterator;
+
+ inline fedge_iterator_base() : parent_class()
+ {
+ }
+
+ inline fedge_iterator_base(const fedge_iterator_base<Nonconst_traits<FEdge *>> &iBrother)
+ : parent_class()
+ {
+ _FEdge = iBrother._FEdge;
+ _first = iBrother._first;
+ _FEdgeB = iBrother._FEdgeB;
+ }
+
+ inline fedge_iterator_base(const fedge_iterator_base<Const_traits<FEdge *>> &iBrother)
+ : parent_class()
+ {
+ _FEdge = iBrother._FEdge;
+ _first = iBrother._first;
+ _FEdgeB = iBrother._FEdgeB;
+ }
+
+ //protected://FIXME
+ public:
+ inline fedge_iterator_base(value_type iEdge, value_type iFEdgeB) : parent_class()
+ {
+ _FEdge = iEdge;
+ _first = iEdge;
+ _FEdgeB = iFEdgeB;
+ }
+
+ public:
+ virtual ~fedge_iterator_base()
+ {
+ }
+
+ // operators
+ // operator corresponding to ++i.
+ inline Self &operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ // operator corresponding to i++, i.e. which returns the value *and then* increments it.
+ // That's why we store the value in a temp.
+ inline Self operator++(int)
+ {
+ Self tmp = *this;
+ increment();
+ return tmp;
+ }
+
+ // operator corresponding to --i
+ inline Self &operator--()
+ {
+ decrement();
+ return *this;
+ }
+
+ // operator corresponding to i--, i.e. which returns the value *and then* increments it.
+ // That's why we store the value in a temp.
+ inline Self operator--(int)
+ {
+ Self tmp = *this;
+ decrement();
+ return tmp;
+ }
+
+ // comparibility
+ virtual bool operator!=(const Self &b) const
+ {
+ return (_FEdge != b._FEdge);
+ }
+
+ virtual bool operator==(const Self &b) const
+ {
+ return !(*this != b);
+ }
+
+ // dereferencing
+ virtual reference operator*() const
+ {
+ return (_FEdge);
+ }
+
+ virtual pointer operator->() const
+ {
+ return &(operator*());
+ }
+
+ public:
+ virtual bool begin() const
+ {
+ return (_FEdge == _first) ? true : false;
+ }
+
+ virtual bool end() const
+ {
+ return (_FEdge == 0) ? true : false;
+ }
+
+ protected:
+ virtual void increment()
+ {
+ _FEdge = _FEdge->nextEdge(); // we don't change or
+ }
+
+ virtual void decrement()
+ {
+ if (0 == _FEdge) {
+ _FEdge = _FEdgeB;
+ return;
+ }
+ _FEdge = _FEdge->previousEdge(); // we don't change or
+ }
};
template<class Traits>
-class vertex_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTag_Traits>
-{
-public:
- typedef typename Traits::value_type value_type;
- typedef typename Traits::difference_type difference_type;
- typedef typename Traits::pointer pointer;
- typedef typename Traits::reference reference;
- typedef vertex_iterator_base<Traits> Self;
-
-protected:
- typedef IteratorBase<Traits, BidirectionalIteratorTag_Traits> parent_class;
-
-public:
- mutable value_type _SVertex;
- FEdge *_NextFEdge;
- FEdge *_PreviousFEdge;
-
-public:
- friend class ViewEdge;
- friend class vertex_iterator;
-
- inline vertex_iterator_base() : parent_class() {}
-
- inline vertex_iterator_base(const vertex_iterator_base<Const_traits<SVertex*> >& iBrother) : parent_class()
- {
- _SVertex = iBrother._SVertex;
- _NextFEdge = iBrother._NextFEdge;
- _PreviousFEdge = iBrother._PreviousFEdge;
- }
-
- inline vertex_iterator_base(const vertex_iterator_base<Nonconst_traits<SVertex*> >& iBrother) : parent_class()
- {
- _SVertex = iBrother._SVertex;
- _NextFEdge = iBrother._NextFEdge;
- _PreviousFEdge = iBrother._PreviousFEdge;
- }
-
-//protected://FIXME
-public:
- inline vertex_iterator_base(value_type iVertex, FEdge *iPreviousFEdge, FEdge *iNextFEdge) : parent_class()
- {
- _SVertex = iVertex;
- _NextFEdge = iNextFEdge;
- _PreviousFEdge = iPreviousFEdge;
- }
-
-public:
- virtual ~vertex_iterator_base() {}
-
- virtual bool begin() const
- {
- return (_PreviousFEdge == 0) ? true : false;
- }
-
- virtual bool end() const
- {
- return (_SVertex == 0) ? true : false;
- }
-
- // operators
- // operator corresponding to ++i
- inline Self& operator++()
- {
- increment();
- return *this;
- }
-
- // operator corresponding to i++, i.e. which returns the value *and then* increments it.
- // That's why we store the value in a temp.
- inline Self operator++(int)
- {
- Self tmp = *this;
- increment();
- return tmp;
- }
-
- // operator corresponding to --i
- inline Self& operator--()
- {
- decrement();
- return *this;
- }
-
- // operator corresponding to --i, i.e. which returns the value *and then* increments it.
- // That's why we store the value in a temp.
- inline Self operator--(int)
- {
- Self tmp = *this;
- decrement();
- return tmp;
- }
-
- // comparibility
- virtual bool operator!=(const Self& b) const
- {
- return (_SVertex != b._SVertex);
- }
-
- virtual bool operator==(const Self& b) const
- {
- return !(*this != b);
- }
-
- // dereferencing
- virtual reference operator*() const
- {
- return (_SVertex);
- }
-
- virtual pointer operator->() const
- {
- return &(operator*());
- }
-
-protected:
- virtual void increment()
- {
- if (!_NextFEdge) {
- _SVertex = NULL;
- return;
- }
- _SVertex = _NextFEdge->vertexB();
- _PreviousFEdge = _NextFEdge;
- _NextFEdge = _NextFEdge->nextEdge();
- }
-
- virtual void decrement()
- {
+class vertex_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTag_Traits> {
+ public:
+ typedef typename Traits::value_type value_type;
+ typedef typename Traits::difference_type difference_type;
+ typedef typename Traits::pointer pointer;
+ typedef typename Traits::reference reference;
+ typedef vertex_iterator_base<Traits> Self;
+
+ protected:
+ typedef IteratorBase<Traits, BidirectionalIteratorTag_Traits> parent_class;
+
+ public:
+ mutable value_type _SVertex;
+ FEdge *_NextFEdge;
+ FEdge *_PreviousFEdge;
+
+ public:
+ friend class ViewEdge;
+ friend class vertex_iterator;
+
+ inline vertex_iterator_base() : parent_class()
+ {
+ }
+
+ inline vertex_iterator_base(const vertex_iterator_base<Const_traits<SVertex *>> &iBrother)
+ : parent_class()
+ {
+ _SVertex = iBrother._SVertex;
+ _NextFEdge = iBrother._NextFEdge;
+ _PreviousFEdge = iBrother._PreviousFEdge;
+ }
+
+ inline vertex_iterator_base(const vertex_iterator_base<Nonconst_traits<SVertex *>> &iBrother)
+ : parent_class()
+ {
+ _SVertex = iBrother._SVertex;
+ _NextFEdge = iBrother._NextFEdge;
+ _PreviousFEdge = iBrother._PreviousFEdge;
+ }
+
+ //protected://FIXME
+ public:
+ inline vertex_iterator_base(value_type iVertex, FEdge *iPreviousFEdge, FEdge *iNextFEdge)
+ : parent_class()
+ {
+ _SVertex = iVertex;
+ _NextFEdge = iNextFEdge;
+ _PreviousFEdge = iPreviousFEdge;
+ }
+
+ public:
+ virtual ~vertex_iterator_base()
+ {
+ }
+
+ virtual bool begin() const
+ {
+ return (_PreviousFEdge == 0) ? true : false;
+ }
+
+ virtual bool end() const
+ {
+ return (_SVertex == 0) ? true : false;
+ }
+
+ // operators
+ // operator corresponding to ++i
+ inline Self &operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ // operator corresponding to i++, i.e. which returns the value *and then* increments it.
+ // That's why we store the value in a temp.
+ inline Self operator++(int)
+ {
+ Self tmp = *this;
+ increment();
+ return tmp;
+ }
+
+ // operator corresponding to --i
+ inline Self &operator--()
+ {
+ decrement();
+ return *this;
+ }
+
+ // operator corresponding to --i, i.e. which returns the value *and then* increments it.
+ // That's why we store the value in a temp.
+ inline Self operator--(int)
+ {
+ Self tmp = *this;
+ decrement();
+ return tmp;
+ }
+
+ // comparibility
+ virtual bool operator!=(const Self &b) const
+ {
+ return (_SVertex != b._SVertex);
+ }
+
+ virtual bool operator==(const Self &b) const
+ {
+ return !(*this != b);
+ }
+
+ // dereferencing
+ virtual reference operator*() const
+ {
+ return (_SVertex);
+ }
+
+ virtual pointer operator->() const
+ {
+ return &(operator*());
+ }
+
+ protected:
+ virtual void increment()
+ {
+ if (!_NextFEdge) {
+ _SVertex = NULL;
+ return;
+ }
+ _SVertex = _NextFEdge->vertexB();
+ _PreviousFEdge = _NextFEdge;
+ _NextFEdge = _NextFEdge->nextEdge();
+ }
+
+ virtual void decrement()
+ {
#if 0
- if (!_SVertex) {
- _SVertex = _PreviousFEdge->vertexB();
- return;
- }
+ if (!_SVertex) {
+ _SVertex = _PreviousFEdge->vertexB();
+ return;
+ }
#endif
- if (!_PreviousFEdge) {
- _SVertex = NULL;
- return;
- }
- _SVertex = _PreviousFEdge->vertexA();
- _NextFEdge = _PreviousFEdge;
- _PreviousFEdge = _PreviousFEdge->previousEdge();
- }
+ if (!_PreviousFEdge) {
+ _SVertex = NULL;
+ return;
+ }
+ _SVertex = _PreviousFEdge->vertexA();
+ _NextFEdge = _PreviousFEdge;
+ _PreviousFEdge = _PreviousFEdge->previousEdge();
+ }
};
-} // end of namespace ViewEdgeInternal
+} // end of namespace ViewEdgeInternal
} /* namespace Freestyle */
-#endif // __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
+#endif // __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
index e2bc45fc03f..ed0f5c9b0bd 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -49,347 +49,365 @@ static const Global &_global = G;
using namespace std;
-template <typename G, typename I>
-static void findOccludee(FEdge *fe, G& /*grid*/, I& occluders, real epsilon, WFace **oaWFace,
- Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices)
+template<typename G, typename I>
+static void findOccludee(FEdge *fe,
+ G & /*grid*/,
+ I &occluders,
+ real epsilon,
+ WFace **oaWFace,
+ Vec3r &u,
+ Vec3r &A,
+ Vec3r &origin,
+ Vec3r &edgeDir,
+ vector<WVertex *> &faceVertices)
{
- WFace *face = NULL;
- if (fe->isSmooth()) {
- FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(fe);
- face = (WFace *)fes->face();
- }
- WFace *oface;
- bool skipFace;
-
- WVertex::incoming_edge_iterator ie;
-
- *oaWFace = NULL;
- if (((fe)->getNature() & Nature::SILHOUETTE) || ((fe)->getNature() & Nature::BORDER)) {
- // we cast a ray from A in the same direction but looking behind
- Vec3r v(-u[0], -u[1], -u[2]);
- bool noIntersection = true;
- real mint = FLT_MAX;
-
- for (occluders.initAfterTarget(); occluders.validAfterTarget(); occluders.nextOccludee()) {
+ WFace *face = NULL;
+ if (fe->isSmooth()) {
+ FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
+ face = (WFace *)fes->face();
+ }
+ WFace *oface;
+ bool skipFace;
+
+ WVertex::incoming_edge_iterator ie;
+
+ *oaWFace = NULL;
+ if (((fe)->getNature() & Nature::SILHOUETTE) || ((fe)->getNature() & Nature::BORDER)) {
+ // we cast a ray from A in the same direction but looking behind
+ Vec3r v(-u[0], -u[1], -u[2]);
+ bool noIntersection = true;
+ real mint = FLT_MAX;
+
+ for (occluders.initAfterTarget(); occluders.validAfterTarget(); occluders.nextOccludee()) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tEvaluating intersection for occludee " << occluders.getWFace() << " and ray " << A <<
- " * " << u << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tEvaluating intersection for occludee " << occluders.getWFace() << " and ray "
+ << A << " * " << u << endl;
+ }
#endif
- oface = occluders.getWFace();
- Polygon3r *p = occluders.getCameraSpacePolygon();
- real d = -((p->getVertices())[0] * p->getNormal());
- real t, t_u, t_v;
-
- if (0 != face) {
- skipFace = false;
-
- if (face == oface)
- continue;
-
- if (faceVertices.empty())
- continue;
-
- for (vector<WVertex*>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
- fv != fvend;
- ++fv)
- {
- if ((*fv)->isBoundary())
- continue;
- WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
- WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
- for (ie = iebegin; ie != ieend; ++ie) {
- if ((*ie) == 0)
- continue;
-
- WFace *sface = (*ie)->GetbFace();
- if (sface == oface) {
- skipFace = true;
- break;
- }
- }
- if (skipFace)
- break;
- }
- if (skipFace)
- continue;
- }
- else {
- // check whether the edge and the polygon plane are coincident:
- //-------------------------------------------------------------
- //first let us compute the plane equation.
- if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, p->getNormal(), d, t, epsilon))
- {
+ oface = occluders.getWFace();
+ Polygon3r *p = occluders.getCameraSpacePolygon();
+ real d = -((p->getVertices())[0] * p->getNormal());
+ real t, t_u, t_v;
+
+ if (0 != face) {
+ skipFace = false;
+
+ if (face == oface)
+ continue;
+
+ if (faceVertices.empty())
+ continue;
+
+ for (vector<WVertex *>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
+ fv != fvend;
+ ++fv) {
+ if ((*fv)->isBoundary())
+ continue;
+ WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
+ WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
+ for (ie = iebegin; ie != ieend; ++ie) {
+ if ((*ie) == 0)
+ continue;
+
+ WFace *sface = (*ie)->GetbFace();
+ if (sface == oface) {
+ skipFace = true;
+ break;
+ }
+ }
+ if (skipFace)
+ break;
+ }
+ if (skipFace)
+ continue;
+ }
+ else {
+ // check whether the edge and the polygon plane are coincident:
+ //-------------------------------------------------------------
+ //first let us compute the plane equation.
+ if (GeomUtils::COINCIDENT ==
+ GeomUtils::intersectRayPlane(origin, edgeDir, p->getNormal(), d, t, epsilon)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tRejecting occluder for target coincidence." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tRejecting occluder for target coincidence." << endl;
+ }
#endif
- continue;
- }
- }
+ continue;
+ }
+ }
- if (p->rayIntersect(A, v, t, t_u, t_v)) {
+ if (p->rayIntersect(A, v, t, t_u, t_v)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tRay " << A << " * " << v << " intersects at time " << t << endl;
- cout << "\t\t(v * normal) == " << (v * p->getNormal()) << " for normal " << p->getNormal() << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tRay " << A << " * " << v << " intersects at time " << t << endl;
+ cout << "\t\t(v * normal) == " << (v * p->getNormal()) << " for normal "
+ << p->getNormal() << endl;
+ }
#endif
- if (fabs(v * p->getNormal()) > 0.0001) {
- if ((t > 0.0)) { // && (t<1.0))
- if (t < mint) {
- *oaWFace = oface;
- mint = t;
- noIntersection = false;
- fe->setOccludeeIntersection(Vec3r(A + t * v));
+ if (fabs(v * p->getNormal()) > 0.0001) {
+ if ((t > 0.0)) { // && (t<1.0))
+ if (t < mint) {
+ *oaWFace = oface;
+ mint = t;
+ noIntersection = false;
+ fe->setOccludeeIntersection(Vec3r(A + t * v));
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tIs occludee" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tIs occludee" << endl;
+ }
#endif
- }
- }
- }
+ }
+ }
+ }
- occluders.reportDepth(A, v, t);
- }
- }
+ occluders.reportDepth(A, v, t);
+ }
+ }
- if (noIntersection)
- *oaWFace = NULL;
- }
+ if (noIntersection)
+ *oaWFace = NULL;
+ }
}
-template <typename G, typename I>
-static void findOccludee(FEdge *fe, G& grid, real epsilon, ViewEdge * /*ve*/, WFace **oaFace)
+template<typename G, typename I>
+static void findOccludee(FEdge *fe, G &grid, real epsilon, ViewEdge * /*ve*/, WFace **oaFace)
{
- Vec3r A;
- Vec3r edgeDir;
- Vec3r origin;
- A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
- edgeDir = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
- edgeDir.normalize();
- origin = Vec3r((fe)->vertexA()->point3D());
- Vec3r u;
- if (grid.orthographicProjection()) {
- u = Vec3r(0.0, 0.0, grid.viewpoint().z() - A.z());
- }
- else {
- u = Vec3r(grid.viewpoint() - A);
- }
- u.normalize();
-
- vector<WVertex*> faceVertices;
-
- WFace *face = NULL;
- if (fe->isSmooth()) {
- FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(fe);
- face = (WFace *)fes->face();
- }
-
- if (face) {
- face->RetrieveVertexList(faceVertices);
- }
-
- I occluders(grid, A, epsilon);
- findOccludee<G, I>(fe, grid, occluders, epsilon, oaFace, u, A, origin, edgeDir, faceVertices);
+ Vec3r A;
+ Vec3r edgeDir;
+ Vec3r origin;
+ A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
+ edgeDir = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
+ edgeDir.normalize();
+ origin = Vec3r((fe)->vertexA()->point3D());
+ Vec3r u;
+ if (grid.orthographicProjection()) {
+ u = Vec3r(0.0, 0.0, grid.viewpoint().z() - A.z());
+ }
+ else {
+ u = Vec3r(grid.viewpoint() - A);
+ }
+ u.normalize();
+
+ vector<WVertex *> faceVertices;
+
+ WFace *face = NULL;
+ if (fe->isSmooth()) {
+ FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
+ face = (WFace *)fes->face();
+ }
+
+ if (face) {
+ face->RetrieveVertexList(faceVertices);
+ }
+
+ I occluders(grid, A, epsilon);
+ findOccludee<G, I>(fe, grid, occluders, epsilon, oaFace, u, A, origin, edgeDir, faceVertices);
}
// computeVisibility takes a pointer to foundOccluders, instead of using a reference,
// so that computeVeryFastVisibility can skip the AddOccluders step with minimal overhead.
-template <typename G, typename I>
-static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon, ViewEdge * /*ve*/, WFace **oaWFace,
- set<ViewShape*> *foundOccluders)
+template<typename G, typename I>
+static int computeVisibility(ViewMap *viewMap,
+ FEdge *fe,
+ G &grid,
+ real epsilon,
+ ViewEdge * /*ve*/,
+ WFace **oaWFace,
+ set<ViewShape *> *foundOccluders)
{
- int qi = 0;
-
- Vec3r center;
- Vec3r edgeDir;
- Vec3r origin;
-
- center = fe->center3d();
- edgeDir = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
- edgeDir.normalize();
- origin = Vec3r(fe->vertexA()->point3D());
-
- Vec3r vp;
- if (grid.orthographicProjection()) {
- vp = Vec3r(center.x(), center.y(), grid.viewpoint().z());
- }
- else {
- vp = Vec3r(grid.viewpoint());
- }
- Vec3r u(vp - center);
- real raylength = u.norm();
- u.normalize();
-
- WFace *face = NULL;
- if (fe->isSmooth()) {
- FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(fe);
- face = (WFace *)fes->face();
- }
- vector<WVertex*> faceVertices;
- WVertex::incoming_edge_iterator ie;
-
- WFace *oface;
- bool skipFace;
-
- if (face)
- face->RetrieveVertexList(faceVertices);
-
- I occluders(grid, center, epsilon);
-
- for (occluders.initBeforeTarget(); occluders.validBeforeTarget(); occluders.nextOccluder()) {
- // If we're dealing with an exact silhouette, check whether we must take care of this occluder of not.
- // (Indeed, we don't consider the occluders that share at least one vertex with the face containing this edge).
- //-----------
- oface = occluders.getWFace();
- Polygon3r *p = occluders.getCameraSpacePolygon();
- real t, t_u, t_v;
+ int qi = 0;
+
+ Vec3r center;
+ Vec3r edgeDir;
+ Vec3r origin;
+
+ center = fe->center3d();
+ edgeDir = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
+ edgeDir.normalize();
+ origin = Vec3r(fe->vertexA()->point3D());
+
+ Vec3r vp;
+ if (grid.orthographicProjection()) {
+ vp = Vec3r(center.x(), center.y(), grid.viewpoint().z());
+ }
+ else {
+ vp = Vec3r(grid.viewpoint());
+ }
+ Vec3r u(vp - center);
+ real raylength = u.norm();
+ u.normalize();
+
+ WFace *face = NULL;
+ if (fe->isSmooth()) {
+ FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
+ face = (WFace *)fes->face();
+ }
+ vector<WVertex *> faceVertices;
+ WVertex::incoming_edge_iterator ie;
+
+ WFace *oface;
+ bool skipFace;
+
+ if (face)
+ face->RetrieveVertexList(faceVertices);
+
+ I occluders(grid, center, epsilon);
+
+ for (occluders.initBeforeTarget(); occluders.validBeforeTarget(); occluders.nextOccluder()) {
+ // If we're dealing with an exact silhouette, check whether we must take care of this occluder of not.
+ // (Indeed, we don't consider the occluders that share at least one vertex with the face containing this edge).
+ //-----------
+ oface = occluders.getWFace();
+ Polygon3r *p = occluders.getCameraSpacePolygon();
+ real t, t_u, t_v;
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tEvaluating intersection for occluder " << (p->getVertices())[0] << (p->getVertices())[1] <<
- (p->getVertices())[2] << endl << "\t\t\tand ray " << vp << " * " << u << " (center " << center <<
- ")" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tEvaluating intersection for occluder " << (p->getVertices())[0]
+ << (p->getVertices())[1] << (p->getVertices())[2] << endl
+ << "\t\t\tand ray " << vp << " * " << u << " (center " << center << ")" << endl;
+ }
#endif
#if LOGGING
- Vec3r v(vp - center);
- real rl = v.norm();
- v.normalize();
- vector<Vec3r> points;
- // Iterate over vertices, storing projections in points
- for (vector<WOEdge*>::const_iterator woe = oface->getEdgeList().begin(), woend = oface->getEdgeList().end();
- woe != woend;
- woe++)
- {
- points.push_back(Vec3r((*woe)->GetaVertex()->GetVertex()));
- }
- Polygon3r p1(points, oface->GetNormal());
- Vec3r v1((p1.getVertices())[0]);
- real d = -(v1 * p->getNormal());
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tp: " << (p->getVertices())[0] << (p->getVertices())[1] << (p->getVertices())[2] << ", norm: " <<
- p->getNormal() << endl;
- cout << "\t\tp1: " << (p1.getVertices())[0] << (p1.getVertices())[1] << (p1.getVertices())[2] << ", norm: " <<
- p1.getNormal() << endl;
- }
+ Vec3r v(vp - center);
+ real rl = v.norm();
+ v.normalize();
+ vector<Vec3r> points;
+ // Iterate over vertices, storing projections in points
+ for (vector<WOEdge *>::const_iterator woe = oface->getEdgeList().begin(),
+ woend = oface->getEdgeList().end();
+ woe != woend;
+ woe++) {
+ points.push_back(Vec3r((*woe)->GetaVertex()->GetVertex()));
+ }
+ Polygon3r p1(points, oface->GetNormal());
+ Vec3r v1((p1.getVertices())[0]);
+ real d = -(v1 * p->getNormal());
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tp: " << (p->getVertices())[0] << (p->getVertices())[1] << (p->getVertices())[2]
+ << ", norm: " << p->getNormal() << endl;
+ cout << "\t\tp1: " << (p1.getVertices())[0] << (p1.getVertices())[1] << (p1.getVertices())[2]
+ << ", norm: " << p1.getNormal() << endl;
+ }
#else
- real d = -((p->getVertices())[0] * p->getNormal());
+ real d = -((p->getVertices())[0] * p->getNormal());
#endif
- if (face) {
+ if (face) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tDetermining face adjacency...";
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tDetermining face adjacency...";
+ }
#endif
- skipFace = false;
+ skipFace = false;
- if (face == oface) {
+ if (face == oface) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << " Rejecting occluder for face concurrency." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << " Rejecting occluder for face concurrency." << endl;
+ }
#endif
- continue;
- }
-
-
- for (vector<WVertex*>::iterator fv = faceVertices.begin(), fvend = faceVertices.end(); fv != fvend; ++fv) {
- if ((*fv)->isBoundary())
- continue;
-
- WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
- WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
- for (ie = iebegin; ie != ieend; ++ie) {
- if ((*ie) == 0)
- continue;
-
- WFace *sface = (*ie)->GetbFace();
- //WFace *sfacea = (*ie)->GetaFace();
- //if ((sface == oface) || (sfacea == oface))
- if (sface == oface) {
- skipFace = true;
- break;
- }
- }
- if (skipFace)
- break;
- }
- if (skipFace) {
+ continue;
+ }
+
+ for (vector<WVertex *>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
+ fv != fvend;
+ ++fv) {
+ if ((*fv)->isBoundary())
+ continue;
+
+ WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
+ WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
+ for (ie = iebegin; ie != ieend; ++ie) {
+ if ((*ie) == 0)
+ continue;
+
+ WFace *sface = (*ie)->GetbFace();
+ //WFace *sfacea = (*ie)->GetaFace();
+ //if ((sface == oface) || (sfacea == oface))
+ if (sface == oface) {
+ skipFace = true;
+ break;
+ }
+ }
+ if (skipFace)
+ break;
+ }
+ if (skipFace) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << " Rejecting occluder for face adjacency." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << " Rejecting occluder for face adjacency." << endl;
+ }
#endif
- continue;
- }
- }
- else {
- // check whether the edge and the polygon plane are coincident:
- //-------------------------------------------------------------
- //first let us compute the plane equation.
- if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, p->getNormal(), d, t, epsilon)) {
+ continue;
+ }
+ }
+ else {
+ // check whether the edge and the polygon plane are coincident:
+ //-------------------------------------------------------------
+ //first let us compute the plane equation.
+ if (GeomUtils::COINCIDENT ==
+ GeomUtils::intersectRayPlane(origin, edgeDir, p->getNormal(), d, t, epsilon)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tRejecting occluder for target coincidence." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tRejecting occluder for target coincidence." << endl;
+ }
#endif
- continue;
- }
- }
+ continue;
+ }
+ }
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- real x;
- if (p1.rayIntersect(center, v, x, t_u, t_v)) {
- cout << "\t\tRay should intersect at time " << (rl - x) << ". Center: " << center << ", V: " << v <<
- ", RL: " << rl << ", T:" << x << endl;
- }
- else {
- cout << "\t\tRay should not intersect. Center: " << center << ", V: " << v << ", RL: " << rl << endl;
- }
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ real x;
+ if (p1.rayIntersect(center, v, x, t_u, t_v)) {
+ cout << "\t\tRay should intersect at time " << (rl - x) << ". Center: " << center
+ << ", V: " << v << ", RL: " << rl << ", T:" << x << endl;
+ }
+ else {
+ cout << "\t\tRay should not intersect. Center: " << center << ", V: " << v
+ << ", RL: " << rl << endl;
+ }
+ }
#endif
- if (p->rayIntersect(center, u, t, t_u, t_v)) {
+ if (p->rayIntersect(center, u, t, t_u, t_v)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tRay " << center << " * " << u << " intersects at time " << t << " (raylength is " <<
- raylength << ")" << endl;
- cout << "\t\t(u * normal) == " << (u * p->getNormal()) << " for normal " << p->getNormal() << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tRay " << center << " * " << u << " intersects at time " << t
+ << " (raylength is " << raylength << ")" << endl;
+ cout << "\t\t(u * normal) == " << (u * p->getNormal()) << " for normal " << p->getNormal()
+ << endl;
+ }
#endif
- if (fabs(u * p->getNormal()) > 0.0001) {
- if ((t > 0.0) && (t < raylength)) {
+ if (fabs(u * p->getNormal()) > 0.0001) {
+ if ((t > 0.0) && (t < raylength)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tIs occluder" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tIs occluder" << endl;
+ }
#endif
- if ( foundOccluders != NULL ) {
- ViewShape *vshape = viewMap->viewShape(oface->GetVertex(0)->shape()->GetId());
- foundOccluders->insert(vshape);
- }
- ++qi;
-
- if (! grid.enableQI())
- break;
- }
-
- occluders.reportDepth(center, u, t);
- }
- }
- }
-
- // Find occludee
- findOccludee<G, I>(fe, grid, occluders, epsilon, oaWFace, u, center, origin, edgeDir, faceVertices);
-
- return qi;
+ if (foundOccluders != NULL) {
+ ViewShape *vshape = viewMap->viewShape(oface->GetVertex(0)->shape()->GetId());
+ foundOccluders->insert(vshape);
+ }
+ ++qi;
+
+ if (!grid.enableQI())
+ break;
+ }
+
+ occluders.reportDepth(center, u, t);
+ }
+ }
+ }
+
+ // Find occludee
+ findOccludee<G, I>(
+ fe, grid, occluders, epsilon, oaWFace, u, center, origin, edgeDir, faceVertices);
+
+ return qi;
}
// computeCumulativeVisibility returns the lowest x such that the majority of FEdges have QI <= x
@@ -400,1052 +418,1108 @@ static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon,
// FEdges are heavily occluded. computeCumulativeVisibility will treat this case as a QI of 22 because 3 out of
// 6 occluders have QI <= 22.
-template <typename G, typename I>
-static void computeCumulativeVisibility(ViewMap *ioViewMap, G& grid, real epsilon, RenderMonitor *iRenderMonitor)
+template<typename G, typename I>
+static void computeCumulativeVisibility(ViewMap *ioViewMap,
+ G &grid,
+ real epsilon,
+ RenderMonitor *iRenderMonitor)
{
- vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
-
- FEdge *fe, *festart;
- int nSamples = 0;
- vector<WFace*> wFaces;
- WFace *wFace = NULL;
- unsigned cnt = 0;
- unsigned cntStep = (unsigned)ceil(0.01f * vedges.size());
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
- for (vector<ViewEdge*>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
- if (iRenderMonitor) {
- if (iRenderMonitor->testBreak())
- break;
- if (cnt % cntStep == 0) {
- stringstream ss;
- ss << "Freestyle: Visibility computations " << (100 * cnt / vedges.size()) << "%";
- iRenderMonitor->setInfo(ss.str());
- iRenderMonitor->progress((float)cnt / vedges.size());
- }
- cnt++;
- }
+ vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
+
+ FEdge *fe, *festart;
+ int nSamples = 0;
+ vector<WFace *> wFaces;
+ WFace *wFace = NULL;
+ unsigned cnt = 0;
+ unsigned cntStep = (unsigned)ceil(0.01f * vedges.size());
+ unsigned tmpQI = 0;
+ unsigned qiClasses[256];
+ unsigned maxIndex, maxCard;
+ unsigned qiMajority;
+ for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
+ if (iRenderMonitor) {
+ if (iRenderMonitor->testBreak())
+ break;
+ if (cnt % cntStep == 0) {
+ stringstream ss;
+ ss << "Freestyle: Visibility computations " << (100 * cnt / vedges.size()) << "%";
+ iRenderMonitor->setInfo(ss.str());
+ iRenderMonitor->progress((float)cnt / vedges.size());
+ }
+ cnt++;
+ }
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Processing ViewEdge " << (*ve)->getId() << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Processing ViewEdge " << (*ve)->getId() << endl;
+ }
#endif
- // Find an edge to test
- if (!(*ve)->isInImage()) {
- // This view edge has been proscenium culled
- (*ve)->setQI(255);
- (*ve)->setaShape(0);
+ // Find an edge to test
+ if (!(*ve)->isInImage()) {
+ // This view edge has been proscenium culled
+ (*ve)->setQI(255);
+ (*ve)->setaShape(0);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tCulled." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tCulled." << endl;
+ }
#endif
- continue;
- }
-
- // Test edge
- festart = (*ve)->fedgeA();
- fe = (*ve)->fedgeA();
- qiMajority = 0;
- do {
- if (fe != NULL && fe->isInImage()) {
- qiMajority++;
- }
- fe = fe->nextEdge();
- } while (fe && fe != festart);
-
- if (qiMajority == 0) {
- // There are no occludable FEdges on this ViewEdge
- // This should be impossible.
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "View Edge in viewport without occludable FEdges: " << (*ve)->getId() << endl;
- }
- // We can recover from this error:
- // Treat this edge as fully visible with no occludee
- (*ve)->setQI(0);
- (*ve)->setaShape(0);
- continue;
- }
- else {
- ++qiMajority;
- qiMajority >>= 1;
- }
+ continue;
+ }
+
+ // Test edge
+ festart = (*ve)->fedgeA();
+ fe = (*ve)->fedgeA();
+ qiMajority = 0;
+ do {
+ if (fe != NULL && fe->isInImage()) {
+ qiMajority++;
+ }
+ fe = fe->nextEdge();
+ } while (fe && fe != festart);
+
+ if (qiMajority == 0) {
+ // There are no occludable FEdges on this ViewEdge
+ // This should be impossible.
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "View Edge in viewport without occludable FEdges: " << (*ve)->getId() << endl;
+ }
+ // We can recover from this error:
+ // Treat this edge as fully visible with no occludee
+ (*ve)->setQI(0);
+ (*ve)->setaShape(0);
+ continue;
+ }
+ else {
+ ++qiMajority;
+ qiMajority >>= 1;
+ }
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tqiMajority: " << qiMajority << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tqiMajority: " << qiMajority << endl;
+ }
#endif
- tmpQI = 0;
- maxIndex = 0;
- maxCard = 0;
- nSamples = 0;
- memset(qiClasses, 0, 256 * sizeof(*qiClasses));
- set<ViewShape*> foundOccluders;
-
- fe = (*ve)->fedgeA();
- do {
- if (!fe || !fe->isInImage()) {
- fe = fe->nextEdge();
- continue;
- }
- if ((maxCard < qiMajority)) {
- //ARB: change &wFace to wFace and use reference in called function
- tmpQI = computeVisibility<G, I>(ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders);
+ tmpQI = 0;
+ maxIndex = 0;
+ maxCard = 0;
+ nSamples = 0;
+ memset(qiClasses, 0, 256 * sizeof(*qiClasses));
+ set<ViewShape *> foundOccluders;
+
+ fe = (*ve)->fedgeA();
+ do {
+ if (!fe || !fe->isInImage()) {
+ fe = fe->nextEdge();
+ continue;
+ }
+ if ((maxCard < qiMajority)) {
+ //ARB: change &wFace to wFace and use reference in called function
+ tmpQI = computeVisibility<G, I>(
+ ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFEdge: visibility " << tmpQI << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFEdge: visibility " << tmpQI << endl;
+ }
#endif
- //ARB: This is an error condition, not an alert condition.
- // Some sort of recovery or abort is necessary.
- if (tmpQI >= 256) {
- cerr << "Warning: too many occluding levels" << endl;
- //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
- tmpQI = 255;
- }
-
- if (++qiClasses[tmpQI] > maxCard) {
- maxCard = qiClasses[tmpQI];
- maxIndex = tmpQI;
- }
- }
- else {
- //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
- //ARB: change &wFace to wFace and use reference in called function
- findOccludee<G, I>(fe, grid, epsilon, *ve, &wFace);
+ //ARB: This is an error condition, not an alert condition.
+ // Some sort of recovery or abort is necessary.
+ if (tmpQI >= 256) {
+ cerr << "Warning: too many occluding levels" << endl;
+ //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
+ tmpQI = 255;
+ }
+
+ if (++qiClasses[tmpQI] > maxCard) {
+ maxCard = qiClasses[tmpQI];
+ maxIndex = tmpQI;
+ }
+ }
+ else {
+ //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
+ //ARB: change &wFace to wFace and use reference in called function
+ findOccludee<G, I>(fe, grid, epsilon, *ve, &wFace);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFEdge: occludee only (" << (wFace != NULL ? "found" : "not found") << ")" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFEdge: occludee only (" << (wFace != NULL ? "found" : "not found") << ")"
+ << endl;
+ }
#endif
- }
-
- // Store test results
- if (wFace) {
- vector<Vec3r> vertices;
- for (int i = 0, numEdges = wFace->numberOfEdges(); i < numEdges; ++i) {
- vertices.push_back(Vec3r(wFace->GetVertex(i)->GetVertex()));
- }
- Polygon3r poly(vertices, wFace->GetNormal());
- poly.userdata = (void *)wFace;
- fe->setaFace(poly);
- wFaces.push_back(wFace);
- fe->setOccludeeEmpty(false);
+ }
+
+ // Store test results
+ if (wFace) {
+ vector<Vec3r> vertices;
+ for (int i = 0, numEdges = wFace->numberOfEdges(); i < numEdges; ++i) {
+ vertices.push_back(Vec3r(wFace->GetVertex(i)->GetVertex()));
+ }
+ Polygon3r poly(vertices, wFace->GetNormal());
+ poly.userdata = (void *)wFace;
+ fe->setaFace(poly);
+ wFaces.push_back(wFace);
+ fe->setOccludeeEmpty(false);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFound occludee" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFound occludee" << endl;
+ }
#endif
- }
- else {
- fe->setOccludeeEmpty(true);
- }
+ }
+ else {
+ fe->setOccludeeEmpty(true);
+ }
- ++nSamples;
- fe = fe->nextEdge();
- } while ((maxCard < qiMajority) && (fe) && (fe != festart));
+ ++nSamples;
+ fe = fe->nextEdge();
+ } while ((maxCard < qiMajority) && (fe) && (fe != festart));
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFinished with " << nSamples << " samples, maxCard = " << maxCard << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFinished with " << nSamples << " samples, maxCard = " << maxCard << endl;
+ }
#endif
- // ViewEdge
- // qi --
- // Find the minimum value that is >= the majority of the QI
- for (unsigned count = 0, i = 0; i < 256; ++i) {
- count += qiClasses[i];
- if (count >= qiMajority) {
- (*ve)->setQI(i);
- break;
- }
- }
- // occluders --
- // I would rather not have to go through the effort of creating this set and then copying out its contents.
- // Is there a reason why ViewEdge::_Occluders cannot be converted to a set<>?
- for (set<ViewShape*>::iterator o = foundOccluders.begin(), oend = foundOccluders.end(); o != oend; ++o) {
- (*ve)->AddOccluder((*o));
- }
+ // ViewEdge
+ // qi --
+ // Find the minimum value that is >= the majority of the QI
+ for (unsigned count = 0, i = 0; i < 256; ++i) {
+ count += qiClasses[i];
+ if (count >= qiMajority) {
+ (*ve)->setQI(i);
+ break;
+ }
+ }
+ // occluders --
+ // I would rather not have to go through the effort of creating this set and then copying out its contents.
+ // Is there a reason why ViewEdge::_Occluders cannot be converted to a set<>?
+ for (set<ViewShape *>::iterator o = foundOccluders.begin(), oend = foundOccluders.end();
+ o != oend;
+ ++o) {
+ (*ve)->AddOccluder((*o));
+ }
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tConclusion: QI = " << maxIndex << ", " << (*ve)->occluders_size() << " occluders." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tConclusion: QI = " << maxIndex << ", " << (*ve)->occluders_size() << " occluders."
+ << endl;
+ }
#else
- (void)maxIndex;
+ (void)maxIndex;
#endif
- // occludee --
- if (!wFaces.empty()) {
- if (wFaces.size() <= (float)nSamples / 2.0f) {
- (*ve)->setaShape(0);
- }
- else {
- ViewShape *vshape = ioViewMap->viewShape((*wFaces.begin())->GetVertex(0)->shape()->GetId());
- (*ve)->setaShape(vshape);
- }
- }
-
- wFaces.clear();
- }
- if (iRenderMonitor && vedges.size()) {
- stringstream ss;
- ss << "Freestyle: Visibility computations " << (100 * cnt / vedges.size()) << "%";
- iRenderMonitor->setInfo(ss.str());
- iRenderMonitor->progress((float)cnt / vedges.size());
- }
+ // occludee --
+ if (!wFaces.empty()) {
+ if (wFaces.size() <= (float)nSamples / 2.0f) {
+ (*ve)->setaShape(0);
+ }
+ else {
+ ViewShape *vshape = ioViewMap->viewShape(
+ (*wFaces.begin())->GetVertex(0)->shape()->GetId());
+ (*ve)->setaShape(vshape);
+ }
+ }
+
+ wFaces.clear();
+ }
+ if (iRenderMonitor && vedges.size()) {
+ stringstream ss;
+ ss << "Freestyle: Visibility computations " << (100 * cnt / vedges.size()) << "%";
+ iRenderMonitor->setInfo(ss.str());
+ iRenderMonitor->progress((float)cnt / vedges.size());
+ }
}
-template <typename G, typename I>
-static void computeDetailedVisibility(ViewMap *ioViewMap, G& grid, real epsilon, RenderMonitor *iRenderMonitor)
+template<typename G, typename I>
+static void computeDetailedVisibility(ViewMap *ioViewMap,
+ G &grid,
+ real epsilon,
+ RenderMonitor *iRenderMonitor)
{
- vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
-
- FEdge *fe, *festart;
- int nSamples = 0;
- vector<WFace*> wFaces;
- WFace *wFace = NULL;
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
- for (vector<ViewEdge*>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
- if (iRenderMonitor && iRenderMonitor->testBreak())
- break;
+ vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
+
+ FEdge *fe, *festart;
+ int nSamples = 0;
+ vector<WFace *> wFaces;
+ WFace *wFace = NULL;
+ unsigned tmpQI = 0;
+ unsigned qiClasses[256];
+ unsigned maxIndex, maxCard;
+ unsigned qiMajority;
+ for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
+ if (iRenderMonitor && iRenderMonitor->testBreak())
+ break;
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Processing ViewEdge " << (*ve)->getId() << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Processing ViewEdge " << (*ve)->getId() << endl;
+ }
#endif
- // Find an edge to test
- if (!(*ve)->isInImage()) {
- // This view edge has been proscenium culled
- (*ve)->setQI(255);
- (*ve)->setaShape(0);
+ // Find an edge to test
+ if (!(*ve)->isInImage()) {
+ // This view edge has been proscenium culled
+ (*ve)->setQI(255);
+ (*ve)->setaShape(0);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tCulled." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tCulled." << endl;
+ }
#endif
- continue;
- }
-
- // Test edge
- festart = (*ve)->fedgeA();
- fe = (*ve)->fedgeA();
- qiMajority = 0;
- do {
- if (fe != NULL && fe->isInImage()) {
- qiMajority++;
- }
- fe = fe->nextEdge();
- } while (fe && fe != festart);
-
- if (qiMajority == 0) {
- // There are no occludable FEdges on this ViewEdge
- // This should be impossible.
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "View Edge in viewport without occludable FEdges: " << (*ve)->getId() << endl;
- }
- // We can recover from this error:
- // Treat this edge as fully visible with no occludee
- (*ve)->setQI(0);
- (*ve)->setaShape(0);
- continue;
- }
- else {
- ++qiMajority;
- qiMajority >>= 1;
- }
+ continue;
+ }
+
+ // Test edge
+ festart = (*ve)->fedgeA();
+ fe = (*ve)->fedgeA();
+ qiMajority = 0;
+ do {
+ if (fe != NULL && fe->isInImage()) {
+ qiMajority++;
+ }
+ fe = fe->nextEdge();
+ } while (fe && fe != festart);
+
+ if (qiMajority == 0) {
+ // There are no occludable FEdges on this ViewEdge
+ // This should be impossible.
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "View Edge in viewport without occludable FEdges: " << (*ve)->getId() << endl;
+ }
+ // We can recover from this error:
+ // Treat this edge as fully visible with no occludee
+ (*ve)->setQI(0);
+ (*ve)->setaShape(0);
+ continue;
+ }
+ else {
+ ++qiMajority;
+ qiMajority >>= 1;
+ }
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tqiMajority: " << qiMajority << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tqiMajority: " << qiMajority << endl;
+ }
#endif
- tmpQI = 0;
- maxIndex = 0;
- maxCard = 0;
- nSamples = 0;
- memset(qiClasses, 0, 256 * sizeof(*qiClasses));
- set<ViewShape*> foundOccluders;
-
- fe = (*ve)->fedgeA();
- do {
- if (fe == NULL || ! fe->isInImage()) {
- fe = fe->nextEdge();
- continue;
- }
- if ((maxCard < qiMajority)) {
- //ARB: change &wFace to wFace and use reference in called function
- tmpQI = computeVisibility<G, I>(ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders);
+ tmpQI = 0;
+ maxIndex = 0;
+ maxCard = 0;
+ nSamples = 0;
+ memset(qiClasses, 0, 256 * sizeof(*qiClasses));
+ set<ViewShape *> foundOccluders;
+
+ fe = (*ve)->fedgeA();
+ do {
+ if (fe == NULL || !fe->isInImage()) {
+ fe = fe->nextEdge();
+ continue;
+ }
+ if ((maxCard < qiMajority)) {
+ //ARB: change &wFace to wFace and use reference in called function
+ tmpQI = computeVisibility<G, I>(
+ ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFEdge: visibility " << tmpQI << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFEdge: visibility " << tmpQI << endl;
+ }
#endif
- //ARB: This is an error condition, not an alert condition.
- // Some sort of recovery or abort is necessary.
- if (tmpQI >= 256) {
- cerr << "Warning: too many occluding levels" << endl;
- //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
- tmpQI = 255;
- }
-
- if (++qiClasses[tmpQI] > maxCard) {
- maxCard = qiClasses[tmpQI];
- maxIndex = tmpQI;
- }
- }
- else {
- //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
- //ARB: change &wFace to wFace and use reference in called function
- findOccludee<G, I>(fe, grid, epsilon, *ve, &wFace);
+ //ARB: This is an error condition, not an alert condition.
+ // Some sort of recovery or abort is necessary.
+ if (tmpQI >= 256) {
+ cerr << "Warning: too many occluding levels" << endl;
+ //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
+ tmpQI = 255;
+ }
+
+ if (++qiClasses[tmpQI] > maxCard) {
+ maxCard = qiClasses[tmpQI];
+ maxIndex = tmpQI;
+ }
+ }
+ else {
+ //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
+ //ARB: change &wFace to wFace and use reference in called function
+ findOccludee<G, I>(fe, grid, epsilon, *ve, &wFace);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFEdge: occludee only (" << (wFace != NULL ? "found" : "not found") << ")" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFEdge: occludee only (" << (wFace != NULL ? "found" : "not found") << ")"
+ << endl;
+ }
#endif
- }
-
- // Store test results
- if (wFace) {
- vector<Vec3r> vertices;
- for (int i = 0, numEdges = wFace->numberOfEdges(); i < numEdges; ++i) {
- vertices.push_back(Vec3r(wFace->GetVertex(i)->GetVertex()));
- }
- Polygon3r poly(vertices, wFace->GetNormal());
- poly.userdata = (void *)wFace;
- fe->setaFace(poly);
- wFaces.push_back(wFace);
- fe->setOccludeeEmpty(false);
+ }
+
+ // Store test results
+ if (wFace) {
+ vector<Vec3r> vertices;
+ for (int i = 0, numEdges = wFace->numberOfEdges(); i < numEdges; ++i) {
+ vertices.push_back(Vec3r(wFace->GetVertex(i)->GetVertex()));
+ }
+ Polygon3r poly(vertices, wFace->GetNormal());
+ poly.userdata = (void *)wFace;
+ fe->setaFace(poly);
+ wFaces.push_back(wFace);
+ fe->setOccludeeEmpty(false);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFound occludee" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFound occludee" << endl;
+ }
#endif
- }
- else {
- fe->setOccludeeEmpty(true);
- }
+ }
+ else {
+ fe->setOccludeeEmpty(true);
+ }
- ++nSamples;
- fe = fe->nextEdge();
- } while ((maxCard < qiMajority) && (fe) && (fe != festart));
+ ++nSamples;
+ fe = fe->nextEdge();
+ } while ((maxCard < qiMajority) && (fe) && (fe != festart));
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFinished with " << nSamples << " samples, maxCard = " << maxCard << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFinished with " << nSamples << " samples, maxCard = " << maxCard << endl;
+ }
#endif
- // ViewEdge
- // qi --
- (*ve)->setQI(maxIndex);
- // occluders --
- // I would rather not have to go through the effort of creating this this set and then copying out its contents.
- // Is there a reason why ViewEdge::_Occluders cannot be converted to a set<>?
- for (set<ViewShape*>::iterator o = foundOccluders.begin(), oend = foundOccluders.end(); o != oend; ++o) {
- (*ve)->AddOccluder((*o));
- }
+ // ViewEdge
+ // qi --
+ (*ve)->setQI(maxIndex);
+ // occluders --
+ // I would rather not have to go through the effort of creating this this set and then copying out its contents.
+ // Is there a reason why ViewEdge::_Occluders cannot be converted to a set<>?
+ for (set<ViewShape *>::iterator o = foundOccluders.begin(), oend = foundOccluders.end();
+ o != oend;
+ ++o) {
+ (*ve)->AddOccluder((*o));
+ }
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tConclusion: QI = " << maxIndex << ", " << (*ve)->occluders_size() << " occluders." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tConclusion: QI = " << maxIndex << ", " << (*ve)->occluders_size() << " occluders."
+ << endl;
+ }
#endif
- // occludee --
- if (!wFaces.empty()) {
- if (wFaces.size() <= (float)nSamples / 2.0f) {
- (*ve)->setaShape(0);
- }
- else {
- ViewShape *vshape = ioViewMap->viewShape((*wFaces.begin())->GetVertex(0)->shape()->GetId());
- (*ve)->setaShape(vshape);
- }
- }
-
- wFaces.clear();
- }
+ // occludee --
+ if (!wFaces.empty()) {
+ if (wFaces.size() <= (float)nSamples / 2.0f) {
+ (*ve)->setaShape(0);
+ }
+ else {
+ ViewShape *vshape = ioViewMap->viewShape(
+ (*wFaces.begin())->GetVertex(0)->shape()->GetId());
+ (*ve)->setaShape(vshape);
+ }
+ }
+
+ wFaces.clear();
+ }
}
-template <typename G, typename I>
-static void computeFastVisibility(ViewMap *ioViewMap, G& grid, real epsilon)
+template<typename G, typename I>
+static void computeFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon)
{
- vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
-
- FEdge *fe, *festart;
- unsigned nSamples = 0;
- vector<WFace*> wFaces;
- WFace *wFace = NULL;
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
- bool even_test;
- for (vector<ViewEdge*>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
- // Find an edge to test
- if (!(*ve)->isInImage()) {
- // This view edge has been proscenium culled
- (*ve)->setQI(255);
- (*ve)->setaShape(0);
- continue;
- }
-
- // Test edge
- festart = (*ve)->fedgeA();
- fe = (*ve)->fedgeA();
-
- even_test = true;
- qiMajority = 0;
- do {
- if (even_test && fe && fe->isInImage()) {
- qiMajority++;
- even_test = !even_test;
- }
- fe = fe->nextEdge();
- } while (fe && fe != festart);
-
- if (qiMajority == 0 ) {
- // There are no occludable FEdges on this ViewEdge
- // This should be impossible.
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "View Edge in viewport without occludable FEdges: " << (*ve)->getId() << endl;
- }
- // We can recover from this error:
- // Treat this edge as fully visible with no occludee
- (*ve)->setQI(0);
- (*ve)->setaShape(0);
- continue;
- }
- else {
- ++qiMajority;
- qiMajority >>= 1;
- }
-
- even_test = true;
- maxIndex = 0;
- maxCard = 0;
- nSamples = 0;
- memset(qiClasses, 0, 256 * sizeof(*qiClasses));
- set<ViewShape*> foundOccluders;
-
- fe = (*ve)->fedgeA();
- do {
- if (!fe || !fe->isInImage()) {
- fe = fe->nextEdge();
- continue;
- }
- if (even_test) {
- if ((maxCard < qiMajority)) {
- //ARB: change &wFace to wFace and use reference in called function
- tmpQI = computeVisibility<G, I>(ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders);
-
- //ARB: This is an error condition, not an alert condition.
- // Some sort of recovery or abort is necessary.
- if (tmpQI >= 256) {
- cerr << "Warning: too many occluding levels" << endl;
- //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
- tmpQI = 255;
- }
-
- if (++qiClasses[tmpQI] > maxCard) {
- maxCard = qiClasses[tmpQI];
- maxIndex = tmpQI;
- }
- }
- else {
- //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
- //ARB: change &wFace to wFace and use reference in called function
- findOccludee<G, I>(fe, grid, epsilon, *ve, &wFace);
- }
-
- if (wFace) {
- vector<Vec3r> vertices;
- for (int i = 0, numEdges = wFace->numberOfEdges(); i < numEdges; ++i) {
- vertices.push_back(Vec3r(wFace->GetVertex(i)->GetVertex()));
- }
- Polygon3r poly(vertices, wFace->GetNormal());
- poly.userdata = (void *)wFace;
- fe->setaFace(poly);
- wFaces.push_back(wFace);
- }
- ++nSamples;
- }
-
- even_test = ! even_test;
- fe = fe->nextEdge();
- } while ((maxCard < qiMajority) && (fe) && (fe != festart));
-
- // qi --
- (*ve)->setQI(maxIndex);
-
- // occluders --
- for (set<ViewShape*>::iterator o = foundOccluders.begin(), oend = foundOccluders.end(); o != oend; ++o) {
- (*ve)->AddOccluder((*o));
- }
-
- // occludee --
- if (!wFaces.empty()) {
- if (wFaces.size() < nSamples / 2) {
- (*ve)->setaShape(0);
- }
- else {
- ViewShape *vshape = ioViewMap->viewShape((*wFaces.begin())->GetVertex(0)->shape()->GetId());
- (*ve)->setaShape(vshape);
- }
- }
-
- wFaces.clear();
- }
+ vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
+
+ FEdge *fe, *festart;
+ unsigned nSamples = 0;
+ vector<WFace *> wFaces;
+ WFace *wFace = NULL;
+ unsigned tmpQI = 0;
+ unsigned qiClasses[256];
+ unsigned maxIndex, maxCard;
+ unsigned qiMajority;
+ bool even_test;
+ for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
+ // Find an edge to test
+ if (!(*ve)->isInImage()) {
+ // This view edge has been proscenium culled
+ (*ve)->setQI(255);
+ (*ve)->setaShape(0);
+ continue;
+ }
+
+ // Test edge
+ festart = (*ve)->fedgeA();
+ fe = (*ve)->fedgeA();
+
+ even_test = true;
+ qiMajority = 0;
+ do {
+ if (even_test && fe && fe->isInImage()) {
+ qiMajority++;
+ even_test = !even_test;
+ }
+ fe = fe->nextEdge();
+ } while (fe && fe != festart);
+
+ if (qiMajority == 0) {
+ // There are no occludable FEdges on this ViewEdge
+ // This should be impossible.
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "View Edge in viewport without occludable FEdges: " << (*ve)->getId() << endl;
+ }
+ // We can recover from this error:
+ // Treat this edge as fully visible with no occludee
+ (*ve)->setQI(0);
+ (*ve)->setaShape(0);
+ continue;
+ }
+ else {
+ ++qiMajority;
+ qiMajority >>= 1;
+ }
+
+ even_test = true;
+ maxIndex = 0;
+ maxCard = 0;
+ nSamples = 0;
+ memset(qiClasses, 0, 256 * sizeof(*qiClasses));
+ set<ViewShape *> foundOccluders;
+
+ fe = (*ve)->fedgeA();
+ do {
+ if (!fe || !fe->isInImage()) {
+ fe = fe->nextEdge();
+ continue;
+ }
+ if (even_test) {
+ if ((maxCard < qiMajority)) {
+ //ARB: change &wFace to wFace and use reference in called function
+ tmpQI = computeVisibility<G, I>(
+ ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders);
+
+ //ARB: This is an error condition, not an alert condition.
+ // Some sort of recovery or abort is necessary.
+ if (tmpQI >= 256) {
+ cerr << "Warning: too many occluding levels" << endl;
+ //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
+ tmpQI = 255;
+ }
+
+ if (++qiClasses[tmpQI] > maxCard) {
+ maxCard = qiClasses[tmpQI];
+ maxIndex = tmpQI;
+ }
+ }
+ else {
+ //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
+ //ARB: change &wFace to wFace and use reference in called function
+ findOccludee<G, I>(fe, grid, epsilon, *ve, &wFace);
+ }
+
+ if (wFace) {
+ vector<Vec3r> vertices;
+ for (int i = 0, numEdges = wFace->numberOfEdges(); i < numEdges; ++i) {
+ vertices.push_back(Vec3r(wFace->GetVertex(i)->GetVertex()));
+ }
+ Polygon3r poly(vertices, wFace->GetNormal());
+ poly.userdata = (void *)wFace;
+ fe->setaFace(poly);
+ wFaces.push_back(wFace);
+ }
+ ++nSamples;
+ }
+
+ even_test = !even_test;
+ fe = fe->nextEdge();
+ } while ((maxCard < qiMajority) && (fe) && (fe != festart));
+
+ // qi --
+ (*ve)->setQI(maxIndex);
+
+ // occluders --
+ for (set<ViewShape *>::iterator o = foundOccluders.begin(), oend = foundOccluders.end();
+ o != oend;
+ ++o) {
+ (*ve)->AddOccluder((*o));
+ }
+
+ // occludee --
+ if (!wFaces.empty()) {
+ if (wFaces.size() < nSamples / 2) {
+ (*ve)->setaShape(0);
+ }
+ else {
+ ViewShape *vshape = ioViewMap->viewShape(
+ (*wFaces.begin())->GetVertex(0)->shape()->GetId());
+ (*ve)->setaShape(vshape);
+ }
+ }
+
+ wFaces.clear();
+ }
}
-template <typename G, typename I>
-static void computeVeryFastVisibility(ViewMap *ioViewMap, G& grid, real epsilon)
+template<typename G, typename I>
+static void computeVeryFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon)
{
- vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
-
- FEdge *fe;
- unsigned qi = 0;
- WFace *wFace = 0;
-
- for (vector<ViewEdge*>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
- // Find an edge to test
- if (!(*ve)->isInImage()) {
- // This view edge has been proscenium culled
- (*ve)->setQI(255);
- (*ve)->setaShape(0);
- continue;
- }
- fe = (*ve)->fedgeA();
- // Find a FEdge inside the occluder proscenium to test for visibility
- FEdge *festart = fe;
- while (fe && !fe->isInImage() && fe != festart) {
- fe = fe->nextEdge();
- }
-
- // Test edge
- if (!fe || !fe->isInImage()) {
- // There are no occludable FEdges on this ViewEdge
- // This should be impossible.
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "View Edge in viewport without occludable FEdges: " << (*ve)->getId() << endl;
- }
- // We can recover from this error:
- // Treat this edge as fully visible with no occludee
- qi = 0;
- wFace = NULL;
- }
- else {
- qi = computeVisibility<G, I>(ioViewMap, fe, grid, epsilon, *ve, &wFace, NULL);
- }
-
- // Store test results
- if (wFace) {
- vector<Vec3r> vertices;
- for (int i = 0, numEdges = wFace->numberOfEdges(); i < numEdges; ++i) {
- vertices.push_back(Vec3r(wFace->GetVertex(i)->GetVertex()));
- }
- Polygon3r poly(vertices, wFace->GetNormal());
- poly.userdata = (void *)wFace;
- fe->setaFace(poly); // This works because setaFace *copies* the polygon
- ViewShape *vshape = ioViewMap->viewShape(wFace->GetVertex(0)->shape()->GetId());
- (*ve)->setaShape(vshape);
- }
- else {
- (*ve)->setaShape(0);
- }
- (*ve)->setQI(qi);
- }
+ vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
+
+ FEdge *fe;
+ unsigned qi = 0;
+ WFace *wFace = 0;
+
+ for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
+ // Find an edge to test
+ if (!(*ve)->isInImage()) {
+ // This view edge has been proscenium culled
+ (*ve)->setQI(255);
+ (*ve)->setaShape(0);
+ continue;
+ }
+ fe = (*ve)->fedgeA();
+ // Find a FEdge inside the occluder proscenium to test for visibility
+ FEdge *festart = fe;
+ while (fe && !fe->isInImage() && fe != festart) {
+ fe = fe->nextEdge();
+ }
+
+ // Test edge
+ if (!fe || !fe->isInImage()) {
+ // There are no occludable FEdges on this ViewEdge
+ // This should be impossible.
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "View Edge in viewport without occludable FEdges: " << (*ve)->getId() << endl;
+ }
+ // We can recover from this error:
+ // Treat this edge as fully visible with no occludee
+ qi = 0;
+ wFace = NULL;
+ }
+ else {
+ qi = computeVisibility<G, I>(ioViewMap, fe, grid, epsilon, *ve, &wFace, NULL);
+ }
+
+ // Store test results
+ if (wFace) {
+ vector<Vec3r> vertices;
+ for (int i = 0, numEdges = wFace->numberOfEdges(); i < numEdges; ++i) {
+ vertices.push_back(Vec3r(wFace->GetVertex(i)->GetVertex()));
+ }
+ Polygon3r poly(vertices, wFace->GetNormal());
+ poly.userdata = (void *)wFace;
+ fe->setaFace(poly); // This works because setaFace *copies* the polygon
+ ViewShape *vshape = ioViewMap->viewShape(wFace->GetVertex(0)->shape()->GetId());
+ (*ve)->setaShape(vshape);
+ }
+ else {
+ (*ve)->setaShape(0);
+ }
+ (*ve)->setQI(qi);
+ }
}
-void ViewMapBuilder::BuildGrid(WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces)
+void ViewMapBuilder::BuildGrid(WingedEdge &we, const BBox<Vec3r> &bbox, unsigned int sceneNumFaces)
{
- _Grid->clear();
- Vec3r size;
- for (unsigned int i = 0; i < 3; i++) {
- size[i] = fabs(bbox.getMax()[i] - bbox.getMin()[i]);
- // let make the grid 1/10 bigger to avoid numerical errors while computing triangles/cells intersections.
- size[i] += size[i] / 10.0;
- if (size[i] == 0) {
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Warning: the bbox size is 0 in dimension " << i << endl;
- }
- }
- }
- _Grid->configure(Vec3r(bbox.getMin() - size / 20.0), size, sceneNumFaces);
-
- // Fill in the grid:
- WFillGrid fillGridRenderer(_Grid, &we);
- fillGridRenderer.fillGrid();
-
- // DEBUG
- _Grid->displayDebug();
+ _Grid->clear();
+ Vec3r size;
+ for (unsigned int i = 0; i < 3; i++) {
+ size[i] = fabs(bbox.getMax()[i] - bbox.getMin()[i]);
+ // let make the grid 1/10 bigger to avoid numerical errors while computing triangles/cells intersections.
+ size[i] += size[i] / 10.0;
+ if (size[i] == 0) {
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Warning: the bbox size is 0 in dimension " << i << endl;
+ }
+ }
+ }
+ _Grid->configure(Vec3r(bbox.getMin() - size / 20.0), size, sceneNumFaces);
+
+ // Fill in the grid:
+ WFillGrid fillGridRenderer(_Grid, &we);
+ fillGridRenderer.fillGrid();
+
+ // DEBUG
+ _Grid->displayDebug();
}
-ViewMap *ViewMapBuilder::BuildViewMap(WingedEdge& we, visibility_algo iAlgo, real epsilon,
- const BBox<Vec3r>& bbox, unsigned int sceneNumFaces)
+ViewMap *ViewMapBuilder::BuildViewMap(WingedEdge &we,
+ visibility_algo iAlgo,
+ real epsilon,
+ const BBox<Vec3r> &bbox,
+ unsigned int sceneNumFaces)
{
- _ViewMap = new ViewMap;
- _currentId = 1;
- _currentFId = 0;
- _currentSVertexId = 0;
+ _ViewMap = new ViewMap;
+ _currentId = 1;
+ _currentFId = 0;
+ _currentSVertexId = 0;
- // Builds initial view edges
- computeInitialViewEdges(we);
+ // Builds initial view edges
+ computeInitialViewEdges(we);
- // Detects cusps
- computeCusps(_ViewMap);
+ // Detects cusps
+ computeCusps(_ViewMap);
- // Compute intersections
- ComputeIntersections(_ViewMap, sweep_line, epsilon);
+ // Compute intersections
+ ComputeIntersections(_ViewMap, sweep_line, epsilon);
- // Compute visibility
- ComputeEdgesVisibility(_ViewMap, we, bbox, sceneNumFaces, iAlgo, epsilon);
+ // Compute visibility
+ ComputeEdgesVisibility(_ViewMap, we, bbox, sceneNumFaces, iAlgo, epsilon);
- return _ViewMap;
+ return _ViewMap;
}
-static inline real distance2D(const Vec3r & point, const real origin[2])
+static inline real distance2D(const Vec3r &point, const real origin[2])
{
- return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
+ return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
}
static inline bool crossesProscenium(real proscenium[4], FEdge *fe)
{
- Vec2r min(proscenium[0], proscenium[2]);
- Vec2r max(proscenium[1], proscenium[3]);
- Vec2r A(fe->vertexA()->getProjectedX(), fe->vertexA()->getProjectedY());
- Vec2r B(fe->vertexB()->getProjectedX(), fe->vertexB()->getProjectedY());
+ Vec2r min(proscenium[0], proscenium[2]);
+ Vec2r max(proscenium[1], proscenium[3]);
+ Vec2r A(fe->vertexA()->getProjectedX(), fe->vertexA()->getProjectedY());
+ Vec2r B(fe->vertexB()->getProjectedX(), fe->vertexB()->getProjectedY());
- return GeomUtils::intersect2dSeg2dArea (min, max, A, B);
+ return GeomUtils::intersect2dSeg2dArea(min, max, A, B);
}
-static inline bool insideProscenium(real proscenium[4], const Vec3r& point)
+static inline bool insideProscenium(real proscenium[4], const Vec3r &point)
{
- return !(point[0] < proscenium[0] || point[0] > proscenium[1] ||
- point[1] < proscenium[2] || point[1] > proscenium[3]);
+ return !(point[0] < proscenium[0] || point[0] > proscenium[1] || point[1] < proscenium[2] ||
+ point[1] > proscenium[3]);
}
-void ViewMapBuilder::CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4],
+void ViewMapBuilder::CullViewEdges(ViewMap *ioViewMap,
+ real viewProscenium[4],
+ real occluderProscenium[4],
bool extensiveFEdgeSearch)
{
- // Cull view edges by marking them as non-displayable.
- // This avoids the complications of trying to delete edges from the ViewMap.
-
- // Non-displayable view edges will be skipped over during visibility calculation.
-
- // View edges will be culled according to their position w.r.t. the viewport proscenium (viewport + 5% border,
- // or some such).
-
- // Get proscenium boundary for culling
- GridHelpers::getDefaultViewProscenium(viewProscenium);
- real prosceniumOrigin[2];
- prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
- prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Proscenium culling:" << endl;
- cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2] <<
- ", " << viewProscenium[3] << "]"<< endl;
- cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]"<< endl;
- }
-
- // A separate occluder proscenium will also be maintained, starting out the same as the viewport proscenium, and
- // expanding as necessary so that it encompasses the center point of at least one feature edge in each retained view
- // edge.
- // The occluder proscenium will be used later to cull occluding triangles before they are inserted into the Grid.
- // The occluder proscenium starts out the same size as the view proscenium
- GridHelpers::getDefaultViewProscenium(occluderProscenium);
-
- // N.B. Freestyle is inconsistent in its use of ViewMap::viewedges_container and vector<ViewEdge*>::iterator.
- // Probably all occurences of vector<ViewEdge*>::iterator should be replaced ViewMap::viewedges_container
- // throughout the code.
- // For each view edge
- ViewMap::viewedges_container::iterator ve, veend;
-
- for (ve = ioViewMap->ViewEdges().begin(), veend = ioViewMap->ViewEdges().end(); ve != veend; ve++) {
- // Overview:
- // Search for a visible feature edge
- // If none: mark view edge as non-displayable
- // Otherwise:
- // Find a feature edge with center point inside occluder proscenium.
- // If none exists, find the feature edge with center point closest to viewport origin.
- // Expand occluder proscenium to enclose center point.
-
- // For each feature edge, while bestOccluderTarget not found and view edge not visibile
- bool bestOccluderTargetFound = false;
- FEdge *bestOccluderTarget = NULL;
- real bestOccluderDistance = 0.0;
- FEdge *festart = (*ve)->fedgeA();
- FEdge *fe = festart;
- // All ViewEdges start culled
- (*ve)->setIsInImage(false);
-
- // For simple visibility calculation: mark a feature edge that is known to have a center point inside the
- // occluder proscenium. Cull all other feature edges.
- do {
- // All FEdges start culled
- fe->setIsInImage(false);
-
- // Look for the visible edge that can most easily be included in the occluder proscenium.
- if (!bestOccluderTargetFound) {
- // If center point is inside occluder proscenium,
- if (insideProscenium(occluderProscenium, fe->center2d())) {
- // Use this feature edge for visibility deterimination
- fe->setIsInImage(true);
- // Mark bestOccluderTarget as found
- bestOccluderTargetFound = true;
- bestOccluderTarget = fe;
- }
- else {
- real d = distance2D(fe->center2d(), prosceniumOrigin);
- // If center point is closer to viewport origin than current target
- if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
- // Then store as bestOccluderTarget
- bestOccluderDistance = d;
- bestOccluderTarget = fe;
- }
- }
- }
-
- // If feature edge crosses the view proscenium
- if (!(*ve)->isInImage() && crossesProscenium(viewProscenium, fe)) {
- // Then the view edge will be included in the image
- (*ve)->setIsInImage(true);
- }
- fe = fe->nextEdge();
- } while (fe && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));
-
- // Either we have run out of FEdges, or we already have the one edge we need to determine visibility
- // Cull all remaining edges.
- while (fe && fe != festart) {
- fe->setIsInImage(false);
- fe = fe->nextEdge();
- }
-
- // If bestOccluderTarget was not found inside the occluder proscenium, we need to expand the occluder
- // proscenium to include it.
- if ((*ve)->isInImage() && bestOccluderTarget != NULL && !bestOccluderTargetFound) {
- // Expand occluder proscenium to enclose bestOccluderTarget
- Vec3r point = bestOccluderTarget->center2d();
- if (point[0] < occluderProscenium[0]) {
- occluderProscenium[0] = point[0];
- }
- else if (point[0] > occluderProscenium[1]) {
- occluderProscenium[1] = point[0];
- }
- if (point[1] < occluderProscenium[2]) {
- occluderProscenium[2] = point[1];
- }
- else if (point[1] > occluderProscenium[3]) {
- occluderProscenium[3] = point[1];
- }
- // Use bestOccluderTarget for visibility determination
- bestOccluderTarget->setIsInImage(true);
- }
- }
-
- // We are done calculating the occluder proscenium.
- // Expand the occluder proscenium by an epsilon to avoid rounding errors.
- const real epsilon = 1.0e-6;
- occluderProscenium[0] -= epsilon;
- occluderProscenium[1] += epsilon;
- occluderProscenium[2] -= epsilon;
- occluderProscenium[3] += epsilon;
-
- // For "Normal" or "Fast" style visibility computation only:
-
- // For more detailed visibility calculation, make a second pass through the view map, marking all feature edges
- // with center points inside the final occluder proscenium. All of these feature edges can be considered during
- // visibility calculation.
-
- // So far we have only found one FEdge per ViewEdge. The "Normal" and "Fast" styles of visibility computation
- // want to consider many FEdges for each ViewEdge.
- // Here we re-scan the view map to find any usable FEdges that we skipped on the first pass, or that have become
- // usable because the occluder proscenium has been expanded since the edge was visited on the first pass.
- if (extensiveFEdgeSearch) {
- // For each view edge,
- for (ve = ioViewMap->ViewEdges().begin(), veend = ioViewMap->ViewEdges().end(); ve != veend; ve++) {
- if (!(*ve)->isInImage()) {
- continue;
- }
- // For each feature edge,
- FEdge *festart = (*ve)->fedgeA();
- FEdge *fe = festart;
- do {
- // If not (already) visible and center point inside occluder proscenium,
- if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
- // Use the feature edge for visibility determination
- fe->setIsInImage(true);
- }
- fe = fe->nextEdge();
- } while (fe && fe != festart);
- }
- }
+ // Cull view edges by marking them as non-displayable.
+ // This avoids the complications of trying to delete edges from the ViewMap.
+
+ // Non-displayable view edges will be skipped over during visibility calculation.
+
+ // View edges will be culled according to their position w.r.t. the viewport proscenium (viewport + 5% border,
+ // or some such).
+
+ // Get proscenium boundary for culling
+ GridHelpers::getDefaultViewProscenium(viewProscenium);
+ real prosceniumOrigin[2];
+ prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
+ prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Proscenium culling:" << endl;
+ cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", "
+ << viewProscenium[2] << ", " << viewProscenium[3] << "]" << endl;
+ cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]" << endl;
+ }
+
+ // A separate occluder proscenium will also be maintained, starting out the same as the viewport proscenium, and
+ // expanding as necessary so that it encompasses the center point of at least one feature edge in each retained view
+ // edge.
+ // The occluder proscenium will be used later to cull occluding triangles before they are inserted into the Grid.
+ // The occluder proscenium starts out the same size as the view proscenium
+ GridHelpers::getDefaultViewProscenium(occluderProscenium);
+
+ // N.B. Freestyle is inconsistent in its use of ViewMap::viewedges_container and vector<ViewEdge*>::iterator.
+ // Probably all occurences of vector<ViewEdge*>::iterator should be replaced ViewMap::viewedges_container
+ // throughout the code.
+ // For each view edge
+ ViewMap::viewedges_container::iterator ve, veend;
+
+ for (ve = ioViewMap->ViewEdges().begin(), veend = ioViewMap->ViewEdges().end(); ve != veend;
+ ve++) {
+ // Overview:
+ // Search for a visible feature edge
+ // If none: mark view edge as non-displayable
+ // Otherwise:
+ // Find a feature edge with center point inside occluder proscenium.
+ // If none exists, find the feature edge with center point closest to viewport origin.
+ // Expand occluder proscenium to enclose center point.
+
+ // For each feature edge, while bestOccluderTarget not found and view edge not visibile
+ bool bestOccluderTargetFound = false;
+ FEdge *bestOccluderTarget = NULL;
+ real bestOccluderDistance = 0.0;
+ FEdge *festart = (*ve)->fedgeA();
+ FEdge *fe = festart;
+ // All ViewEdges start culled
+ (*ve)->setIsInImage(false);
+
+ // For simple visibility calculation: mark a feature edge that is known to have a center point inside the
+ // occluder proscenium. Cull all other feature edges.
+ do {
+ // All FEdges start culled
+ fe->setIsInImage(false);
+
+ // Look for the visible edge that can most easily be included in the occluder proscenium.
+ if (!bestOccluderTargetFound) {
+ // If center point is inside occluder proscenium,
+ if (insideProscenium(occluderProscenium, fe->center2d())) {
+ // Use this feature edge for visibility deterimination
+ fe->setIsInImage(true);
+ // Mark bestOccluderTarget as found
+ bestOccluderTargetFound = true;
+ bestOccluderTarget = fe;
+ }
+ else {
+ real d = distance2D(fe->center2d(), prosceniumOrigin);
+ // If center point is closer to viewport origin than current target
+ if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
+ // Then store as bestOccluderTarget
+ bestOccluderDistance = d;
+ bestOccluderTarget = fe;
+ }
+ }
+ }
+
+ // If feature edge crosses the view proscenium
+ if (!(*ve)->isInImage() && crossesProscenium(viewProscenium, fe)) {
+ // Then the view edge will be included in the image
+ (*ve)->setIsInImage(true);
+ }
+ fe = fe->nextEdge();
+ } while (fe && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));
+
+ // Either we have run out of FEdges, or we already have the one edge we need to determine visibility
+ // Cull all remaining edges.
+ while (fe && fe != festart) {
+ fe->setIsInImage(false);
+ fe = fe->nextEdge();
+ }
+
+ // If bestOccluderTarget was not found inside the occluder proscenium, we need to expand the occluder
+ // proscenium to include it.
+ if ((*ve)->isInImage() && bestOccluderTarget != NULL && !bestOccluderTargetFound) {
+ // Expand occluder proscenium to enclose bestOccluderTarget
+ Vec3r point = bestOccluderTarget->center2d();
+ if (point[0] < occluderProscenium[0]) {
+ occluderProscenium[0] = point[0];
+ }
+ else if (point[0] > occluderProscenium[1]) {
+ occluderProscenium[1] = point[0];
+ }
+ if (point[1] < occluderProscenium[2]) {
+ occluderProscenium[2] = point[1];
+ }
+ else if (point[1] > occluderProscenium[3]) {
+ occluderProscenium[3] = point[1];
+ }
+ // Use bestOccluderTarget for visibility determination
+ bestOccluderTarget->setIsInImage(true);
+ }
+ }
+
+ // We are done calculating the occluder proscenium.
+ // Expand the occluder proscenium by an epsilon to avoid rounding errors.
+ const real epsilon = 1.0e-6;
+ occluderProscenium[0] -= epsilon;
+ occluderProscenium[1] += epsilon;
+ occluderProscenium[2] -= epsilon;
+ occluderProscenium[3] += epsilon;
+
+ // For "Normal" or "Fast" style visibility computation only:
+
+ // For more detailed visibility calculation, make a second pass through the view map, marking all feature edges
+ // with center points inside the final occluder proscenium. All of these feature edges can be considered during
+ // visibility calculation.
+
+ // So far we have only found one FEdge per ViewEdge. The "Normal" and "Fast" styles of visibility computation
+ // want to consider many FEdges for each ViewEdge.
+ // Here we re-scan the view map to find any usable FEdges that we skipped on the first pass, or that have become
+ // usable because the occluder proscenium has been expanded since the edge was visited on the first pass.
+ if (extensiveFEdgeSearch) {
+ // For each view edge,
+ for (ve = ioViewMap->ViewEdges().begin(), veend = ioViewMap->ViewEdges().end(); ve != veend;
+ ve++) {
+ if (!(*ve)->isInImage()) {
+ continue;
+ }
+ // For each feature edge,
+ FEdge *festart = (*ve)->fedgeA();
+ FEdge *fe = festart;
+ do {
+ // If not (already) visible and center point inside occluder proscenium,
+ if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
+ // Use the feature edge for visibility determination
+ fe->setIsInImage(true);
+ }
+ fe = fe->nextEdge();
+ } while (fe && fe != festart);
+ }
+ }
}
-void ViewMapBuilder::computeInitialViewEdges(WingedEdge& we)
+void ViewMapBuilder::computeInitialViewEdges(WingedEdge &we)
{
- vector<WShape*> wshapes = we.getWShapes();
- SShape *psShape;
-
- for (vector<WShape*>::const_iterator it = wshapes.begin(); it != wshapes.end(); it++) {
- if (_pRenderMonitor && _pRenderMonitor->testBreak())
- break;
-
- // create the embedding
- psShape = new SShape;
- psShape->setId((*it)->GetId());
- psShape->setName((*it)->getName());
- psShape->setLibraryPath((*it)->getLibraryPath());
- psShape->setFrsMaterials((*it)->frs_materials()); // FIXME
-
- // create the view shape
- ViewShape *vshape = new ViewShape(psShape);
- // add this view shape to the view map:
- _ViewMap->AddViewShape(vshape);
-
- // we want to number the view edges in a unique way for the while scene.
- _pViewEdgeBuilder->setCurrentViewId(_currentId);
- // we want to number the feature edges in a unique way for the while scene.
- _pViewEdgeBuilder->setCurrentFId(_currentFId);
- // we want to number the SVertex in a unique way for the while scene.
- _pViewEdgeBuilder->setCurrentSVertexId(_currentFId);
- _pViewEdgeBuilder->BuildViewEdges(dynamic_cast<WXShape*>(*it), vshape, _ViewMap->ViewEdges(),
- _ViewMap->ViewVertices(), _ViewMap->FEdges(), _ViewMap->SVertices());
-
- _currentId = _pViewEdgeBuilder->currentViewId() + 1;
- _currentFId = _pViewEdgeBuilder->currentFId() + 1;
- _currentSVertexId = _pViewEdgeBuilder->currentSVertexId() + 1;
-
- psShape->ComputeBBox();
- }
+ vector<WShape *> wshapes = we.getWShapes();
+ SShape *psShape;
+
+ for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); it++) {
+ if (_pRenderMonitor && _pRenderMonitor->testBreak())
+ break;
+
+ // create the embedding
+ psShape = new SShape;
+ psShape->setId((*it)->GetId());
+ psShape->setName((*it)->getName());
+ psShape->setLibraryPath((*it)->getLibraryPath());
+ psShape->setFrsMaterials((*it)->frs_materials()); // FIXME
+
+ // create the view shape
+ ViewShape *vshape = new ViewShape(psShape);
+ // add this view shape to the view map:
+ _ViewMap->AddViewShape(vshape);
+
+ // we want to number the view edges in a unique way for the while scene.
+ _pViewEdgeBuilder->setCurrentViewId(_currentId);
+ // we want to number the feature edges in a unique way for the while scene.
+ _pViewEdgeBuilder->setCurrentFId(_currentFId);
+ // we want to number the SVertex in a unique way for the while scene.
+ _pViewEdgeBuilder->setCurrentSVertexId(_currentFId);
+ _pViewEdgeBuilder->BuildViewEdges(dynamic_cast<WXShape *>(*it),
+ vshape,
+ _ViewMap->ViewEdges(),
+ _ViewMap->ViewVertices(),
+ _ViewMap->FEdges(),
+ _ViewMap->SVertices());
+
+ _currentId = _pViewEdgeBuilder->currentViewId() + 1;
+ _currentFId = _pViewEdgeBuilder->currentFId() + 1;
+ _currentSVertexId = _pViewEdgeBuilder->currentSVertexId() + 1;
+
+ psShape->ComputeBBox();
+ }
}
void ViewMapBuilder::computeCusps(ViewMap *ioViewMap)
{
- vector<ViewVertex*> newVVertices;
- vector<ViewEdge*> newVEdges;
- ViewMap::viewedges_container& vedges = ioViewMap->ViewEdges();
- ViewMap::viewedges_container::iterator ve = vedges.begin(), veend = vedges.end();
- for (; ve != veend; ++ve) {
- if (_pRenderMonitor && _pRenderMonitor->testBreak())
- break;
- if ((!((*ve)->getNature() & Nature::SILHOUETTE)) || (!((*ve)->fedgeA()->isSmooth())))
- continue;
- FEdge *fe = (*ve)->fedgeA();
- FEdge *fefirst = fe;
- bool first = true;
- bool positive = true;
- do {
- FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(fe);
- Vec3r A((fes)->vertexA()->point3d());
- Vec3r B((fes)->vertexB()->point3d());
- Vec3r AB(B - A);
- AB.normalize();
- Vec3r m((A + B) / 2.0);
- Vec3r crossP(AB ^ (fes)->normal());
- crossP.normalize();
- Vec3r viewvector;
- if (_orthographicProjection) {
- viewvector = Vec3r(0.0, 0.0, m.z() - _viewpoint.z());
- }
- else {
- viewvector = Vec3r(m - _viewpoint);
- }
- viewvector.normalize();
- if (first) {
- if (((crossP) * (viewvector)) > 0)
- positive = true;
- else
- positive = false;
- first = false;
- }
- // If we're in a positive part, we need a stronger negative value to change
- NonTVertex *cusp = NULL;
- if (positive) {
- if (((crossP) * (viewvector)) < -0.1) {
- // state changes
- positive = false;
- // creates and insert cusp
- cusp = dynamic_cast<NonTVertex*>(ioViewMap->InsertViewVertex(fes->vertexA(), newVEdges));
- if (cusp)
- cusp->setNature(cusp->getNature() | Nature::CUSP);
- }
- }
- else {
- // If we're in a negative part, we need a stronger negative value to change
- if (((crossP) * (viewvector)) > 0.1) {
- positive = true;
- cusp = dynamic_cast<NonTVertex*>(ioViewMap->InsertViewVertex(fes->vertexA(), newVEdges));
- if (cusp)
- cusp->setNature(cusp->getNature() | Nature::CUSP);
- }
- }
- fe = fe->nextEdge();
- } while (fe && fe != fefirst);
- }
- for (ve = newVEdges.begin(), veend = newVEdges.end(); ve != veend; ++ve) {
- (*ve)->viewShape()->AddEdge(*ve);
- vedges.push_back(*ve);
- }
+ vector<ViewVertex *> newVVertices;
+ vector<ViewEdge *> newVEdges;
+ ViewMap::viewedges_container &vedges = ioViewMap->ViewEdges();
+ ViewMap::viewedges_container::iterator ve = vedges.begin(), veend = vedges.end();
+ for (; ve != veend; ++ve) {
+ if (_pRenderMonitor && _pRenderMonitor->testBreak())
+ break;
+ if ((!((*ve)->getNature() & Nature::SILHOUETTE)) || (!((*ve)->fedgeA()->isSmooth())))
+ continue;
+ FEdge *fe = (*ve)->fedgeA();
+ FEdge *fefirst = fe;
+ bool first = true;
+ bool positive = true;
+ do {
+ FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
+ Vec3r A((fes)->vertexA()->point3d());
+ Vec3r B((fes)->vertexB()->point3d());
+ Vec3r AB(B - A);
+ AB.normalize();
+ Vec3r m((A + B) / 2.0);
+ Vec3r crossP(AB ^ (fes)->normal());
+ crossP.normalize();
+ Vec3r viewvector;
+ if (_orthographicProjection) {
+ viewvector = Vec3r(0.0, 0.0, m.z() - _viewpoint.z());
+ }
+ else {
+ viewvector = Vec3r(m - _viewpoint);
+ }
+ viewvector.normalize();
+ if (first) {
+ if (((crossP) * (viewvector)) > 0)
+ positive = true;
+ else
+ positive = false;
+ first = false;
+ }
+ // If we're in a positive part, we need a stronger negative value to change
+ NonTVertex *cusp = NULL;
+ if (positive) {
+ if (((crossP) * (viewvector)) < -0.1) {
+ // state changes
+ positive = false;
+ // creates and insert cusp
+ cusp = dynamic_cast<NonTVertex *>(
+ ioViewMap->InsertViewVertex(fes->vertexA(), newVEdges));
+ if (cusp)
+ cusp->setNature(cusp->getNature() | Nature::CUSP);
+ }
+ }
+ else {
+ // If we're in a negative part, we need a stronger negative value to change
+ if (((crossP) * (viewvector)) > 0.1) {
+ positive = true;
+ cusp = dynamic_cast<NonTVertex *>(
+ ioViewMap->InsertViewVertex(fes->vertexA(), newVEdges));
+ if (cusp)
+ cusp->setNature(cusp->getNature() | Nature::CUSP);
+ }
+ }
+ fe = fe->nextEdge();
+ } while (fe && fe != fefirst);
+ }
+ for (ve = newVEdges.begin(), veend = newVEdges.end(); ve != veend; ++ve) {
+ (*ve)->viewShape()->AddEdge(*ve);
+ vedges.push_back(*ve);
+ }
}
-void ViewMapBuilder::ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox,
- real epsilon, bool cull, GridDensityProviderFactory& factory)
+void ViewMapBuilder::ComputeCumulativeVisibility(ViewMap *ioViewMap,
+ WingedEdge &we,
+ const BBox<Vec3r> &bbox,
+ real epsilon,
+ bool cull,
+ GridDensityProviderFactory &factory)
{
- AutoPtr<GridHelpers::Transform> transform;
- AutoPtr<OccluderSource> source;
-
- if (_orthographicProjection) {
- transform.reset(new BoxGrid::Transform);
- }
- else {
- transform.reset(new SphericalGrid::Transform);
- }
-
- if (cull) {
- source.reset(new CulledOccluderSource(*transform, we, *ioViewMap, true));
- }
- else {
- source.reset(new OccluderSource(*transform, we));
- }
-
- AutoPtr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
-
- if (_orthographicProjection) {
- BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
- computeCumulativeVisibility<BoxGrid, BoxGrid::Iterator>(ioViewMap, grid, epsilon, _pRenderMonitor);
- }
- else {
- SphericalGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
- computeCumulativeVisibility<SphericalGrid, SphericalGrid::Iterator>(ioViewMap, grid, epsilon, _pRenderMonitor);
- }
+ AutoPtr<GridHelpers::Transform> transform;
+ AutoPtr<OccluderSource> source;
+
+ if (_orthographicProjection) {
+ transform.reset(new BoxGrid::Transform);
+ }
+ else {
+ transform.reset(new SphericalGrid::Transform);
+ }
+
+ if (cull) {
+ source.reset(new CulledOccluderSource(*transform, we, *ioViewMap, true));
+ }
+ else {
+ source.reset(new OccluderSource(*transform, we));
+ }
+
+ AutoPtr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
+
+ if (_orthographicProjection) {
+ BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
+ computeCumulativeVisibility<BoxGrid, BoxGrid::Iterator>(
+ ioViewMap, grid, epsilon, _pRenderMonitor);
+ }
+ else {
+ SphericalGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
+ computeCumulativeVisibility<SphericalGrid, SphericalGrid::Iterator>(
+ ioViewMap, grid, epsilon, _pRenderMonitor);
+ }
}
-void ViewMapBuilder::ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox,
- real epsilon, bool cull, GridDensityProviderFactory& factory)
+void ViewMapBuilder::ComputeDetailedVisibility(ViewMap *ioViewMap,
+ WingedEdge &we,
+ const BBox<Vec3r> &bbox,
+ real epsilon,
+ bool cull,
+ GridDensityProviderFactory &factory)
{
- AutoPtr<GridHelpers::Transform> transform;
- AutoPtr<OccluderSource> source;
-
- if (_orthographicProjection) {
- transform.reset(new BoxGrid::Transform);
- }
- else {
- transform.reset(new SphericalGrid::Transform);
- }
-
- if (cull) {
- source.reset(new CulledOccluderSource(*transform, we, *ioViewMap, true));
- }
- else {
- source.reset(new OccluderSource(*transform, we));
- }
-
- AutoPtr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
-
- if (_orthographicProjection) {
- BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
- computeDetailedVisibility<BoxGrid, BoxGrid::Iterator>(ioViewMap, grid, epsilon, _pRenderMonitor);
- }
- else {
- SphericalGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
- computeDetailedVisibility<SphericalGrid, SphericalGrid::Iterator>(ioViewMap, grid, epsilon, _pRenderMonitor);
- }
+ AutoPtr<GridHelpers::Transform> transform;
+ AutoPtr<OccluderSource> source;
+
+ if (_orthographicProjection) {
+ transform.reset(new BoxGrid::Transform);
+ }
+ else {
+ transform.reset(new SphericalGrid::Transform);
+ }
+
+ if (cull) {
+ source.reset(new CulledOccluderSource(*transform, we, *ioViewMap, true));
+ }
+ else {
+ source.reset(new OccluderSource(*transform, we));
+ }
+
+ AutoPtr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
+
+ if (_orthographicProjection) {
+ BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
+ computeDetailedVisibility<BoxGrid, BoxGrid::Iterator>(
+ ioViewMap, grid, epsilon, _pRenderMonitor);
+ }
+ else {
+ SphericalGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
+ computeDetailedVisibility<SphericalGrid, SphericalGrid::Iterator>(
+ ioViewMap, grid, epsilon, _pRenderMonitor);
+ }
}
-void ViewMapBuilder::ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox,
- unsigned int sceneNumFaces, visibility_algo iAlgo, real epsilon)
+void ViewMapBuilder::ComputeEdgesVisibility(ViewMap *ioViewMap,
+ WingedEdge &we,
+ const BBox<Vec3r> &bbox,
+ unsigned int sceneNumFaces,
+ visibility_algo iAlgo,
+ real epsilon)
{
#if 0
- iAlgo = ray_casting; // for testing algorithms equivalence
+ iAlgo = ray_casting; // for testing algorithms equivalence
#endif
- switch (iAlgo) {
- case ray_casting:
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Using ordinary ray casting" << endl;
- }
- BuildGrid(we, bbox, sceneNumFaces);
- ComputeRayCastingVisibility(ioViewMap, epsilon);
- break;
- case ray_casting_fast:
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Using fast ray casting" << endl;
- }
- BuildGrid(we, bbox, sceneNumFaces);
- ComputeFastRayCastingVisibility(ioViewMap, epsilon);
- break;
- case ray_casting_very_fast:
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Using very fast ray casting" << endl;
- }
- BuildGrid(we, bbox, sceneNumFaces);
- ComputeVeryFastRayCastingVisibility(ioViewMap, epsilon);
- break;
- case ray_casting_culled_adaptive_traditional:
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Using culled adaptive grid with heuristic density and traditional QI calculation" << endl;
- }
- try {
- HeuristicGridDensityProviderFactory factory(0.5f, sceneNumFaces);
- ComputeDetailedVisibility(ioViewMap, we, bbox, epsilon, true, factory);
- }
- catch (...) {
- // Last resort catch to make sure RAII semantics hold for OptimizedGrid. Can be replaced with
- // try...catch block around main() if the program as a whole is converted to RAII
-
- // This is the little-mentioned caveat of RAII: RAII does not work unless destructors are always
- // called, but destructors are only called if all exceptions are caught (or std::terminate() is
- // replaced).
-
- // We don't actually handle the exception here, so re-throw it now that our destructors have had a
- // chance to run.
- throw;
- }
- break;
- case ray_casting_adaptive_traditional:
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Using unculled adaptive grid with heuristic density and traditional QI calculation" << endl;
- }
- try {
- HeuristicGridDensityProviderFactory factory(0.5f, sceneNumFaces);
- ComputeDetailedVisibility(ioViewMap, we, bbox, epsilon, false, factory);
- }
- catch (...) {
- throw;
- }
- break;
- case ray_casting_culled_adaptive_cumulative:
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Using culled adaptive grid with heuristic density and cumulative QI calculation" << endl;
- }
- try {
- HeuristicGridDensityProviderFactory factory(0.5f, sceneNumFaces);
- ComputeCumulativeVisibility(ioViewMap, we, bbox, epsilon, true, factory);
- }
- catch (...) {
- throw;
- }
- break;
- case ray_casting_adaptive_cumulative:
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Using unculled adaptive grid with heuristic density and cumulative QI calculation" << endl;
- }
- try {
- HeuristicGridDensityProviderFactory factory(0.5f, sceneNumFaces);
- ComputeCumulativeVisibility(ioViewMap, we, bbox, epsilon, false, factory);
- }
- catch (...) {
- throw;
- }
- break;
- default:
- break;
- }
+ switch (iAlgo) {
+ case ray_casting:
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Using ordinary ray casting" << endl;
+ }
+ BuildGrid(we, bbox, sceneNumFaces);
+ ComputeRayCastingVisibility(ioViewMap, epsilon);
+ break;
+ case ray_casting_fast:
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Using fast ray casting" << endl;
+ }
+ BuildGrid(we, bbox, sceneNumFaces);
+ ComputeFastRayCastingVisibility(ioViewMap, epsilon);
+ break;
+ case ray_casting_very_fast:
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Using very fast ray casting" << endl;
+ }
+ BuildGrid(we, bbox, sceneNumFaces);
+ ComputeVeryFastRayCastingVisibility(ioViewMap, epsilon);
+ break;
+ case ray_casting_culled_adaptive_traditional:
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Using culled adaptive grid with heuristic density and traditional QI calculation"
+ << endl;
+ }
+ try {
+ HeuristicGridDensityProviderFactory factory(0.5f, sceneNumFaces);
+ ComputeDetailedVisibility(ioViewMap, we, bbox, epsilon, true, factory);
+ }
+ catch (...) {
+ // Last resort catch to make sure RAII semantics hold for OptimizedGrid. Can be replaced with
+ // try...catch block around main() if the program as a whole is converted to RAII
+
+ // This is the little-mentioned caveat of RAII: RAII does not work unless destructors are always
+ // called, but destructors are only called if all exceptions are caught (or std::terminate() is
+ // replaced).
+
+ // We don't actually handle the exception here, so re-throw it now that our destructors have had a
+ // chance to run.
+ throw;
+ }
+ break;
+ case ray_casting_adaptive_traditional:
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout
+ << "Using unculled adaptive grid with heuristic density and traditional QI calculation"
+ << endl;
+ }
+ try {
+ HeuristicGridDensityProviderFactory factory(0.5f, sceneNumFaces);
+ ComputeDetailedVisibility(ioViewMap, we, bbox, epsilon, false, factory);
+ }
+ catch (...) {
+ throw;
+ }
+ break;
+ case ray_casting_culled_adaptive_cumulative:
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Using culled adaptive grid with heuristic density and cumulative QI calculation"
+ << endl;
+ }
+ try {
+ HeuristicGridDensityProviderFactory factory(0.5f, sceneNumFaces);
+ ComputeCumulativeVisibility(ioViewMap, we, bbox, epsilon, true, factory);
+ }
+ catch (...) {
+ throw;
+ }
+ break;
+ case ray_casting_adaptive_cumulative:
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Using unculled adaptive grid with heuristic density and cumulative QI calculation"
+ << endl;
+ }
+ try {
+ HeuristicGridDensityProviderFactory factory(0.5f, sceneNumFaces);
+ ComputeCumulativeVisibility(ioViewMap, we, bbox, epsilon, false, factory);
+ }
+ catch (...) {
+ throw;
+ }
+ break;
+ default:
+ break;
+ }
}
static const unsigned gProgressBarMaxSteps = 10;
@@ -1453,960 +1527,984 @@ static const unsigned gProgressBarMinSize = 2000;
void ViewMapBuilder::ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon)
{
- vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
- bool progressBarDisplay = false;
- unsigned progressBarStep = 0;
- unsigned vEdgesSize = vedges.size();
- unsigned fEdgesSize = ioViewMap->FEdges().size();
-
- if (_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) {
- unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
- progressBarStep = vEdgesSize / progressBarSteps;
- _pProgressBar->reset();
- _pProgressBar->setLabelText("Computing Ray casting Visibility");
- _pProgressBar->setTotalSteps(progressBarSteps);
- _pProgressBar->setProgress(0);
- progressBarDisplay = true;
- }
-
- unsigned counter = progressBarStep;
- FEdge *fe, *festart;
- int nSamples = 0;
- vector<Polygon3r*> aFaces;
- Polygon3r *aFace = NULL;
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
- static unsigned timestamp = 1;
- for (vector<ViewEdge*>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
- if (_pRenderMonitor && _pRenderMonitor->testBreak())
- break;
+ vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
+ bool progressBarDisplay = false;
+ unsigned progressBarStep = 0;
+ unsigned vEdgesSize = vedges.size();
+ unsigned fEdgesSize = ioViewMap->FEdges().size();
+
+ if (_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) {
+ unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
+ progressBarStep = vEdgesSize / progressBarSteps;
+ _pProgressBar->reset();
+ _pProgressBar->setLabelText("Computing Ray casting Visibility");
+ _pProgressBar->setTotalSteps(progressBarSteps);
+ _pProgressBar->setProgress(0);
+ progressBarDisplay = true;
+ }
+
+ unsigned counter = progressBarStep;
+ FEdge *fe, *festart;
+ int nSamples = 0;
+ vector<Polygon3r *> aFaces;
+ Polygon3r *aFace = NULL;
+ unsigned tmpQI = 0;
+ unsigned qiClasses[256];
+ unsigned maxIndex, maxCard;
+ unsigned qiMajority;
+ static unsigned timestamp = 1;
+ for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
+ if (_pRenderMonitor && _pRenderMonitor->testBreak())
+ break;
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "Processing ViewEdge " << (*ve)->getId() << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "Processing ViewEdge " << (*ve)->getId() << endl;
+ }
#endif
- festart = (*ve)->fedgeA();
- fe = (*ve)->fedgeA();
- qiMajority = 1;
- do {
- qiMajority++;
- fe = fe->nextEdge();
- } while (fe && fe != festart);
- qiMajority >>= 1;
+ festart = (*ve)->fedgeA();
+ fe = (*ve)->fedgeA();
+ qiMajority = 1;
+ do {
+ qiMajority++;
+ fe = fe->nextEdge();
+ } while (fe && fe != festart);
+ qiMajority >>= 1;
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tqiMajority: " << qiMajority << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tqiMajority: " << qiMajority << endl;
+ }
#endif
- tmpQI = 0;
- maxIndex = 0;
- maxCard = 0;
- nSamples = 0;
- fe = (*ve)->fedgeA();
- memset(qiClasses, 0, 256 * sizeof(*qiClasses));
- set<ViewShape*> occluders;
- do {
- if ((maxCard < qiMajority)) {
- tmpQI = ComputeRayCastingVisibility(fe, _Grid, epsilon, occluders, &aFace, timestamp++);
+ tmpQI = 0;
+ maxIndex = 0;
+ maxCard = 0;
+ nSamples = 0;
+ fe = (*ve)->fedgeA();
+ memset(qiClasses, 0, 256 * sizeof(*qiClasses));
+ set<ViewShape *> occluders;
+ do {
+ if ((maxCard < qiMajority)) {
+ tmpQI = ComputeRayCastingVisibility(fe, _Grid, epsilon, occluders, &aFace, timestamp++);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFEdge: visibility " << tmpQI << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFEdge: visibility " << tmpQI << endl;
+ }
#endif
- //ARB: This is an error condition, not an alert condition.
- // Some sort of recovery or abort is necessary.
- if (tmpQI >= 256) {
- cerr << "Warning: too many occluding levels" << endl;
- //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
- tmpQI = 255;
- }
-
- if (++qiClasses[tmpQI] > maxCard) {
- maxCard = qiClasses[tmpQI];
- maxIndex = tmpQI;
- }
- }
- else {
- //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
- FindOccludee(fe, _Grid, epsilon, &aFace, timestamp++);
+ //ARB: This is an error condition, not an alert condition.
+ // Some sort of recovery or abort is necessary.
+ if (tmpQI >= 256) {
+ cerr << "Warning: too many occluding levels" << endl;
+ //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
+ tmpQI = 255;
+ }
+
+ if (++qiClasses[tmpQI] > maxCard) {
+ maxCard = qiClasses[tmpQI];
+ maxIndex = tmpQI;
+ }
+ }
+ else {
+ //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
+ FindOccludee(fe, _Grid, epsilon, &aFace, timestamp++);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFEdge: occludee only (" << (aFace != NULL ? "found" : "not found") << ")" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFEdge: occludee only (" << (aFace != NULL ? "found" : "not found") << ")"
+ << endl;
+ }
#endif
- }
+ }
- if (aFace) {
- fe->setaFace(*aFace);
- aFaces.push_back(aFace);
- fe->setOccludeeEmpty(false);
+ if (aFace) {
+ fe->setaFace(*aFace);
+ aFaces.push_back(aFace);
+ fe->setOccludeeEmpty(false);
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFound occludee" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFound occludee" << endl;
+ }
#endif
- }
- else {
- //ARB: We are arbitrarily using the last observed value for occludee (almost always the value observed
- // for the edge before festart). Is that meaningful?
- // ...in fact, _occludeeEmpty seems to be unused.
- fe->setOccludeeEmpty(true);
- }
-
- ++nSamples;
- fe = fe->nextEdge();
- } while ((maxCard < qiMajority) && (fe) && (fe != festart));
+ }
+ else {
+ //ARB: We are arbitrarily using the last observed value for occludee (almost always the value observed
+ // for the edge before festart). Is that meaningful?
+ // ...in fact, _occludeeEmpty seems to be unused.
+ fe->setOccludeeEmpty(true);
+ }
+
+ ++nSamples;
+ fe = fe->nextEdge();
+ } while ((maxCard < qiMajority) && (fe) && (fe != festart));
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tFinished with " << nSamples << " samples, maxCard = " << maxCard << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tFinished with " << nSamples << " samples, maxCard = " << maxCard << endl;
+ }
#endif
- // ViewEdge
- // qi --
- (*ve)->setQI(maxIndex);
- // occluders --
- for (set<ViewShape*>::iterator o = occluders.begin(), oend = occluders.end(); o != oend; ++o)
- (*ve)->AddOccluder((*o));
+ // ViewEdge
+ // qi --
+ (*ve)->setQI(maxIndex);
+ // occluders --
+ for (set<ViewShape *>::iterator o = occluders.begin(), oend = occluders.end(); o != oend; ++o)
+ (*ve)->AddOccluder((*o));
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\tConclusion: QI = " << maxIndex << ", " << (*ve)->occluders_size() << " occluders." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\tConclusion: QI = " << maxIndex << ", " << (*ve)->occluders_size() << " occluders."
+ << endl;
+ }
#endif
- // occludee --
- if (!aFaces.empty()) {
- if (aFaces.size() <= (float)nSamples / 2.0f) {
- (*ve)->setaShape(0);
- }
- else {
- vector<Polygon3r*>::iterator p = aFaces.begin();
- WFace *wface = (WFace *)((*p)->userdata);
- ViewShape *vshape = ioViewMap->viewShape(wface->GetVertex(0)->shape()->GetId());
- ++p;
- (*ve)->setaShape(vshape);
- }
- }
-
- if (progressBarDisplay) {
- counter--;
- if (counter <= 0) {
- counter = progressBarStep;
- _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
- }
- }
- aFaces.clear();
- }
+ // occludee --
+ if (!aFaces.empty()) {
+ if (aFaces.size() <= (float)nSamples / 2.0f) {
+ (*ve)->setaShape(0);
+ }
+ else {
+ vector<Polygon3r *>::iterator p = aFaces.begin();
+ WFace *wface = (WFace *)((*p)->userdata);
+ ViewShape *vshape = ioViewMap->viewShape(wface->GetVertex(0)->shape()->GetId());
+ ++p;
+ (*ve)->setaShape(vshape);
+ }
+ }
+
+ if (progressBarDisplay) {
+ counter--;
+ if (counter <= 0) {
+ counter = progressBarStep;
+ _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
+ }
+ }
+ aFaces.clear();
+ }
}
void ViewMapBuilder::ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon)
{
- vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
- bool progressBarDisplay = false;
- unsigned progressBarStep = 0;
- unsigned vEdgesSize = vedges.size();
- unsigned fEdgesSize = ioViewMap->FEdges().size();
-
- if (_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) {
- unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
- progressBarStep = vEdgesSize / progressBarSteps;
- _pProgressBar->reset();
- _pProgressBar->setLabelText("Computing Ray casting Visibility");
- _pProgressBar->setTotalSteps(progressBarSteps);
- _pProgressBar->setProgress(0);
- progressBarDisplay = true;
- }
-
- unsigned counter = progressBarStep;
- FEdge *fe, *festart;
- unsigned nSamples = 0;
- vector<Polygon3r*> aFaces;
- Polygon3r *aFace = NULL;
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
- static unsigned timestamp = 1;
- bool even_test;
- for (vector<ViewEdge*>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
- if (_pRenderMonitor && _pRenderMonitor->testBreak())
- break;
-
- festart = (*ve)->fedgeA();
- fe = (*ve)->fedgeA();
- qiMajority = 1;
- do {
- qiMajority++;
- fe = fe->nextEdge();
- } while (fe && fe != festart);
- if (qiMajority >= 4)
- qiMajority >>= 2;
- else
- qiMajority = 1;
-
- set<ViewShape*> occluders;
-
- even_test = true;
- maxIndex = 0;
- maxCard = 0;
- nSamples = 0;
- memset(qiClasses, 0, 256 * sizeof(*qiClasses));
- fe = (*ve)->fedgeA();
- do {
- if (even_test) {
- if ((maxCard < qiMajority)) {
- tmpQI = ComputeRayCastingVisibility(fe, _Grid, epsilon, occluders, &aFace, timestamp++);
-
- //ARB: This is an error condition, not an alert condition.
- // Some sort of recovery or abort is necessary.
- if (tmpQI >= 256) {
- cerr << "Warning: too many occluding levels" << endl;
- //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
- tmpQI = 255;
- }
-
- if (++qiClasses[tmpQI] > maxCard) {
- maxCard = qiClasses[tmpQI];
- maxIndex = tmpQI;
- }
- }
- else {
- //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
- FindOccludee(fe, _Grid, epsilon, &aFace, timestamp++);
- }
-
- if (aFace) {
- fe->setaFace(*aFace);
- aFaces.push_back(aFace);
- }
- ++nSamples;
- even_test = false;
- }
- else {
- even_test = true;
- }
- fe = fe->nextEdge();
- } while ((maxCard < qiMajority) && (fe) && (fe != festart));
-
- (*ve)->setQI(maxIndex);
-
- if (!aFaces.empty()) {
- if (aFaces.size() < nSamples / 2) {
- (*ve)->setaShape(0);
- }
- else {
- vector<Polygon3r*>::iterator p = aFaces.begin();
- WFace *wface = (WFace *)((*p)->userdata);
- ViewShape *vshape = ioViewMap->viewShape(wface->GetVertex(0)->shape()->GetId());
- ++p;
+ vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
+ bool progressBarDisplay = false;
+ unsigned progressBarStep = 0;
+ unsigned vEdgesSize = vedges.size();
+ unsigned fEdgesSize = ioViewMap->FEdges().size();
+
+ if (_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) {
+ unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
+ progressBarStep = vEdgesSize / progressBarSteps;
+ _pProgressBar->reset();
+ _pProgressBar->setLabelText("Computing Ray casting Visibility");
+ _pProgressBar->setTotalSteps(progressBarSteps);
+ _pProgressBar->setProgress(0);
+ progressBarDisplay = true;
+ }
+
+ unsigned counter = progressBarStep;
+ FEdge *fe, *festart;
+ unsigned nSamples = 0;
+ vector<Polygon3r *> aFaces;
+ Polygon3r *aFace = NULL;
+ unsigned tmpQI = 0;
+ unsigned qiClasses[256];
+ unsigned maxIndex, maxCard;
+ unsigned qiMajority;
+ static unsigned timestamp = 1;
+ bool even_test;
+ for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
+ if (_pRenderMonitor && _pRenderMonitor->testBreak())
+ break;
+
+ festart = (*ve)->fedgeA();
+ fe = (*ve)->fedgeA();
+ qiMajority = 1;
+ do {
+ qiMajority++;
+ fe = fe->nextEdge();
+ } while (fe && fe != festart);
+ if (qiMajority >= 4)
+ qiMajority >>= 2;
+ else
+ qiMajority = 1;
+
+ set<ViewShape *> occluders;
+
+ even_test = true;
+ maxIndex = 0;
+ maxCard = 0;
+ nSamples = 0;
+ memset(qiClasses, 0, 256 * sizeof(*qiClasses));
+ fe = (*ve)->fedgeA();
+ do {
+ if (even_test) {
+ if ((maxCard < qiMajority)) {
+ tmpQI = ComputeRayCastingVisibility(fe, _Grid, epsilon, occluders, &aFace, timestamp++);
+
+ //ARB: This is an error condition, not an alert condition.
+ // Some sort of recovery or abort is necessary.
+ if (tmpQI >= 256) {
+ cerr << "Warning: too many occluding levels" << endl;
+ //ARB: Wild guess: instead of aborting or corrupting memory, treat as tmpQI == 255
+ tmpQI = 255;
+ }
+
+ if (++qiClasses[tmpQI] > maxCard) {
+ maxCard = qiClasses[tmpQI];
+ maxIndex = tmpQI;
+ }
+ }
+ else {
+ //ARB: FindOccludee is redundant if ComputeRayCastingVisibility has been called
+ FindOccludee(fe, _Grid, epsilon, &aFace, timestamp++);
+ }
+
+ if (aFace) {
+ fe->setaFace(*aFace);
+ aFaces.push_back(aFace);
+ }
+ ++nSamples;
+ even_test = false;
+ }
+ else {
+ even_test = true;
+ }
+ fe = fe->nextEdge();
+ } while ((maxCard < qiMajority) && (fe) && (fe != festart));
+
+ (*ve)->setQI(maxIndex);
+
+ if (!aFaces.empty()) {
+ if (aFaces.size() < nSamples / 2) {
+ (*ve)->setaShape(0);
+ }
+ else {
+ vector<Polygon3r *>::iterator p = aFaces.begin();
+ WFace *wface = (WFace *)((*p)->userdata);
+ ViewShape *vshape = ioViewMap->viewShape(wface->GetVertex(0)->shape()->GetId());
+ ++p;
#if 0
- for (; p != pend; ++p) {
- WFace *f = (WFace*)((*p)->userdata);
- ViewShape *vs = ioViewMap->viewShape(f->GetVertex(0)->shape()->GetId());
- if (vs != vshape) {
- sameShape = false;
- break;
- }
- }
- if (sameShape)
+ for (; p != pend; ++p) {
+ WFace *f = (WFace*)((*p)->userdata);
+ ViewShape *vs = ioViewMap->viewShape(f->GetVertex(0)->shape()->GetId());
+ if (vs != vshape) {
+ sameShape = false;
+ break;
+ }
+ }
+ if (sameShape)
#endif
- (*ve)->setaShape(vshape);
- }
- }
-
- //(*ve)->setaFace(aFace);
-
- if (progressBarDisplay) {
- counter--;
- if (counter <= 0) {
- counter = progressBarStep;
- _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
- }
- }
- aFaces.clear();
- }
+ (*ve)->setaShape(vshape);
+ }
+ }
+
+ //(*ve)->setaFace(aFace);
+
+ if (progressBarDisplay) {
+ counter--;
+ if (counter <= 0) {
+ counter = progressBarStep;
+ _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
+ }
+ }
+ aFaces.clear();
+ }
}
void ViewMapBuilder::ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon)
{
- vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
- bool progressBarDisplay = false;
- unsigned progressBarStep = 0;
- unsigned vEdgesSize = vedges.size();
- unsigned fEdgesSize = ioViewMap->FEdges().size();
-
- if (_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) {
- unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
- progressBarStep = vEdgesSize / progressBarSteps;
- _pProgressBar->reset();
- _pProgressBar->setLabelText("Computing Ray casting Visibility");
- _pProgressBar->setTotalSteps(progressBarSteps);
- _pProgressBar->setProgress(0);
- progressBarDisplay = true;
- }
-
- unsigned counter = progressBarStep;
- FEdge *fe;
- unsigned qi = 0;
- Polygon3r *aFace = NULL;
- static unsigned timestamp = 1;
- for (vector<ViewEdge*>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
- if (_pRenderMonitor && _pRenderMonitor->testBreak())
- break;
-
- set<ViewShape*> occluders;
-
- fe = (*ve)->fedgeA();
- qi = ComputeRayCastingVisibility(fe, _Grid, epsilon, occluders, &aFace, timestamp++);
- if (aFace) {
- fe->setaFace(*aFace);
- WFace *wface = (WFace *)(aFace->userdata);
- ViewShape *vshape = ioViewMap->viewShape(wface->GetVertex(0)->shape()->GetId());
- (*ve)->setaShape(vshape);
- }
- else {
- (*ve)->setaShape(0);
- }
-
- (*ve)->setQI(qi);
-
- if (progressBarDisplay) {
- counter--;
- if (counter <= 0) {
- counter = progressBarStep;
- _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
- }
- }
- }
+ vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
+ bool progressBarDisplay = false;
+ unsigned progressBarStep = 0;
+ unsigned vEdgesSize = vedges.size();
+ unsigned fEdgesSize = ioViewMap->FEdges().size();
+
+ if (_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) {
+ unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
+ progressBarStep = vEdgesSize / progressBarSteps;
+ _pProgressBar->reset();
+ _pProgressBar->setLabelText("Computing Ray casting Visibility");
+ _pProgressBar->setTotalSteps(progressBarSteps);
+ _pProgressBar->setProgress(0);
+ progressBarDisplay = true;
+ }
+
+ unsigned counter = progressBarStep;
+ FEdge *fe;
+ unsigned qi = 0;
+ Polygon3r *aFace = NULL;
+ static unsigned timestamp = 1;
+ for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
+ if (_pRenderMonitor && _pRenderMonitor->testBreak())
+ break;
+
+ set<ViewShape *> occluders;
+
+ fe = (*ve)->fedgeA();
+ qi = ComputeRayCastingVisibility(fe, _Grid, epsilon, occluders, &aFace, timestamp++);
+ if (aFace) {
+ fe->setaFace(*aFace);
+ WFace *wface = (WFace *)(aFace->userdata);
+ ViewShape *vshape = ioViewMap->viewShape(wface->GetVertex(0)->shape()->GetId());
+ (*ve)->setaShape(vshape);
+ }
+ else {
+ (*ve)->setaShape(0);
+ }
+
+ (*ve)->setQI(qi);
+
+ if (progressBarDisplay) {
+ counter--;
+ if (counter <= 0) {
+ counter = progressBarStep;
+ _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
+ }
+ }
+ }
}
-void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
- Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices)
+void ViewMapBuilder::FindOccludee(FEdge *fe,
+ Grid *iGrid,
+ real epsilon,
+ Polygon3r **oaPolygon,
+ unsigned timestamp,
+ Vec3r &u,
+ Vec3r &A,
+ Vec3r &origin,
+ Vec3r &edgeDir,
+ vector<WVertex *> &faceVertices)
{
- WFace *face = NULL;
- if (fe->isSmooth()) {
- FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(fe);
- face = (WFace *)fes->face();
- }
- OccludersSet occluders;
- WFace *oface;
- bool skipFace;
-
- WVertex::incoming_edge_iterator ie;
- OccludersSet::iterator p, pend;
-
- *oaPolygon = NULL;
- if (((fe)->getNature() & Nature::SILHOUETTE) || ((fe)->getNature() & Nature::BORDER)) {
- occluders.clear();
- // we cast a ray from A in the same direction but looking behind
- Vec3r v(-u[0], -u[1], -u[2]);
- iGrid->castInfiniteRay(A, v, occluders, timestamp);
-
- bool noIntersection = true;
- real mint = FLT_MAX;
- // we met some occluders, let us fill the aShape field with the first intersected occluder
- for (p = occluders.begin(), pend = occluders.end(); p != pend; p++) {
- // check whether the edge and the polygon plane are coincident:
- //-------------------------------------------------------------
- //first let us compute the plane equation.
- oface = (WFace *)(*p)->userdata;
- Vec3r v1(((*p)->getVertices())[0]);
- Vec3r normal((*p)->getNormal());
- real d = -(v1 * normal);
- real t, t_u, t_v;
-
- if (face) {
- skipFace = false;
-
- if (face == oface)
- continue;
-
- if (faceVertices.empty())
- continue;
-
- for (vector<WVertex*>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
- fv != fvend;
- ++fv)
- {
- if ((*fv)->isBoundary())
- continue;
- WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
- WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
- for (ie = iebegin; ie != ieend; ++ie) {
- if ((*ie) == 0)
- continue;
-
- WFace *sface = (*ie)->GetbFace();
- if (sface == oface) {
- skipFace = true;
- break;
- }
- }
- if (skipFace)
- break;
- }
- if (skipFace)
- continue;
- }
- else {
- if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, normal, d, t, epsilon))
- continue;
- }
- if ((*p)->rayIntersect(A, v, t, t_u, t_v)) {
- if (fabs(v * normal) > 0.0001) {
- if (t > 0.0) { // && t < 1.0) {
- if (t < mint) {
- *oaPolygon = (*p);
- mint = t;
- noIntersection = false;
- fe->setOccludeeIntersection(Vec3r(A + t * v));
- }
- }
- }
- }
- }
-
- if (noIntersection)
- *oaPolygon = NULL;
- }
+ WFace *face = NULL;
+ if (fe->isSmooth()) {
+ FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
+ face = (WFace *)fes->face();
+ }
+ OccludersSet occluders;
+ WFace *oface;
+ bool skipFace;
+
+ WVertex::incoming_edge_iterator ie;
+ OccludersSet::iterator p, pend;
+
+ *oaPolygon = NULL;
+ if (((fe)->getNature() & Nature::SILHOUETTE) || ((fe)->getNature() & Nature::BORDER)) {
+ occluders.clear();
+ // we cast a ray from A in the same direction but looking behind
+ Vec3r v(-u[0], -u[1], -u[2]);
+ iGrid->castInfiniteRay(A, v, occluders, timestamp);
+
+ bool noIntersection = true;
+ real mint = FLT_MAX;
+ // we met some occluders, let us fill the aShape field with the first intersected occluder
+ for (p = occluders.begin(), pend = occluders.end(); p != pend; p++) {
+ // check whether the edge and the polygon plane are coincident:
+ //-------------------------------------------------------------
+ //first let us compute the plane equation.
+ oface = (WFace *)(*p)->userdata;
+ Vec3r v1(((*p)->getVertices())[0]);
+ Vec3r normal((*p)->getNormal());
+ real d = -(v1 * normal);
+ real t, t_u, t_v;
+
+ if (face) {
+ skipFace = false;
+
+ if (face == oface)
+ continue;
+
+ if (faceVertices.empty())
+ continue;
+
+ for (vector<WVertex *>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
+ fv != fvend;
+ ++fv) {
+ if ((*fv)->isBoundary())
+ continue;
+ WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
+ WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
+ for (ie = iebegin; ie != ieend; ++ie) {
+ if ((*ie) == 0)
+ continue;
+
+ WFace *sface = (*ie)->GetbFace();
+ if (sface == oface) {
+ skipFace = true;
+ break;
+ }
+ }
+ if (skipFace)
+ break;
+ }
+ if (skipFace)
+ continue;
+ }
+ else {
+ if (GeomUtils::COINCIDENT ==
+ GeomUtils::intersectRayPlane(origin, edgeDir, normal, d, t, epsilon))
+ continue;
+ }
+ if ((*p)->rayIntersect(A, v, t, t_u, t_v)) {
+ if (fabs(v * normal) > 0.0001) {
+ if (t > 0.0) { // && t < 1.0) {
+ if (t < mint) {
+ *oaPolygon = (*p);
+ mint = t;
+ noIntersection = false;
+ fe->setOccludeeIntersection(Vec3r(A + t * v));
+ }
+ }
+ }
+ }
+ }
+
+ if (noIntersection)
+ *oaPolygon = NULL;
+ }
}
-void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp)
+void ViewMapBuilder::FindOccludee(
+ FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp)
{
- OccludersSet occluders;
-
- Vec3r A;
- Vec3r edgeDir;
- Vec3r origin;
- A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
- edgeDir = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
- edgeDir.normalize();
- origin = Vec3r((fe)->vertexA()->point3D());
- Vec3r u;
- if (_orthographicProjection) {
- u = Vec3r(0.0, 0.0, _viewpoint.z() - A.z());
- }
- else {
- u = Vec3r(_viewpoint - A);
- }
- u.normalize();
- if (A < iGrid->getOrigin())
- cerr << "Warning: point is out of the grid for fedge " << fe->getId().getFirst() << "-" <<
- fe->getId().getSecond() << endl;
-
- vector<WVertex*> faceVertices;
-
- WFace *face = NULL;
- if (fe->isSmooth()) {
- FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(fe);
- face = (WFace *)fes->face();
- }
- if (face)
- face->RetrieveVertexList(faceVertices);
-
- return FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, A, origin, edgeDir, faceVertices);
+ OccludersSet occluders;
+
+ Vec3r A;
+ Vec3r edgeDir;
+ Vec3r origin;
+ A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
+ edgeDir = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
+ edgeDir.normalize();
+ origin = Vec3r((fe)->vertexA()->point3D());
+ Vec3r u;
+ if (_orthographicProjection) {
+ u = Vec3r(0.0, 0.0, _viewpoint.z() - A.z());
+ }
+ else {
+ u = Vec3r(_viewpoint - A);
+ }
+ u.normalize();
+ if (A < iGrid->getOrigin())
+ cerr << "Warning: point is out of the grid for fedge " << fe->getId().getFirst() << "-"
+ << fe->getId().getSecond() << endl;
+
+ vector<WVertex *> faceVertices;
+
+ WFace *face = NULL;
+ if (fe->isSmooth()) {
+ FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
+ face = (WFace *)fes->face();
+ }
+ if (face)
+ face->RetrieveVertexList(faceVertices);
+
+ return FindOccludee(
+ fe, iGrid, epsilon, oaPolygon, timestamp, u, A, origin, edgeDir, faceVertices);
}
-int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
- Polygon3r **oaPolygon, unsigned timestamp)
+int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe,
+ Grid *iGrid,
+ real epsilon,
+ set<ViewShape *> &oOccluders,
+ Polygon3r **oaPolygon,
+ unsigned timestamp)
{
- OccludersSet occluders;
- int qi = 0;
-
- Vec3r center;
- Vec3r edgeDir;
- Vec3r origin;
-
- center = fe->center3d();
- edgeDir = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
- edgeDir.normalize();
- origin = Vec3r(fe->vertexA()->point3D());
- // Is the edge outside the view frustum ?
- Vec3r gridOrigin(iGrid->getOrigin());
- Vec3r gridExtremity(iGrid->getOrigin() + iGrid->gridSize());
-
- if ((center.x() < gridOrigin.x()) || (center.y() < gridOrigin.y()) || (center.z() < gridOrigin.z()) ||
- (center.x() > gridExtremity.x()) || (center.y() > gridExtremity.y()) || (center.z() > gridExtremity.z()))
- {
- cerr << "Warning: point is out of the grid for fedge " << fe->getId() << endl;
- //return 0;
- }
+ OccludersSet occluders;
+ int qi = 0;
+
+ Vec3r center;
+ Vec3r edgeDir;
+ Vec3r origin;
+
+ center = fe->center3d();
+ edgeDir = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
+ edgeDir.normalize();
+ origin = Vec3r(fe->vertexA()->point3D());
+ // Is the edge outside the view frustum ?
+ Vec3r gridOrigin(iGrid->getOrigin());
+ Vec3r gridExtremity(iGrid->getOrigin() + iGrid->gridSize());
+
+ if ((center.x() < gridOrigin.x()) || (center.y() < gridOrigin.y()) ||
+ (center.z() < gridOrigin.z()) || (center.x() > gridExtremity.x()) ||
+ (center.y() > gridExtremity.y()) || (center.z() > gridExtremity.z())) {
+ cerr << "Warning: point is out of the grid for fedge " << fe->getId() << endl;
+ //return 0;
+ }
#if 0
- Vec3r A(fe->vertexA()->point2d());
- Vec3r B(fe->vertexB()->point2d());
- int viewport[4];
- SilhouetteGeomEngine::retrieveViewport(viewport);
- if ((A.x() < viewport[0]) || (A.x() > viewport[2]) || (A.y() < viewport[1]) || (A.y() > viewport[3]) ||
- (B.x() < viewport[0]) || (B.x() > viewport[2]) || (B.y() < viewport[1]) || (B.y() > viewport[3]))
- {
- cerr << "Warning: point is out of the grid for fedge " << fe->getId() << endl;
- //return 0;
- }
+ Vec3r A(fe->vertexA()->point2d());
+ Vec3r B(fe->vertexB()->point2d());
+ int viewport[4];
+ SilhouetteGeomEngine::retrieveViewport(viewport);
+ if ((A.x() < viewport[0]) || (A.x() > viewport[2]) || (A.y() < viewport[1]) || (A.y() > viewport[3]) ||
+ (B.x() < viewport[0]) || (B.x() > viewport[2]) || (B.y() < viewport[1]) || (B.y() > viewport[3]))
+ {
+ cerr << "Warning: point is out of the grid for fedge " << fe->getId() << endl;
+ //return 0;
+ }
#endif
- Vec3r vp;
- if (_orthographicProjection) {
- vp = Vec3r(center.x(), center.y(), _viewpoint.z());
- }
- else {
- vp = Vec3r(_viewpoint);
- }
- Vec3r u(vp - center);
- real raylength = u.norm();
- u.normalize();
+ Vec3r vp;
+ if (_orthographicProjection) {
+ vp = Vec3r(center.x(), center.y(), _viewpoint.z());
+ }
+ else {
+ vp = Vec3r(_viewpoint);
+ }
+ Vec3r u(vp - center);
+ real raylength = u.norm();
+ u.normalize();
#if 0
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "grid origin " << iGrid->getOrigin().x() << "," << iGrid->getOrigin().y() << ","
- << iGrid->getOrigin().z() << endl;
- cout << "center " << center.x() << "," << center.y() << "," << center.z() << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "grid origin " << iGrid->getOrigin().x() << "," << iGrid->getOrigin().y() << ","
+ << iGrid->getOrigin().z() << endl;
+ cout << "center " << center.x() << "," << center.y() << "," << center.z() << endl;
+ }
#endif
- iGrid->castRay(center, vp, occluders, timestamp);
-
- WFace *face = NULL;
- if (fe->isSmooth()) {
- FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
- face = (WFace *)fes->face();
- }
- vector<WVertex *> faceVertices;
- WVertex::incoming_edge_iterator ie;
-
- WFace *oface;
- bool skipFace;
- OccludersSet::iterator p, pend;
- if (face)
- face->RetrieveVertexList(faceVertices);
-
- for (p = occluders.begin(), pend = occluders.end(); p != pend; p++) {
- // If we're dealing with an exact silhouette, check whether we must take care of this occluder of not.
- // (Indeed, we don't consider the occluders that share at least one vertex with the face containing this edge).
- //-----------
- oface = (WFace *)(*p)->userdata;
+ iGrid->castRay(center, vp, occluders, timestamp);
+
+ WFace *face = NULL;
+ if (fe->isSmooth()) {
+ FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
+ face = (WFace *)fes->face();
+ }
+ vector<WVertex *> faceVertices;
+ WVertex::incoming_edge_iterator ie;
+
+ WFace *oface;
+ bool skipFace;
+ OccludersSet::iterator p, pend;
+ if (face)
+ face->RetrieveVertexList(faceVertices);
+
+ for (p = occluders.begin(), pend = occluders.end(); p != pend; p++) {
+ // If we're dealing with an exact silhouette, check whether we must take care of this occluder of not.
+ // (Indeed, we don't consider the occluders that share at least one vertex with the face containing this edge).
+ //-----------
+ oface = (WFace *)(*p)->userdata;
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tEvaluating intersection for occluder " << ((*p)->getVertices())[0] <<
- ((*p)->getVertices())[1] << ((*p)->getVertices())[2] << endl << "\t\t\tand ray " << vp <<
- " * " << u << " (center " << center << ")" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tEvaluating intersection for occluder " << ((*p)->getVertices())[0]
+ << ((*p)->getVertices())[1] << ((*p)->getVertices())[2] << endl
+ << "\t\t\tand ray " << vp << " * " << u << " (center " << center << ")" << endl;
+ }
#endif
- Vec3r v1(((*p)->getVertices())[0]);
- Vec3r normal((*p)->getNormal());
- real d = -(v1 * normal);
- real t, t_u, t_v;
+ Vec3r v1(((*p)->getVertices())[0]);
+ Vec3r normal((*p)->getNormal());
+ real d = -(v1 * normal);
+ real t, t_u, t_v;
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tp: " << ((*p)->getVertices())[0] << ((*p)->getVertices())[1] << ((*p)->getVertices())[2] <<
- ", norm: " << (*p)->getNormal() << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tp: " << ((*p)->getVertices())[0] << ((*p)->getVertices())[1]
+ << ((*p)->getVertices())[2] << ", norm: " << (*p)->getNormal() << endl;
+ }
#endif
- if (face) {
+ if (face) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tDetermining face adjacency...";
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tDetermining face adjacency...";
+ }
#endif
- skipFace = false;
+ skipFace = false;
- if (face == oface) {
+ if (face == oface) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << " Rejecting occluder for face concurrency." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << " Rejecting occluder for face concurrency." << endl;
+ }
#endif
- continue;
- }
-
- for (vector<WVertex*>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
- fv != fvend;
- ++fv)
- {
- if ((*fv)->isBoundary())
- continue;
-
- WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
- WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
- for (ie = iebegin; ie != ieend; ++ie) {
- if ((*ie) == 0)
- continue;
-
- WFace *sface = (*ie)->GetbFace();
- //WFace *sfacea = (*ie)->GetaFace();
- //if ((sface == oface) || (sfacea == oface)) {
- if (sface == oface) {
- skipFace = true;
- break;
- }
- }
- if (skipFace)
- break;
- }
- if (skipFace) {
+ continue;
+ }
+
+ for (vector<WVertex *>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
+ fv != fvend;
+ ++fv) {
+ if ((*fv)->isBoundary())
+ continue;
+
+ WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
+ WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
+ for (ie = iebegin; ie != ieend; ++ie) {
+ if ((*ie) == 0)
+ continue;
+
+ WFace *sface = (*ie)->GetbFace();
+ //WFace *sfacea = (*ie)->GetaFace();
+ //if ((sface == oface) || (sfacea == oface)) {
+ if (sface == oface) {
+ skipFace = true;
+ break;
+ }
+ }
+ if (skipFace)
+ break;
+ }
+ if (skipFace) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << " Rejecting occluder for face adjacency." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << " Rejecting occluder for face adjacency." << endl;
+ }
#endif
- continue;
- }
- }
- else {
- // check whether the edge and the polygon plane are coincident:
- //-------------------------------------------------------------
- //first let us compute the plane equation.
-
- if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, normal, d, t, epsilon)) {
+ continue;
+ }
+ }
+ else {
+ // check whether the edge and the polygon plane are coincident:
+ //-------------------------------------------------------------
+ //first let us compute the plane equation.
+
+ if (GeomUtils::COINCIDENT ==
+ GeomUtils::intersectRayPlane(origin, edgeDir, normal, d, t, epsilon)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tRejecting occluder for target coincidence." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tRejecting occluder for target coincidence." << endl;
+ }
#endif
- continue;
- }
- }
+ continue;
+ }
+ }
- if ((*p)->rayIntersect(center, u, t, t_u, t_v)) {
+ if ((*p)->rayIntersect(center, u, t, t_u, t_v)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tRay " << vp << " * " << u << " intersects at time " << t << " (raylength is " <<
- raylength << ")" << endl;
- cout << "\t\t(u * normal) == " << (u * normal) << " for normal " << normal << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tRay " << vp << " * " << u << " intersects at time " << t << " (raylength is "
+ << raylength << ")" << endl;
+ cout << "\t\t(u * normal) == " << (u * normal) << " for normal " << normal << endl;
+ }
#endif
- if (fabs(u * normal) > 0.0001) {
- if ((t>0.0) && (t<raylength)) {
+ if (fabs(u * normal) > 0.0001) {
+ if ((t > 0.0) && (t < raylength)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tIs occluder" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tIs occluder" << endl;
+ }
#endif
- WFace *f = (WFace *)((*p)->userdata);
- ViewShape *vshape = _ViewMap->viewShape(f->GetVertex(0)->shape()->GetId());
- oOccluders.insert(vshape);
- ++qi;
- if (!_EnableQI)
- break;
- }
- }
- }
- }
-
- // Find occludee
- FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, center, origin, edgeDir, faceVertices);
-
- return qi;
+ WFace *f = (WFace *)((*p)->userdata);
+ ViewShape *vshape = _ViewMap->viewShape(f->GetVertex(0)->shape()->GetId());
+ oOccluders.insert(vshape);
+ ++qi;
+ if (!_EnableQI)
+ break;
+ }
+ }
+ }
+ }
+
+ // Find occludee
+ FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, center, origin, edgeDir, faceVertices);
+
+ return qi;
}
-void ViewMapBuilder::ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo, real epsilon)
+void ViewMapBuilder::ComputeIntersections(ViewMap *ioViewMap,
+ intersection_algo iAlgo,
+ real epsilon)
{
- switch (iAlgo) {
- case sweep_line:
- ComputeSweepLineIntersections(ioViewMap, epsilon);
- break;
- default:
- break;
- }
+ switch (iAlgo) {
+ case sweep_line:
+ ComputeSweepLineIntersections(ioViewMap, epsilon);
+ break;
+ default:
+ break;
+ }
#if 0
- if (_global.debug & G_DEBUG_FREESTYLE) {
- ViewMap::viewvertices_container& vvertices = ioViewMap->ViewVertices();
- for (ViewMap::viewvertices_container::iterator vv = vvertices.begin(), vvend = vvertices.end();
- vv != vvend; ++vv)
- {
- if ((*vv)->getNature() == Nature::T_VERTEX) {
- TVertex *tvertex = (TVertex *)(*vv);
- cout << "TVertex " << tvertex->getId() << " has :" << endl;
- cout << "FrontEdgeA: " << tvertex->frontEdgeA().first << endl;
- cout << "FrontEdgeB: " << tvertex->frontEdgeB().first << endl;
- cout << "BackEdgeA: " << tvertex->backEdgeA().first << endl;
- cout << "BackEdgeB: " << tvertex->backEdgeB().first << endl << endl;
- }
- }
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ ViewMap::viewvertices_container& vvertices = ioViewMap->ViewVertices();
+ for (ViewMap::viewvertices_container::iterator vv = vvertices.begin(), vvend = vvertices.end();
+ vv != vvend; ++vv)
+ {
+ if ((*vv)->getNature() == Nature::T_VERTEX) {
+ TVertex *tvertex = (TVertex *)(*vv);
+ cout << "TVertex " << tvertex->getId() << " has :" << endl;
+ cout << "FrontEdgeA: " << tvertex->frontEdgeA().first << endl;
+ cout << "FrontEdgeB: " << tvertex->frontEdgeB().first << endl;
+ cout << "BackEdgeA: " << tvertex->backEdgeA().first << endl;
+ cout << "BackEdgeB: " << tvertex->backEdgeB().first << endl << endl;
+ }
+ }
+ }
#endif
}
-struct less_SVertex2D : public binary_function<SVertex *, SVertex *, bool>
-{
- real epsilon;
-
- less_SVertex2D(real eps) : binary_function<SVertex *, SVertex *, bool>()
- {
- epsilon = eps;
- }
-
- bool operator()(SVertex *x, SVertex *y)
- {
- Vec3r A = x->point2D();
- Vec3r B = y->point2D();
- for (unsigned int i = 0; i < 3; i++) {
- if ((fabs(A[i] - B[i])) < epsilon)
- continue;
- if (A[i] < B[i])
- return true;
- if (A[i] > B[i])
- return false;
- }
- return false;
- }
+struct less_SVertex2D : public binary_function<SVertex *, SVertex *, bool> {
+ real epsilon;
+
+ less_SVertex2D(real eps) : binary_function<SVertex *, SVertex *, bool>()
+ {
+ epsilon = eps;
+ }
+
+ bool operator()(SVertex *x, SVertex *y)
+ {
+ Vec3r A = x->point2D();
+ Vec3r B = y->point2D();
+ for (unsigned int i = 0; i < 3; i++) {
+ if ((fabs(A[i] - B[i])) < epsilon)
+ continue;
+ if (A[i] < B[i])
+ return true;
+ if (A[i] > B[i])
+ return false;
+ }
+ return false;
+ }
};
typedef Segment<FEdge *, Vec3r> segment;
typedef Intersection<segment> intersection;
-struct less_Intersection : public binary_function<intersection *, intersection *, bool>
-{
- segment *edge;
-
- less_Intersection(segment *iEdge) : binary_function<intersection *, intersection *, bool>()
- {
- edge = iEdge;
- }
-
- bool operator()(intersection *x, intersection *y)
- {
- real tx = x->getParameter(edge);
- real ty = y->getParameter(edge);
- if (tx > ty)
- return true;
- return false;
- }
+struct less_Intersection : public binary_function<intersection *, intersection *, bool> {
+ segment *edge;
+
+ less_Intersection(segment *iEdge) : binary_function<intersection *, intersection *, bool>()
+ {
+ edge = iEdge;
+ }
+
+ bool operator()(intersection *x, intersection *y)
+ {
+ real tx = x->getParameter(edge);
+ real ty = y->getParameter(edge);
+ if (tx > ty)
+ return true;
+ return false;
+ }
};
-struct silhouette_binary_rule : public binary_rule<segment, segment>
-{
- silhouette_binary_rule() : binary_rule<segment, segment>() {}
+struct silhouette_binary_rule : public binary_rule<segment, segment> {
+ silhouette_binary_rule() : binary_rule<segment, segment>()
+ {
+ }
- virtual bool operator()(segment& s1, segment& s2)
- {
- FEdge *f1 = s1.edge();
- FEdge *f2 = s2.edge();
+ virtual bool operator()(segment &s1, segment &s2)
+ {
+ FEdge *f1 = s1.edge();
+ FEdge *f2 = s2.edge();
- if ((!(((f1)->getNature() & Nature::SILHOUETTE) || ((f1)->getNature() & Nature::BORDER))) &&
- (!(((f2)->getNature() & Nature::SILHOUETTE) || ((f2)->getNature() & Nature::BORDER))))
- {
- return false;
- }
+ if ((!(((f1)->getNature() & Nature::SILHOUETTE) || ((f1)->getNature() & Nature::BORDER))) &&
+ (!(((f2)->getNature() & Nature::SILHOUETTE) || ((f2)->getNature() & Nature::BORDER)))) {
+ return false;
+ }
- return true;
- }
+ return true;
+ }
};
void ViewMapBuilder::ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon)
{
- vector<SVertex *>& svertices = ioViewMap->SVertices();
- bool progressBarDisplay = false;
- unsigned sVerticesSize = svertices.size();
- unsigned fEdgesSize = ioViewMap->FEdges().size();
+ vector<SVertex *> &svertices = ioViewMap->SVertices();
+ bool progressBarDisplay = false;
+ unsigned sVerticesSize = svertices.size();
+ unsigned fEdgesSize = ioViewMap->FEdges().size();
#if 0
- if (_global.debug & G_DEBUG_FREESTYLE) {
- ViewMap::fedges_container& fedges = ioViewMap->FEdges();
- for (ViewMap::fedges_container::const_iterator f = fedges.begin(), end = fedges.end(); f != end; ++f) {
- cout << (*f)->aMaterialIndex() << "-" << (*f)->bMaterialIndex() << endl;
- }
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ ViewMap::fedges_container& fedges = ioViewMap->FEdges();
+ for (ViewMap::fedges_container::const_iterator f = fedges.begin(), end = fedges.end(); f != end; ++f) {
+ cout << (*f)->aMaterialIndex() << "-" << (*f)->bMaterialIndex() << endl;
+ }
+ }
#endif
- unsigned progressBarStep = 0;
-
- if (_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) {
- unsigned progressBarSteps = min(gProgressBarMaxSteps, sVerticesSize);
- progressBarStep = sVerticesSize / progressBarSteps;
- _pProgressBar->reset();
- _pProgressBar->setLabelText("Computing Sweep Line Intersections");
- _pProgressBar->setTotalSteps(progressBarSteps);
- _pProgressBar->setProgress(0);
- progressBarDisplay = true;
- }
-
- unsigned counter = progressBarStep;
-
- sort(svertices.begin(), svertices.end(), less_SVertex2D(epsilon));
-
- SweepLine<FEdge *, Vec3r> SL;
-
- vector<FEdge *>& ioEdges = ioViewMap->FEdges();
-
- vector<segment*> segments;
-
- vector<FEdge*>::iterator fe, fend;
-
- for (fe = ioEdges.begin(), fend = ioEdges.end(); fe != fend; fe++) {
- segment *s = new segment((*fe), (*fe)->vertexA()->point2D(), (*fe)->vertexB()->point2D());
- (*fe)->userdata = s;
- segments.push_back(s);
- }
-
- vector<segment*> vsegments;
- for (vector<SVertex*>::iterator sv = svertices.begin(), svend = svertices.end(); sv != svend; sv++) {
- if (_pRenderMonitor && _pRenderMonitor->testBreak())
- break;
-
- const vector<FEdge*>& vedges = (*sv)->fedges();
-
- for (vector<FEdge *>::const_iterator sve = vedges.begin(), sveend = vedges.end(); sve != sveend; sve++) {
- vsegments.push_back((segment *)((*sve)->userdata));
- }
-
- Vec3r evt((*sv)->point2D());
- silhouette_binary_rule sbr;
- SL.process(evt, vsegments, sbr, epsilon);
-
- if (progressBarDisplay) {
- counter--;
- if (counter <= 0) {
- counter = progressBarStep;
- _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
- }
- }
- vsegments.clear();
- }
-
- if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
- // delete segments
- if (!segments.empty()) {
- vector<segment*>::iterator s, send;
- for (s = segments.begin(), send = segments.end(); s != send; s++) {
- delete *s;
- }
- }
- return;
- }
-
- // reset userdata:
- for (fe = ioEdges.begin(), fend = ioEdges.end(); fe != fend; fe++)
- (*fe)->userdata = NULL;
-
- // list containing the new edges resulting from splitting operations.
- vector<FEdge*> newEdges;
-
- // retrieve the intersected edges:
- vector<segment*>& iedges = SL.intersectedEdges();
- // retrieve the intersections:
- vector<intersection*>& intersections = SL.intersections();
-
- int id = 0;
- // create a view vertex for each intersection and linked this one with the intersection object
- vector<intersection*>::iterator i, iend;
- for (i = intersections.begin(), iend = intersections.end(); i != iend; i++) {
- FEdge *fA = (*i)->EdgeA->edge();
- FEdge *fB = (*i)->EdgeB->edge();
-
- Vec3r A1 = fA->vertexA()->point3D();
- Vec3r A2 = fA->vertexB()->point3D();
- Vec3r B1 = fB->vertexA()->point3D();
- Vec3r B2 = fB->vertexB()->point3D();
-
- Vec3r a1 = fA->vertexA()->point2D();
- Vec3r a2 = fA->vertexB()->point2D();
- Vec3r b1 = fB->vertexA()->point2D();
- Vec3r b2 = fB->vertexB()->point2D();
-
- real ta = (*i)->tA;
- real tb = (*i)->tB;
-
- if ((ta < -epsilon) || (ta > 1 + epsilon))
- cerr << "Warning: 2D intersection out of range for edge " << fA->vertexA()->getId() << " - " <<
- fA->vertexB()->getId() << endl;
-
- if ((tb < -epsilon) || (tb > 1 + epsilon))
- cerr << "Warning: 2D intersection out of range for edge " << fB->vertexA()->getId() << " - " <<
- fB->vertexB()->getId() << endl;
-
- real Ta = SilhouetteGeomEngine::ImageToWorldParameter(fA, ta);
- real Tb = SilhouetteGeomEngine::ImageToWorldParameter(fB, tb);
-
- if ((Ta < -epsilon) || (Ta > 1 + epsilon))
- cerr << "Warning: 3D intersection out of range for edge " << fA->vertexA()->getId() << " - " <<
- fA->vertexB()->getId() << endl;
-
- if ((Tb < -epsilon) || (Tb > 1 + epsilon))
- cerr << "Warning: 3D intersection out of range for edge " << fB->vertexA()->getId() << " - " <<
- fB->vertexB()->getId() << endl;
+ unsigned progressBarStep = 0;
+
+ if (_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) {
+ unsigned progressBarSteps = min(gProgressBarMaxSteps, sVerticesSize);
+ progressBarStep = sVerticesSize / progressBarSteps;
+ _pProgressBar->reset();
+ _pProgressBar->setLabelText("Computing Sweep Line Intersections");
+ _pProgressBar->setTotalSteps(progressBarSteps);
+ _pProgressBar->setProgress(0);
+ progressBarDisplay = true;
+ }
+
+ unsigned counter = progressBarStep;
+
+ sort(svertices.begin(), svertices.end(), less_SVertex2D(epsilon));
+
+ SweepLine<FEdge *, Vec3r> SL;
+
+ vector<FEdge *> &ioEdges = ioViewMap->FEdges();
+
+ vector<segment *> segments;
+
+ vector<FEdge *>::iterator fe, fend;
+
+ for (fe = ioEdges.begin(), fend = ioEdges.end(); fe != fend; fe++) {
+ segment *s = new segment((*fe), (*fe)->vertexA()->point2D(), (*fe)->vertexB()->point2D());
+ (*fe)->userdata = s;
+ segments.push_back(s);
+ }
+
+ vector<segment *> vsegments;
+ for (vector<SVertex *>::iterator sv = svertices.begin(), svend = svertices.end(); sv != svend;
+ sv++) {
+ if (_pRenderMonitor && _pRenderMonitor->testBreak())
+ break;
+
+ const vector<FEdge *> &vedges = (*sv)->fedges();
+
+ for (vector<FEdge *>::const_iterator sve = vedges.begin(), sveend = vedges.end();
+ sve != sveend;
+ sve++) {
+ vsegments.push_back((segment *)((*sve)->userdata));
+ }
+
+ Vec3r evt((*sv)->point2D());
+ silhouette_binary_rule sbr;
+ SL.process(evt, vsegments, sbr, epsilon);
+
+ if (progressBarDisplay) {
+ counter--;
+ if (counter <= 0) {
+ counter = progressBarStep;
+ _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
+ }
+ }
+ vsegments.clear();
+ }
+
+ if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
+ // delete segments
+ if (!segments.empty()) {
+ vector<segment *>::iterator s, send;
+ for (s = segments.begin(), send = segments.end(); s != send; s++) {
+ delete *s;
+ }
+ }
+ return;
+ }
+
+ // reset userdata:
+ for (fe = ioEdges.begin(), fend = ioEdges.end(); fe != fend; fe++)
+ (*fe)->userdata = NULL;
+
+ // list containing the new edges resulting from splitting operations.
+ vector<FEdge *> newEdges;
+
+ // retrieve the intersected edges:
+ vector<segment *> &iedges = SL.intersectedEdges();
+ // retrieve the intersections:
+ vector<intersection *> &intersections = SL.intersections();
+
+ int id = 0;
+ // create a view vertex for each intersection and linked this one with the intersection object
+ vector<intersection *>::iterator i, iend;
+ for (i = intersections.begin(), iend = intersections.end(); i != iend; i++) {
+ FEdge *fA = (*i)->EdgeA->edge();
+ FEdge *fB = (*i)->EdgeB->edge();
+
+ Vec3r A1 = fA->vertexA()->point3D();
+ Vec3r A2 = fA->vertexB()->point3D();
+ Vec3r B1 = fB->vertexA()->point3D();
+ Vec3r B2 = fB->vertexB()->point3D();
+
+ Vec3r a1 = fA->vertexA()->point2D();
+ Vec3r a2 = fA->vertexB()->point2D();
+ Vec3r b1 = fB->vertexA()->point2D();
+ Vec3r b2 = fB->vertexB()->point2D();
+
+ real ta = (*i)->tA;
+ real tb = (*i)->tB;
+
+ if ((ta < -epsilon) || (ta > 1 + epsilon))
+ cerr << "Warning: 2D intersection out of range for edge " << fA->vertexA()->getId() << " - "
+ << fA->vertexB()->getId() << endl;
+
+ if ((tb < -epsilon) || (tb > 1 + epsilon))
+ cerr << "Warning: 2D intersection out of range for edge " << fB->vertexA()->getId() << " - "
+ << fB->vertexB()->getId() << endl;
+
+ real Ta = SilhouetteGeomEngine::ImageToWorldParameter(fA, ta);
+ real Tb = SilhouetteGeomEngine::ImageToWorldParameter(fB, tb);
+
+ if ((Ta < -epsilon) || (Ta > 1 + epsilon))
+ cerr << "Warning: 3D intersection out of range for edge " << fA->vertexA()->getId() << " - "
+ << fA->vertexB()->getId() << endl;
+
+ if ((Tb < -epsilon) || (Tb > 1 + epsilon))
+ cerr << "Warning: 3D intersection out of range for edge " << fB->vertexA()->getId() << " - "
+ << fB->vertexB()->getId() << endl;
#if 0
- if (_global.debug & G_DEBUG_FREESTYLE) {
- if ((Ta < -epsilon) || (Ta > 1 + epsilon) || (Tb < -epsilon) || (Tb > 1 + epsilon)) {
- printf("ta %.12e\n", ta);
- printf("tb %.12e\n", tb);
- printf("a1 %e, %e -- a2 %e, %e\n", a1[0], a1[1], a2[0], a2[1]);
- printf("b1 %e, %e -- b2 %e, %e\n", b1[0], b1[1], b2[0], b2[1]);
- //printf("line([%e, %e], [%e, %e]);\n", a1[0], a2[0], a1[1], a2[1]);
- //printf("line([%e, %e], [%e, %e]);\n", b1[0], b2[0], b1[1], b2[1]);
- if ((Ta < -epsilon) || (Ta > 1 + epsilon))
- printf("Ta %.12e\n", Ta);
- if ((Tb < -epsilon) || (Tb > 1 + epsilon))
- printf("Tb %.12e\n", Tb);
- printf("A1 %e, %e, %e -- A2 %e, %e, %e\n", A1[0], A1[1], A1[2], A2[0], A2[1], A2[2]);
- printf("B1 %e, %e, %e -- B2 %e, %e, %e\n", B1[0], B1[1], B1[2], B2[0], B2[1], B2[2]);
- }
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ if ((Ta < -epsilon) || (Ta > 1 + epsilon) || (Tb < -epsilon) || (Tb > 1 + epsilon)) {
+ printf("ta %.12e\n", ta);
+ printf("tb %.12e\n", tb);
+ printf("a1 %e, %e -- a2 %e, %e\n", a1[0], a1[1], a2[0], a2[1]);
+ printf("b1 %e, %e -- b2 %e, %e\n", b1[0], b1[1], b2[0], b2[1]);
+ //printf("line([%e, %e], [%e, %e]);\n", a1[0], a2[0], a1[1], a2[1]);
+ //printf("line([%e, %e], [%e, %e]);\n", b1[0], b2[0], b1[1], b2[1]);
+ if ((Ta < -epsilon) || (Ta > 1 + epsilon))
+ printf("Ta %.12e\n", Ta);
+ if ((Tb < -epsilon) || (Tb > 1 + epsilon))
+ printf("Tb %.12e\n", Tb);
+ printf("A1 %e, %e, %e -- A2 %e, %e, %e\n", A1[0], A1[1], A1[2], A2[0], A2[1], A2[2]);
+ printf("B1 %e, %e, %e -- B2 %e, %e, %e\n", B1[0], B1[1], B1[2], B2[0], B2[1], B2[2]);
+ }
+ }
#endif
- TVertex *tvertex = ioViewMap->CreateTVertex(Vec3r(A1 + Ta * (A2 - A1)), Vec3r(a1 + ta * (a2 - a1)), fA,
- Vec3r(B1 + Tb * (B2 - B1)), Vec3r(b1 + tb * (b2 - b1)), fB, id);
-
- (*i)->userdata = tvertex;
- ++id;
- }
-
- progressBarStep = 0;
-
- if (progressBarDisplay) {
- unsigned iEdgesSize = iedges.size();
- unsigned progressBarSteps = min(gProgressBarMaxSteps, iEdgesSize);
- progressBarStep = iEdgesSize / progressBarSteps;
- _pProgressBar->reset();
- _pProgressBar->setLabelText("Splitting intersected edges");
- _pProgressBar->setTotalSteps(progressBarSteps);
- _pProgressBar->setProgress(0);
- }
-
- counter = progressBarStep;
-
- vector<TVertex*> edgeVVertices;
- vector<ViewEdge*> newVEdges;
- vector<segment*>::iterator s, send;
- for (s = iedges.begin(), send = iedges.end(); s != send; s++) {
- edgeVVertices.clear();
- newEdges.clear();
- newVEdges.clear();
-
- FEdge *fedge = (*s)->edge();
- ViewEdge *vEdge = fedge->viewedge();
- ViewShape *shape = vEdge->viewShape();
-
- vector<intersection*>& eIntersections = (*s)->intersections();
- // we first need to sort these intersections from farther to closer to A
- sort(eIntersections.begin(), eIntersections.end(), less_Intersection(*s));
- for (i = eIntersections.begin(), iend = eIntersections.end(); i != iend; i++)
- edgeVVertices.push_back((TVertex *)(*i)->userdata);
-
- shape->SplitEdge(fedge, edgeVVertices, ioViewMap->FEdges(), ioViewMap->ViewEdges());
-
- if (progressBarDisplay) {
- counter--;
- if (counter <= 0) {
- counter = progressBarStep;
- _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
- }
- }
- }
-
- // reset userdata:
- for (fe = ioEdges.begin(), fend = ioEdges.end(); fe != fend; fe++)
- (*fe)->userdata = NULL;
-
- // delete segments
- if (!segments.empty()) {
- for (s = segments.begin(), send = segments.end(); s != send; s++) {
- delete *s;
- }
- }
+ TVertex *tvertex = ioViewMap->CreateTVertex(Vec3r(A1 + Ta * (A2 - A1)),
+ Vec3r(a1 + ta * (a2 - a1)),
+ fA,
+ Vec3r(B1 + Tb * (B2 - B1)),
+ Vec3r(b1 + tb * (b2 - b1)),
+ fB,
+ id);
+
+ (*i)->userdata = tvertex;
+ ++id;
+ }
+
+ progressBarStep = 0;
+
+ if (progressBarDisplay) {
+ unsigned iEdgesSize = iedges.size();
+ unsigned progressBarSteps = min(gProgressBarMaxSteps, iEdgesSize);
+ progressBarStep = iEdgesSize / progressBarSteps;
+ _pProgressBar->reset();
+ _pProgressBar->setLabelText("Splitting intersected edges");
+ _pProgressBar->setTotalSteps(progressBarSteps);
+ _pProgressBar->setProgress(0);
+ }
+
+ counter = progressBarStep;
+
+ vector<TVertex *> edgeVVertices;
+ vector<ViewEdge *> newVEdges;
+ vector<segment *>::iterator s, send;
+ for (s = iedges.begin(), send = iedges.end(); s != send; s++) {
+ edgeVVertices.clear();
+ newEdges.clear();
+ newVEdges.clear();
+
+ FEdge *fedge = (*s)->edge();
+ ViewEdge *vEdge = fedge->viewedge();
+ ViewShape *shape = vEdge->viewShape();
+
+ vector<intersection *> &eIntersections = (*s)->intersections();
+ // we first need to sort these intersections from farther to closer to A
+ sort(eIntersections.begin(), eIntersections.end(), less_Intersection(*s));
+ for (i = eIntersections.begin(), iend = eIntersections.end(); i != iend; i++)
+ edgeVVertices.push_back((TVertex *)(*i)->userdata);
+
+ shape->SplitEdge(fedge, edgeVVertices, ioViewMap->FEdges(), ioViewMap->ViewEdges());
+
+ if (progressBarDisplay) {
+ counter--;
+ if (counter <= 0) {
+ counter = progressBarStep;
+ _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
+ }
+ }
+ }
+
+ // reset userdata:
+ for (fe = ioEdges.begin(), fend = ioEdges.end(); fe != fend; fe++)
+ (*fe)->userdata = NULL;
+
+ // delete segments
+ if (!segments.empty()) {
+ for (s = segments.begin(), send = segments.end(); s != send; s++) {
+ delete *s;
+ }
+ }
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
index 4148ef5e436..0e3dbf9148e 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
@@ -47,210 +47,246 @@
#include "../winged_edge/WXEdge.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
using namespace Geometry;
-class ViewMapBuilder
-{
-private:
- ViewMap *_ViewMap; // result
- //SilhouetteGeomEngine _GeomEngine;
- ProgressBar *_pProgressBar;
- RenderMonitor *_pRenderMonitor;
- Vec3r _viewpoint;
- bool _orthographicProjection;
- Grid *_Grid;
- ViewEdgeXBuilder *_pViewEdgeBuilder;
- bool _EnableQI;
- double _epsilon;
-
- // tmp values:
- int _currentId;
- int _currentFId;
- int _currentSVertexId;
-
-public:
- typedef enum {
- sweep_line,
- } intersection_algo;
-
- typedef enum {
- ray_casting,
- ray_casting_fast,
- ray_casting_very_fast,
- ray_casting_culled_adaptive_traditional,
- ray_casting_adaptive_traditional,
- ray_casting_culled_adaptive_cumulative,
- ray_casting_adaptive_cumulative,
- } visibility_algo;
-
- inline ViewMapBuilder()
- {
- _pProgressBar = NULL;
- _pRenderMonitor = NULL;
- _Grid = NULL;
- _currentId = 1;
- _currentFId = 0;
- _currentSVertexId = 0;
- _pViewEdgeBuilder = new ViewEdgeXBuilder;
- _EnableQI = true;
- }
-
- inline ~ViewMapBuilder()
- {
- if (_pViewEdgeBuilder) {
- delete _pViewEdgeBuilder;
- _pViewEdgeBuilder = NULL;
- }
- }
-
- /* Build Grid for ray casting */
- /*! Build non-culled Grid in camera space for ray casting */
- void BuildGrid(WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces);
-
- /*! Compute Shapes from a WingedEdge containing a list of WShapes */
- void computeInitialViewEdges(WingedEdge&);
-
- /*! Compute Cusps */
- void computeCusps(ViewMap *ioViewMap);
-
- /*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of each cusp SVertex
- * We use a hysteresis approach to avoid noise.
- */
- void DetectCusps(ViewEdge *ioEdge);
-
- /*! Sets the current viewpoint */
- inline void setViewpoint(const Vec3r& ivp)
- {
- _viewpoint = ivp;
- SilhouetteGeomEngine::setViewpoint(ivp);
- }
-
- /*! Sets the current transformation
- * iModelViewMatrix
- * The 4x4 model view matrix, in column major order (openGL like).
- * iProjection matrix
- * The 4x4 projection matrix, in column major order (openGL like).
- * iViewport
- * The viewport. 4 real array: origin.x, origin.y, width, length
- */
- inline void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
- const int iViewport[4], real iFocalLength, real /*iAspect*/, real /*iFovy*/)
- {
- _orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
- SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
- }
-
- inline void setFrustum(real iZnear, real iZfar)
- {
- SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
- }
-
- /*! Builds the scene view map returns the list the view map
- * it is up to the caller to delete this ViewMap
- * iWRoot
- * The root group node containing the WEdge structured scene
- */
- ViewMap *BuildViewMap(WingedEdge& we, visibility_algo iAlgo, real epsilon, const BBox<Vec3r>& bbox,
- unsigned int sceneNumFaces);
-
- void CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4],
- bool extensiveFEdgeSearch = true);
-
- /*! computes the intersection between all 2D feature edges of the scene.
- * ioViewMap
- * The view map. It is modified by the method.
- * The list of all features edges of the scene.
- * Each time an intersection is found, the 2 intersecting edges are splitted (creating 2 new vertices)
- * At the end, this list is updated with the adding of all new created edges (resulting from splitting).
- * iAlgo
- * The algo to use for computing the intersections
- */
- void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon = 1.0e-06);
-
- /*! Computes the 2D scene silhouette edges visibility
- * iGrid
- * For the Ray Casting algorithm.
- */
- void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces,
- visibility_algo iAlgo = ray_casting, real epsilon = 1.0e-6);
-
- void setGrid(Grid *iGrid)
- {
- _Grid = iGrid;
- }
-
- /*! accessors */
-
- /*! Modifiers */
- inline void setProgressBar(ProgressBar *iProgressBar)
- {
- _pProgressBar = iProgressBar;
- }
-
- inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
- {
- _pRenderMonitor = iRenderMonitor;
- }
-
- inline void setEnableQI(bool iBool)
- {
- _EnableQI = iBool;
- }
-
-protected:
- /*! Computes intersections on all edges of the scene using a sweep line algorithm */
- void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1.0e-6);
-
- /*! Computes the 2D scene silhouette edges visibility using a ray casting. On each edge, a ray is cast
- * to check its quantitative invisibility. The list of occluders are each time stored in the tested edge.
- * ioViewMap
- * The view map.
- * The 2D scene silhouette edges as FEdges.
- * These edges have already been splitted at their intersections points.
- * Thus, these edges do not intersect anymore.
- * The visibility corresponding to each edge of ioScene is set is this edge.
- */
- void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
- void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
- void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
-
- void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
- bool cull, GridDensityProviderFactory& factory);
- void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
- bool cull, GridDensityProviderFactory& factory);
-
- /*! Compute the visibility for the FEdge fe.
- * The occluders are added to fe occluders list.
- * fe
- * The FEdge
- * iGrid
- * The grid used to compute the ray casting visibility
- * epsilon
- * The epsilon used for computation
- * oShapeId
- * fe is the border (in 2D) between 2 2D spaces.
- * if fe is a silhouette, One of these 2D spaces is occupied by the shape to which fe belongs (on its left)
- * and the other one is either occupied by another shape or empty or occupied by the same shape.
- * We use this ray csating operation to determine which shape lies on fe's right.
- * The result is the shape id stored in oShapeId
- */
- int ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
- Polygon3r **oaPolygon, unsigned timestamp);
- // FIXME
- void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
- void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
- Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices);
+class ViewMapBuilder {
+ private:
+ ViewMap *_ViewMap; // result
+ //SilhouetteGeomEngine _GeomEngine;
+ ProgressBar *_pProgressBar;
+ RenderMonitor *_pRenderMonitor;
+ Vec3r _viewpoint;
+ bool _orthographicProjection;
+ Grid *_Grid;
+ ViewEdgeXBuilder *_pViewEdgeBuilder;
+ bool _EnableQI;
+ double _epsilon;
+
+ // tmp values:
+ int _currentId;
+ int _currentFId;
+ int _currentSVertexId;
+
+ public:
+ typedef enum {
+ sweep_line,
+ } intersection_algo;
+
+ typedef enum {
+ ray_casting,
+ ray_casting_fast,
+ ray_casting_very_fast,
+ ray_casting_culled_adaptive_traditional,
+ ray_casting_adaptive_traditional,
+ ray_casting_culled_adaptive_cumulative,
+ ray_casting_adaptive_cumulative,
+ } visibility_algo;
+
+ inline ViewMapBuilder()
+ {
+ _pProgressBar = NULL;
+ _pRenderMonitor = NULL;
+ _Grid = NULL;
+ _currentId = 1;
+ _currentFId = 0;
+ _currentSVertexId = 0;
+ _pViewEdgeBuilder = new ViewEdgeXBuilder;
+ _EnableQI = true;
+ }
+
+ inline ~ViewMapBuilder()
+ {
+ if (_pViewEdgeBuilder) {
+ delete _pViewEdgeBuilder;
+ _pViewEdgeBuilder = NULL;
+ }
+ }
+
+ /* Build Grid for ray casting */
+ /*! Build non-culled Grid in camera space for ray casting */
+ void BuildGrid(WingedEdge &we, const BBox<Vec3r> &bbox, unsigned int sceneNumFaces);
+
+ /*! Compute Shapes from a WingedEdge containing a list of WShapes */
+ void computeInitialViewEdges(WingedEdge &);
+
+ /*! Compute Cusps */
+ void computeCusps(ViewMap *ioViewMap);
+
+ /*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of each cusp SVertex
+ * We use a hysteresis approach to avoid noise.
+ */
+ void DetectCusps(ViewEdge *ioEdge);
+
+ /*! Sets the current viewpoint */
+ inline void setViewpoint(const Vec3r &ivp)
+ {
+ _viewpoint = ivp;
+ SilhouetteGeomEngine::setViewpoint(ivp);
+ }
+
+ /*! Sets the current transformation
+ * iModelViewMatrix
+ * The 4x4 model view matrix, in column major order (openGL like).
+ * iProjection matrix
+ * The 4x4 projection matrix, in column major order (openGL like).
+ * iViewport
+ * The viewport. 4 real array: origin.x, origin.y, width, length
+ */
+ inline void setTransform(const real iModelViewMatrix[4][4],
+ const real iProjectionMatrix[4][4],
+ const int iViewport[4],
+ real iFocalLength,
+ real /*iAspect*/,
+ real /*iFovy*/)
+ {
+ _orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
+ SilhouetteGeomEngine::setTransform(
+ iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
+ }
+
+ inline void setFrustum(real iZnear, real iZfar)
+ {
+ SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
+ }
+
+ /*! Builds the scene view map returns the list the view map
+ * it is up to the caller to delete this ViewMap
+ * iWRoot
+ * The root group node containing the WEdge structured scene
+ */
+ ViewMap *BuildViewMap(WingedEdge &we,
+ visibility_algo iAlgo,
+ real epsilon,
+ const BBox<Vec3r> &bbox,
+ unsigned int sceneNumFaces);
+
+ void CullViewEdges(ViewMap *ioViewMap,
+ real viewProscenium[4],
+ real occluderProscenium[4],
+ bool extensiveFEdgeSearch = true);
+
+ /*! computes the intersection between all 2D feature edges of the scene.
+ * ioViewMap
+ * The view map. It is modified by the method.
+ * The list of all features edges of the scene.
+ * Each time an intersection is found, the 2 intersecting edges are splitted (creating 2 new vertices)
+ * At the end, this list is updated with the adding of all new created edges (resulting from splitting).
+ * iAlgo
+ * The algo to use for computing the intersections
+ */
+ void ComputeIntersections(ViewMap *ioViewMap,
+ intersection_algo iAlgo = sweep_line,
+ real epsilon = 1.0e-06);
+
+ /*! Computes the 2D scene silhouette edges visibility
+ * iGrid
+ * For the Ray Casting algorithm.
+ */
+ void ComputeEdgesVisibility(ViewMap *ioViewMap,
+ WingedEdge &we,
+ const BBox<Vec3r> &bbox,
+ unsigned int sceneNumFaces,
+ visibility_algo iAlgo = ray_casting,
+ real epsilon = 1.0e-6);
+
+ void setGrid(Grid *iGrid)
+ {
+ _Grid = iGrid;
+ }
+
+ /*! accessors */
+
+ /*! Modifiers */
+ inline void setProgressBar(ProgressBar *iProgressBar)
+ {
+ _pProgressBar = iProgressBar;
+ }
+
+ inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
+ {
+ _pRenderMonitor = iRenderMonitor;
+ }
+
+ inline void setEnableQI(bool iBool)
+ {
+ _EnableQI = iBool;
+ }
+
+ protected:
+ /*! Computes intersections on all edges of the scene using a sweep line algorithm */
+ void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1.0e-6);
+
+ /*! Computes the 2D scene silhouette edges visibility using a ray casting. On each edge, a ray is cast
+ * to check its quantitative invisibility. The list of occluders are each time stored in the tested edge.
+ * ioViewMap
+ * The view map.
+ * The 2D scene silhouette edges as FEdges.
+ * These edges have already been splitted at their intersections points.
+ * Thus, these edges do not intersect anymore.
+ * The visibility corresponding to each edge of ioScene is set is this edge.
+ */
+ void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
+ void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
+ void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
+
+ void ComputeCumulativeVisibility(ViewMap *ioViewMap,
+ WingedEdge &we,
+ const BBox<Vec3r> &bbox,
+ real epsilon,
+ bool cull,
+ GridDensityProviderFactory &factory);
+ void ComputeDetailedVisibility(ViewMap *ioViewMap,
+ WingedEdge &we,
+ const BBox<Vec3r> &bbox,
+ real epsilon,
+ bool cull,
+ GridDensityProviderFactory &factory);
+
+ /*! Compute the visibility for the FEdge fe.
+ * The occluders are added to fe occluders list.
+ * fe
+ * The FEdge
+ * iGrid
+ * The grid used to compute the ray casting visibility
+ * epsilon
+ * The epsilon used for computation
+ * oShapeId
+ * fe is the border (in 2D) between 2 2D spaces.
+ * if fe is a silhouette, One of these 2D spaces is occupied by the shape to which fe belongs (on its left)
+ * and the other one is either occupied by another shape or empty or occupied by the same shape.
+ * We use this ray csating operation to determine which shape lies on fe's right.
+ * The result is the shape id stored in oShapeId
+ */
+ int ComputeRayCastingVisibility(FEdge *fe,
+ Grid *iGrid,
+ real epsilon,
+ set<ViewShape *> &oOccluders,
+ Polygon3r **oaPolygon,
+ unsigned timestamp);
+ // FIXME
+ void FindOccludee(
+ FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
+ void FindOccludee(FEdge *fe,
+ Grid *iGrid,
+ real epsilon,
+ Polygon3r **oaPolygon,
+ unsigned timestamp,
+ Vec3r &u,
+ Vec3r &A,
+ Vec3r &origin,
+ Vec3r &edgeDir,
+ vector<WVertex *> &faceVertices);
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapBuilder")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapBuilder")
#endif
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_VIEW_MAP_BUILDER_H__
+#endif // __FREESTYLE_VIEW_MAP_BUILDER_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
index 6a37467a867..65336f593c7 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
@@ -31,22 +31,24 @@
# define READ(n) in.read((char *)(&(n)), sizeof((n)))
#endif
-#define WRITE_IF_NON_NULL(ptr) \
- if (ptr) { \
- WRITE((ptr)->userdata); \
- } \
- else { \
- WRITE(ZERO); \
- } (void)0
+#define WRITE_IF_NON_NULL(ptr) \
+ if (ptr) { \
+ WRITE((ptr)->userdata); \
+ } \
+ else { \
+ WRITE(ZERO); \
+ } \
+ (void)0
#define READ_IF_NON_NULL(ptr, array) \
- READ(tmp); \
- if (tmp) { \
- (ptr) = (array)[tmp]; \
- } \
- else { \
- (ptr) = NULL; \
- } (void)0
+ READ(tmp); \
+ if (tmp) { \
+ (ptr) = (array)[tmp]; \
+ } \
+ else { \
+ (ptr) = NULL; \
+ } \
+ (void)0
namespace Freestyle {
@@ -58,1155 +60,1170 @@ static ViewMap *g_vm;
//////////////////// 'load' Functions ////////////////////
-inline int load(istream& in, Vec3r& v)
+inline int load(istream &in, Vec3r &v)
{
- if (Options::getFlags() & Options::FLOAT_VECTORS) {
- float tmp;
- READ(tmp);
- v[0] = tmp;
- READ(tmp);
- v[1] = tmp;
- READ(tmp);
- v[2] = tmp;
- }
- else {
- Vec3r::value_type tmp;
- READ(tmp);
- v[0] = tmp;
- READ(tmp);
- v[1] = tmp;
- READ(tmp);
- v[2] = tmp;
- }
- return 0;
+ if (Options::getFlags() & Options::FLOAT_VECTORS) {
+ float tmp;
+ READ(tmp);
+ v[0] = tmp;
+ READ(tmp);
+ v[1] = tmp;
+ READ(tmp);
+ v[2] = tmp;
+ }
+ else {
+ Vec3r::value_type tmp;
+ READ(tmp);
+ v[0] = tmp;
+ READ(tmp);
+ v[1] = tmp;
+ READ(tmp);
+ v[2] = tmp;
+ }
+ return 0;
}
-inline int load(istream& in, Polygon3r& p)
+inline int load(istream &in, Polygon3r &p)
{
- unsigned tmp;
-
- // Id
- READ(tmp);
- p.setId(tmp);
-
- // vertices (List)
- vector<Vec3r> tmp_vec;
- Vec3r v;
- READ(tmp);
- for (unsigned int i = 0; i < tmp; i++) {
- load(in, v);
- tmp_vec.push_back(v);
- }
- p.setVertices(tmp_vec);
-
- // min & max
- // Already computed (in the SetVertices() method)
-
- return 0;
+ unsigned tmp;
+
+ // Id
+ READ(tmp);
+ p.setId(tmp);
+
+ // vertices (List)
+ vector<Vec3r> tmp_vec;
+ Vec3r v;
+ READ(tmp);
+ for (unsigned int i = 0; i < tmp; i++) {
+ load(in, v);
+ tmp_vec.push_back(v);
+ }
+ p.setVertices(tmp_vec);
+
+ // min & max
+ // Already computed (in the SetVertices() method)
+
+ return 0;
}
-inline int load(istream& in, FrsMaterial& m)
+inline int load(istream &in, FrsMaterial &m)
{
- float tmp_array[4];
- int i;
-
- // Diffuse
- for (i = 0; i < 4; i++)
- READ(tmp_array[i]);
- m.setDiffuse(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
-
- // Specular
- for (i = 0; i < 4; i++)
- READ(tmp_array[i]);
- m.setSpecular(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
-
- // Ambient
- for (i = 0; i < 4; i++)
- READ(tmp_array[i]);
- m.setAmbient(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
-
- // Emission
- for (i = 0; i < 4; i++)
- READ(tmp_array[i]);
- m.setEmission(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
-
- // Shininess
- READ(tmp_array[0]);
- m.setShininess(tmp_array[0]);
-
- return 0;
+ float tmp_array[4];
+ int i;
+
+ // Diffuse
+ for (i = 0; i < 4; i++)
+ READ(tmp_array[i]);
+ m.setDiffuse(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
+
+ // Specular
+ for (i = 0; i < 4; i++)
+ READ(tmp_array[i]);
+ m.setSpecular(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
+
+ // Ambient
+ for (i = 0; i < 4; i++)
+ READ(tmp_array[i]);
+ m.setAmbient(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
+
+ // Emission
+ for (i = 0; i < 4; i++)
+ READ(tmp_array[i]);
+ m.setEmission(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
+
+ // Shininess
+ READ(tmp_array[0]);
+ m.setShininess(tmp_array[0]);
+
+ return 0;
}
-static int load(istream& in, ViewShape *vs)
+static int load(istream &in, ViewShape *vs)
{
- if (!vs || !vs->sshape())
- return 1;
-
- // SShape
-
- // -> Id
- Id::id_type id1, id2;
- READ(id1);
- READ(id2);
- vs->sshape()->setId(Id(id1, id2));
-
- // -> Importance
- float importance;
- READ(importance);
- vs->sshape()->setImportance(importance);
-
- // -> BBox
- // Not necessary (only used during view map computatiom)
-
- unsigned i, size, tmp;
-
- // -> Material
- READ(size);
- vector<FrsMaterial> frs_materials;
- FrsMaterial m;
- for (i = 0; i < size; ++i) {
- load(in, m);
- frs_materials.push_back(m);
- }
- vs->sshape()->setFrsMaterials(frs_materials);
-
- // -> VerticesList (List)
- READ(size);
- for (i = 0; i < size; i++) {
- SVertex *sv;
- READ_IF_NON_NULL(sv, g_vm->SVertices());
- vs->sshape()->AddNewVertex(sv);
- }
-
- // -> Chains (List)
- READ(size);
- for (i = 0; i < size; i++) {
- FEdge *fe;
- READ_IF_NON_NULL(fe, g_vm->FEdges());
- vs->sshape()->AddChain(fe);
- }
-
- // -> EdgesList (List)
- READ(size);
- for (i = 0; i < size; i++) {
- FEdge *fe;
- READ_IF_NON_NULL(fe, g_vm->FEdges());
- vs->sshape()->AddEdge(fe);
- }
-
- // ViewEdges (List)
- READ(size);
- for (i = 0; i < size; i++) {
- ViewEdge *ve;
- READ_IF_NON_NULL(ve, g_vm->ViewEdges());
- vs->AddEdge(ve);
- }
-
- // ViewVertices (List)
- READ(size);
- for (i = 0; i < size; i++) {
- ViewVertex *vv;
- READ_IF_NON_NULL(vv, g_vm->ViewVertices());
- vs->AddVertex(vv);
- }
-
- return 0;
+ if (!vs || !vs->sshape())
+ return 1;
+
+ // SShape
+
+ // -> Id
+ Id::id_type id1, id2;
+ READ(id1);
+ READ(id2);
+ vs->sshape()->setId(Id(id1, id2));
+
+ // -> Importance
+ float importance;
+ READ(importance);
+ vs->sshape()->setImportance(importance);
+
+ // -> BBox
+ // Not necessary (only used during view map computatiom)
+
+ unsigned i, size, tmp;
+
+ // -> Material
+ READ(size);
+ vector<FrsMaterial> frs_materials;
+ FrsMaterial m;
+ for (i = 0; i < size; ++i) {
+ load(in, m);
+ frs_materials.push_back(m);
+ }
+ vs->sshape()->setFrsMaterials(frs_materials);
+
+ // -> VerticesList (List)
+ READ(size);
+ for (i = 0; i < size; i++) {
+ SVertex *sv;
+ READ_IF_NON_NULL(sv, g_vm->SVertices());
+ vs->sshape()->AddNewVertex(sv);
+ }
+
+ // -> Chains (List)
+ READ(size);
+ for (i = 0; i < size; i++) {
+ FEdge *fe;
+ READ_IF_NON_NULL(fe, g_vm->FEdges());
+ vs->sshape()->AddChain(fe);
+ }
+
+ // -> EdgesList (List)
+ READ(size);
+ for (i = 0; i < size; i++) {
+ FEdge *fe;
+ READ_IF_NON_NULL(fe, g_vm->FEdges());
+ vs->sshape()->AddEdge(fe);
+ }
+
+ // ViewEdges (List)
+ READ(size);
+ for (i = 0; i < size; i++) {
+ ViewEdge *ve;
+ READ_IF_NON_NULL(ve, g_vm->ViewEdges());
+ vs->AddEdge(ve);
+ }
+
+ // ViewVertices (List)
+ READ(size);
+ for (i = 0; i < size; i++) {
+ ViewVertex *vv;
+ READ_IF_NON_NULL(vv, g_vm->ViewVertices());
+ vs->AddVertex(vv);
+ }
+
+ return 0;
}
-
-static int load(istream& in, FEdge *fe)
+static int load(istream &in, FEdge *fe)
{
- if (!fe)
- return 1;
-
- bool b;
-
- FEdgeSmooth *fesmooth = NULL;
- FEdgeSharp *fesharp = NULL;
- if (fe->isSmooth()) {
- fesmooth = dynamic_cast<FEdgeSmooth*>(fe);
- }
- else {
- fesharp = dynamic_cast<FEdgeSharp*>(fe);
- }
-
- // Id
- Id::id_type id1, id2;
- READ(id1);
- READ(id2);
- fe->setId(Id(id1, id2));
-
- // Nature
- Nature::EdgeNature nature;
- READ(nature);
- fe->setNature(nature);
-
-#if 0 // hasVisibilityPoint
- bool b;
- READ(b);
- fe->setHasVisibilityPoint(b);
+ if (!fe)
+ return 1;
+
+ bool b;
+
+ FEdgeSmooth *fesmooth = NULL;
+ FEdgeSharp *fesharp = NULL;
+ if (fe->isSmooth()) {
+ fesmooth = dynamic_cast<FEdgeSmooth *>(fe);
+ }
+ else {
+ fesharp = dynamic_cast<FEdgeSharp *>(fe);
+ }
+
+ // Id
+ Id::id_type id1, id2;
+ READ(id1);
+ READ(id2);
+ fe->setId(Id(id1, id2));
+
+ // Nature
+ Nature::EdgeNature nature;
+ READ(nature);
+ fe->setNature(nature);
+
+#if 0 // hasVisibilityPoint
+ bool b;
+ READ(b);
+ fe->setHasVisibilityPoint(b);
#endif
- Vec3r v;
- unsigned int matindex;
+ Vec3r v;
+ unsigned int matindex;
#if 0
- // VisibilityPointA
- load(in, v);
- fe->setVisibilityPointA(v);
+ // VisibilityPointA
+ load(in, v);
+ fe->setVisibilityPointA(v);
- // VisibilityPointB
- load(in, v);
- fe->setVisibilityPointB(v);
+ // VisibilityPointB
+ load(in, v);
+ fe->setVisibilityPointB(v);
#endif
- if (fe->isSmooth()) {
- // Normal
- load(in, v);
- fesmooth->setNormal(v);
-
- // Material
- READ(matindex);
- fesmooth->setFrsMaterialIndex(matindex);
- }
- else {
- // aNormal
- load(in, v);
- fesharp->setNormalA(v);
-
- // bNormal
- load(in, v);
- fesharp->setNormalB(v);
-
- // Materials
- READ(matindex);
- fesharp->setaFrsMaterialIndex(matindex);
- READ(matindex);
- fesharp->setbFrsMaterialIndex(matindex);
- }
-
- unsigned tmp;
-
- // VertexA
- SVertex *sva;
- READ_IF_NON_NULL(sva, g_vm->SVertices());
- fe->setVertexA(sva);
-
- // VertexB
- SVertex *svb;
- READ_IF_NON_NULL(svb, g_vm->SVertices());
- fe->setVertexB(svb);
-
- // NextEdge
- FEdge *nfe;
- READ_IF_NON_NULL(nfe, g_vm->FEdges());
- fe->setNextEdge(nfe);
-
- // PreviousEdge
- FEdge *pfe;
- READ_IF_NON_NULL(pfe, g_vm->FEdges());
- fe->setPreviousEdge(pfe);
-
- // ViewEdge
- ViewEdge *ve;
- READ_IF_NON_NULL(ve, g_vm->ViewEdges());
- fe->setViewEdge(ve);
-
- // Face
- // Not necessary (only used during view map computatiom)
-
- Polygon3r p;
-
- // aFace
- load(in, p);
- fe->setaFace(p);
-
- // occludeeEmpty
- READ(b);
- fe->setOccludeeEmpty(b);
-
- // occludeeIntersection
- load(in, v);
- fe->setOccludeeIntersection(v);
-
- return 0;
+ if (fe->isSmooth()) {
+ // Normal
+ load(in, v);
+ fesmooth->setNormal(v);
+
+ // Material
+ READ(matindex);
+ fesmooth->setFrsMaterialIndex(matindex);
+ }
+ else {
+ // aNormal
+ load(in, v);
+ fesharp->setNormalA(v);
+
+ // bNormal
+ load(in, v);
+ fesharp->setNormalB(v);
+
+ // Materials
+ READ(matindex);
+ fesharp->setaFrsMaterialIndex(matindex);
+ READ(matindex);
+ fesharp->setbFrsMaterialIndex(matindex);
+ }
+
+ unsigned tmp;
+
+ // VertexA
+ SVertex *sva;
+ READ_IF_NON_NULL(sva, g_vm->SVertices());
+ fe->setVertexA(sva);
+
+ // VertexB
+ SVertex *svb;
+ READ_IF_NON_NULL(svb, g_vm->SVertices());
+ fe->setVertexB(svb);
+
+ // NextEdge
+ FEdge *nfe;
+ READ_IF_NON_NULL(nfe, g_vm->FEdges());
+ fe->setNextEdge(nfe);
+
+ // PreviousEdge
+ FEdge *pfe;
+ READ_IF_NON_NULL(pfe, g_vm->FEdges());
+ fe->setPreviousEdge(pfe);
+
+ // ViewEdge
+ ViewEdge *ve;
+ READ_IF_NON_NULL(ve, g_vm->ViewEdges());
+ fe->setViewEdge(ve);
+
+ // Face
+ // Not necessary (only used during view map computatiom)
+
+ Polygon3r p;
+
+ // aFace
+ load(in, p);
+ fe->setaFace(p);
+
+ // occludeeEmpty
+ READ(b);
+ fe->setOccludeeEmpty(b);
+
+ // occludeeIntersection
+ load(in, v);
+ fe->setOccludeeIntersection(v);
+
+ return 0;
}
-static int load(istream& in, SVertex *sv)
+static int load(istream &in, SVertex *sv)
{
- if (!sv)
- return 1;
-
- // Id
- Id::id_type id1, id2;
- READ(id1);
- READ(id2);
- sv->setId(Id(id1, id2));
-
- Vec3r v;
-
- // Point3D
- load(in, v);
- sv->setPoint3D(v);
-
- // Point2D
- load(in, v);
- sv->setPoint2D(v);
-
- unsigned tmp;
-
- // Shape
- ViewShape *vs;
- READ_IF_NON_NULL(vs, g_vm->ViewShapes());
- sv->setShape(vs->sshape());
-
- // pViewVertex
- ViewVertex *vv;
- READ_IF_NON_NULL(vv, g_vm->ViewVertices());
- sv->setViewVertex(vv);
-
- unsigned i, size;
-
- // Normals (List)
- READ(size);
- for (i = 0; i < size; i++) {
- load(in, v);
- sv->AddNormal(v);
- }
-
- // FEdges (List)
- READ(size);
- FEdge *fe;
- for (i = 0; i < size; i++) {
- READ_IF_NON_NULL(fe, g_vm->FEdges());
- sv->AddFEdge(fe);
- }
-
- return 0;
+ if (!sv)
+ return 1;
+
+ // Id
+ Id::id_type id1, id2;
+ READ(id1);
+ READ(id2);
+ sv->setId(Id(id1, id2));
+
+ Vec3r v;
+
+ // Point3D
+ load(in, v);
+ sv->setPoint3D(v);
+
+ // Point2D
+ load(in, v);
+ sv->setPoint2D(v);
+
+ unsigned tmp;
+
+ // Shape
+ ViewShape *vs;
+ READ_IF_NON_NULL(vs, g_vm->ViewShapes());
+ sv->setShape(vs->sshape());
+
+ // pViewVertex
+ ViewVertex *vv;
+ READ_IF_NON_NULL(vv, g_vm->ViewVertices());
+ sv->setViewVertex(vv);
+
+ unsigned i, size;
+
+ // Normals (List)
+ READ(size);
+ for (i = 0; i < size; i++) {
+ load(in, v);
+ sv->AddNormal(v);
+ }
+
+ // FEdges (List)
+ READ(size);
+ FEdge *fe;
+ for (i = 0; i < size; i++) {
+ READ_IF_NON_NULL(fe, g_vm->FEdges());
+ sv->AddFEdge(fe);
+ }
+
+ return 0;
}
-
-static int load(istream& in, ViewEdge *ve)
+static int load(istream &in, ViewEdge *ve)
{
- if (!ve)
- return 1;
-
- unsigned tmp;
-
- // Id
- Id::id_type id1, id2;
- READ(id1);
- READ(id2);
- ve->setId(Id(id1, id2));
-
- // Nature
- Nature::EdgeNature nature;
- READ(nature);
- ve->setNature(nature);
-
- // QI
- READ(tmp);
- ve->setQI(tmp);
-
- // Shape
- ViewShape *vs;
- READ_IF_NON_NULL(vs, g_vm->ViewShapes());
- ve->setShape(vs);
-
- // aShape
- ViewShape *avs;
- READ_IF_NON_NULL(avs, g_vm->ViewShapes());
- ve->setaShape(avs);
-
- // FEdgeA
- FEdge *fea;
- READ_IF_NON_NULL(fea, g_vm->FEdges());
- ve->setFEdgeA(fea);
-
- // FEdgeB
- FEdge *feb;
- READ_IF_NON_NULL(feb, g_vm->FEdges());
- ve->setFEdgeB(feb);
-
- // A
- ViewVertex *vva;
- READ_IF_NON_NULL(vva, g_vm->ViewVertices());
- ve->setA(vva);
-
- // B
- ViewVertex *vvb;
- READ_IF_NON_NULL(vvb, g_vm->ViewVertices());
- ve->setB(vvb);
-
- // Occluders (List)
- if (!(Options::getFlags() & Options::NO_OCCLUDERS)) {
- unsigned size;
- READ(size);
- ViewShape *vso;
- for (unsigned int i = 0; i < size; i++) {
- READ_IF_NON_NULL(vso, g_vm->ViewShapes());
- ve->AddOccluder(vso);
- }
- }
-
- return 0;
+ if (!ve)
+ return 1;
+
+ unsigned tmp;
+
+ // Id
+ Id::id_type id1, id2;
+ READ(id1);
+ READ(id2);
+ ve->setId(Id(id1, id2));
+
+ // Nature
+ Nature::EdgeNature nature;
+ READ(nature);
+ ve->setNature(nature);
+
+ // QI
+ READ(tmp);
+ ve->setQI(tmp);
+
+ // Shape
+ ViewShape *vs;
+ READ_IF_NON_NULL(vs, g_vm->ViewShapes());
+ ve->setShape(vs);
+
+ // aShape
+ ViewShape *avs;
+ READ_IF_NON_NULL(avs, g_vm->ViewShapes());
+ ve->setaShape(avs);
+
+ // FEdgeA
+ FEdge *fea;
+ READ_IF_NON_NULL(fea, g_vm->FEdges());
+ ve->setFEdgeA(fea);
+
+ // FEdgeB
+ FEdge *feb;
+ READ_IF_NON_NULL(feb, g_vm->FEdges());
+ ve->setFEdgeB(feb);
+
+ // A
+ ViewVertex *vva;
+ READ_IF_NON_NULL(vva, g_vm->ViewVertices());
+ ve->setA(vva);
+
+ // B
+ ViewVertex *vvb;
+ READ_IF_NON_NULL(vvb, g_vm->ViewVertices());
+ ve->setB(vvb);
+
+ // Occluders (List)
+ if (!(Options::getFlags() & Options::NO_OCCLUDERS)) {
+ unsigned size;
+ READ(size);
+ ViewShape *vso;
+ for (unsigned int i = 0; i < size; i++) {
+ READ_IF_NON_NULL(vso, g_vm->ViewShapes());
+ ve->AddOccluder(vso);
+ }
+ }
+
+ return 0;
}
-
-static int load(istream& in, ViewVertex *vv)
+static int load(istream &in, ViewVertex *vv)
{
- if (!vv)
- return 1;
-
- unsigned tmp;
- bool b;
-
- // Nature
- Nature::VertexNature nature;
- READ(nature);
- vv->setNature(nature);
-
- if (vv->getNature() & Nature::T_VERTEX) {
- TVertex *tv = dynamic_cast<TVertex*>(vv);
-
- // Id
- Id::id_type id1, id2;
- READ(id1);
- READ(id2);
- tv->setId(Id(id1, id2));
-
- // FrontSVertex
- SVertex *fsv;
- READ_IF_NON_NULL(fsv, g_vm->SVertices());
- tv->setFrontSVertex(fsv);
-
- // BackSVertex
- SVertex *bsv;
- READ_IF_NON_NULL(bsv, g_vm->SVertices());
- tv->setBackSVertex(bsv);
-
- // FrontEdgeA
- ViewEdge *fea;
- READ_IF_NON_NULL(fea, g_vm->ViewEdges());
- READ(b);
- tv->setFrontEdgeA(fea, b);
-
- // FrontEdgeB
- ViewEdge *feb;
- READ_IF_NON_NULL(feb, g_vm->ViewEdges());
- READ(b);
- tv->setFrontEdgeB(feb, b);
-
- // BackEdgeA
- ViewEdge *bea;
- READ_IF_NON_NULL(bea, g_vm->ViewEdges());
- READ(b);
- tv->setBackEdgeA(bea, b);
-
- // BackEdgeB
- ViewEdge *beb;
- READ_IF_NON_NULL(beb, g_vm->ViewEdges());
- READ(b);
- tv->setBackEdgeB(beb, b);
- }
- else if (vv->getNature() & Nature::NON_T_VERTEX) {
- NonTVertex *ntv = dynamic_cast<NonTVertex*>(vv);
-
- // SVertex
- SVertex *sv;
- READ_IF_NON_NULL(sv, g_vm->SVertices());
- ntv->setSVertex(sv);
-
- // ViewEdges (List)
- unsigned size;
- READ(size);
- ViewEdge *ve;
- for (unsigned int i = 0; i < size; i++) {
- READ_IF_NON_NULL(ve, g_vm->ViewEdges());
- READ(b);
- ntv->AddViewEdge(ve, b);
- }
- }
-
- return 0;
+ if (!vv)
+ return 1;
+
+ unsigned tmp;
+ bool b;
+
+ // Nature
+ Nature::VertexNature nature;
+ READ(nature);
+ vv->setNature(nature);
+
+ if (vv->getNature() & Nature::T_VERTEX) {
+ TVertex *tv = dynamic_cast<TVertex *>(vv);
+
+ // Id
+ Id::id_type id1, id2;
+ READ(id1);
+ READ(id2);
+ tv->setId(Id(id1, id2));
+
+ // FrontSVertex
+ SVertex *fsv;
+ READ_IF_NON_NULL(fsv, g_vm->SVertices());
+ tv->setFrontSVertex(fsv);
+
+ // BackSVertex
+ SVertex *bsv;
+ READ_IF_NON_NULL(bsv, g_vm->SVertices());
+ tv->setBackSVertex(bsv);
+
+ // FrontEdgeA
+ ViewEdge *fea;
+ READ_IF_NON_NULL(fea, g_vm->ViewEdges());
+ READ(b);
+ tv->setFrontEdgeA(fea, b);
+
+ // FrontEdgeB
+ ViewEdge *feb;
+ READ_IF_NON_NULL(feb, g_vm->ViewEdges());
+ READ(b);
+ tv->setFrontEdgeB(feb, b);
+
+ // BackEdgeA
+ ViewEdge *bea;
+ READ_IF_NON_NULL(bea, g_vm->ViewEdges());
+ READ(b);
+ tv->setBackEdgeA(bea, b);
+
+ // BackEdgeB
+ ViewEdge *beb;
+ READ_IF_NON_NULL(beb, g_vm->ViewEdges());
+ READ(b);
+ tv->setBackEdgeB(beb, b);
+ }
+ else if (vv->getNature() & Nature::NON_T_VERTEX) {
+ NonTVertex *ntv = dynamic_cast<NonTVertex *>(vv);
+
+ // SVertex
+ SVertex *sv;
+ READ_IF_NON_NULL(sv, g_vm->SVertices());
+ ntv->setSVertex(sv);
+
+ // ViewEdges (List)
+ unsigned size;
+ READ(size);
+ ViewEdge *ve;
+ for (unsigned int i = 0; i < size; i++) {
+ READ_IF_NON_NULL(ve, g_vm->ViewEdges());
+ READ(b);
+ ntv->AddViewEdge(ve, b);
+ }
+ }
+
+ return 0;
}
//////////////////// 'save' Functions ////////////////////
-inline int save(ostream& out, const Vec3r& v)
+inline int save(ostream &out, const Vec3r &v)
{
- if (Options::getFlags() & Options::FLOAT_VECTORS) {
- float tmp;
-
- tmp = v[0];
- WRITE(tmp);
- tmp = v[1];
- WRITE(tmp);
- tmp = v[2];
- WRITE(tmp);
- }
- else {
- Vec3r::value_type tmp;
-
- tmp = v[0];
- WRITE(tmp);
- tmp = v[1];
- WRITE(tmp);
- tmp = v[2];
- WRITE(tmp);
- }
- return 0;
+ if (Options::getFlags() & Options::FLOAT_VECTORS) {
+ float tmp;
+
+ tmp = v[0];
+ WRITE(tmp);
+ tmp = v[1];
+ WRITE(tmp);
+ tmp = v[2];
+ WRITE(tmp);
+ }
+ else {
+ Vec3r::value_type tmp;
+
+ tmp = v[0];
+ WRITE(tmp);
+ tmp = v[1];
+ WRITE(tmp);
+ tmp = v[2];
+ WRITE(tmp);
+ }
+ return 0;
}
-
-inline int save(ostream& out, const Polygon3r& p)
+inline int save(ostream &out, const Polygon3r &p)
{
- unsigned tmp;
+ unsigned tmp;
- // Id
- tmp = p.getId();
- WRITE(tmp);
+ // Id
+ tmp = p.getId();
+ WRITE(tmp);
- // vertices (List)
- tmp = p.getVertices().size();
- WRITE(tmp);
- for (vector<Vec3r>::const_iterator i = p.getVertices().begin(); i != p.getVertices().end(); i++) {
- save(out, *i);
- }
+ // vertices (List)
+ tmp = p.getVertices().size();
+ WRITE(tmp);
+ for (vector<Vec3r>::const_iterator i = p.getVertices().begin(); i != p.getVertices().end();
+ i++) {
+ save(out, *i);
+ }
- // min & max
- // Do not need to be saved
+ // min & max
+ // Do not need to be saved
- return 0;
+ return 0;
}
-inline int save(ostream& out, const FrsMaterial& m)
+inline int save(ostream &out, const FrsMaterial &m)
{
- unsigned i;
+ unsigned i;
- // Diffuse
- for (i = 0; i < 4; i++)
- WRITE(m.diffuse()[i]);
+ // Diffuse
+ for (i = 0; i < 4; i++)
+ WRITE(m.diffuse()[i]);
- // Specular
- for (i = 0; i < 4; i++)
- WRITE(m.specular()[i]);
+ // Specular
+ for (i = 0; i < 4; i++)
+ WRITE(m.specular()[i]);
- // Ambient
- for (i = 0; i < 4; i++)
- WRITE(m.ambient()[i]);
+ // Ambient
+ for (i = 0; i < 4; i++)
+ WRITE(m.ambient()[i]);
- // Emission
- for (i = 0; i < 4; i++)
- WRITE(m.emission()[i]);
+ // Emission
+ for (i = 0; i < 4; i++)
+ WRITE(m.emission()[i]);
- // Shininess
- float shininess = m.shininess();
- WRITE(shininess);
+ // Shininess
+ float shininess = m.shininess();
+ WRITE(shininess);
- return 0;
+ return 0;
}
-static int save(ostream& out, ViewShape *vs)
+static int save(ostream &out, ViewShape *vs)
{
- if (!vs || !vs->sshape()) {
- cerr << "Warning: null ViewShape" << endl;
- return 1;
- }
-
- unsigned tmp;
-
- // SShape
-
- // -> Id
- Id::id_type id = vs->sshape()->getId().getFirst();
- WRITE(id);
- id = vs->sshape()->getId().getSecond();
- WRITE(id);
-
- // -> Importance
- float importance = vs->sshape()->importance();
- WRITE(importance);
-
- // -> BBox
- // Not necessary (only used during view map computatiom)
-
- // -> Material
- unsigned int size = vs->sshape()->frs_materials().size();
- WRITE(size);
- for (unsigned int i = 0; i < size; ++i)
- save(out, vs->sshape()->frs_material(i));
-
- // -> VerticesList (List)
- tmp = vs->sshape()->getVertexList().size();
- WRITE(tmp);
- for (vector<SVertex*>::const_iterator i1 = vs->sshape()->getVertexList().begin();
- i1 != vs->sshape()->getVertexList().end();
- i1++)
- {
- WRITE_IF_NON_NULL(*i1);
- }
-
- // -> Chains (List)
- tmp = vs->sshape()->getChains().size();
- WRITE(tmp);
- for (vector<FEdge*>::const_iterator i2 = vs->sshape()->getChains().begin();
- i2 != vs->sshape()->getChains().end();
- i2++)
- {
- WRITE_IF_NON_NULL(*i2);
- }
-
- // -> EdgesList (List)
- tmp = vs->sshape()->getEdgeList().size();
- WRITE(tmp);
- for (vector<FEdge*>::const_iterator i3 = vs->sshape()->getEdgeList().begin();
- i3 != vs->sshape()->getEdgeList().end();
- i3++)
- {
- WRITE_IF_NON_NULL(*i3);
- }
-
- // ViewEdges (List)
- tmp = vs->edges().size();
- WRITE(tmp);
- for (vector<ViewEdge*>::const_iterator i4 = vs->edges().begin(); i4 != vs->edges().end(); i4++) {
- WRITE_IF_NON_NULL(*i4);
- }
-
- // ViewVertices (List)
- tmp = vs->vertices().size();
- WRITE(tmp);
- for (vector<ViewVertex*>::const_iterator i5 = vs->vertices().begin(); i5 != vs->vertices().end(); i5++) {
- WRITE_IF_NON_NULL(*i5);
- }
-
- return 0;
+ if (!vs || !vs->sshape()) {
+ cerr << "Warning: null ViewShape" << endl;
+ return 1;
+ }
+
+ unsigned tmp;
+
+ // SShape
+
+ // -> Id
+ Id::id_type id = vs->sshape()->getId().getFirst();
+ WRITE(id);
+ id = vs->sshape()->getId().getSecond();
+ WRITE(id);
+
+ // -> Importance
+ float importance = vs->sshape()->importance();
+ WRITE(importance);
+
+ // -> BBox
+ // Not necessary (only used during view map computatiom)
+
+ // -> Material
+ unsigned int size = vs->sshape()->frs_materials().size();
+ WRITE(size);
+ for (unsigned int i = 0; i < size; ++i)
+ save(out, vs->sshape()->frs_material(i));
+
+ // -> VerticesList (List)
+ tmp = vs->sshape()->getVertexList().size();
+ WRITE(tmp);
+ for (vector<SVertex *>::const_iterator i1 = vs->sshape()->getVertexList().begin();
+ i1 != vs->sshape()->getVertexList().end();
+ i1++) {
+ WRITE_IF_NON_NULL(*i1);
+ }
+
+ // -> Chains (List)
+ tmp = vs->sshape()->getChains().size();
+ WRITE(tmp);
+ for (vector<FEdge *>::const_iterator i2 = vs->sshape()->getChains().begin();
+ i2 != vs->sshape()->getChains().end();
+ i2++) {
+ WRITE_IF_NON_NULL(*i2);
+ }
+
+ // -> EdgesList (List)
+ tmp = vs->sshape()->getEdgeList().size();
+ WRITE(tmp);
+ for (vector<FEdge *>::const_iterator i3 = vs->sshape()->getEdgeList().begin();
+ i3 != vs->sshape()->getEdgeList().end();
+ i3++) {
+ WRITE_IF_NON_NULL(*i3);
+ }
+
+ // ViewEdges (List)
+ tmp = vs->edges().size();
+ WRITE(tmp);
+ for (vector<ViewEdge *>::const_iterator i4 = vs->edges().begin(); i4 != vs->edges().end();
+ i4++) {
+ WRITE_IF_NON_NULL(*i4);
+ }
+
+ // ViewVertices (List)
+ tmp = vs->vertices().size();
+ WRITE(tmp);
+ for (vector<ViewVertex *>::const_iterator i5 = vs->vertices().begin();
+ i5 != vs->vertices().end();
+ i5++) {
+ WRITE_IF_NON_NULL(*i5);
+ }
+
+ return 0;
}
-
-static int save(ostream& out, FEdge *fe)
+static int save(ostream &out, FEdge *fe)
{
- if (!fe) {
- cerr << "Warning: null FEdge" << endl;
- return 1;
- }
+ if (!fe) {
+ cerr << "Warning: null FEdge" << endl;
+ return 1;
+ }
- FEdgeSmooth *fesmooth = dynamic_cast<FEdgeSmooth*>(fe);
- FEdgeSharp *fesharp = dynamic_cast<FEdgeSharp*>(fe);
+ FEdgeSmooth *fesmooth = dynamic_cast<FEdgeSmooth *>(fe);
+ FEdgeSharp *fesharp = dynamic_cast<FEdgeSharp *>(fe);
- // Id
- Id::id_type id = fe->getId().getFirst();
- WRITE(id);
- id = fe->getId().getSecond();
- WRITE(id);
+ // Id
+ Id::id_type id = fe->getId().getFirst();
+ WRITE(id);
+ id = fe->getId().getSecond();
+ WRITE(id);
- // Nature
- Nature::EdgeNature nature = fe->getNature();
- WRITE(nature);
+ // Nature
+ Nature::EdgeNature nature = fe->getNature();
+ WRITE(nature);
- bool b;
+ bool b;
#if 0
- // hasVisibilityPoint
- b = fe->hasVisibilityPoint();
- WRITE(b);
+ // hasVisibilityPoint
+ b = fe->hasVisibilityPoint();
+ WRITE(b);
- // VisibilityPointA
- save(out, fe->visibilityPointA());
+ // VisibilityPointA
+ save(out, fe->visibilityPointA());
- // VisibilityPointB
- save(out, fe->visibilityPointB());
+ // VisibilityPointB
+ save(out, fe->visibilityPointB());
#endif
- unsigned index;
- if (fe->isSmooth()) {
- // normal
- save(out, fesmooth->normal());
- // material
- index = fesmooth->frs_materialIndex();
- WRITE(index);
- }
- else {
- // aNormal
- save(out, fesharp->normalA());
- // bNormal
- save(out, fesharp->normalB());
- // aMaterial
- index = fesharp->aFrsMaterialIndex();
- WRITE(index);
- // bMaterial
- index = fesharp->bFrsMaterialIndex();
- WRITE(index);
- }
-
- // VertexA
- WRITE_IF_NON_NULL(fe->vertexA());
-
- // VertexB
- WRITE_IF_NON_NULL(fe->vertexB());
-
- // NextEdge
- WRITE_IF_NON_NULL(fe->nextEdge());
-
- // PreviousEdge
- WRITE_IF_NON_NULL(fe->previousEdge());
-
- // ViewEdge
- WRITE_IF_NON_NULL(fe->viewedge());
-
- // Face
- // Not necessary (only used during view map computatiom)
-
- // aFace
- save(out, (Polygon3r&)fe->aFace());
-
- // occludeeEmpty
- b = fe->getOccludeeEmpty();
- WRITE(b);
-
- // occludeeIntersection
- save(out, fe->getOccludeeIntersection());
-
- return 0;
+ unsigned index;
+ if (fe->isSmooth()) {
+ // normal
+ save(out, fesmooth->normal());
+ // material
+ index = fesmooth->frs_materialIndex();
+ WRITE(index);
+ }
+ else {
+ // aNormal
+ save(out, fesharp->normalA());
+ // bNormal
+ save(out, fesharp->normalB());
+ // aMaterial
+ index = fesharp->aFrsMaterialIndex();
+ WRITE(index);
+ // bMaterial
+ index = fesharp->bFrsMaterialIndex();
+ WRITE(index);
+ }
+
+ // VertexA
+ WRITE_IF_NON_NULL(fe->vertexA());
+
+ // VertexB
+ WRITE_IF_NON_NULL(fe->vertexB());
+
+ // NextEdge
+ WRITE_IF_NON_NULL(fe->nextEdge());
+
+ // PreviousEdge
+ WRITE_IF_NON_NULL(fe->previousEdge());
+
+ // ViewEdge
+ WRITE_IF_NON_NULL(fe->viewedge());
+
+ // Face
+ // Not necessary (only used during view map computatiom)
+
+ // aFace
+ save(out, (Polygon3r &)fe->aFace());
+
+ // occludeeEmpty
+ b = fe->getOccludeeEmpty();
+ WRITE(b);
+
+ // occludeeIntersection
+ save(out, fe->getOccludeeIntersection());
+
+ return 0;
}
-static int save(ostream& out, SVertex *sv)
+static int save(ostream &out, SVertex *sv)
{
- if (!sv) {
- cerr << "Warning: null SVertex" << endl;
- return 1;
- }
-
- unsigned tmp;
-
- // Id
- Id::id_type id = sv->getId().getFirst();
- WRITE(id);
- id = sv->getId().getSecond();
- WRITE(id);
-
- Vec3r v;
-
- // Point3D
- v = sv->point3D();
- save(out, sv->point3D());
-
- // Point2D
- v = sv->point2D();
- save(out, v);
-
- // Shape
- WRITE_IF_NON_NULL(sv->shape());
-
- // pViewVertex
- WRITE_IF_NON_NULL(sv->viewvertex());
-
- // Normals (List)
- // Note: the 'size()' method of a set doesn't seem to return the actual size of the given set, so we have to
- // hack it...
- set<Vec3r>::const_iterator i;
- for (i = sv->normals().begin(), tmp = 0; i != sv->normals().end(); i++, tmp++);
- WRITE(tmp);
- for (i = sv->normals().begin(); i != sv->normals().end(); i++)
- save(out, *i);
-
- // FEdges (List)
- tmp = sv->fedges().size();
- WRITE(tmp);
- for (vector<FEdge*>::const_iterator j = sv->fedges_begin(); j != sv->fedges_end(); j++) {
- WRITE_IF_NON_NULL(*j);
- }
-
- return 0;
+ if (!sv) {
+ cerr << "Warning: null SVertex" << endl;
+ return 1;
+ }
+
+ unsigned tmp;
+
+ // Id
+ Id::id_type id = sv->getId().getFirst();
+ WRITE(id);
+ id = sv->getId().getSecond();
+ WRITE(id);
+
+ Vec3r v;
+
+ // Point3D
+ v = sv->point3D();
+ save(out, sv->point3D());
+
+ // Point2D
+ v = sv->point2D();
+ save(out, v);
+
+ // Shape
+ WRITE_IF_NON_NULL(sv->shape());
+
+ // pViewVertex
+ WRITE_IF_NON_NULL(sv->viewvertex());
+
+ // Normals (List)
+ // Note: the 'size()' method of a set doesn't seem to return the actual size of the given set, so we have to
+ // hack it...
+ set<Vec3r>::const_iterator i;
+ for (i = sv->normals().begin(), tmp = 0; i != sv->normals().end(); i++, tmp++)
+ ;
+ WRITE(tmp);
+ for (i = sv->normals().begin(); i != sv->normals().end(); i++)
+ save(out, *i);
+
+ // FEdges (List)
+ tmp = sv->fedges().size();
+ WRITE(tmp);
+ for (vector<FEdge *>::const_iterator j = sv->fedges_begin(); j != sv->fedges_end(); j++) {
+ WRITE_IF_NON_NULL(*j);
+ }
+
+ return 0;
}
-
-static int save(ostream& out, ViewEdge *ve)
+static int save(ostream &out, ViewEdge *ve)
{
- if (!ve) {
- cerr << "Warning: null ViewEdge" << endl;
- return 1;
- }
+ if (!ve) {
+ cerr << "Warning: null ViewEdge" << endl;
+ return 1;
+ }
- unsigned tmp;
+ unsigned tmp;
- // Id
- Id::id_type id = ve->getId().getFirst();
- WRITE(id);
- id = ve->getId().getSecond();
- WRITE(id);
+ // Id
+ Id::id_type id = ve->getId().getFirst();
+ WRITE(id);
+ id = ve->getId().getSecond();
+ WRITE(id);
- // Nature
- Nature::EdgeNature nature = ve->getNature();
- WRITE(nature);
+ // Nature
+ Nature::EdgeNature nature = ve->getNature();
+ WRITE(nature);
- // QI
- unsigned qi = ve->qi();
- WRITE(qi);
+ // QI
+ unsigned qi = ve->qi();
+ WRITE(qi);
- // Shape
- WRITE_IF_NON_NULL(ve->shape());
+ // Shape
+ WRITE_IF_NON_NULL(ve->shape());
- // aShape
- WRITE_IF_NON_NULL(ve->aShape());
+ // aShape
+ WRITE_IF_NON_NULL(ve->aShape());
- // FEdgeA
- WRITE_IF_NON_NULL(ve->fedgeA());
+ // FEdgeA
+ WRITE_IF_NON_NULL(ve->fedgeA());
- // FEdgeB
- WRITE_IF_NON_NULL(ve->fedgeB());
+ // FEdgeB
+ WRITE_IF_NON_NULL(ve->fedgeB());
- // A
- WRITE_IF_NON_NULL(ve->A());
+ // A
+ WRITE_IF_NON_NULL(ve->A());
- // B
- WRITE_IF_NON_NULL(ve->B());
+ // B
+ WRITE_IF_NON_NULL(ve->B());
- // Occluders (List)
- if (!(Options::getFlags() & Options::NO_OCCLUDERS)) {
- tmp = ve->occluders().size();
- WRITE(tmp);
- for (vector<ViewShape*>::const_iterator i = ve->occluders().begin(); i != ve->occluders().end(); i++) {
- WRITE_IF_NON_NULL((*i));
- }
- }
+ // Occluders (List)
+ if (!(Options::getFlags() & Options::NO_OCCLUDERS)) {
+ tmp = ve->occluders().size();
+ WRITE(tmp);
+ for (vector<ViewShape *>::const_iterator i = ve->occluders().begin();
+ i != ve->occluders().end();
+ i++) {
+ WRITE_IF_NON_NULL((*i));
+ }
+ }
- return 0;
+ return 0;
}
-
-static int save(ostream& out, ViewVertex *vv)
+static int save(ostream &out, ViewVertex *vv)
{
- if (!vv) {
- cerr << "Warning: null ViewVertex" << endl;
- return 1;
- }
-
- // Nature
- Nature::VertexNature nature = vv->getNature();
- WRITE(nature);
-
- if (vv->getNature() & Nature::T_VERTEX) {
- TVertex *tv = dynamic_cast<TVertex*>(vv);
-
- // Id
- Id::id_type id = tv->getId().getFirst();
- WRITE(id);
- id = tv->getId().getSecond();
- WRITE(id);
-
- // FrontSVertex
- WRITE_IF_NON_NULL(tv->frontSVertex());
-
- // BackSVertex
- WRITE_IF_NON_NULL(tv->backSVertex());
-
- // FrontEdgeA
- WRITE_IF_NON_NULL(tv->frontEdgeA().first);
- WRITE(tv->frontEdgeA().second);
-
- // FrontEdgeB
- WRITE_IF_NON_NULL(tv->frontEdgeB().first);
- WRITE(tv->frontEdgeB().second);
-
- // BackEdgeA
- WRITE_IF_NON_NULL(tv->backEdgeA().first);
- WRITE(tv->backEdgeA().second);
-
- // BackEdgeB
- WRITE_IF_NON_NULL(tv->backEdgeB().first);
- WRITE(tv->backEdgeB().second);
- }
- else if (vv->getNature() & Nature::NON_T_VERTEX) {
- NonTVertex *ntv = dynamic_cast<NonTVertex*>(vv);
-
- // SVertex
- WRITE_IF_NON_NULL(ntv->svertex());
-
- // ViewEdges (List)
- unsigned size = ntv->viewedges().size();
- WRITE(size);
- vector<ViewVertex::directedViewEdge>::const_iterator i = ntv->viewedges().begin();
- for (; i != ntv->viewedges().end(); i++) {
- WRITE_IF_NON_NULL(i->first);
- WRITE(i->second);
- }
- }
- else {
- cerr << "Warning: unexpected ViewVertex nature" << endl;
- return 1;
- }
-
- return 0;
+ if (!vv) {
+ cerr << "Warning: null ViewVertex" << endl;
+ return 1;
+ }
+
+ // Nature
+ Nature::VertexNature nature = vv->getNature();
+ WRITE(nature);
+
+ if (vv->getNature() & Nature::T_VERTEX) {
+ TVertex *tv = dynamic_cast<TVertex *>(vv);
+
+ // Id
+ Id::id_type id = tv->getId().getFirst();
+ WRITE(id);
+ id = tv->getId().getSecond();
+ WRITE(id);
+
+ // FrontSVertex
+ WRITE_IF_NON_NULL(tv->frontSVertex());
+
+ // BackSVertex
+ WRITE_IF_NON_NULL(tv->backSVertex());
+
+ // FrontEdgeA
+ WRITE_IF_NON_NULL(tv->frontEdgeA().first);
+ WRITE(tv->frontEdgeA().second);
+
+ // FrontEdgeB
+ WRITE_IF_NON_NULL(tv->frontEdgeB().first);
+ WRITE(tv->frontEdgeB().second);
+
+ // BackEdgeA
+ WRITE_IF_NON_NULL(tv->backEdgeA().first);
+ WRITE(tv->backEdgeA().second);
+
+ // BackEdgeB
+ WRITE_IF_NON_NULL(tv->backEdgeB().first);
+ WRITE(tv->backEdgeB().second);
+ }
+ else if (vv->getNature() & Nature::NON_T_VERTEX) {
+ NonTVertex *ntv = dynamic_cast<NonTVertex *>(vv);
+
+ // SVertex
+ WRITE_IF_NON_NULL(ntv->svertex());
+
+ // ViewEdges (List)
+ unsigned size = ntv->viewedges().size();
+ WRITE(size);
+ vector<ViewVertex::directedViewEdge>::const_iterator i = ntv->viewedges().begin();
+ for (; i != ntv->viewedges().end(); i++) {
+ WRITE_IF_NON_NULL(i->first);
+ WRITE(i->second);
+ }
+ }
+ else {
+ cerr << "Warning: unexpected ViewVertex nature" << endl;
+ return 1;
+ }
+
+ return 0;
}
-} // End of namespace Internal
-
+} // End of namespace Internal
//////////////////// "Public" 'load' and 'save' functions ////////////////////
-#define SET_PROGRESS(n) \
- if (pb) { \
- pb->setProgress((n)); \
- } (void)0
+#define SET_PROGRESS(n) \
+ if (pb) { \
+ pb->setProgress((n)); \
+ } \
+ (void)0
-int load(istream& in, ViewMap *vm, ProgressBar *pb)
+int load(istream &in, ViewMap *vm, ProgressBar *pb)
{
- if (!vm)
- return 1;
-
- //soc unused - unsigned tmp;
- int err = 0;
- Internal::g_vm = vm;
-
- // Management of the progress bar (if present)
- if (pb) {
- pb->reset();
- pb->setLabelText("Loading View Map...");
- pb->setTotalSteps(6);
- pb->setProgress(0);
- }
-
- // Read and set the options
- unsigned char flags;
- READ(flags);
- Options::setFlags(flags);
-
- // Read the size of the five ViewMap's lists (with some extra information for the ViewVertices)
- // and instantiate them (with default costructors)
- unsigned vs_s, fe_s, fe_rle1, fe_rle2, sv_s, ve_s, vv_s, vv_rle1, vv_rle2;
- READ(vs_s);
- READ(fe_s);
-
- if (fe_s) {
- bool b;
- READ(b);
- for (READ(fe_rle1), fe_rle2 = 0; fe_rle1 <= fe_s; fe_rle2 = fe_rle1, READ(fe_rle1)) {
- if (b) {
- for (unsigned int i = fe_rle2; i < fe_rle1; i++) {
- FEdgeSmooth *fes = new FEdgeSmooth;
- vm->AddFEdge(fes);
- }
- b = !b;
- }
- else if (!b) {
- for (unsigned int i = fe_rle2; i < fe_rle1; i++) {
- FEdgeSharp *fes = new FEdgeSharp;
- vm->AddFEdge(fes);
- }
- b = !b;
- }
- }
- }
-
- READ(sv_s);
- READ(ve_s);
- READ(vv_s);
-
- if (vv_s) {
- Nature::VertexNature nature;
- READ(nature);
- for (READ(vv_rle1), vv_rle2 = 0; vv_rle1 <= vv_s; vv_rle2 = vv_rle1, READ(vv_rle1)) {
- if (nature & Nature::T_VERTEX) {
- for (unsigned int i = vv_rle2; i < vv_rle1; i++) {
- TVertex *tv = new TVertex();
- vm->AddViewVertex(tv);
- }
- nature = Nature::NON_T_VERTEX;
- }
- else if (nature & Nature::NON_T_VERTEX) {
- for (unsigned int i = vv_rle2; i < vv_rle1; i++) {
- NonTVertex *ntv = new NonTVertex();
- vm->AddViewVertex(ntv);
- }
- nature = Nature::T_VERTEX;
- }
- }
- }
-
- for (unsigned int i0 = 0; i0 < vs_s; i0++) {
- SShape *ss = new SShape();
- ViewShape *vs = new ViewShape();
- vs->setSShape(ss);
- ss->setViewShape(vs);
- vm->AddViewShape(vs);
- }
+ if (!vm)
+ return 1;
+
+ //soc unused - unsigned tmp;
+ int err = 0;
+ Internal::g_vm = vm;
+
+ // Management of the progress bar (if present)
+ if (pb) {
+ pb->reset();
+ pb->setLabelText("Loading View Map...");
+ pb->setTotalSteps(6);
+ pb->setProgress(0);
+ }
+
+ // Read and set the options
+ unsigned char flags;
+ READ(flags);
+ Options::setFlags(flags);
+
+ // Read the size of the five ViewMap's lists (with some extra information for the ViewVertices)
+ // and instantiate them (with default costructors)
+ unsigned vs_s, fe_s, fe_rle1, fe_rle2, sv_s, ve_s, vv_s, vv_rle1, vv_rle2;
+ READ(vs_s);
+ READ(fe_s);
+
+ if (fe_s) {
+ bool b;
+ READ(b);
+ for (READ(fe_rle1), fe_rle2 = 0; fe_rle1 <= fe_s; fe_rle2 = fe_rle1, READ(fe_rle1)) {
+ if (b) {
+ for (unsigned int i = fe_rle2; i < fe_rle1; i++) {
+ FEdgeSmooth *fes = new FEdgeSmooth;
+ vm->AddFEdge(fes);
+ }
+ b = !b;
+ }
+ else if (!b) {
+ for (unsigned int i = fe_rle2; i < fe_rle1; i++) {
+ FEdgeSharp *fes = new FEdgeSharp;
+ vm->AddFEdge(fes);
+ }
+ b = !b;
+ }
+ }
+ }
+
+ READ(sv_s);
+ READ(ve_s);
+ READ(vv_s);
+
+ if (vv_s) {
+ Nature::VertexNature nature;
+ READ(nature);
+ for (READ(vv_rle1), vv_rle2 = 0; vv_rle1 <= vv_s; vv_rle2 = vv_rle1, READ(vv_rle1)) {
+ if (nature & Nature::T_VERTEX) {
+ for (unsigned int i = vv_rle2; i < vv_rle1; i++) {
+ TVertex *tv = new TVertex();
+ vm->AddViewVertex(tv);
+ }
+ nature = Nature::NON_T_VERTEX;
+ }
+ else if (nature & Nature::NON_T_VERTEX) {
+ for (unsigned int i = vv_rle2; i < vv_rle1; i++) {
+ NonTVertex *ntv = new NonTVertex();
+ vm->AddViewVertex(ntv);
+ }
+ nature = Nature::T_VERTEX;
+ }
+ }
+ }
+
+ for (unsigned int i0 = 0; i0 < vs_s; i0++) {
+ SShape *ss = new SShape();
+ ViewShape *vs = new ViewShape();
+ vs->setSShape(ss);
+ ss->setViewShape(vs);
+ vm->AddViewShape(vs);
+ }
#if 0
- for (unsigned int i1 = 0; i1 < fe_s; i1++) {
- FEdge *fe = new FEdge();
- vm->AddFEdge(fe);
- }
+ for (unsigned int i1 = 0; i1 < fe_s; i1++) {
+ FEdge *fe = new FEdge();
+ vm->AddFEdge(fe);
+ }
#endif
- for (unsigned int i2 = 0; i2 < sv_s; i2++) {
- SVertex *sv = new SVertex();
- vm->AddSVertex(sv);
- }
- for (unsigned int i3 = 0; i3 < ve_s; i3++) {
- ViewEdge *ve = new ViewEdge();
- vm->AddViewEdge(ve);
- }
-
- // Read the values for all the objects created above
- SET_PROGRESS(1);
- for (vector<ViewShape*>::const_iterator i4 = vm->ViewShapes().begin(); i4 != vm->ViewShapes().end(); i4++)
- err += Internal::load(in, *i4);
- SET_PROGRESS(2);
- for (vector<FEdge*>::const_iterator i5 = vm->FEdges().begin(); i5 != vm->FEdges().end(); i5++)
- err += Internal::load(in, *i5);
- SET_PROGRESS(3);
- for (vector<SVertex*>::const_iterator i6 = vm->SVertices().begin(); i6 != vm->SVertices().end(); i6++)
- err += Internal::load(in, *i6);
- SET_PROGRESS(4);
- for (vector<ViewEdge*>::const_iterator i7 = vm->ViewEdges().begin(); i7 != vm->ViewEdges().end(); i7++)
- err += Internal::load(in, *i7);
- SET_PROGRESS(5);
- for (vector<ViewVertex*>::const_iterator i8 = vm->ViewVertices().begin(); i8 != vm->ViewVertices().end(); i8++)
- err += Internal::load(in, *i8);
- SET_PROGRESS(6);
-
- // Read the shape id to index mapping
- unsigned map_s;
- READ(map_s);
- unsigned id, index;
- for (unsigned int i4 = 0; i4 < map_s; ++i4) {
- READ(id);
- READ(index);
- vm->shapeIdToIndexMap()[id] = index;
- }
-
- return err;
+ for (unsigned int i2 = 0; i2 < sv_s; i2++) {
+ SVertex *sv = new SVertex();
+ vm->AddSVertex(sv);
+ }
+ for (unsigned int i3 = 0; i3 < ve_s; i3++) {
+ ViewEdge *ve = new ViewEdge();
+ vm->AddViewEdge(ve);
+ }
+
+ // Read the values for all the objects created above
+ SET_PROGRESS(1);
+ for (vector<ViewShape *>::const_iterator i4 = vm->ViewShapes().begin();
+ i4 != vm->ViewShapes().end();
+ i4++)
+ err += Internal::load(in, *i4);
+ SET_PROGRESS(2);
+ for (vector<FEdge *>::const_iterator i5 = vm->FEdges().begin(); i5 != vm->FEdges().end(); i5++)
+ err += Internal::load(in, *i5);
+ SET_PROGRESS(3);
+ for (vector<SVertex *>::const_iterator i6 = vm->SVertices().begin(); i6 != vm->SVertices().end();
+ i6++)
+ err += Internal::load(in, *i6);
+ SET_PROGRESS(4);
+ for (vector<ViewEdge *>::const_iterator i7 = vm->ViewEdges().begin();
+ i7 != vm->ViewEdges().end();
+ i7++)
+ err += Internal::load(in, *i7);
+ SET_PROGRESS(5);
+ for (vector<ViewVertex *>::const_iterator i8 = vm->ViewVertices().begin();
+ i8 != vm->ViewVertices().end();
+ i8++)
+ err += Internal::load(in, *i8);
+ SET_PROGRESS(6);
+
+ // Read the shape id to index mapping
+ unsigned map_s;
+ READ(map_s);
+ unsigned id, index;
+ for (unsigned int i4 = 0; i4 < map_s; ++i4) {
+ READ(id);
+ READ(index);
+ vm->shapeIdToIndexMap()[id] = index;
+ }
+
+ return err;
}
-
-int save(ostream& out, ViewMap *vm, ProgressBar *pb)
+int save(ostream &out, ViewMap *vm, ProgressBar *pb)
{
- if (!vm)
- return 1;
-
- int err = 0;
-
- // Management of the progress bar (if present)
- if (pb) {
- pb->reset();
- pb->setLabelText("Saving View Map...");
- pb->setTotalSteps(6);
- pb->setProgress(0);
- }
-
- // For every object, initialize its userdata member to its index in the ViewMap list
- for (unsigned int i0 = 0; i0 < vm->ViewShapes().size(); i0++) {
- vm->ViewShapes()[i0]->userdata = POINTER_FROM_UINT(i0);
- vm->ViewShapes()[i0]->sshape()->userdata = POINTER_FROM_UINT(i0);
- }
- for (unsigned int i1 = 0; i1 < vm->FEdges().size(); i1++)
- vm->FEdges()[i1]->userdata = POINTER_FROM_UINT(i1);
- for (unsigned int i2 = 0; i2 < vm->SVertices().size(); i2++)
- vm->SVertices()[i2]->userdata = POINTER_FROM_UINT(i2);
- for (unsigned int i3 = 0; i3 < vm->ViewEdges().size(); i3++)
- vm->ViewEdges()[i3]->userdata = POINTER_FROM_UINT(i3);
- for (unsigned int i4 = 0; i4 < vm->ViewVertices().size(); i4++)
- vm->ViewVertices()[i4]->userdata = POINTER_FROM_UINT(i4);
-
- // Write the current options
- unsigned char flags = Options::getFlags();
- WRITE(flags);
-
- // Write the size of the five lists (with some extra information for the ViewVertices)
- unsigned size;
- size = vm->ViewShapes().size();
- WRITE(size);
- size = vm->FEdges().size();
- WRITE(size);
- if (size) {
- bool b = vm->FEdges()[0]->isSmooth();
- WRITE(b);
- for (unsigned int i = 0; i < size; i++) {
- while (i < size && (vm->FEdges()[i]->isSmooth() == b))
- i++;
- if (i < size) {
- WRITE(i);
- b = !b;
- }
- }
- WRITE(size);
- size++;
- WRITE(size);
- }
- size = vm->SVertices().size();
- WRITE(size);
- size = vm->ViewEdges().size();
- WRITE(size);
- size = vm->ViewVertices().size();
- WRITE(size);
- if (size) {
- Nature::VertexNature nature = vm->ViewVertices()[0]->getNature();
- WRITE(nature);
- nature &= ~Nature::VIEW_VERTEX;
- for (unsigned int i = 0; i < size; i++) {
- while (i < size && (vm->ViewVertices()[i]->getNature() & nature))
- i++;
- if (i < size) {
- WRITE(i);
- nature = vm->ViewVertices()[i]->getNature() & ~Nature::VIEW_VERTEX;
- }
- }
- WRITE(size);
- size++;
- WRITE(size);
- }
-
- // Write all the elts of the ViewShapes List
- SET_PROGRESS(1);
- for (vector<ViewShape*>::const_iterator i5 = vm->ViewShapes().begin(); i5 != vm->ViewShapes().end(); i5++)
- err += Internal::save(out, *i5);
- SET_PROGRESS(2);
- for (vector<FEdge*>::const_iterator i6 = vm->FEdges().begin(); i6 != vm->FEdges().end(); i6++)
- err += Internal::save(out, *i6);
- SET_PROGRESS(3);
- for (vector<SVertex*>::const_iterator i7 = vm->SVertices().begin(); i7 != vm->SVertices().end(); i7++)
- err += Internal::save(out, *i7);
- SET_PROGRESS(4);
- for (vector<ViewEdge*>::const_iterator i8 = vm->ViewEdges().begin(); i8 != vm->ViewEdges().end(); i8++)
- err += Internal::save(out, *i8);
- SET_PROGRESS(5);
- for (vector<ViewVertex*>::const_iterator i9 = vm->ViewVertices().begin(); i9 != vm->ViewVertices().end(); i9++)
- err += Internal::save(out, *i9);
-
- // Write the shape id to index mapping
- size = vm->shapeIdToIndexMap().size();
- WRITE(size);
- unsigned int id, index;
- for (ViewMap::id_to_index_map::iterator mit = vm->shapeIdToIndexMap().begin(),
- mitend = vm->shapeIdToIndexMap().end();
- mit != mitend;
- ++mit)
- {
- id = mit->first;
- index = mit->second;
- WRITE(id);
- WRITE(index);
- }
-
- // Reset 'userdata' members
- for (vector<ViewShape*>::const_iterator j0 = vm->ViewShapes().begin(); j0 != vm->ViewShapes().end(); j0++) {
- (*j0)->userdata = NULL;
- (*j0)->sshape()->userdata = NULL;
- }
- for (vector<FEdge*>::const_iterator j1 = vm->FEdges().begin(); j1 != vm->FEdges().end(); j1++)
- (*j1)->userdata = NULL;
- for (vector<SVertex*>::const_iterator j2 = vm->SVertices().begin(); j2 != vm->SVertices().end(); j2++)
- (*j2)->userdata = NULL;
- for (vector<ViewEdge*>::const_iterator j3 = vm->ViewEdges().begin(); j3 != vm->ViewEdges().end(); j3++)
- (*j3)->userdata = NULL;
- for (vector<ViewVertex*>::const_iterator j4 = vm->ViewVertices().begin(); j4 != vm->ViewVertices().end(); j4++)
- (*j4)->userdata = NULL;
- SET_PROGRESS(6);
-
- return err;
+ if (!vm)
+ return 1;
+
+ int err = 0;
+
+ // Management of the progress bar (if present)
+ if (pb) {
+ pb->reset();
+ pb->setLabelText("Saving View Map...");
+ pb->setTotalSteps(6);
+ pb->setProgress(0);
+ }
+
+ // For every object, initialize its userdata member to its index in the ViewMap list
+ for (unsigned int i0 = 0; i0 < vm->ViewShapes().size(); i0++) {
+ vm->ViewShapes()[i0]->userdata = POINTER_FROM_UINT(i0);
+ vm->ViewShapes()[i0]->sshape()->userdata = POINTER_FROM_UINT(i0);
+ }
+ for (unsigned int i1 = 0; i1 < vm->FEdges().size(); i1++)
+ vm->FEdges()[i1]->userdata = POINTER_FROM_UINT(i1);
+ for (unsigned int i2 = 0; i2 < vm->SVertices().size(); i2++)
+ vm->SVertices()[i2]->userdata = POINTER_FROM_UINT(i2);
+ for (unsigned int i3 = 0; i3 < vm->ViewEdges().size(); i3++)
+ vm->ViewEdges()[i3]->userdata = POINTER_FROM_UINT(i3);
+ for (unsigned int i4 = 0; i4 < vm->ViewVertices().size(); i4++)
+ vm->ViewVertices()[i4]->userdata = POINTER_FROM_UINT(i4);
+
+ // Write the current options
+ unsigned char flags = Options::getFlags();
+ WRITE(flags);
+
+ // Write the size of the five lists (with some extra information for the ViewVertices)
+ unsigned size;
+ size = vm->ViewShapes().size();
+ WRITE(size);
+ size = vm->FEdges().size();
+ WRITE(size);
+ if (size) {
+ bool b = vm->FEdges()[0]->isSmooth();
+ WRITE(b);
+ for (unsigned int i = 0; i < size; i++) {
+ while (i < size && (vm->FEdges()[i]->isSmooth() == b))
+ i++;
+ if (i < size) {
+ WRITE(i);
+ b = !b;
+ }
+ }
+ WRITE(size);
+ size++;
+ WRITE(size);
+ }
+ size = vm->SVertices().size();
+ WRITE(size);
+ size = vm->ViewEdges().size();
+ WRITE(size);
+ size = vm->ViewVertices().size();
+ WRITE(size);
+ if (size) {
+ Nature::VertexNature nature = vm->ViewVertices()[0]->getNature();
+ WRITE(nature);
+ nature &= ~Nature::VIEW_VERTEX;
+ for (unsigned int i = 0; i < size; i++) {
+ while (i < size && (vm->ViewVertices()[i]->getNature() & nature))
+ i++;
+ if (i < size) {
+ WRITE(i);
+ nature = vm->ViewVertices()[i]->getNature() & ~Nature::VIEW_VERTEX;
+ }
+ }
+ WRITE(size);
+ size++;
+ WRITE(size);
+ }
+
+ // Write all the elts of the ViewShapes List
+ SET_PROGRESS(1);
+ for (vector<ViewShape *>::const_iterator i5 = vm->ViewShapes().begin();
+ i5 != vm->ViewShapes().end();
+ i5++)
+ err += Internal::save(out, *i5);
+ SET_PROGRESS(2);
+ for (vector<FEdge *>::const_iterator i6 = vm->FEdges().begin(); i6 != vm->FEdges().end(); i6++)
+ err += Internal::save(out, *i6);
+ SET_PROGRESS(3);
+ for (vector<SVertex *>::const_iterator i7 = vm->SVertices().begin(); i7 != vm->SVertices().end();
+ i7++)
+ err += Internal::save(out, *i7);
+ SET_PROGRESS(4);
+ for (vector<ViewEdge *>::const_iterator i8 = vm->ViewEdges().begin();
+ i8 != vm->ViewEdges().end();
+ i8++)
+ err += Internal::save(out, *i8);
+ SET_PROGRESS(5);
+ for (vector<ViewVertex *>::const_iterator i9 = vm->ViewVertices().begin();
+ i9 != vm->ViewVertices().end();
+ i9++)
+ err += Internal::save(out, *i9);
+
+ // Write the shape id to index mapping
+ size = vm->shapeIdToIndexMap().size();
+ WRITE(size);
+ unsigned int id, index;
+ for (ViewMap::id_to_index_map::iterator mit = vm->shapeIdToIndexMap().begin(),
+ mitend = vm->shapeIdToIndexMap().end();
+ mit != mitend;
+ ++mit) {
+ id = mit->first;
+ index = mit->second;
+ WRITE(id);
+ WRITE(index);
+ }
+
+ // Reset 'userdata' members
+ for (vector<ViewShape *>::const_iterator j0 = vm->ViewShapes().begin();
+ j0 != vm->ViewShapes().end();
+ j0++) {
+ (*j0)->userdata = NULL;
+ (*j0)->sshape()->userdata = NULL;
+ }
+ for (vector<FEdge *>::const_iterator j1 = vm->FEdges().begin(); j1 != vm->FEdges().end(); j1++)
+ (*j1)->userdata = NULL;
+ for (vector<SVertex *>::const_iterator j2 = vm->SVertices().begin(); j2 != vm->SVertices().end();
+ j2++)
+ (*j2)->userdata = NULL;
+ for (vector<ViewEdge *>::const_iterator j3 = vm->ViewEdges().begin();
+ j3 != vm->ViewEdges().end();
+ j3++)
+ (*j3)->userdata = NULL;
+ for (vector<ViewVertex *>::const_iterator j4 = vm->ViewVertices().begin();
+ j4 != vm->ViewVertices().end();
+ j4++)
+ (*j4)->userdata = NULL;
+ SET_PROGRESS(6);
+
+ return err;
}
-
//////////////////// Options ////////////////////
namespace Options {
@@ -1216,40 +1233,40 @@ namespace Internal {
static unsigned char g_flags = 0;
static string g_models_path;
-} // End of namespace Internal
+} // End of namespace Internal
void setFlags(const unsigned char flags)
{
- Internal::g_flags = flags;
+ Internal::g_flags = flags;
}
void addFlags(const unsigned char flags)
{
- Internal::g_flags |= flags;
+ Internal::g_flags |= flags;
}
void rmFlags(const unsigned char flags)
{
- Internal::g_flags &= ~flags;
+ Internal::g_flags &= ~flags;
}
unsigned char getFlags()
{
- return Internal::g_flags;
+ return Internal::g_flags;
}
-void setModelsPath(const string& path)
+void setModelsPath(const string &path)
{
- Internal::g_models_path = path;
+ Internal::g_models_path = path;
}
string getModelsPath()
{
- return Internal::g_models_path;
+ return Internal::g_models_path;
}
-} // End of namepace Options
+} // namespace Options
-} // End of namespace ViewMapIO
+} // End of namespace ViewMapIO
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.h b/source/blender/freestyle/intern/view_map/ViewMapIO.h
index 57eb450d45b..98d27852c8d 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIO.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapIO.h
@@ -36,9 +36,9 @@ namespace ViewMapIO {
static const unsigned ZERO = UINT_MAX;
-int load(istream& in, ViewMap *vm, ProgressBar *pb = NULL);
+int load(istream &in, ViewMap *vm, ProgressBar *pb = NULL);
-int save(ostream& out, ViewMap *vm, ProgressBar *pb = NULL);
+int save(ostream &out, ViewMap *vm, ProgressBar *pb = NULL);
namespace Options {
@@ -53,60 +53,54 @@ void rmFlags(const unsigned char flags);
unsigned char getFlags();
-void setModelsPath(const string& path);
+void setModelsPath(const string &path);
string getModelsPath();
-}; // End of namepace Options
+}; // namespace Options
#ifdef IRIX
namespace Internal {
-template <unsigned S>
-ostream& write(ostream& out, const char *str)
+template<unsigned S> ostream &write(ostream &out, const char *str)
{
- out.put(str[S - 1]);
- return write<S - 1>(out, str);
+ out.put(str[S - 1]);
+ return write<S - 1>(out, str);
}
-template<>
-ostream& write<1>(ostream& out, const char *str)
+template<> ostream &write<1>(ostream &out, const char *str)
{
- return out.put(str[0]);
+ return out.put(str[0]);
}
-template<>
-ostream& write<0>(ostream& out, const char *)
+template<> ostream &write<0>(ostream &out, const char *)
{
- return out;
+ return out;
}
-template <unsigned S>
-istream& read(istream& in, char *str)
+template<unsigned S> istream &read(istream &in, char *str)
{
- in.get(str[S - 1]);
- return read<S - 1>(in, str);
+ in.get(str[S - 1]);
+ return read<S - 1>(in, str);
}
-template<>
-istream& read<1>(istream& in, char *str)
+template<> istream &read<1>(istream &in, char *str)
{
- return in.get(str[0]);
+ return in.get(str[0]);
}
-template<>
-istream& read<0>(istream& in, char *)
+template<> istream &read<0>(istream &in, char *)
{
- return in;
+ return in;
}
-} // End of namespace Internal
+} // End of namespace Internal
-#endif // IRIX
+#endif // IRIX
-} // End of namespace ViewMapIO
+} // End of namespace ViewMapIO
} /* namespace Freestyle */
-#endif // __FREESTYLE_VIEW_MAP_IO_H__
+#endif // __FREESTYLE_VIEW_MAP_IO_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIterators.h b/source/blender/freestyle/intern/view_map/ViewMapIterators.h
index c8a5b6e5d42..7182c5d3362 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIterators.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapIterators.h
@@ -24,7 +24,7 @@
#include "ViewMap.h"
-#include "../system/Iterator.h" //soc
+#include "../system/Iterator.h" //soc
namespace Freestyle {
@@ -51,176 +51,180 @@ namespace ViewVertexInternal {
* An instance of an orientedViewEdgeIterator can only be obtained from a ViewVertex by calling edgesBegin()
* or edgesEnd().
*/
-class orientedViewEdgeIterator : public Iterator
-{
-public:
- friend class ViewVertex;
- friend class TVertex;
- friend class NonTVertex;
- friend class ViewEdge;
-
- // FIXME
- typedef TVertex::edge_pointers_container edge_pointers_container;
- typedef NonTVertex::edges_container edges_container;
-
-protected:
- Nature::VertexNature _Nature; // the nature of the underlying vertex
- // T vertex attributes
- edge_pointers_container::iterator _tbegin;
- edge_pointers_container::iterator _tend;
- edge_pointers_container::iterator _tvertex_iter;
-
- // Non TVertex attributes
- edges_container::iterator _begin;
- edges_container::iterator _end;
- edges_container::iterator _nontvertex_iter;
-
-public:
- /*! Default constructor */
- inline orientedViewEdgeIterator() {}
-
- inline orientedViewEdgeIterator(Nature::VertexNature iNature)
- {
- _Nature = iNature;
- }
-
- /*! Copy constructor */
- orientedViewEdgeIterator(const orientedViewEdgeIterator& iBrother)
- {
- _Nature = iBrother._Nature;
- if (_Nature & Nature::T_VERTEX) {
- _tbegin = iBrother._tbegin;
- _tend = iBrother._tend;
- _tvertex_iter = iBrother._tvertex_iter;
- }
- else {
- _begin = iBrother._begin;
- _end = iBrother._end;
- _nontvertex_iter = iBrother._nontvertex_iter;
- }
- }
-
- virtual ~orientedViewEdgeIterator() {}
-
-public:
- inline orientedViewEdgeIterator(edge_pointers_container::iterator begin, edge_pointers_container::iterator end,
- edge_pointers_container::iterator iter)
- {
- _Nature = Nature::T_VERTEX;
- _tbegin = begin;
- _tend = end;
- _tvertex_iter = iter;
- }
-
- inline orientedViewEdgeIterator(edges_container::iterator begin, edges_container::iterator end,
- edges_container::iterator iter)
- {
- _Nature = Nature::NON_T_VERTEX;
- _begin = begin;
- _end = end;
- _nontvertex_iter = iter;
- }
-
-public:
- /*! Tells whether the ViewEdge pointed by this iterator is the first one of the iteration list or not. */
- virtual bool isBegin() const
- {
- if (_Nature & Nature::T_VERTEX)
- return (_tvertex_iter == _tbegin);
- else
- return (_nontvertex_iter == _begin);
- }
-
- /*! Tells whether the ViewEdge pointed by this iterator is after the last one of the iteration list or not. */
- virtual bool isEnd() const
- {
- if (_Nature & Nature::T_VERTEX)
- return (_tvertex_iter == _tend);
- else
- return (_nontvertex_iter == _end);
- }
-
- // operators
- /*! Increments. In the scripting language, call "increment()". */
- // operator corresponding to ++i
- virtual orientedViewEdgeIterator& operator++()
- {
- increment();
- return *this;
- }
-
- // operator corresponding to i++, i.e. which returns the value *and then* increments.
- // That's why we store the value in a temp.
- virtual orientedViewEdgeIterator operator++(int)
- {
- orientedViewEdgeIterator tmp = *this;
- increment();
- return tmp;
- }
-
- // comparibility
- /*! operator != */
- virtual bool operator!=(const orientedViewEdgeIterator& b) const
- {
- if (_Nature & Nature::T_VERTEX)
- return (_tvertex_iter != b._tvertex_iter);
- else
- return (_nontvertex_iter != b._nontvertex_iter);
- }
-
- /*! operator == */
- virtual bool operator==(const orientedViewEdgeIterator& b) const
- {
- return !(*this != b);
- }
-
- // dereferencing
- /*! Returns a reference to the pointed orientedViewEdge.
- * In the scripting language, you must call "getObject()" instead.
- */
- virtual ViewVertex::directedViewEdge& operator*() const
- {
- if (_Nature & Nature::T_VERTEX)
- //return _tvertex_iter;
- return **_tvertex_iter;
- else
- return (*_nontvertex_iter);
- }
- /*! Returns a pointer to the pointed orientedViewEdge.
- * Can't be called in the scripting language.
- */
- virtual ViewVertex::directedViewEdge *operator->() const
- {
- return &(operator*());
- }
-
-public:
- /*! increments.*/
- virtual inline int increment()
- {
- if (_Nature & Nature::T_VERTEX) {
- ViewVertex::directedViewEdge tmp = (**_tvertex_iter);
- ++_tvertex_iter;
- if (_tvertex_iter != _tend) {
- // FIXME : pquoi deja ?
- ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter);
- if (tmp2.first == tmp.first)
- ++_tvertex_iter;
- }
- }
- else {
- ++_nontvertex_iter;
- }
- return 0;
- }
+class orientedViewEdgeIterator : public Iterator {
+ public:
+ friend class ViewVertex;
+ friend class TVertex;
+ friend class NonTVertex;
+ friend class ViewEdge;
+
+ // FIXME
+ typedef TVertex::edge_pointers_container edge_pointers_container;
+ typedef NonTVertex::edges_container edges_container;
+
+ protected:
+ Nature::VertexNature _Nature; // the nature of the underlying vertex
+ // T vertex attributes
+ edge_pointers_container::iterator _tbegin;
+ edge_pointers_container::iterator _tend;
+ edge_pointers_container::iterator _tvertex_iter;
+
+ // Non TVertex attributes
+ edges_container::iterator _begin;
+ edges_container::iterator _end;
+ edges_container::iterator _nontvertex_iter;
+
+ public:
+ /*! Default constructor */
+ inline orientedViewEdgeIterator()
+ {
+ }
+
+ inline orientedViewEdgeIterator(Nature::VertexNature iNature)
+ {
+ _Nature = iNature;
+ }
+
+ /*! Copy constructor */
+ orientedViewEdgeIterator(const orientedViewEdgeIterator &iBrother)
+ {
+ _Nature = iBrother._Nature;
+ if (_Nature & Nature::T_VERTEX) {
+ _tbegin = iBrother._tbegin;
+ _tend = iBrother._tend;
+ _tvertex_iter = iBrother._tvertex_iter;
+ }
+ else {
+ _begin = iBrother._begin;
+ _end = iBrother._end;
+ _nontvertex_iter = iBrother._nontvertex_iter;
+ }
+ }
+
+ virtual ~orientedViewEdgeIterator()
+ {
+ }
+
+ public:
+ inline orientedViewEdgeIterator(edge_pointers_container::iterator begin,
+ edge_pointers_container::iterator end,
+ edge_pointers_container::iterator iter)
+ {
+ _Nature = Nature::T_VERTEX;
+ _tbegin = begin;
+ _tend = end;
+ _tvertex_iter = iter;
+ }
+
+ inline orientedViewEdgeIterator(edges_container::iterator begin,
+ edges_container::iterator end,
+ edges_container::iterator iter)
+ {
+ _Nature = Nature::NON_T_VERTEX;
+ _begin = begin;
+ _end = end;
+ _nontvertex_iter = iter;
+ }
+
+ public:
+ /*! Tells whether the ViewEdge pointed by this iterator is the first one of the iteration list or not. */
+ virtual bool isBegin() const
+ {
+ if (_Nature & Nature::T_VERTEX)
+ return (_tvertex_iter == _tbegin);
+ else
+ return (_nontvertex_iter == _begin);
+ }
+
+ /*! Tells whether the ViewEdge pointed by this iterator is after the last one of the iteration list or not. */
+ virtual bool isEnd() const
+ {
+ if (_Nature & Nature::T_VERTEX)
+ return (_tvertex_iter == _tend);
+ else
+ return (_nontvertex_iter == _end);
+ }
+
+ // operators
+ /*! Increments. In the scripting language, call "increment()". */
+ // operator corresponding to ++i
+ virtual orientedViewEdgeIterator &operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ // operator corresponding to i++, i.e. which returns the value *and then* increments.
+ // That's why we store the value in a temp.
+ virtual orientedViewEdgeIterator operator++(int)
+ {
+ orientedViewEdgeIterator tmp = *this;
+ increment();
+ return tmp;
+ }
+
+ // comparibility
+ /*! operator != */
+ virtual bool operator!=(const orientedViewEdgeIterator &b) const
+ {
+ if (_Nature & Nature::T_VERTEX)
+ return (_tvertex_iter != b._tvertex_iter);
+ else
+ return (_nontvertex_iter != b._nontvertex_iter);
+ }
+
+ /*! operator == */
+ virtual bool operator==(const orientedViewEdgeIterator &b) const
+ {
+ return !(*this != b);
+ }
+
+ // dereferencing
+ /*! Returns a reference to the pointed orientedViewEdge.
+ * In the scripting language, you must call "getObject()" instead.
+ */
+ virtual ViewVertex::directedViewEdge &operator*() const
+ {
+ if (_Nature & Nature::T_VERTEX)
+ //return _tvertex_iter;
+ return **_tvertex_iter;
+ else
+ return (*_nontvertex_iter);
+ }
+ /*! Returns a pointer to the pointed orientedViewEdge.
+ * Can't be called in the scripting language.
+ */
+ virtual ViewVertex::directedViewEdge *operator->() const
+ {
+ return &(operator*());
+ }
+
+ public:
+ /*! increments.*/
+ virtual inline int increment()
+ {
+ if (_Nature & Nature::T_VERTEX) {
+ ViewVertex::directedViewEdge tmp = (**_tvertex_iter);
+ ++_tvertex_iter;
+ if (_tvertex_iter != _tend) {
+ // FIXME : pquoi deja ?
+ ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter);
+ if (tmp2.first == tmp.first)
+ ++_tvertex_iter;
+ }
+ }
+ else {
+ ++_nontvertex_iter;
+ }
+ return 0;
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:orientedViewEdgeIterator")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:orientedViewEdgeIterator")
#endif
-
};
-} // ViewVertexInternal namespace
+} // namespace ViewVertexInternal
/**********************************/
/* */
@@ -237,166 +241,165 @@ namespace ViewEdgeInternal {
//
/////////////////////////////////////////////////
-class SVertexIterator : public Interface0DIteratorNested
-{
-public:
- SVertexIterator()
- {
- _vertex = NULL;
- _begin = NULL;
- _previous_edge = NULL;
- _next_edge = NULL;
- _t = 0;
- }
-
- SVertexIterator(const SVertexIterator& vi)
- {
- _vertex = vi._vertex;
- _begin = vi._begin;
- _previous_edge = vi._previous_edge;
- _next_edge = vi._next_edge;
- _t = vi._t;
- }
-
- SVertexIterator(SVertex *v, SVertex *begin, FEdge *prev, FEdge *next, float t)
- {
- _vertex = v;
- _begin = begin;
- _previous_edge = prev;
- _next_edge = next;
- _t = t;
- }
-
- SVertexIterator& operator=(const SVertexIterator& vi)
- {
- _vertex = vi._vertex;
- _begin = vi._begin;
- _previous_edge = vi._previous_edge;
- _next_edge = vi._next_edge;
- _t = vi._t;
- return *this;
- }
-
- virtual ~SVertexIterator() {}
-
- virtual string getExactTypeName() const
- {
- return "SVertexIterator";
- }
-
- virtual SVertex& operator*()
- {
- return *_vertex;
- }
-
- virtual SVertex *operator->()
- {
- return &(operator*());
- }
-
- virtual SVertexIterator& operator++()
- {
- increment();
- return *this;
- }
-
- virtual SVertexIterator operator++(int)
- {
- SVertexIterator ret(*this);
- increment();
- return ret;
- }
-
- virtual SVertexIterator& operator--()
- {
- decrement();
- return *this;
- }
-
- virtual SVertexIterator operator--(int)
- {
- SVertexIterator ret(*this);
- decrement();
- return ret;
- }
-
- virtual int increment()
- {
- if (!_next_edge) {
- _vertex = NULL;
- return 0;
- }
- _t += (float)_next_edge->getLength2D();
- _vertex = _next_edge->vertexB();
- _previous_edge = _next_edge;
- _next_edge = _next_edge->nextEdge();
- return 0;
- }
-
- virtual int decrement()
- {
- if (!_previous_edge) {
- _vertex = NULL;
- return 0;
- }
- if ((!_next_edge) && (!_vertex)) {
- _vertex = _previous_edge->vertexB();
- return 0;
- }
- _t -= (float)_previous_edge->getLength2D();
- _vertex = _previous_edge->vertexA();
- _next_edge = _previous_edge;
- _previous_edge = _previous_edge->previousEdge();
- return 0;
- }
-
- virtual bool isBegin() const
- {
- return _vertex == _begin;
- }
-
- virtual bool isEnd() const
- {
- return (!_vertex) || (_vertex == _begin && _previous_edge);
- }
-
- virtual float t() const
- {
- return _t;
- }
-
- virtual float u() const
- {
- return _t / (float)_next_edge->viewedge()->getLength2D();
- }
-
- virtual bool operator==(const Interface0DIteratorNested& it) const
- {
- const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator*>(&it);
- if (!it_exact)
- return false;
- return (_vertex == it_exact->_vertex);
- }
-
- virtual SVertexIterator *copy() const
- {
- return new SVertexIterator(*this);
- }
-
-private:
- SVertex *_vertex;
- SVertex *_begin;
- FEdge *_previous_edge;
- FEdge *_next_edge;
- float _t; // curvilinear abscissa
+class SVertexIterator : public Interface0DIteratorNested {
+ public:
+ SVertexIterator()
+ {
+ _vertex = NULL;
+ _begin = NULL;
+ _previous_edge = NULL;
+ _next_edge = NULL;
+ _t = 0;
+ }
+
+ SVertexIterator(const SVertexIterator &vi)
+ {
+ _vertex = vi._vertex;
+ _begin = vi._begin;
+ _previous_edge = vi._previous_edge;
+ _next_edge = vi._next_edge;
+ _t = vi._t;
+ }
+
+ SVertexIterator(SVertex *v, SVertex *begin, FEdge *prev, FEdge *next, float t)
+ {
+ _vertex = v;
+ _begin = begin;
+ _previous_edge = prev;
+ _next_edge = next;
+ _t = t;
+ }
+
+ SVertexIterator &operator=(const SVertexIterator &vi)
+ {
+ _vertex = vi._vertex;
+ _begin = vi._begin;
+ _previous_edge = vi._previous_edge;
+ _next_edge = vi._next_edge;
+ _t = vi._t;
+ return *this;
+ }
+
+ virtual ~SVertexIterator()
+ {
+ }
+
+ virtual string getExactTypeName() const
+ {
+ return "SVertexIterator";
+ }
+
+ virtual SVertex &operator*()
+ {
+ return *_vertex;
+ }
+
+ virtual SVertex *operator->()
+ {
+ return &(operator*());
+ }
+
+ virtual SVertexIterator &operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ virtual SVertexIterator operator++(int)
+ {
+ SVertexIterator ret(*this);
+ increment();
+ return ret;
+ }
+
+ virtual SVertexIterator &operator--()
+ {
+ decrement();
+ return *this;
+ }
+
+ virtual SVertexIterator operator--(int)
+ {
+ SVertexIterator ret(*this);
+ decrement();
+ return ret;
+ }
+
+ virtual int increment()
+ {
+ if (!_next_edge) {
+ _vertex = NULL;
+ return 0;
+ }
+ _t += (float)_next_edge->getLength2D();
+ _vertex = _next_edge->vertexB();
+ _previous_edge = _next_edge;
+ _next_edge = _next_edge->nextEdge();
+ return 0;
+ }
+
+ virtual int decrement()
+ {
+ if (!_previous_edge) {
+ _vertex = NULL;
+ return 0;
+ }
+ if ((!_next_edge) && (!_vertex)) {
+ _vertex = _previous_edge->vertexB();
+ return 0;
+ }
+ _t -= (float)_previous_edge->getLength2D();
+ _vertex = _previous_edge->vertexA();
+ _next_edge = _previous_edge;
+ _previous_edge = _previous_edge->previousEdge();
+ return 0;
+ }
+
+ virtual bool isBegin() const
+ {
+ return _vertex == _begin;
+ }
+
+ virtual bool isEnd() const
+ {
+ return (!_vertex) || (_vertex == _begin && _previous_edge);
+ }
+
+ virtual float t() const
+ {
+ return _t;
+ }
+
+ virtual float u() const
+ {
+ return _t / (float)_next_edge->viewedge()->getLength2D();
+ }
+
+ virtual bool operator==(const Interface0DIteratorNested &it) const
+ {
+ const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator *>(&it);
+ if (!it_exact)
+ return false;
+ return (_vertex == it_exact->_vertex);
+ }
+
+ virtual SVertexIterator *copy() const
+ {
+ return new SVertexIterator(*this);
+ }
+
+ private:
+ SVertex *_vertex;
+ SVertex *_begin;
+ FEdge *_previous_edge;
+ FEdge *_next_edge;
+ float _t; // curvilinear abscissa
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SVertexIterator")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SVertexIterator")
#endif
-
};
-
//
// ViewEdgeIterator (base class)
//
@@ -407,173 +410,173 @@ private:
* ViewEdge) to go when pointing on a given ViewEdge.
* ::Caution::: the dereferencing operator returns a *pointer* to the pointed ViewEdge.
*/
-class ViewEdgeIterator : public Iterator
-{
-public:
- /*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation.
- * \param begin:
- * The ViewEdge from where to start the iteration.
- * \param orientation:
- * If true, we'll look for the next ViewEdge among the ViewEdges that surround the ending ViewVertex of begin.
- * If false, we'll search over the ViewEdges surrounding the ending ViewVertex of begin.
- */
- ViewEdgeIterator(ViewEdge *begin = NULL, bool orientation = true)
- {
- _orientation = orientation;
- _edge = begin;
- _begin = begin;
- }
-
- /*! Copy constructor */
- ViewEdgeIterator(const ViewEdgeIterator& it)
- {
- _orientation = it._orientation;
- _edge = it._edge;
- _begin = it._begin;
- }
-
- virtual ~ViewEdgeIterator() {}
-
- /*! Returns the string "ViewEdgeIterator" */
- virtual string getExactTypeName() const
- {
- return "ViewEdgeIterator";
- }
-
- /*! Returns the current pointed ViewEdge. */
- ViewEdge *getCurrentEdge()
- {
- return _edge;
- }
-
- /*! Sets the current pointed ViewEdge. */
- void setCurrentEdge(ViewEdge *edge)
- {
- _edge = edge;
- }
-
- /*! Returns the first ViewEdge used for the iteration. */
- ViewEdge *getBegin()
- {
- return _begin;
- }
-
- /*! Sets the first ViewEdge used for the iteration. */
- void setBegin(ViewEdge *begin)
- {
- _begin = begin;
- }
-
- /*! Gets the orientation of the pointed ViewEdge in the iteration. */
- bool getOrientation() const
- {
- return _orientation;
- }
-
- /*! Sets the orientation of the pointed ViewEdge in the iteration. */
- void setOrientation(bool orientation)
- {
- _orientation = orientation;
- }
-
- /*! Changes the current orientation. */
- void changeOrientation()
- {
- _orientation = !_orientation;
- }
-
- /*! Returns a *pointer* to the pointed ViewEdge. */
- virtual ViewEdge *operator*()
- {
- return _edge;
- }
-
- virtual ViewEdge *operator->()
- {
- return operator*();
- }
-
- /*! Increments. In the scripting language, call "increment()". */
- virtual ViewEdgeIterator& operator++()
- {
- increment();
- return *this;
- }
-
- /*! Increments. In the scripting language, call "increment()". */
- virtual ViewEdgeIterator operator++(int)
- {
- ViewEdgeIterator tmp(*this);
- increment();
- return tmp;
- }
-
- /*! increments. */
- virtual int increment()
- {
- cerr << "Warning: method increment() not implemented" << endl;
- return 0;
- }
-
- /*! Decrements. In the scripting language, call "decrement()". */
- virtual ViewEdgeIterator& operator--()
- {
- decrement();
- return *this;
- }
-
- /*! Decrements. In the scripting language, call "decrement()". */
- virtual ViewEdgeIterator operator--(int)
- {
- ViewEdgeIterator tmp(*this);
- decrement();
- return tmp;
- }
-
- /*! decrements. */
- virtual int decrement()
- {
- cerr << "Warning: method decrement() not implemented" << endl;
- return 0;
- }
-
- /*! Returns true if the pointed ViewEdge is the first one used for the iteration. */
- virtual bool isBegin() const
- {
- return _edge == _begin;
- }
-
- /*! Returns true if the pointed ViewEdge* equals 0. */
- virtual bool isEnd() const
- {
- return !_edge;
- }
-
- /*! operator == */
- virtual bool operator==(ViewEdgeIterator& it) const
- {
- return _edge == it._edge;
- }
-
- /*! operator != */
- virtual bool operator!=(ViewEdgeIterator& it) const
- {
- return !(*this == it);
- }
-
-protected:
- bool _orientation;
- ViewEdge *_edge;
- ViewEdge *_begin;
+class ViewEdgeIterator : public Iterator {
+ public:
+ /*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation.
+ * \param begin:
+ * The ViewEdge from where to start the iteration.
+ * \param orientation:
+ * If true, we'll look for the next ViewEdge among the ViewEdges that surround the ending ViewVertex of begin.
+ * If false, we'll search over the ViewEdges surrounding the ending ViewVertex of begin.
+ */
+ ViewEdgeIterator(ViewEdge *begin = NULL, bool orientation = true)
+ {
+ _orientation = orientation;
+ _edge = begin;
+ _begin = begin;
+ }
+
+ /*! Copy constructor */
+ ViewEdgeIterator(const ViewEdgeIterator &it)
+ {
+ _orientation = it._orientation;
+ _edge = it._edge;
+ _begin = it._begin;
+ }
+
+ virtual ~ViewEdgeIterator()
+ {
+ }
+
+ /*! Returns the string "ViewEdgeIterator" */
+ virtual string getExactTypeName() const
+ {
+ return "ViewEdgeIterator";
+ }
+
+ /*! Returns the current pointed ViewEdge. */
+ ViewEdge *getCurrentEdge()
+ {
+ return _edge;
+ }
+
+ /*! Sets the current pointed ViewEdge. */
+ void setCurrentEdge(ViewEdge *edge)
+ {
+ _edge = edge;
+ }
+
+ /*! Returns the first ViewEdge used for the iteration. */
+ ViewEdge *getBegin()
+ {
+ return _begin;
+ }
+
+ /*! Sets the first ViewEdge used for the iteration. */
+ void setBegin(ViewEdge *begin)
+ {
+ _begin = begin;
+ }
+
+ /*! Gets the orientation of the pointed ViewEdge in the iteration. */
+ bool getOrientation() const
+ {
+ return _orientation;
+ }
+
+ /*! Sets the orientation of the pointed ViewEdge in the iteration. */
+ void setOrientation(bool orientation)
+ {
+ _orientation = orientation;
+ }
+
+ /*! Changes the current orientation. */
+ void changeOrientation()
+ {
+ _orientation = !_orientation;
+ }
+
+ /*! Returns a *pointer* to the pointed ViewEdge. */
+ virtual ViewEdge *operator*()
+ {
+ return _edge;
+ }
+
+ virtual ViewEdge *operator->()
+ {
+ return operator*();
+ }
+
+ /*! Increments. In the scripting language, call "increment()". */
+ virtual ViewEdgeIterator &operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ /*! Increments. In the scripting language, call "increment()". */
+ virtual ViewEdgeIterator operator++(int)
+ {
+ ViewEdgeIterator tmp(*this);
+ increment();
+ return tmp;
+ }
+
+ /*! increments. */
+ virtual int increment()
+ {
+ cerr << "Warning: method increment() not implemented" << endl;
+ return 0;
+ }
+
+ /*! Decrements. In the scripting language, call "decrement()". */
+ virtual ViewEdgeIterator &operator--()
+ {
+ decrement();
+ return *this;
+ }
+
+ /*! Decrements. In the scripting language, call "decrement()". */
+ virtual ViewEdgeIterator operator--(int)
+ {
+ ViewEdgeIterator tmp(*this);
+ decrement();
+ return tmp;
+ }
+
+ /*! decrements. */
+ virtual int decrement()
+ {
+ cerr << "Warning: method decrement() not implemented" << endl;
+ return 0;
+ }
+
+ /*! Returns true if the pointed ViewEdge is the first one used for the iteration. */
+ virtual bool isBegin() const
+ {
+ return _edge == _begin;
+ }
+
+ /*! Returns true if the pointed ViewEdge* equals 0. */
+ virtual bool isEnd() const
+ {
+ return !_edge;
+ }
+
+ /*! operator == */
+ virtual bool operator==(ViewEdgeIterator &it) const
+ {
+ return _edge == it._edge;
+ }
+
+ /*! operator != */
+ virtual bool operator!=(ViewEdgeIterator &it) const
+ {
+ return !(*this == it);
+ }
+
+ protected:
+ bool _orientation;
+ ViewEdge *_edge;
+ ViewEdge *_begin;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdgeIterator")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdgeIterator")
#endif
-
};
-} // end of namespace ViewEdgeInternal
+} // end of namespace ViewEdgeInternal
} /* namespace Freestyle */
-#endif // __FREESTYLE_VIEW_MAP_ITERATORS_H__
+#endif // __FREESTYLE_VIEW_MAP_ITERATORS_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp b/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
index 62656c6ade6..8abd464b0cf 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
@@ -25,16 +25,16 @@ namespace Freestyle {
NodeGroup *ViewMapTesselator::Tesselate(ViewMap *iViewMap)
{
- if (0 == iViewMap->ViewEdges().size())
- return NULL;
+ if (0 == iViewMap->ViewEdges().size())
+ return NULL;
- const vector<ViewEdge*>& viewedges = iViewMap->ViewEdges();
- return Tesselate(viewedges.begin(), viewedges.end());
+ const vector<ViewEdge *> &viewedges = iViewMap->ViewEdges();
+ return Tesselate(viewedges.begin(), viewedges.end());
}
NodeGroup *ViewMapTesselator::Tesselate(WShape *)
{
- return NULL;
+ return NULL;
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
index a24a7cfdf18..2173ea42fab 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
@@ -34,7 +34,7 @@
#include "../winged_edge/WEdge.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
@@ -44,100 +44,105 @@ class NodeGroup;
class SShape;
class WShape;
-class ViewMapTesselator
-{
-public:
- inline ViewMapTesselator()
- {
- _nature = Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE;
- _FrsMaterial.setDiffuse(0, 0, 0, 1);
- _overloadFrsMaterial = false;
- }
-
- virtual ~ViewMapTesselator() {}
-
- /*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a ViewMap */
- NodeGroup *Tesselate(ViewMap *iViewMap);
-
- /*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a set of
- * view edges
- */
- template<class ViewEdgesIterator>
- NodeGroup *Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end);
-
- /*! Builds a set of lines rep contained among a NodeShape, from a WShape */
- NodeGroup *Tesselate(WShape *iWShape);
-
- inline void setNature(Nature::EdgeNature iNature)
- {
- _nature = iNature;
- }
-
- inline void setFrsMaterial(const FrsMaterial& iMaterial)
- {
- _FrsMaterial = iMaterial;
- _overloadFrsMaterial = true;
- }
-
- inline Nature::EdgeNature nature()
- {
- return _nature;
- }
-
- inline const FrsMaterial& frs_material() const
- {
- return _FrsMaterial;
- }
-
-protected:
- virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
-
-private:
- Nature::EdgeNature _nature;
- FrsMaterial _FrsMaterial;
- bool _overloadFrsMaterial;
+class ViewMapTesselator {
+ public:
+ inline ViewMapTesselator()
+ {
+ _nature = Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE;
+ _FrsMaterial.setDiffuse(0, 0, 0, 1);
+ _overloadFrsMaterial = false;
+ }
+
+ virtual ~ViewMapTesselator()
+ {
+ }
+
+ /*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a ViewMap */
+ NodeGroup *Tesselate(ViewMap *iViewMap);
+
+ /*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a set of
+ * view edges
+ */
+ template<class ViewEdgesIterator>
+ NodeGroup *Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end);
+
+ /*! Builds a set of lines rep contained among a NodeShape, from a WShape */
+ NodeGroup *Tesselate(WShape *iWShape);
+
+ inline void setNature(Nature::EdgeNature iNature)
+ {
+ _nature = iNature;
+ }
+
+ inline void setFrsMaterial(const FrsMaterial &iMaterial)
+ {
+ _FrsMaterial = iMaterial;
+ _overloadFrsMaterial = true;
+ }
+
+ inline Nature::EdgeNature nature()
+ {
+ return _nature;
+ }
+
+ inline const FrsMaterial &frs_material() const
+ {
+ return _FrsMaterial;
+ }
+
+ protected:
+ virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
+
+ private:
+ Nature::EdgeNature _nature;
+ FrsMaterial _FrsMaterial;
+ bool _overloadFrsMaterial;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator")
#endif
};
/*! Class to tesselate the 2D projected silhouette */
-class ViewMapTesselator2D : public ViewMapTesselator
-{
-public:
- inline ViewMapTesselator2D() : ViewMapTesselator() {}
- virtual ~ViewMapTesselator2D() {}
-
-protected:
- virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
- {
- iLine->AddVertex(v->point2D());
- }
+class ViewMapTesselator2D : public ViewMapTesselator {
+ public:
+ inline ViewMapTesselator2D() : ViewMapTesselator()
+ {
+ }
+ virtual ~ViewMapTesselator2D()
+ {
+ }
+
+ protected:
+ virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
+ {
+ iLine->AddVertex(v->point2D());
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator2D")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator2D")
#endif
-
};
/*! Class to tesselate the 3D silhouette */
-class ViewMapTesselator3D : public ViewMapTesselator
-{
-public:
- inline ViewMapTesselator3D() : ViewMapTesselator() {}
- virtual ~ViewMapTesselator3D() {}
-
-protected:
- virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
- {
- iLine->AddVertex(v->point3D());
- }
+class ViewMapTesselator3D : public ViewMapTesselator {
+ public:
+ inline ViewMapTesselator3D() : ViewMapTesselator()
+ {
+ }
+ virtual ~ViewMapTesselator3D()
+ {
+ }
+
+ protected:
+ virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
+ {
+ iLine->AddVertex(v->point3D());
+ }
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator3D")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator3D")
#endif
-
};
//
@@ -148,73 +153,73 @@ protected:
template<class ViewEdgesIterator>
NodeGroup *ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
{
- NodeGroup *group = new NodeGroup;
- NodeShape *tshape = new NodeShape;
- group->AddChild(tshape);
- //tshape->frs_material().setDiffuse(0.0f, 0.0f, 0.0f, 1.0f);
- tshape->setFrsMaterial(_FrsMaterial);
+ NodeGroup *group = new NodeGroup;
+ NodeShape *tshape = new NodeShape;
+ group->AddChild(tshape);
+ //tshape->frs_material().setDiffuse(0.0f, 0.0f, 0.0f, 1.0f);
+ tshape->setFrsMaterial(_FrsMaterial);
- LineRep *line;
+ LineRep *line;
- FEdge *firstEdge;
- FEdge *nextFEdge, *currentEdge;
+ FEdge *firstEdge;
+ FEdge *nextFEdge, *currentEdge;
- int id = 0;
- //for (vector<ViewEdge*>::const_iterator c = viewedges.begin(), cend = viewedges.end(); c != cend; c++)
- for (ViewEdgesIterator c = begin, cend = end; c != cend; c++) {
+ int id = 0;
+ //for (vector<ViewEdge*>::const_iterator c = viewedges.begin(), cend = viewedges.end(); c != cend; c++)
+ for (ViewEdgesIterator c = begin, cend = end; c != cend; c++) {
#if 0
- if ((*c)->qi() > 0) {
- continue;
- }
- if (!((*c)->nature() & (_nature))) {
- continue;
- }
+ if ((*c)->qi() > 0) {
+ continue;
+ }
+ if (!((*c)->nature() & (_nature))) {
+ continue;
+ }
#endif
- firstEdge = (*c)->fedgeA();
+ firstEdge = (*c)->fedgeA();
#if 0
- if (firstEdge->invisibility() > 0)
- continue;
+ if (firstEdge->invisibility() > 0)
+ continue;
#endif
- line = new OrientedLineRep();
- if (_overloadFrsMaterial)
- line->setFrsMaterial(_FrsMaterial);
-
- // there might be chains containing a single element
- if (0 == (firstEdge)->nextEdge()) {
- line->setStyle(LineRep::LINES);
- //line->AddVertex((*c)->vertexA()->point3D());
- //line->AddVertex((*c)->vertexB()->point3D());
- AddVertexToLine(line, firstEdge->vertexA());
- AddVertexToLine(line, firstEdge->vertexB());
- }
- else {
- line->setStyle(LineRep::LINE_STRIP);
-
- //firstEdge = (*c);
- nextFEdge = firstEdge;
- currentEdge = firstEdge;
- do {
- //line->AddVertex(nextFEdge->vertexA()->point3D());
- AddVertexToLine(line, nextFEdge->vertexA());
- currentEdge = nextFEdge;
- nextFEdge = nextFEdge->nextEdge();
- } while ((nextFEdge != NULL) && (nextFEdge != firstEdge));
- // Add the last vertex
- //line->AddVertex(currentEdge->vertexB()->point3D());
- AddVertexToLine(line, currentEdge->vertexB());
- }
-
- line->setId((*c)->getId().getFirst());
- line->ComputeBBox();
- tshape->AddRep(line);
- id++;
- }
-
- return group;
+ line = new OrientedLineRep();
+ if (_overloadFrsMaterial)
+ line->setFrsMaterial(_FrsMaterial);
+
+ // there might be chains containing a single element
+ if (0 == (firstEdge)->nextEdge()) {
+ line->setStyle(LineRep::LINES);
+ //line->AddVertex((*c)->vertexA()->point3D());
+ //line->AddVertex((*c)->vertexB()->point3D());
+ AddVertexToLine(line, firstEdge->vertexA());
+ AddVertexToLine(line, firstEdge->vertexB());
+ }
+ else {
+ line->setStyle(LineRep::LINE_STRIP);
+
+ //firstEdge = (*c);
+ nextFEdge = firstEdge;
+ currentEdge = firstEdge;
+ do {
+ //line->AddVertex(nextFEdge->vertexA()->point3D());
+ AddVertexToLine(line, nextFEdge->vertexA());
+ currentEdge = nextFEdge;
+ nextFEdge = nextFEdge->nextEdge();
+ } while ((nextFEdge != NULL) && (nextFEdge != firstEdge));
+ // Add the last vertex
+ //line->AddVertex(currentEdge->vertexB()->point3D());
+ AddVertexToLine(line, currentEdge->vertexB());
+ }
+
+ line->setId((*c)->getId().getFirst());
+ line->ComputeBBox();
+ tshape->AddRep(line);
+ id++;
+ }
+
+ return group;
}
} /* namespace Freestyle */
-#endif // __FREESTYLE_VIEW_MAP_TESSELATOR_H__
+#endif // __FREESTYLE_VIEW_MAP_TESSELATOR_H__