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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-01-02 05:55:30 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-01-02 05:55:30 +0400
commit699da2fb0d9012cef5e45cc1b547a01fd92dbc1c (patch)
treeeb6e3de1f90387af1a2628bbc79d51327e3ac248 /source/blender/freestyle/intern
parent520ab93465d8056bf6d4a4115743daaee4c2fd66 (diff)
Yet another big style clean-up patch by Bastien Montagne, thanks a lot!
Now the code style is acceptable for the merge now, according to Bastien. Thanks again Bastien for having this done! :)
Diffstat (limited to 'source/blender/freestyle/intern')
-rw-r--r--source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp102
-rw-r--r--source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h88
-rw-r--r--source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp108
-rw-r--r--source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h91
-rw-r--r--source/blender/freestyle/intern/view_map/BoxGrid.cpp169
-rw-r--r--source/blender/freestyle/intern/view_map/BoxGrid.h316
-rw-r--r--source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp236
-rw-r--r--source/blender/freestyle/intern/view_map/CulledOccluderSource.h82
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp1342
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.h422
-rw-r--r--source/blender/freestyle/intern/view_map/Functions0D.cpp638
-rw-r--r--source/blender/freestyle/intern/view_map/Functions0D.h950
-rw-r--r--source/blender/freestyle/intern/view_map/Functions1D.cpp444
-rw-r--r--source/blender/freestyle/intern/view_map/Functions1D.h1060
-rw-r--r--source/blender/freestyle/intern/view_map/GridDensityProvider.h137
-rw-r--r--source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp92
-rw-r--r--source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h88
-rw-r--r--source/blender/freestyle/intern/view_map/Interface0D.h630
-rw-r--r--source/blender/freestyle/intern/view_map/Interface1D.h382
-rw-r--r--source/blender/freestyle/intern/view_map/OccluderSource.cpp120
-rw-r--r--source/blender/freestyle/intern/view_map/OccluderSource.h78
-rw-r--r--source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp96
-rw-r--r--source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h90
-rw-r--r--source/blender/freestyle/intern/view_map/Silhouette.cpp680
-rw-r--r--source/blender/freestyle/intern/view_map/Silhouette.h3163
-rw-r--r--source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp361
-rw-r--r--source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h235
-rw-r--r--source/blender/freestyle/intern/view_map/SphericalGrid.cpp166
-rw-r--r--source/blender/freestyle/intern/view_map/SphericalGrid.h322
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.cpp477
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.h271
-rw-r--r--source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp1403
-rw-r--r--source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h414
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.cpp1278
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.h3019
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h1464
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp3934
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.h471
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIO.cpp2365
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIO.h233
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIterators.h1065
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp65
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.h329
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.cpp1112
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.h243
-rw-r--r--source/blender/freestyle/intern/winged_edge/Nature.h138
-rw-r--r--source/blender/freestyle/intern/winged_edge/WEdge.cpp1179
-rw-r--r--source/blender/freestyle/intern/winged_edge/WEdge.h2183
-rw-r--r--source/blender/freestyle/intern/winged_edge/WFillGrid.cpp118
-rw-r--r--source/blender/freestyle/intern/winged_edge/WFillGrid.h132
-rw-r--r--source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp117
-rw-r--r--source/blender/freestyle/intern/winged_edge/WSFillGrid.h130
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdge.cpp550
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdge.h1295
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp90
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h79
-rw-r--r--source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp665
-rw-r--r--source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h318
58 files changed, 19902 insertions, 17923 deletions
diff --git a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
index 15b2b3343cc..c7925026cd5 100644
--- a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
@@ -1,52 +1,58 @@
-//
-// Filename : ArbitraryGridDensityProvider.cpp
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-2-5
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-2-5
+ */
#include "ArbitraryGridDensityProvider.h"
-ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells)
- : GridDensityProvider(source), numCells(numCells)
+ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4],
+ unsigned numCells)
+: GridDensityProvider(source), numCells(numCells)
{
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);
-
+
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);
@@ -54,9 +60,9 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& sourc
initialize (proscenium);
}
-ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider () {}
+ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider() {}
-void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
+void ArbitraryGridDensityProvider::initialize(const real proscenium[4])
{
float prosceniumWidth = (proscenium[1] - proscenium[0]);
float prosceniumHeight = (proscenium[3] - proscenium[2]);
@@ -70,11 +76,11 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
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) ) {
+ float safetyZone = 0.1f;
+ if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
}
- if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
+ if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
}
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
@@ -85,24 +91,26 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
}
ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigned numCells)
- : numCells(numCells)
+: numCells(numCells)
{
}
-ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory () {}
+ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory() {}
-auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
+auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source,
+ const real proscenium[4])
{
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, proscenium, numCells));
}
-auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
+auto_ptr<GridDensityProvider>
+ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform)
{
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
}
-auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
}
-
diff --git a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
index f863b2132a7..f8d43f19936 100644
--- a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
@@ -1,48 +1,54 @@
-//
-// Filename : ArbitraryGridDensityProvider.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-2-5
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
+#define __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef ARBITRARYGRIDDENSITYPROVIDER_H
-#define ARBITRARYGRIDDENSITYPROVIDER_H
+/** \file blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-2-5
+ */
#include "GridDensityProvider.h"
-class ArbitraryGridDensityProvider : public GridDensityProvider {
+class ArbitraryGridDensityProvider : public GridDensityProvider
+{
// Disallow copying and assignment
- ArbitraryGridDensityProvider (const ArbitraryGridDensityProvider& other);
- ArbitraryGridDensityProvider& operator= (const ArbitraryGridDensityProvider& other);
+ 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, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform, unsigned numCells);
ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells);
- virtual ~ArbitraryGridDensityProvider ();
+ virtual ~ArbitraryGridDensityProvider();
protected:
unsigned numCells;
@@ -51,17 +57,19 @@ private:
void initialize (const real proscenium[4]);
};
-class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory {
+class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory
+{
public:
ArbitraryGridDensityProviderFactory(unsigned numCells);
- ~ArbitraryGridDensityProviderFactory ();
+ ~ArbitraryGridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
+ auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
+
protected:
unsigned numCells;
};
-#endif // ARBITRARYGRIDDENSITYPROVIDER_H
-
+#endif // __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
diff --git a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
index 8b4c60a7fea..4832d08f2bc 100644
--- a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
@@ -1,69 +1,75 @@
-//
-// Filename : AverageAreaGridDensityProvider.cpp
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-2-9
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-2-9
+ */
#include "AverageAreaGridDensityProvider.h"
-AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor)
- : GridDensityProvider(source)
+AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4],
+ real sizeFactor)
+: GridDensityProvider(source)
{
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);
-
- 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);
- initialize (proscenium, sizeFactor);
+ initialize(proscenium, sizeFactor);
}
-AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider () {}
+AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider() {}
-void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real sizeFactor)
+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() ) {
+ for (source.begin(); source.isValid(); source.next()) {
Polygon3r& poly(source.getGridSpacePolygon());
Vec3r min, max;
poly.getBBox(min, max);
@@ -82,11 +88,11 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
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) ) {
+ float safetyZone = 0.1f;
+ if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
}
- if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
+ if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
}
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
@@ -97,24 +103,26 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
}
AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(real sizeFactor)
- : sizeFactor(sizeFactor)
+: sizeFactor(sizeFactor)
{
}
-AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory () {}
+AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory() {}
-auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
+auto_ptr<GridDensityProvider>
+AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
}
-auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
+auto_ptr<GridDensityProvider>
+AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform)
{
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
}
-auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
}
-
diff --git a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
index 73d28f006a7..05d2ae1ed9d 100644
--- a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
@@ -1,67 +1,72 @@
-//
-// Filename : AverageAreaGridDensityProvider.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-2-9
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
+#define __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef AVERAGEAREAGRIDDENSITYPROVIDER_H
-#define AVERAGEAREAGRIDDENSITYPROVIDER_H
+/** \file blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-2-9
+ */
#include "GridDensityProvider.h"
-class AverageAreaGridDensityProvider : public GridDensityProvider {
+class AverageAreaGridDensityProvider : public GridDensityProvider
+{
// Disallow copying and assignment
- AverageAreaGridDensityProvider (const AverageAreaGridDensityProvider& other);
- AverageAreaGridDensityProvider& operator= (const AverageAreaGridDensityProvider& other);
+ 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, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform, real sizeFactor);
AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor);
- virtual ~AverageAreaGridDensityProvider ();
-
-protected:
+ virtual ~AverageAreaGridDensityProvider();
private:
- void initialize (const real proscenium[4], real sizeFactor);
+ void initialize (const real proscenium[4], real sizeFactor);
};
-class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory {
+class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory
+{
public:
AverageAreaGridDensityProviderFactory(real sizeFactor);
- ~AverageAreaGridDensityProviderFactory ();
+ ~AverageAreaGridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
+ auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
real sizeFactor;
};
-#endif // AVERAGEAREAGRIDDENSITYPROVIDER_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 757cf7b6559..6b2804b17ce 100644
--- a/source/blender/freestyle/intern/view_map/BoxGrid.cpp
+++ b/source/blender/freestyle/intern/view_map/BoxGrid.cpp
@@ -1,36 +1,41 @@
-//
-// Filename : BoxGrid.cpp
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-1-29
-//
-///////////////////////////////////////////////////////////////////////////////
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/BoxGrid.cpp
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-1-29
+ */
-#include "BoxGrid.h"
-
-#include <stdexcept>
#include <algorithm>
+#include <stdexcept>
+
+#include "BoxGrid.h"
using namespace std;
@@ -42,11 +47,12 @@ using namespace std;
// 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) {
+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;
@@ -54,11 +60,13 @@ void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
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;
}
-void BoxGrid::Cell::indexPolygons() {
+void BoxGrid::Cell::indexPolygons()
+{
// Sort occluders by their shallowest points.
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
}
@@ -66,47 +74,49 @@ void BoxGrid::Cell::indexPolygons() {
// 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);
- #if boxgridlogging == 1
- 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 BOX_GRID_LOGGING
+ 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();
}
-BoxGrid::Iterator::~Iterator () {}
+BoxGrid::Iterator::~Iterator() {}
// BoxGrid
/////////////////
-BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI)
- : _viewpoint(viewpoint),
- _enableQI(enableQI)
+BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
+ bool enableQI)
+: _viewpoint(viewpoint), _enableQI(enableQI)
{
- cout << "Generate Cell structure" << endl;
// Generate Cell structure
+ cout << "Generate Cell structure" << endl;
assignCells(source, density, viewMap);
- cout << "Distribute occluders" << endl;
+
// Fill Cells
+ cout << "Distribute occluders" << endl;
distributePolygons(source);
- cout << "Reorganize cells" << endl;
+
// Reorganize Cells
+ cout << "Reorganize cells" << endl;
reorganizeCells();
+
cout << "Ready to use BoxGrid" << endl;
}
-BoxGrid::~BoxGrid () {
-}
+BoxGrid::~BoxGrid() {}
-void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap) {
+void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap)
+{
_cellSize = density.cellSize();
_cellsX = density.cellsX();
_cellsY = density.cellsY();
@@ -115,20 +125,19 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
// 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 ) {
+ 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() ) {
+ for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
+ if ((*f)->isInImage()) {
Vec3r point = transform((*f)->center3d());
- unsigned i, j;
+ unsigned int i, j;
getCellCoordinates(point, i, j);
- if ( _cells[i * _cellsY + j] == NULL ) {
+ if (_cells[i * _cellsY + j] == NULL) {
// This is an uninitialized cell
-
real x, y, width, height;
x = _cellOrigin[0] + _cellSize * i;
@@ -145,19 +154,21 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
}
}
-void BoxGrid::distributePolygons (OccluderSource& source) {
+void BoxGrid::distributePolygons(OccluderSource& source)
+{
unsigned long nFaces = 0;
unsigned long nKeptFaces = 0;
- for ( source.begin(); source.isValid(); source.next() ) {
- OccluderData* occluder = NULL;
+ for (source.begin(); source.isValid(); source.next()) {
+ OccluderData *occluder = NULL;
try {
- if ( insertOccluder(source, occluder) ) {
+ if (insertOccluder(source, occluder)) {
_faces.push_back(occluder);
++nKeptFaces;
}
- } catch (...) {
+ }
+ 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
@@ -170,41 +181,47 @@ void BoxGrid::distributePolygons (OccluderSource& source) {
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
}
-void BoxGrid::reorganizeCells () {
+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 ) {
+ 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));
}
-BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point) {
- unsigned x, y;
+BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point)
+{
+ unsigned int x, y;
getCellCoordinates(point, x, y);
return _cells[x * _cellsY + y];
}
-bool BoxGrid::orthographicProjection () const {
+bool BoxGrid::orthographicProjection() const
+{
return true;
}
-const Vec3r& BoxGrid::viewpoint() const {
+const Vec3r& BoxGrid::viewpoint() const
+{
return _viewpoint;
}
-bool BoxGrid::enableQI() const {
+bool BoxGrid::enableQI() const
+{
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]);
}
-
diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.h b/source/blender/freestyle/intern/view_map/BoxGrid.h
index 43de8d713d5..9c8875865ef 100644
--- a/source/blender/freestyle/intern/view_map/BoxGrid.h
+++ b/source/blender/freestyle/intern/view_map/BoxGrid.h
@@ -1,78 +1,87 @@
-//
-// Filename : BoxGrid.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-1-29
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOXGRID_H
-#define BOXGRID_H
-
-#define boxgridlogging 0
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_BOX_GRID_H__
+#define __FREESTYLE_BOX_GRID_H__
+
+/** \file blender/freestyle/intern/view_map/BoxGrid.h
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-1-29
+ */
+
+#define BOX_GRID_LOGGING FALSE
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector>
-// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
+// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
// so it should be a safe fall-back.
//#include <vector>
//#include <deque>
+
+#include "GridDensityProvider.h"
+#include "OccluderSource.h"
#include "ViewMap.h"
-#include "../winged_edge/WEdge.h"
-#include "../geometry/Polygon.h"
-#include "../system/PointerSequence.h"
+
#include "../geometry/BBox.h"
#include "../geometry/GridHelpers.h"
-#include "OccluderSource.h"
-#include "GridDensityProvider.h"
+#include "../geometry/Polygon.h"
+
+#include "../system/PointerSequence.h"
+
+#include "../winged_edge/WEdge.h"
class BoxGrid
{
public:
// Helper classes
- struct OccluderData {
- explicit OccluderData (OccluderSource& source, Polygon3r& p);
+ 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.
+ // 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;
};
private:
- struct Cell {
+ struct Cell
+ {
// Can't store Cell in a vector without copy and assign
- //Cell(const Cell& other);
- //Cell& operator= (const Cell& other);
+ // Cell(const Cell& other);
+ // Cell& operator=(const Cell& other);
- explicit Cell ();
- ~Cell ();
+ explicit Cell();
+ ~Cell();
- static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b);
+ 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);
@@ -84,43 +93,37 @@ private:
};
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 {
+ /* 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=1e-06);
- ~Iterator ();
- void initBeforeTarget ();
- void initAfterTarget ();
- void nextOccluder ();
- void nextOccludee ();
+ 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();
+ WFace *getWFace() const;
+ Polygon3r *getCameraSpacePolygon();
void reportDepth(Vec3r origin, Vec3r u, real t);
+
private:
bool testOccluder(bool wantOccludee);
void markCurrentOccludeeCandidate(real depth);
- Cell* _cell;
+ Cell *_cell;
Vec3r _target;
bool _foundOccludee;
real _occludeeDepth;
@@ -128,37 +131,39 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate;
};
- class Transform : public GridHelpers::Transform {
+ class Transform : public GridHelpers::Transform
+ {
public:
- explicit Transform ();
- explicit Transform (Transform& other);
- Vec3r operator() (const Vec3r& point) const;
+ 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);
+ BoxGrid& operator=(const BoxGrid& other);
+
public:
- explicit BoxGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
+ 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
+ // 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);
+ Cell *findCell(const Vec3r& point);
// Accessors:
bool orthographicProjection() const;
const Vec3r& viewpoint() const;
- bool enableQI() const;
+ bool enableQI() const;
Transform transform;
private:
@@ -176,51 +181,52 @@ private:
bool _enableQI;
};
-inline void BoxGrid::Iterator::initBeforeTarget () {
+inline void BoxGrid::Iterator::initBeforeTarget()
+{
_current = _cell->faces.begin();
- while ( _current != _cell->faces.end() && ! testOccluder(false) ) {
+ while (_current != _cell->faces.end() && !testOccluder(false)) {
++_current;
}
}
-inline void BoxGrid::Iterator::initAfterTarget () {
- if ( _foundOccludee ) {
- #if boxgridlogging == 1
+inline void BoxGrid::Iterator::initAfterTarget()
+{
+ if (_foundOccludee) {
+ #if BOX_GRID_LOGGING
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
#endif
_current = _occludeeCandidate;
return;
}
- #if boxgridlogging == 1
+ #if BOX_GRID_LOGGING
std::cout << "\tStarting occludee search from current position" << std::endl;
#endif
- while ( _current != _cell->faces.end() && ! testOccluder(true) ) {
+ while (_current != _cell->faces.end() && !testOccluder(true)) {
++_current;
}
}
-inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
+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.
+ 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 boxgridlogging == 1
+ #if BOX_GRID_LOGGING
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
- for ( unsigned i = 1; i < (*_current)->poly.getVertices().size(); ++i ) {
+ 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 boxgridlogging == 1
+ if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
+ #if BOX_GRID_LOGGING
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
#endif
_current = _cell->faces.end();
@@ -230,16 +236,17 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
}
// Specific continue or stop conditions when searching for each type
- if ( wantOccludee ) {
- if ( (*_current)->deepest < _target[2] ) {
- #if boxgridlogging == 1
+ if (wantOccludee) {
+ if ((*_current)->deepest < _target[2]) {
+ #if BOX_GRID_LOGGING
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
#endif
return false;
}
- } else {
- if ( (*_current)->shallowest > _target[2] ) {
- #if boxgridlogging == 1
+ }
+ else {
+ if ((*_current)->shallowest > _target[2]) {
+ #if BOX_GRID_LOGGING
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
#endif
return true;
@@ -251,67 +258,73 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
// 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 boxgridlogging == 1
+ if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
+ #if BOX_GRID_LOGGING
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
#endif
return false;
}
// We've done all the corner cutting we can.
- // Let the caller work out whether or not
- // the geometry is correct.
+ // 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) {
+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];
- #if boxgridlogging == 1
+ #if BOX_GRID_LOGGING
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
#endif
- if ( depth > _target[2] ) {
- #if boxgridlogging == 1
+ if (depth > _target[2]) {
+ #if BOX_GRID_LOGGING
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 ) {
+ if (! _foundOccludee || _occludeeDepth > depth) {
markCurrentOccludeeCandidate(depth);
- }
- } else {
- #if boxgridlogging == 1
+ }
+ }
+ else {
+ #if BOX_GRID_LOGGING
std::cout << std::endl;
#endif
}
}
-inline void BoxGrid::Iterator::nextOccluder () {
- if ( _current != _cell->faces.end() ) {
+inline void BoxGrid::Iterator::nextOccluder()
+{
+ if (_current != _cell->faces.end()) {
do {
++_current;
- } while ( _current != _cell->faces.end() && ! testOccluder(false) );
+ } while (_current != _cell->faces.end() && ! testOccluder(false));
}
}
-inline void BoxGrid::Iterator::nextOccludee () {
- if ( _current != _cell->faces.end() ) {
+inline void BoxGrid::Iterator::nextOccludee()
+{
+ if (_current != _cell->faces.end()) {
do {
++_current;
- } while ( _current != _cell->faces.end() && ! testOccluder(true) );
+ } while (_current != _cell->faces.end() && ! testOccluder(true));
}
}
-inline bool BoxGrid::Iterator::validBeforeTarget () {
+inline bool BoxGrid::Iterator::validBeforeTarget()
+{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
}
-inline bool BoxGrid::Iterator::validAfterTarget () {
+inline bool BoxGrid::Iterator::validAfterTarget()
+{
return _current != _cell->faces.end();
}
-inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
- #if boxgridlogging == 1
+inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth)
+{
+ #if BOX_GRID_LOGGING
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
#endif
_occludeeCandidate = _current;
@@ -319,18 +332,20 @@ inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
_foundOccludee = true;
}
-inline WFace* BoxGrid::Iterator::getWFace() const {
+inline WFace* BoxGrid::Iterator::getWFace() const
+{
return (*_current)->face;
}
-inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon() {
+inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon()
+{
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;
@@ -339,9 +354,10 @@ inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p
deepest = max[2];
}
-inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
- if ( GridHelpers::insideProscenium (boundary, poly) ) {
- if ( occluder == NULL) {
+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);
@@ -350,7 +366,8 @@ inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& pol
}
}
-inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) {
+inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
+{
Polygon3r& poly(source.getGridSpacePolygon());
occluder = NULL;
@@ -361,9 +378,9 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
getCellCoordinates(bbMin, startX, startY);
getCellCoordinates(bbMax, endX, endY);
- for ( unsigned i = startX; i <= endX; ++i ) {
- for ( unsigned j = startY; j <= endY; ++j ) {
- if ( _cells[i * _cellsY + j] != NULL ) {
+ 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);
}
}
@@ -372,5 +389,4 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
return occluder != NULL;
}
-#endif // BOXGRID_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 ea57da93347..0e01a70181a 100644
--- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
+++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
@@ -1,67 +1,74 @@
-//
-// Filename : CulledOccluderSource.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2010-12-21
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/CulledOccluderSource.cpp
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2010-12-21
+ */
#include "CulledOccluderSource.h"
-#include "../geometry/GridHelpers.h"
+
#include "FRS_freestyle.h"
-CulledOccluderSource::CulledOccluderSource (const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap, bool extensiveFEdgeSearch)
- : OccluderSource(t, we),
- rejected(0),
- gridSpaceOccluderProsceniumInitialized(false)
+#include "../geometry/GridHelpers.h"
+
+CulledOccluderSource::CulledOccluderSource(const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap,
+ bool extensiveFEdgeSearch)
+: OccluderSource(t, we), rejected(0), gridSpaceOccluderProsceniumInitialized(false)
{
cullViewEdges(viewMap, extensiveFEdgeSearch);
- // If we have not found any visible FEdges during our cull, then there is nothing
- // to iterate over. Short-circuit everything.
+ // 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() ) {
+ if (valid && ! testCurrent()) {
next();
}
}
-CulledOccluderSource::~CulledOccluderSource() {
-}
+CulledOccluderSource::~CulledOccluderSource() {}
-bool CulledOccluderSource::testCurrent() {
- if ( valid ) {
+bool CulledOccluderSource::testCurrent()
+{
+ if (valid) {
// The test for gridSpaceOccluderProsceniumInitialized should not be necessary
- return gridSpaceOccluderProsceniumInitialized && GridHelpers::insideProscenium (gridSpaceOccluderProscenium, cachedPolygon);
+ return gridSpaceOccluderProsceniumInitialized &&
+ GridHelpers::insideProscenium(gridSpaceOccluderProscenium, cachedPolygon);
}
return false;
}
-bool CulledOccluderSource::next() {
- while ( OccluderSource::next() ) {
- if ( testCurrent() ) {
+bool CulledOccluderSource::next()
+{
+ while (OccluderSource::next()) {
+ if (testCurrent()) {
++rejected;
return true;
}
@@ -70,17 +77,20 @@ bool CulledOccluderSource::next() {
return false;
}
-void CulledOccluderSource::getOccluderProscenium(real proscenium[4]) {
- for ( unsigned i = 0; i < 4; ++i ) {
+void CulledOccluderSource::getOccluderProscenium(real proscenium[4])
+{
+ 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]));
}
-static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
+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());
@@ -89,20 +99,20 @@ static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
return GeomUtils::intersect2dSeg2dArea (min, max, A, B);
}
-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] );
+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]);
}
-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.
+ // This avoids the complications of trying to delete edges from the ViewMap.
- // Non-displayable view edges will be skipped over during
- // visibility calculation.
+ // 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,
+ // 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
@@ -112,34 +122,30 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
cout << "Proscenium culling:" << endl;
- cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2] << ", " << viewProscenium[3] << "]"<< 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
+ // 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.
+ // 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++) {
+ 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.
+ // 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
@@ -151,28 +157,27 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// 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.
+ // 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()) ) {
+ // 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 {
+ }
+ else {
real d = distance2D(fe->center2d(), prosceniumOrigin);
// If center point is closer to viewport origin than current target
- if ( bestOccluderTarget == NULL || d < bestOccluderDistance ) {
+ if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
// Then store as bestOccluderTarget
bestOccluderDistance = d;
bestOccluderTarget = fe;
@@ -181,33 +186,35 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
}
// If feature edge crosses the view proscenium
- if ( ! (*ve)->isInImage() && crossesProscenium(viewProscenium, fe) ) {
+ 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() ) );
+ } 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 ) {
+ 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 ) {
+ if ((*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound) {
// Expand occluder proscenium to enclose bestOccluderTarget
Vec3r point = bestOccluderTarget->center2d();
- if ( point[0] < occluderProscenium[0] ) {
+ if (point[0] < occluderProscenium[0]) {
occluderProscenium[0] = point[0];
- } else if ( point[0] > occluderProscenium[1] ) {
+ }
+ else if (point[0] > occluderProscenium[1]) {
occluderProscenium[1] = point[0];
}
- if ( point[1] < occluderProscenium[2] ) {
+ if (point[1] < occluderProscenium[2]) {
occluderProscenium[2] = point[1];
- } else if ( point[1] > occluderProscenium[3] ) {
+ }
+ else if (point[1] > occluderProscenium[3]) {
occluderProscenium[3] = point[1];
}
// Use bestOccluderTarget for visibility determination
@@ -225,22 +232,18 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// 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 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() ) {
+ for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
+ if (!(*ve)->isInImage()) {
continue;
}
// For each feature edge,
@@ -248,30 +251,31 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
FEdge *fe = festart;
do {
// If not (already) visible and center point inside occluder proscenium,
- if ( ! fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d()) ) {
+ 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 );
+ } 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.
+ // 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 {
+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;
}
}
-
diff --git a/source/blender/freestyle/intern/view_map/CulledOccluderSource.h b/source/blender/freestyle/intern/view_map/CulledOccluderSource.h
index 3c00d5e34ad..a9c5484ca9c 100644
--- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.h
+++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.h
@@ -1,46 +1,52 @@
-//
-// Filename : CulledOccluderSource.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2010-12-21
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef CULLEDOCCLUDERSOURCE_H
-#define CULLEDOCCLUDERSOURCE_H
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
+#define __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
+
+/** \file blender/freestyle/intern/view_map/CulledOccluderSource.h
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2010-12-21
+ */
#include "OccluderSource.h"
#include "ViewMap.h"
-class CulledOccluderSource : public OccluderSource {
+class CulledOccluderSource : public OccluderSource
+{
// Disallow copying and assignment
- CulledOccluderSource (const CulledOccluderSource& other);
- CulledOccluderSource& operator= (const CulledOccluderSource& other);
+ CulledOccluderSource(const CulledOccluderSource& other);
+ CulledOccluderSource& operator=(const CulledOccluderSource& other);
public:
- CulledOccluderSource (const GridHelpers::Transform& transform, WingedEdge& we, ViewMap& viewMap, bool extensiveFEdgeSearch = true);
+ CulledOccluderSource(const GridHelpers::Transform& transform, WingedEdge& we, ViewMap& viewMap,
+ bool extensiveFEdgeSearch = true);
virtual ~CulledOccluderSource();
void cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch);
@@ -51,7 +57,7 @@ public:
private:
bool testCurrent();
- void expandGridSpaceOccluderProscenium(FEdge* fe);
+ void expandGridSpaceOccluderProscenium(FEdge *fe);
real occluderProscenium[4];
real gridSpaceOccluderProscenium[4];
@@ -60,4 +66,4 @@ private:
bool gridSpaceOccluderProsceniumInitialized;
};
-#endif // CULLEDOCCLUDERSOURCE_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 1d52f37236e..9631c93cd7e 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
@@ -1,767 +1,749 @@
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/FEdgeXDetector.cpp
+ * \ingroup freestyle
+ * \brief Detects/flags/builds extended features edges on the WXEdge structure
+ * \author Stephane Grabli
+ * \date 26/10/2003
+ */
+
+#include <float.h>
+#include <math.h>
#include "FEdgeXDetector.h"
-#include "float.h"
+
#include "../geometry/GeomUtils.h"
-#include <math.h>
#include "../geometry/normal_cycle.h"
-void FEdgeXDetector::processShapes(WingedEdge& we) {
- bool progressBarDisplay = false;
- Vec3r Min, Max;
- 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);
- wxs->bbox(Min, Max);
- _bbox_diagonal = (Max-Min).norm();
- 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();
- }
- _computeViewIndependant = true;
- } else if (!(wxs)->getComputeViewIndependantFlag()) {
- wxs->Reset();
- _computeViewIndependant = false;
- } else {
- _computeViewIndependant = 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->setComputeViewIndependantFlag(false);
- _computeViewIndependant = false;
- _changes = false;
-
- // reset user data
- (*it)->ResetUserData();
- }
+void FEdgeXDetector::processShapes(WingedEdge& we)
+{
+ bool progressBarDisplay = false;
+ Vec3r Min, Max;
+ 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);
+ wxs->bbox(Min, Max);
+ _bbox_diagonal = (Max - Min).norm();
+ 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();
+ }
+ _computeViewIndependant = true;
+ }
+ else if (!(wxs)->getComputeViewIndependantFlag()) {
+ wxs->Reset();
+ _computeViewIndependant = false;
+ }
+ else {
+ _computeViewIndependant = 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->setComputeViewIndependantFlag(false);
+ _computeViewIndependant = 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;
- _meanEdgeSize = iWShape->getMeanEdgeSize();
-
- 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::preProcessShape(WXShape *iWShape)
+{
+ _meanK1 = 0;
+ _meanKr = 0;
+ _minK1 = FLT_MAX;
+ _maxK1 = -FLT_MAX;
+ _minKr = FLT_MAX;
+ _maxKr = -FLT_MAX;
+ _nPoints = 0;
+ _meanEdgeSize = iWShape->getMeanEdgeSize();
+
+ 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){
- Vec3r firstPoint = iFace->GetVertex(0)->GetVertex();
- Vec3r N = iFace->GetNormal();
-
- // Compute the dot product between V (=_Viewpoint - firstPoint) and N:
- Vec3r V;
- if (_orthographicProjection) {
- V = Vec3r(0.0, 0.0, _Viewpoint.z() - firstPoint.z());
- } else {
- V = Vec3r(_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 {
- Vec3r dist_vec(iFace->center() - _Viewpoint);
- iFace->setZ(dist_vec.norm());
- }
+void FEdgeXDetector::preProcessFace(WXFace *iFace)
+{
+ Vec3r firstPoint = iFace->GetVertex(0)->GetVertex();
+ Vec3r N = iFace->GetNormal();
+
+ // Compute the dot product between V (=_Viewpoint - firstPoint) and N:
+ Vec3r V;
+ if (_orthographicProjection) {
+ V = Vec3r(0.0, 0.0, _Viewpoint.z() - firstPoint.z());
+ }
+ else {
+ V = Vec3r(_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 {
+ Vec3r dist_vec(iFace->center() - _Viewpoint);
+ iFace->setZ(dist_vec.norm());
+ }
}
-void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
- // 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 independant stuff
- if(_computeViewIndependant){
- 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;
+void FEdgeXDetector::computeCurvatures(WXVertex *vertex)
+{
+ // 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 independant stuff
+ if (_computeViewIndependant) {
+ 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));
- }
+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));
+ }
}
void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
{
-
- // SILHOUETTE LAYER
- Vec3r normal;
- // Compute the dot products between View direction and N at each vertex
- // of the face:
- Vec3r point;
- int closestPointId = 0;
- real 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();
- Vec3r V;
- if (_orthographicProjection) {
- V = Vec3r(0.0, 0.0, _Viewpoint.z() - point.z());
- } else {
- V = Vec3r(_Viewpoint - point);
- }
- V.normalize();
- real d = normal * V;
- faceLayer->PushDotP(d);
- // Find the point the closest to the viewpoint
- if (_orthographicProjection) {
- dist = point.z() - _Viewpoint.z();
- } else {
- Vec3r 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
+ Vec3r normal;
+ // Compute the dot products between View direction and N at each vertex of the face:
+ Vec3r point;
+ int closestPointId = 0;
+ real 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();
+ Vec3r V;
+ if (_orthographicProjection) {
+ V = Vec3r(0.0, 0.0, _Viewpoint.z() - point.z());
+ }
+ else {
+ V = Vec3r(_Viewpoint - point);
+ }
+ V.normalize();
+ real d = normal * V;
+ faceLayer->PushDotP(d);
+ // Find the point the closest to the viewpoint
+ if (_orthographicProjection) {
+ dist = point.z() - _Viewpoint.z();
+ }
+ else {
+ Vec3r 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(!_computeViewIndependant)
- 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::processBorderShape(WXShape *iWShape)
+{
+ if (!_computeViewIndependant)
+ 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(!_computeViewIndependant)
- 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::processCreaseShape(WXShape *iWShape)
+{
+ if (!_computeViewIndependant)
+ 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);
-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((!_computeViewIndependant))
- 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));
- }
+ if (!_computeViewIndependant)
+ 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);
- }
-
- 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);
+ }
+
+ 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);
+ }
+ }
}
-// 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.e-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 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));
-
-// // 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);
-// // }
-// }
+#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 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
// SUGGESTIVE CONTOURS
//////////////////////
-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));
- }
+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));
+ }
}
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);
- }
-
- // 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));
- }
+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));
+ }
}
-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 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 wether 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.e-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();
+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 wether 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(!_computeViewIndependant)
- 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::processMaterialBoundaryShape(WXShape *iWShape)
+{
+ if (!_computeViewIndependant)
+ 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));
- }
+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));
+ }
}
-void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge) {
- if (iEdge->GetMark()) {
- iEdge->AddNature(Nature::EDGE_MARK);
- }
+void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge)
+{
+ 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);
- }
+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);
+ }
}
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
index 2fd6a4a1e8f..1b211264402 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
@@ -1,203 +1,241 @@
-//
-// Filename : FEdgeXDetector.h
-// Author(s) : Stephane Grabli
-// Purpose : Detects/flags/builds extended features edges on the
-// WXEdge structure
-// Date of creation : 26/10/2003
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-#ifndef FEDGEXDETECTOR_H
-# define FEDGEXDETECTOR_H
-
-# include <vector>
-# include "../system/FreestyleConfig.h"
-# include "../geometry/Geom.h"
-# include "../winged_edge/WXEdge.h"
-# include "../winged_edge/Curvature.h"
-# include "../system/ProgressBar.h"
-# include "../system/RenderMonitor.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-using namespace Geometry;
+#ifndef __FREESTYLE_FEDGE_X_DETECTOR_H__
+#define __FREESTYLE_FEDGE_X_DETECTOR_H__
-/*! This class takes as input a WXEdge structure and fills it
+/** \file blender/freestyle/intern/view_map/FEdgeXDetector.h
+ * \ingroup freestyle
+ * \brief Detects/flags/builds extended features edges on the WXEdge structure
+ * \author Stephane Grabli
+ * \date 26/10/2003
*/
+#include <vector>
+
+#include "../geometry/Geom.h"
+
+#include "../system/FreestyleConfig.h"
+#include "../system/ProgressBar.h"
+#include "../system/RenderMonitor.h"
+
+#include "../winged_edge/Curvature.h"
+#include "../winged_edge/WXEdge.h"
+
+using namespace Geometry;
+
+/*! This class takes as input a WXEdge structure and fills it */
class LIB_VIEW_MAP_EXPORT FEdgeXDetector
{
public:
-
- FEdgeXDetector() {
- _pProgressBar = 0;
- _pRenderMonitor = 0;
- _computeViewIndependant = true;
- _bbox_diagonal = 1.0;
- _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.
- */
- inline void setCreaseAngle(real 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(real 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 Vec3r& 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(real r) {
- if(r!=_sphereRadius){
- _sphereRadius = r;
- _changes=true;
- }
- }
-
- inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;}
-
- inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;}
+ FEdgeXDetector()
+ {
+ _pProgressBar = NULL;
+ _pRenderMonitor = NULL;
+ _computeViewIndependant = true;
+ _bbox_diagonal = 1.0;
+ _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(real 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(real 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 Vec3r& 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(real r)
+ {
+ if (r != _sphereRadius) {
+ _sphereRadius = r;
+ _changes=true;
+ }
+ }
+
+ inline void setProgressBar(ProgressBar *iProgressBar)
+ {
+ _pProgressBar = iProgressBar;
+ }
+
+ inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
+ {
+ _pRenderMonitor = iRenderMonitor;
+ }
protected:
-
- Vec3r _Viewpoint;
- real _bbox_diagonal; // diagonal of the current processed shape bbox
- //oldtmp values
- bool _computeViewIndependant;
- 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;
- real _sphereRadius; // expressed as a ratio of the mean edge size
- real _creaseAngle; // [-1, 1] compared with the inner product of face normals
- bool _changes;
-
- real _kr_derivative_epsilon;
-
- ProgressBar *_pProgressBar;
- RenderMonitor *_pRenderMonitor;
+ Vec3r _Viewpoint;
+ real _bbox_diagonal; // diagonal of the current processed shape bbox
+ //oldtmp values
+ bool _computeViewIndependant;
+ 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;
+ real _sphereRadius; // expressed as a ratio of the mean edge size
+ real _creaseAngle; // [-1, 1] compared with the inner product of face normals
+ bool _changes;
+
+ real _kr_derivative_epsilon;
+
+ ProgressBar *_pProgressBar;
+ RenderMonitor *_pRenderMonitor;
};
-#endif // FEDGEDXETECTOR_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 a9f997e66b0..b6821afcb93 100644
--- a/source/blender/freestyle/intern/view_map/Functions0D.cpp
+++ b/source/blender/freestyle/intern/view_map/Functions0D.cpp
@@ -1,357 +1,371 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/view_map/Functions0D.cpp
+ * \ingroup freestyle
+ * \brief Functions taking 0D input
+ * \author Stephane Grabli
+ * \author Emmanuel Turquin
+ * \date 01/07/2003
+ */
-# include "Functions0D.h"
-# include "ViewMap.h"
+#include "Functions0D.h"
+#include "ViewMap.h"
using namespace std;
namespace Functions0D {
- // Internal function
- FEdge* getFEdge(Interface0D& it1, Interface0D& it2){
- return it1.getFEdge(it2);
- }
+// Internal function
+FEdge *getFEdge(Interface0D& it1, Interface0D& it2)
+{
+ return it1.getFEdge(it2);
+}
- 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 = 0;
- }
- 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 = 0;
- }
- else if(last)
- {
- fe1 = previous->getFEdge(*it);
- fe2 = 0;
- }
- else
- {
- fe1 = previous->getFEdge(*it);
- fe2 = it->getFEdge(*next);
- }
- }
- }
+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);
+ }
+ }
+}
- void getViewEdges(Interface0DIterator &it,
- ViewEdge *&ve1,
- ViewEdge *&ve2)
- {
- FEdge * fe1, *fe2;
- getFEdges(it, fe1, fe2);
- ve1 = fe1->viewedge();
- if(fe2 != 0)
- {
- ve2 = fe2->viewedge();
- if(ve2 == ve1)
- ve2 = 0;
- }
- else
- ve2 = 0;
- }
+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;
+ }
+}
- ViewShape* getShapeF0D(Interface0DIterator& it)
- {
- ViewEdge *ve1, *ve2;
- getViewEdges(it, ve1, ve2);
- return ve1->viewShape();
- }
+ViewShape *getShapeF0D(Interface0DIterator& it)
+{
+ ViewEdge *ve1, *ve2;
+ getViewEdges(it, ve1, ve2);
+ return ve1->viewShape();
+}
- 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();
+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));
+ for (; oit != oitend; ++oit)
+ oOccluders.insert((*oit));
- if(ve2!=0){
- oit = ve2->occluders_begin();
- oitend = ve2->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){
- ViewEdge * ve1, *ve2;
- getViewEdges(it, ve1, ve2);
- ViewShape *aShape = ve1->aShape();
- return aShape;
- }
-
- //
- 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());
+ViewShape *getOccludeeF0D(Interface0DIterator& it)
+{
+ ViewEdge *ve1, *ve2;
+ getViewEdges(it, ve1, ve2);
+ ViewShape *aShape = ve1->aShape();
+ return aShape;
+}
- 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 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());
- 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
- {
+ 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)
+{
+ 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());
+ }
+ 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 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) {
- Interface0DIterator tmp1 = iter, tmp2 = iter;
- ++tmp2;
- unsigned count = 1;
- while((!tmp1.isBegin()) && (count < 3))
- {
- --tmp1;
- ++count;
- }
- while((!tmp2.isEnd()) && (count < 3))
- {
+int Curvature2DAngleF0D::operator()(Interface0DIterator& iter)
+{
+ Interface0DIterator tmp1 = iter, tmp2 = iter;
++tmp2;
- ++count;
- }
- if(count < 3) {
- // if we only have 2 vertices
- result = 0;
- return 0;
+ 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;
+ 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);
+ 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) {
- FEdge *fe1, *fe2;
- getFEdges(iter, fe1, fe2);
- result = fe1->z_discontinuity();
- if(fe2!=0){
- result += fe2->z_discontinuity();
- result /= 2.f;
- }
- return 0;
- }
+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;
+}
- 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 != 0)
- {
- Vec3f e2(fe2->orientation2d());
- Vec2f n2(e2[1], -e2[0]);
- n += n2;
- }
- n.normalize();
- result = n;
+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;
- }
+}
- int MaterialF0D::operator()(Interface0DIterator& iter) {
- FEdge *fe1, *fe2;
- getFEdges(iter,fe1,fe2);
- if(fe1 == 0)
- return -1;
- if(fe1->isSmooth())
- result = ((FEdgeSmooth*)fe1)->frs_material();
- else
- result = ((FEdgeSharp*)fe1)->bFrsMaterial();
- // const SShape * sshape = getShapeF0D(iter);
- // return sshape->material();
- return 0;
- }
+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();
+#if 0
+ const SShape *sshape = getShapeF0D(iter);
+ return sshape->material();
+#endif
+ return 0;
+}
- int ShapeIdF0D::operator()(Interface0DIterator& iter) {
- ViewShape * vshape = getShapeF0D(iter);
- result = vshape->getId();
+int ShapeIdF0D::operator()(Interface0DIterator& iter)
+{
+ ViewShape *vshape = getShapeF0D(iter);
+ result = vshape->getId();
return 0;
- }
+}
- int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter) {
- ViewEdge * ve1, *ve2;
- getViewEdges(iter,ve1,ve2);
- unsigned int qi1, qi2;
- qi1 = ve1->qi();
- if(ve2 != 0){
- qi2 = ve2->qi();
- if(qi2!=qi1)
- cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
- }
- result = qi1;
+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)
+ cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
+ }
+ result = qi1;
return 0;
- }
+}
- int CurveNatureF0D::operator()(Interface0DIterator& iter) {
- Nature::EdgeNature nat = 0;
- ViewEdge * ve1, *ve2;
- getViewEdges(iter, ve1, ve2);
- nat |= ve1->getNature();
- if(ve2!=0)
- nat |= ve2->getNature();
- result = nat;
+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;
- }
+}
- int GetOccludersF0D::operator()(Interface0DIterator& iter) {
- set<ViewShape*> occluders;
- getOccludersF0D(iter,occluders);
+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));
- }
+ //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) {
- result = getShapeF0D(iter);
+int GetShapeF0D::operator()(Interface0DIterator& iter)
+{
+ result = getShapeF0D(iter);
return 0;
- }
+}
- int GetOccludeeF0D::operator()(Interface0DIterator& iter) {
- result = getOccludeeF0D(iter);
+int GetOccludeeF0D::operator()(Interface0DIterator& iter)
+{
+ result = getOccludeeF0D(iter);
return 0;
- }
+}
} // end of namespace Functions0D
diff --git a/source/blender/freestyle/intern/view_map/Functions0D.h b/source/blender/freestyle/intern/view_map/Functions0D.h
index 4adbc8a1bf5..03ab008736c 100644
--- a/source/blender/freestyle/intern/view_map/Functions0D.h
+++ b/source/blender/freestyle/intern/view_map/Functions0D.h
@@ -1,64 +1,70 @@
-//
-// Filename : Functions0D.h
-// Author(s) : Stephane Grabli, Emmanuel Turquin
-// Purpose : Functions taking 0D input
-// Date of creation : 01/07/2003
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_FUNCTIONS_0D_H__
+#define __FREESTYLE_FUNCTIONS_0D_H__
+
+/** \file blender/freestyle/intern/view_map/Functions0D.h
+ * \ingroup freestyle
+ * \brief Functions taking 0D input
+ * \author Stephane Grabli
+ * \author Emmanuel Turquin
+ * \date 01/07/2003
+ */
+
+#include <set>
+#include <vector>
+
+#include "Interface0D.h"
+
+#include "../geometry/Geom.h"
+
+#include "../python/Director.h"
+
+#include "../scene_graph/FrsMaterial.h"
+
+#include "../system/Exception.h"
+#include "../system/Precision.h"
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef FUNCTIONS0D_H
-# define FUNCTIONS0D_H
-
-# include "../system/Precision.h"
-# include "Interface0D.h"
-# include "../geometry/Geom.h"
-# include "../system/Exception.h"
-# include "../scene_graph/FrsMaterial.h"
-# include <set>
-# include <vector>
class FEdge;
class ViewEdge;
class SShape;
using namespace Geometry;
-#include "../python/Director.h"
-
//
// UnaryFunction0D (base class for functions in 0D)
//
///////////////////////////////////////////////////////////
-template <class T>
-/*! Base class for Unary Functions (functors) working
- * on Interface0DIterator.
- * A unary function will be used by calling
- * its operator() on an Interface0DIterator.
- * \attention In the scripting language, there exists
- * several prototypes depending on the returned value type.
- * For example, you would inherit from a UnaryFunction0DDouble
- * if you wish to define a function that returns a double.
+/*! Base class for Unary Functions (functors) working on Interface0DIterator.
+ * A unary function will be used by calling its operator() on an Interface0DIterator.
+ * \attention In the scripting language, there exists several prototypes depending on the returned value type.
+ * For example, you would inherit from a UnaryFunction0DDouble if you wish to define a function that returns a double.
* The different existing prototypes are:
* - UnaryFunction0DVoid
* - UnaryFunction0DUnsigned
@@ -68,433 +74,459 @@ template <class T>
* - UnaryFunction0DVec2f
* - UnaryFunction0DVec3f
*/
+template <class T>
class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction0D
{
public:
-
T result;
PyObject *py_uf0D;
- /*! The type of the value
- * returned by the functor.
- */
- typedef T ReturnedValueType;
- /*! Default constructor. */
-UnaryFunction0D() { py_uf0D = 0;}
- /*! 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.
- */
- virtual int operator()(Interface0DIterator& iter) {
- return Director_BPy_UnaryFunction0D___call__( this, py_uf0D, iter );
- }
-
+ /*! 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.
+ */
+ virtual int operator()(Interface0DIterator& iter)
+ {
+ return Director_BPy_UnaryFunction0D___call__(this, py_uf0D, iter);
+ }
};
-# ifdef SWIG
-%feature("director") UnaryFunction0D<void>;
-%feature("director") UnaryFunction0D<unsigned>;
-%feature("director") UnaryFunction0D<float>;
-%feature("director") UnaryFunction0D<double>;
-%feature("director") UnaryFunction0D<Vec2f>;
-%feature("director") UnaryFunction0D<Vec3f>;
-%feature("director") UnaryFunction0D<Id>;
-
-%template(UnaryFunction0DVoid) UnaryFunction0D<void>;
-%template(UnaryFunction0DUnsigned) UnaryFunction0D<unsigned>;
-%template(UnaryFunction0DFloat) UnaryFunction0D<float>;
-%template(UnaryFunction0DDouble) UnaryFunction0D<double>;
-%template(UnaryFunction0DVec2f) UnaryFunction0D<Vec2f>;
-%template(UnaryFunction0DVec3f) UnaryFunction0D<Vec3f>;
-%template(UnaryFunction0DId) UnaryFunction0D<Id>;
-%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
-%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
-# endif // SWIG
-
+#ifdef SWIG
+%feature("director") UnaryFunction0D<void>;
+%feature("director") UnaryFunction0D<unsigned>;
+%feature("director") UnaryFunction0D<float>;
+%feature("director") UnaryFunction0D<double>;
+%feature("director") UnaryFunction0D<Vec2f>;
+%feature("director") UnaryFunction0D<Vec3f>;
+%feature("director") UnaryFunction0D<Id>;
+
+%template(UnaryFunction0DVoid) UnaryFunction0D<void>;
+%template(UnaryFunction0DUnsigned) UnaryFunction0D<unsigned>;
+%template(UnaryFunction0DFloat) UnaryFunction0D<float>;
+%template(UnaryFunction0DDouble) UnaryFunction0D<double>;
+%template(UnaryFunction0DVec2f) UnaryFunction0D<Vec2f>;
+%template(UnaryFunction0DVec3f) UnaryFunction0D<Vec3f>;
+%template(UnaryFunction0DId) UnaryFunction0D<Id>;
+%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
+%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
+#endif // SWIG
//
// Functions definitions
//
///////////////////////////////////////////////////////////
class ViewShape;
+
namespace Functions0D {
- // GetXF0D
- /*! Returns the X 3D coordinate of an Interface0D. */
- class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
- {
- 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 LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real>
- {
- 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 LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real>
- {
- 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 LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real>
- {
- 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 LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real>
- {
- 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 LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real>
- {
- 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real>
- {
- public:
- /*! Returns the string "Curvature2DAngleF0D"*/
- string getName() const {
- return "Curvature2DAngleF0D";
- }
- /*! the () operator.*/
- int operator()(Interface0DIterator& iter);
- };
-
- // ZDiscontinuity
- /*! Returns a real giving the distance between
- * and Interface0D and the shape that lies behind (occludee).
- * This distance is evaluated in the camera space and normalized
- * between 0 and 1. Therefore, if no oject is occluded by the
- * shape to which the Interface0D belongs to, 1 is returned.
- */
- class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
- {
- 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 LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f>
- {
- public:
- /*! Returns the string "Normal2DF0D"*/
- string getName() const {
- return "Normal2DF0D";
- }
- /*! the () operator.*/
- int operator()(Interface0DIterator& iter);
- };
-
- // MaterialF0D
- /*! Returns the material of the object evaluated at the Interface0D.
- * This evaluation can be ambiguous (in the case of a TVertex for example.
- * This functor tries to remove this ambiguity using the context
- * offered by the 1D element to which the Interface0DIterator& belongs
- * to and by arbitrary chosing the material of the face
- * that lies on its left when following the 1D element if there
- * are two different materials on each side of the point.
- * 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 LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
- {
- public:
- /*! Returns the string "MaterialF0D"*/
- string getName() const {
- return "MaterialF0D";
- }
- /*! the () operator.*/
- int operator()(Interface0DIterator& iter);
- };
-
- // ShapeIdF0D
- /*! Returns the Id of the Shape the Interface0D belongs to.
- * This evaluation can be ambiguous (in the case of a TVertex for example).
- * This functor tries to remove this ambiguity using the context
- * offered by the 1D element to which the Interface0DIterator& belongs
- * to.
- * 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 LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
- {
- public:
- /*! Returns the string "ShapeIdF0D"*/
- string getName() const {
- return "ShapeIdF0D";
- }
- /*! the () operator.*/
- int operator()(Interface0DIterator& iter);
- };
-
- // QiF0D
- /*! Returns the quantitative invisibility of this Interface0D.
- * This evaluation can be ambiguous (in the case of a TVertex for example).
- * This functor tries to remove this ambiguity using the context
- * offered by the 1D element to which the Interface0DIterator& belongs
- * to.
- * 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
- {
- public:
- /*! Returns the string "GetOccludeeF0D"*/
- string getName() const {
- return "GetOccludeeF0D";
- }
- /*! the () operator.*/
- int operator()(Interface0DIterator& iter);
- };
-
-
-
- /////////////////////////// Internal ////////////////////////////
-
- // getFEdge
- LIB_VIEW_MAP_EXPORT
- FEdge* getFEdge(Interface0D& it1, Interface0D& it2);
-
- // getFEdges
- LIB_VIEW_MAP_EXPORT
- void getFEdges(Interface0DIterator& it,
- FEdge*& fe1,
- FEdge*& fe2);
-
- // getViewEdges
- LIB_VIEW_MAP_EXPORT
- void getViewEdges(Interface0DIterator& it,
- ViewEdge *&ve1,
- ViewEdge *&ve2);
-
- // getShapeF0D
- LIB_VIEW_MAP_EXPORT
- ViewShape* getShapeF0D(Interface0DIterator& it);
-
- // getOccludersF0D
- LIB_VIEW_MAP_EXPORT
- void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
-
- // getOccludeeF0D
- LIB_VIEW_MAP_EXPORT
- ViewShape* getOccludeeF0D(Interface0DIterator& it);
+// GetXF0D
+/*! Returns the X 3D coordinate of an Interface0D. */
+class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
+{
+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 LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real>
+{
+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 LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real>
+{
+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 LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real>
+{
+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 LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real>
+{
+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 LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real>
+{
+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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real>
+{
+public:
+ /*! Returns the string "Curvature2DAngleF0D" */
+ string getName() const
+ {
+ return "Curvature2DAngleF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator& iter);
+};
+
+// ZDiscontinuity
+/*! Returns a real giving the distance between and Interface0D and the shape that lies behind (occludee).
+ * This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no oject is occluded
+ * by the shape to which the Interface0D belongs to, 1 is returned.
+ */
+class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
+{
+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 LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f>
+{
+public:
+ /*! Returns the string "Normal2DF0D" */
+ string getName() const
+ {
+ return "Normal2DF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator& iter);
+};
+
+// MaterialF0D
+/*! Returns the material of the object evaluated at the Interface0D.
+ * This evaluation can be ambiguous (in the case of a TVertex for example.
+ * This functor tries to remove this ambiguity using the context offered by the 1D element to which the
+ * Interface0DIterator& belongs to and by arbitrary chosing the material of the face that lies on its left when
+ * following the 1D element if there are two different materials on each side of the point.
+ * 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 LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
+{
+public:
+ /*! Returns the string "MaterialF0D" */
+ string getName() const
+ {
+ return "MaterialF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator& iter);
+};
+
+// ShapeIdF0D
+/*! Returns the Id of the Shape the Interface0D belongs to.
+ * This evaluation can be ambiguous (in the case of a TVertex for example).
+ * This functor tries to remove this ambiguity using the context offered by the 1D element to which the
+ * Interface0DIterator& belongs to.
+ * 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 LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
+{
+public:
+ /*! Returns the string "ShapeIdF0D" */
+ string getName() const
+ {
+ return "ShapeIdF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator& iter);
+};
+
+// QiF0D
+/*! Returns the quantitative invisibility of this Interface0D.
+* This evaluation can be ambiguous (in the case of a TVertex for example).
+* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
+* Interface0DIterator& belongs to.
+* 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
+{
+public:
+ /*! Returns the string "GetOccludeeF0D" */
+ string getName() const
+ {
+ return "GetOccludeeF0D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface0DIterator& iter);
+};
+
+
+/////////////////////////// Internal ////////////////////////////
+
+// getFEdge
+LIB_VIEW_MAP_EXPORT
+FEdge *getFEdge(Interface0D& it1, Interface0D& it2);
+
+// getFEdges
+LIB_VIEW_MAP_EXPORT
+void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
+
+// getViewEdges
+LIB_VIEW_MAP_EXPORT
+void getViewEdges(Interface0DIterator& it, ViewEdge *&ve1, ViewEdge *&ve2);
+
+// getShapeF0D
+LIB_VIEW_MAP_EXPORT
+ViewShape *getShapeF0D(Interface0DIterator& it);
+
+// getOccludersF0D
+LIB_VIEW_MAP_EXPORT
+void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
+
+// getOccludeeF0D
+LIB_VIEW_MAP_EXPORT
+ViewShape *getOccludeeF0D(Interface0DIterator& it);
} // end of namespace Functions0D
-#endif // FUNCTIONS0D_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 8545c660084..f17a568ffee 100644
--- a/source/blender/freestyle/intern/view_map/Functions1D.cpp
+++ b/source/blender/freestyle/intern/view_map/Functions1D.cpp
@@ -1,231 +1,271 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/view_map/Functions1D.cpp
+ * \ingroup freestyle
+ * \brief Functions taking 1D input
+ * \author Stephane Grabli
+ * \author Emmanuel Turquin
+ * \date 01/07/2003
+ */
# include "Functions1D.h"
+
using namespace std;
namespace Functions1D {
- int GetXF1D::operator()(Interface1D& inter) {
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+int GetXF1D::operator()(Interface1D& inter)
+{
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
- }
+}
- int GetYF1D::operator()(Interface1D& inter) {
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+int GetYF1D::operator()(Interface1D& inter)
+{
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
- }
+}
- int GetZF1D::operator()(Interface1D& inter) {
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+int GetZF1D::operator()(Interface1D& inter)
+{
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
- }
+}
- int GetProjectedXF1D::operator()(Interface1D& inter) {
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+int GetProjectedXF1D::operator()(Interface1D& inter)
+{
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
- }
+}
- int GetProjectedYF1D::operator()(Interface1D& inter) {
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+int GetProjectedYF1D::operator()(Interface1D& inter)
+{
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
- }
+}
- int GetProjectedZF1D::operator()(Interface1D& inter) {
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+int GetProjectedZF1D::operator()(Interface1D& inter)
+{
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
- }
+}
- 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);
+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;
- }
+}
- int Orientation3DF1D::operator()(Interface1D& inter) {
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+int Orientation3DF1D::operator()(Interface1D& inter)
+{
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
- }
+}
- int ZDiscontinuityF1D::operator()(Interface1D& inter) {
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+int ZDiscontinuityF1D::operator()(Interface1D& inter)
+{
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
- }
-
- int QuantitativeInvisibilityF1D::operator()(Interface1D& inter) {
- ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
+}
+
+int QuantitativeInvisibilityF1D::operator()(Interface1D& inter)
+{
+ ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
- result = ve->qi();
- return 0;
+ result = ve->qi();
+ return 0;
}
- FEdge *fe = dynamic_cast<FEdge*>(&inter);
+ FEdge *fe = dynamic_cast<FEdge*>(&inter);
if (fe) {
- result = ve->qi();
- return 0;
- }
- result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
- return 0;
- }
-
- 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;
- }
-
- int TimeStampF1D::operator()(Interface1D& inter) {
- TimeStamp *timestamp = TimeStamp::instance();
- inter.setTimeStamp(timestamp->getTimeStamp());
- return 0;
- }
-
- int ChainingTimeStampF1D::operator()(Interface1D& inter) {
- TimeStamp *timestamp = TimeStamp::instance();
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if(ve)
- ve->setChainingTimeStamp(timestamp->getTimeStamp());
- return 0;
- }
-
- int IncrementChainingTimeStampF1D::operator()(Interface1D& inter) {
- ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
- if(ve)
- ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1);
- return 0;
- }
-
- 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;
- }
-
- 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;
- }
-
- int GetOccludeeF1D::operator()(Interface1D& inter) {
- vector<ViewShape*> shapesVector;
- set<ViewShape*> shapesSet;
- ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve){
- ViewShape * aShape = ve->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){
- ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
- if (ve){
- ViewShape * aShape = ve->aShape();
- if(aShape == 0){
- oShapes.insert(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){
- 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){
- 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));
- }
- }
+ result = ve->qi();
+ return 0;
+ }
+ result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
+ return 0;
+}
+
+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;
+}
+
+int TimeStampF1D::operator()(Interface1D& inter)
+{
+ TimeStamp *timestamp = TimeStamp::instance();
+ inter.setTimeStamp(timestamp->getTimeStamp());
+ return 0;
+}
+
+int ChainingTimeStampF1D::operator()(Interface1D& inter)
+{
+ TimeStamp *timestamp = TimeStamp::instance();
+ ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
+ if (ve)
+ ve->setChainingTimeStamp(timestamp->getTimeStamp());
+ return 0;
+}
+
+int IncrementChainingTimeStampF1D::operator()(Interface1D& inter)
+{
+ ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
+ if (ve)
+ ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1);
+ return 0;
+}
+
+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;
+}
+
+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;
+}
+
+int GetOccludeeF1D::operator()(Interface1D& inter)
+{
+ vector<ViewShape*> shapesVector;
+ set<ViewShape*> shapesSet;
+ ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
+ if (ve) {
+ ViewShape *aShape = ve->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)
+{
+ ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
+ if (ve) {
+ ViewShape *aShape = ve->aShape();
+ if (aShape == 0) {
+ oShapes.insert(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)
+{
+ 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)
+{
+ 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
diff --git a/source/blender/freestyle/intern/view_map/Functions1D.h b/source/blender/freestyle/intern/view_map/Functions1D.h
index ba42b25b47e..f1885aa1762 100644
--- a/source/blender/freestyle/intern/view_map/Functions1D.h
+++ b/source/blender/freestyle/intern/view_map/Functions1D.h
@@ -1,41 +1,48 @@
-//
-// Filename : Functions1D.h
-// Author(s) : Stephane Grabli, Emmanuel Turquin
-// Purpose : Functions taking 1D input
-// Date of creation : 01/07/2003
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_FUNCTIONS_1D_H__
+#define __FREESTYLE_FUNCTIONS_1D_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/view_map/Functions1D.h
+ * \ingroup freestyle
+ * \brief Functions taking 1D input
+ * \author Stephane Grabli
+ * \author Emmanuel Turquin
+ * \date 01/07/2003
+ */
-#ifndef FUNCTIONS1D_HPP
-# define FUNCTIONS1D_HPP
+#include "Functions0D.h"
+#include "Interface1D.h"
+#include "ViewMap.h"
-# include "ViewMap.h"
-# include "Functions0D.h"
-# include "Interface1D.h"
-# include "../system/Precision.h"
-# include "../system/TimeStamp.h"
-# include "../system/FreestyleConfig.h"
+#include "../system/FreestyleConfig.h"
+#include "../system/Precision.h"
+#include "../system/TimeStamp.h"
#include "../python/Director.h"
@@ -44,14 +51,10 @@
//
///////////////////////////////////////////////////////////
-/*! Base class for Unary Functions (functors) working
- * on Interface1D.
- * A unary function will be used by calling
- * its operator() on an Interface1D.
- * \attention In the scripting language, there exists
- * several prototypes depending on the returned value type.
- * For example, you would inherit from a UnaryFunction1DDouble
- * if you wish to define a function that returns a double.
+/*! Base class for Unary Functions (functors) working on Interface1D.
+ * A unary function will be used by calling its operator() on an Interface1D.
+ * \attention In the scripting language, there exists several prototypes depending on the returned value type.
+ * For example, you would inherit from a UnaryFunction1DDouble if you wish to define a function that returns a double.
* The different existing prototypes are:
* - UnaryFunction1DVoid
* - UnaryFunction1DUnsigned
@@ -65,81 +68,104 @@ template <class T>
class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction1D
{
public:
-
T result;
PyObject *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.
- */
- 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;
- }
+ /*! The type of the value returned by the functor. */
+ typedef T ReturnedValueType;
-protected:
+ /*! 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.
+ */
+ 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;
+ }
- IntegrationType _integration;
+protected:
+ IntegrationType _integration;
};
class UnaryFunction1D_void
{
public:
-
PyObject *py_uf1D;
- UnaryFunction1D_void(){_integration = MEAN;}
- UnaryFunction1D_void(IntegrationType iType){_integration = iType;}
+ UnaryFunction1D_void()
+ {
+ _integration = MEAN;
+ }
+
+ UnaryFunction1D_void(IntegrationType iType)
+ {
+ _integration = iType;
+ }
+
virtual ~UnaryFunction1D_void() {}
-
- virtual string getName() const {
+
+ virtual string getName() const
+ {
return "UnaryFunction1D_void";
}
-
- int operator()(Interface1D& inter) {
- return Director_BPy_UnaryFunction1D___call__( this, py_uf1D, inter );
+
+ int operator()(Interface1D& inter)
+ {
+ return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
+ }
+
+ void setIntegrationType(IntegrationType integration)
+ {
+ _integration = integration;
+ }
+
+ IntegrationType getIntegrationType() const
+ {
+ return _integration;
}
-
- void setIntegrationType(IntegrationType integration) { _integration = integration; }
- IntegrationType getIntegrationType() const { return _integration; }
-
- protected:
- IntegrationType _integration;
+
+protected:
+ IntegrationType _integration;
};
@@ -150,406 +176,452 @@ public:
namespace Functions1D {
- // GetXF1D
- /*! Returns the X 3D coordinate of an Interface1D. */
- class LIB_VIEW_MAP_EXPORT GetXF1D : public UnaryFunction1D<real>
- {
- 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<real>(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 LIB_VIEW_MAP_EXPORT GetYF1D : public UnaryFunction1D<real>
- {
- 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<real>(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 LIB_VIEW_MAP_EXPORT GetZF1D : public UnaryFunction1D<real>
- {
- 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<real>(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 LIB_VIEW_MAP_EXPORT GetProjectedXF1D : public UnaryFunction1D<real>
- {
- 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<real>(iType){}
- public:
- /*! 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 LIB_VIEW_MAP_EXPORT GetProjectedYF1D : public UnaryFunction1D<real>
- {
- 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<real>(iType){}
- public:
- /*! 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 LIB_VIEW_MAP_EXPORT GetProjectedZF1D : public UnaryFunction1D<real>
- {
- 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<real>(iType){}
- public:
- /*! Returns the string "GetProjectedZF1D"*/
- string getName() const {
- return "GetProjectedZF1D";
- }
- /*! the () operator.*/
- int operator()(Interface1D& inter);
- };
-
- // Orientation2DF1D
- /*! Returns the 2D orientation as a Vec2f*/
- class LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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
- /*! Returns a real giving the distance between
- * and Interface1D and the shape that lies behind (occludee).
- * This distance is evaluated in the camera space and normalized
- * between 0 and 1. Therefore, if no oject is occluded by the
- * shape to which the Interface1D belongs to, 1 is returned.
- */
- class LIB_VIEW_MAP_EXPORT ZDiscontinuityF1D : public UnaryFunction1D<real>
- {
- 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<real>(iType){}
- /*! Returns the string "ZDiscontinuityF1D"*/
- string getName() const {
- return "ZDiscontinuityF1D";
- }
- /*! the () operator.*/
- int operator()(Interface1D& inter);
- };
-
- // QuantitativeInvisibilityF1D
- /*! Returns the Quantitative Invisibility of an Interface1D element.
- * If the Interface1D is a ViewEdge, then there is no ambiguity
- * concerning the result. But, if the Interface1D results of a chaining
- * (chain, stroke), then it might be made of several 1D elements
- * of different Quantitative Invisibilities.
- */
- class LIB_VIEW_MAP_EXPORT 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
+// GetXF1D
+/*! Returns the X 3D coordinate of an Interface1D. */
+class LIB_VIEW_MAP_EXPORT GetXF1D : public UnaryFunction1D<real>
+{
+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<real>(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 LIB_VIEW_MAP_EXPORT GetYF1D : public UnaryFunction1D<real>
+{
+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<real>(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 LIB_VIEW_MAP_EXPORT GetZF1D : public UnaryFunction1D<real>
+{
+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<real>(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 LIB_VIEW_MAP_EXPORT GetProjectedXF1D : public UnaryFunction1D<real>
+{
+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<real>(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 LIB_VIEW_MAP_EXPORT GetProjectedYF1D : public UnaryFunction1D<real>
+{
+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<real>(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 LIB_VIEW_MAP_EXPORT GetProjectedZF1D : public UnaryFunction1D<real>
+{
+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<real>(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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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
+/*! Returns a real giving the distance between and Interface1D and the shape that lies behind (occludee).
+ * This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no oject is occluded
+ * by the shape to which the Interface1D belongs to, 1 is returned.
+ */
+class LIB_VIEW_MAP_EXPORT ZDiscontinuityF1D : public UnaryFunction1D<real>
+{
+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<real>(iType) {}
+
+ /*! Returns the string "ZDiscontinuityF1D" */
+ string getName() const
+ {
+ return "ZDiscontinuityF1D";
+ }
+
+ /*! the () operator. */
+ int operator()(Interface1D& inter);
+};
+
+// QuantitativeInvisibilityF1D
+/*! Returns the Quantitative Invisibility of an Interface1D element.
+ * If the Interface1D is a ViewEdge, then there is no ambiguity concerning the result. But, if the Interface1D
+ * results of a chaining (chain, stroke), then it might be made of several 1D elements of different
+ * Quantitative Invisibilities.
+ */
+class LIB_VIEW_MAP_EXPORT 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
/*! Returns the nature of the Interface1D (silhouette, ridge, crease...).
* Except if the Interface1D is a ViewEdge, this result might be ambiguous.
- * 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.
+ * 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 LIB_VIEW_MAP_EXPORT 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
+class LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT TimeStampF1D : public UnaryFunction1D_void
- {
- public:
- /*! Returns the string "TimeStampF1D"*/
- string getName() const {
- return "TimeStampF1D";
- }
- /*! the () operator.*/
- int operator()(Interface1D& inter);
- };
-
- // IncrementChainingTimeStampF1D
+class LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT IncrementChainingTimeStampF1D : public UnaryFunction1D_void
- {
- public:
- /*! Returns the string "IncrementChainingTimeStampF1D"*/
- string getName() const {
- return "IncrementChainingTimeStampF1D";
- }
- /*! the () operator.*/
- int operator()(Interface1D& inter);
- };
-
- // ChainingTimeStampF1D
+class LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT ChainingTimeStampF1D : public UnaryFunction1D_void
- {
- public:
- /*! Returns the string "ChainingTimeStampF1D"*/
- string getName() const {
- return "ChainingTimeStampF1D";
- }
- /*! the () operator.*/
- int operator()(Interface1D& inter);
- };
-
-
- // Curvature2DAngleF1D
+class LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT Curvature2DAngleF1D : public UnaryFunction1D<real>
- {
- 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<real>(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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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
- LIB_VIEW_MAP_EXPORT
- void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
-
- // getOccludersF1D
- LIB_VIEW_MAP_EXPORT
- void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes);
-
- // getShapeF1D
- LIB_VIEW_MAP_EXPORT
- void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
-
+class LIB_VIEW_MAP_EXPORT Curvature2DAngleF1D : public UnaryFunction1D<real>
+{
+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<real>(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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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 LIB_VIEW_MAP_EXPORT 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
+LIB_VIEW_MAP_EXPORT
+void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
+
+// getOccludersF1D
+LIB_VIEW_MAP_EXPORT
+void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes);
+
+// getShapeF1D
+LIB_VIEW_MAP_EXPORT
+void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
+
} // end of namespace Functions1D
-#endif // FUNCTIONS1D_HPP
+#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 078fc5f2c98..cc711fedece 100644
--- a/source/blender/freestyle/intern/view_map/GridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/GridDensityProvider.h
@@ -1,93 +1,108 @@
-//
-// Filename : GridDensityProvider.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-2-5
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef GRIDDENSITYPROVIDER_H
-#define GRIDDENSITYPROVIDER_H
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_GRID_DENSITY_PROVIDER_H__
+#define __FREESTYLE_GRID_DENSITY_PROVIDER_H__
+
+/** \file blender/freestyle/intern/view_map/GridDensityProvider.h
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-2-5
+ */
#include <stdexcept>
#include <memory>
+
#include "OccluderSource.h"
+
#include "../geometry/BBox.h"
-class GridDensityProvider {
+class GridDensityProvider
+{
// Disallow copying and assignment
- GridDensityProvider (const GridDensityProvider& other);
- GridDensityProvider& operator= (const GridDensityProvider& other);
+ GridDensityProvider(const GridDensityProvider& other);
+ GridDensityProvider& operator=(const GridDensityProvider& other);
public:
- GridDensityProvider (OccluderSource& source)
- : source(source) {
- }
+ GridDensityProvider(OccluderSource& source) : source(source) {}
virtual ~GridDensityProvider() {};
- float cellSize() {
+ float cellSize()
+ {
return _cellSize;
}
- unsigned cellsX() {
+ unsigned cellsX()
+ {
return _cellsX;
}
- unsigned cellsY() {
+ unsigned cellsY()
+ {
return _cellsY;
}
- float cellOrigin(int index) {
- if ( index < 2 ) {
+ float cellOrigin(int index)
+ {
+ if (index < 2) {
return _cellOrigin[index];
- } else {
+ }
+ else {
throw new out_of_range("GridDensityProvider::cellOrigin can take only indexes of 0 or 1.");
}
}
- static void calculateOptimalProscenium(OccluderSource& source, real proscenium[4]) {
+ static void calculateOptimalProscenium(OccluderSource& source, real proscenium[4])
+ {
source.begin();
- if ( source.isValid() ) {
+ 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() ) {
+ while (source.isValid()) {
GridHelpers::expandProscenium (proscenium, source.getGridSpacePolygon());
source.next();
}
}
- cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << ")" << endl;
+ 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]) {
+ static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox,
+ real proscenium[4])
+ {
real z;
// We want to use the z-coordinate closest to the camera to determine the proscenium face
- if ( ::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2]) ) {
+ if (::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2])) {
z = bbox.getMin()[2];
- } else {
+ }
+ else {
z = bbox.getMax()[2];
}
// Now calculate the proscenium according to the min and max values of the x and y coordinates
@@ -98,7 +113,8 @@ public:
proscenium[1] = std::max(minPoint[0], maxPoint[0]);
proscenium[2] = std::min(minPoint[1], maxPoint[1]);
proscenium[3] = std::max(minPoint[1], maxPoint[1]);
- cout << "Proscenium : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << endl;
+ cout << "Proscenium : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", "
+ << proscenium[3] << endl;
}
protected:
@@ -108,24 +124,23 @@ protected:
float _cellOrigin[2];
};
-class GridDensityProviderFactory {
+class GridDensityProviderFactory
+{
// Disallow copying and assignment
GridDensityProviderFactory (const GridDensityProviderFactory& other);
GridDensityProviderFactory& operator= (const GridDensityProviderFactory& other);
public:
- GridDensityProviderFactory()
- {
- }
+ GridDensityProviderFactory() {}
- virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) =0;
+ virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) = 0;
- virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform) =0;
+ virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform) = 0;
- virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) =0;
+ virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) = 0;
virtual ~GridDensityProviderFactory () {}
};
-#endif // GRIDDENSITYPROVIDER_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 05b70af90b3..5e17c85808b 100644
--- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
+++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
@@ -1,74 +1,84 @@
-//
-// Filename : HeuristicGridDensityProviderFactory.cpp
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-2-8
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-2-8
+ */
#include "HeuristicGridDensityProviderFactory.h"
HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces)
- : sizeFactor(sizeFactor), numFaces(numFaces)
+: sizeFactor(sizeFactor), numFaces(numFaces)
{
}
-HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory () {}
+HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory() {}
-auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
+auto_ptr<GridDensityProvider>
+HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
- if ( avg->cellSize() > p23->cellSize() ) {
+ if (avg->cellSize() > p23->cellSize()) {
return (auto_ptr<GridDensityProvider>) p23;
- } else {
+ }
+ else {
return (auto_ptr<GridDensityProvider>) avg;
}
}
-auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
+auto_ptr<GridDensityProvider>
+HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform)
{
- auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
+ auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox,
+ transform, sizeFactor));
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
- if ( avg->cellSize() > p23->cellSize() ) {
+ if (avg->cellSize() > p23->cellSize()) {
return (auto_ptr<GridDensityProvider>) p23;
- } else {
+ }
+ else {
return (auto_ptr<GridDensityProvider>) avg;
}
}
-auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{
real proscenium[4];
GridDensityProvider::calculateOptimalProscenium(source, proscenium);
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
- if ( avg->cellSize() > p23->cellSize() ) {
+ if (avg->cellSize() > p23->cellSize()) {
return (auto_ptr<GridDensityProvider>) p23;
- } else {
+ }
+ else {
return (auto_ptr<GridDensityProvider>) avg;
}
}
-
diff --git a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
index d32c4ae4407..a7557f04565 100644
--- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
+++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
@@ -1,48 +1,55 @@
-//
-// Filename : HeuristicGridDensityProviderFactory.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-2-8
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef HEURISTICGRIDDENSITYPROVIDERFACTORY_H
-#define HEURISTICGRIDDENSITYPROVIDERFACTORY_H
-
-// #include <memory> // provided by GridDensityProvider.h
-// #include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
-#include "Pow23GridDensityProvider.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
+#define __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
+
+/** \file blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-2-8
+ */
+
+//#include <memory> // provided by GridDensityProvider.h
+
#include "AverageAreaGridDensityProvider.h"
+//#include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
+#include "Pow23GridDensityProvider.h"
-class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory {
+class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory
+{
public:
HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
- ~HeuristicGridDensityProviderFactory ();
+ ~HeuristicGridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
+ auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
@@ -50,5 +57,4 @@ protected:
unsigned numFaces;
};
-#endif // HEURISTICGRIDDENSITYPROVIDERFACTORY_H
-
+#endif // __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
diff --git a/source/blender/freestyle/intern/view_map/Interface0D.h b/source/blender/freestyle/intern/view_map/Interface0D.h
index 48d956eec19..bbf93deadb7 100644
--- a/source/blender/freestyle/intern/view_map/Interface0D.h
+++ b/source/blender/freestyle/intern/view_map/Interface0D.h
@@ -1,45 +1,53 @@
-//
-// Filename : Interface0D.h
-// Author(s) : Emmanuel Turquin
-// Purpose : Interface to 0D elts
-// Date of creation : 01/07/2003
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_INTERFACE_0D_H__
+#define __FREESTYLE_INTERFACE_0D_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef INTERFACE0D_H
-# define INTERFACE0D_H
-
-# include <Python.h>
-# include <string>
-# include <iostream>
-# include "../system/Id.h"
-# include "../system/Precision.h"
-# include "../winged_edge/Nature.h"
-# include "../geometry/Geom.h"
-using namespace std;
+/** \file blender/freestyle/intern/view_map/Interface0D.h
+ * \ingroup freestyle
+ * \brief Interface to 0D elts
+ * \author Emmanuel Turquin
+ * \date 01/07/2003
+ */
+
+#include <iostream>
+#include <Python.h>
+#include <string>
+
+#include "../geometry/Geom.h"
+#include "../system/Id.h"
#include "../system/Iterator.h" //soc
+#include "../system/Precision.h"
+
+#include "../winged_edge/Nature.h"
+
+using namespace std;
//
// Interface0D
@@ -51,114 +59,128 @@ class SVertex;
class ViewVertex;
class NonTVertex;
class TVertex;
+
/*! Base class for any 0D element. */
class Interface0D
{
public:
-
- /*! Default constructor */
- Interface0D() {}
- virtual ~Interface0D() {}; //soc
-
- /*! Returns the string "Interface0D".*/
- virtual string getExactTypeName() const {
- return "Interface0D";
- }
-
- // Data access methods
-
- /*! Returns the 3D x coordinate of the point. */
- virtual real getX() const {
- PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
- return 0;
- }
-
- /*! Returns the 3D y coordinate of the point. */
- virtual real getY() const {
- PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
- return 0;
- }
-
- /*! Returns the 3D z coordinate of the point. */
- virtual real getZ() const {
- PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
- return 0;
- }
-
- /*! Returns the 3D point. */
- virtual Geometry::Vec3f getPoint3D() const {
- PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
- return 0;
- }
-
- /*! Returns the 2D x coordinate of the point. */
- virtual real getProjectedX() const {
- PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
- return 0;
- }
-
- /*! Returns the 2D y coordinate of the point. */
- virtual real getProjectedY() const {
- PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
- return 0;
- }
-
- /*! Returns the 2D z coordinate of the point. */
- virtual real getProjectedZ() const {
- PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
- return 0;
- }
-
- /*! Returns the 2D point. */
- virtual Geometry::Vec2f getPoint2D() const {
- PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
- return 0;
- }
-
- /*! Returns the FEdge that lies between this Interface0D and the
- * Interface0D given as argument. */
- virtual FEdge* getFEdge(Interface0D&) {
- PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
- return 0;
- }
-
- /*! Returns the Id of the point. */
- virtual Id getId() const {
- PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
- return 0;
- }
-
- /*! Returns the nature of the point. */
- virtual Nature::VertexNature getNature() const {
- PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
- return Nature::POINT;
- }
-
-
- /*! Cast the Interface0D in SVertex if it can be. */
- virtual SVertex * castToSVertex(){
- PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
- return 0;
- }
-
- /*! Cast the Interface0D in ViewVertex if it can be. */
- virtual ViewVertex * castToViewVertex(){
- PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
- return 0;
- }
-
- /*! Cast the Interface0D in NonTVertex if it can be. */
- virtual NonTVertex * castToNonTVertex(){
- PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
- return 0;
- }
-
- /*! Cast the Interface0D in TVertex if it can be. */
- virtual TVertex * castToTVertex(){
- PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
- return 0;
- }
-
+ /*! Default constructor */
+ Interface0D() {}
+ virtual ~Interface0D() {}; //soc
+
+ /*! Returns the string "Interface0D". */
+ virtual string getExactTypeName() const
+ {
+ return "Interface0D";
+ }
+
+ // Data access methods
+
+ /*! Returns the 3D x coordinate of the point. */
+ virtual real getX() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the 3D y coordinate of the point. */
+ virtual real getY() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the 3D z coordinate of the point. */
+ virtual real getZ() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the 3D point. */
+ virtual Geometry::Vec3f getPoint3D() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the 2D x coordinate of the point. */
+ virtual real getProjectedX() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the 2D y coordinate of the point. */
+ virtual real getProjectedY() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the 2D z coordinate of the point. */
+ virtual real getProjectedZ() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the 2D point. */
+ virtual Geometry::Vec2f getPoint2D() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */
+ virtual FEdge* getFEdge(Interface0D&)
+ {
+ PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the Id of the point. */
+ virtual Id getId() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the nature of the point. */
+ virtual Nature::VertexNature getNature() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
+ return Nature::POINT;
+ }
+
+
+ /*! Cast the Interface0D in SVertex if it can be. */
+ virtual SVertex *castToSVertex()
+ {
+ PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
+ return 0;
+ }
+
+ /*! Cast the Interface0D in ViewVertex if it can be. */
+ virtual ViewVertex * castToViewVertex()
+ {
+ PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
+ return 0;
+ }
+
+ /*! Cast the Interface0D in NonTVertex if it can be. */
+ virtual NonTVertex *castToNonTVertex()
+ {
+ PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
+ return 0;
+ }
+
+ /*! Cast the Interface0D in TVertex if it can be. */
+ virtual TVertex *castToTVertex()
+ {
+ PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
+ return 0;
+ }
};
@@ -170,39 +192,42 @@ public:
class Interface0DIteratorNested : public Iterator
{
public:
+ virtual ~Interface0DIteratorNested() {}
- 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;
};
@@ -212,149 +237,154 @@ public:
//////////////////////////////////////////////////
/*! Class defining an iterator over Interface0D elements.
- * An instance of this iterator is always obtained
- * from a 1D element.
- * \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.
+ * An instance of this iterator is always obtained from a 1D element.
+ * \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.
*/
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();
+ }
+
+ /*! 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();
+ }
- 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();
- }
-
- /*! 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;
+ Interface0DIteratorNested *_iterator;
};
-#endif // INTERFACE0D_H
+#endif // __FREESTYLE_INTERFACE_0D_H__
diff --git a/source/blender/freestyle/intern/view_map/Interface1D.h b/source/blender/freestyle/intern/view_map/Interface1D.h
index 60cc0ebcb7e..440c6f275b8 100644
--- a/source/blender/freestyle/intern/view_map/Interface1D.h
+++ b/source/blender/freestyle/intern/view_map/Interface1D.h
@@ -1,125 +1,126 @@
-//
-// Filename : Interface1D.h
-// Author(s) : Emmanuel Turquin
-// Purpose : Interface to 1D elts
-// Date of creation : 01/07/2003
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_INTERFACE_1D_H__
+#define __FREESTYLE_INTERFACE_1D_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/view_map/Interface1D.h
+ * \ingroup freestyle
+ * \brief Interface 1D and related tools definitions
+ * \author Emmanuel Turquin
+ * \date 01/07/2003
+ */
+
+#include <float.h>
+#include <iostream>
+#include <Python.h>
+#include <string>
-#ifndef INTERFACE1D_H
-# define INTERFACE1D_H
+#include "Functions0D.h"
-# include <Python.h>
-# include <string>
-# include <iostream>
-# include <float.h>
-# include "../system/Id.h"
-# include "../system/Precision.h"
-# include "../winged_edge/Nature.h"
-# include "Functions0D.h"
+#include "../system/Id.h"
+#include "../system/Precision.h"
+
+#include "../winged_edge/Nature.h"
using namespace std;
-/*! \file Interface1D.h
- * Interface1D and related tools definitions
- */
+
// Integration method
-/*! The different integration
- * methods that can be invoked
- * to integrate into a single value the set of values obtained
+/*! The different integration methods that can be invoked to integrate into a single value the set of values obtained
* 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.
+/*! Returns a single value from a set of values evaluated at each 0D element of this 1D element.
* \param fun
* The UnaryFunction0D used to compute a value at each Interface0D.
* \param it
- * The Interface0DIterator used to iterate over the 0D elements of
- * this 1D element. The integration will occur over the 0D elements
- * starting from the one pointed by it.
+ * The Interface0DIterator used to iterate over the 0D elements of this 1D element. The integration will occur
+ * over the 0D elements starting from the one pointed by it.
* \param it_end
- * The Interface0DIterator pointing the end of the 0D elements of the
- * 1D element.
+ * The Interface0DIterator pointing the end of the 0D elements of the 1D element.
* \param integration_type
- * The integration method used to compute a single value from
- * a set of values.
+ * 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,
- 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;
+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;
}
- res /= (size ? size : 1);
- break;
- }
- return res;
+ return res;
}
//
@@ -131,96 +132,99 @@ T integrate(UnaryFunction0D<T>& fun,
class Interface1D
{
public:
+ /*! Default constructor */
+ Interface1D()
+ {
+ _timeStamp = 0;
+ }
+
+ virtual ~Interface1D() {}; //soc
+
+ /*! Returns the string "Interface1D". */
+ virtual string getExactTypeName() const
+ {
+ return "Interface1D";
+ }
+
+ // Iterator access
- /*! Default constructor */
- Interface1D() {_timeStamp=0;}
- virtual ~Interface1D() {}; //soc
-
- /*! 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() {
- PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
- return Interface0DIterator();
- }
-
- /*! Returns an iterator over the Interface1D vertices,
- * pointing after the last vertex.
- */
- virtual Interface0DIterator verticesEnd(){
- PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
- return Interface0DIterator();
- }
-
- /*! 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.f) {
- PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
- return Interface0DIterator();
- }
-
- /*! 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.f) {
- PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
- return Interface0DIterator();
- }
-
- // Data access methods
-
- /*! Returns the 2D length of the 1D element. */
- virtual real getLength2D() const {
- PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
- return 0;
- }
-
- /*! Returns the Id of the 1D element .*/
- virtual Id getId() const {
- PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
- return Id(0, 0);
- }
-
-
- // 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 {
- PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
- return Nature::NO_FEATURE;
- }
-
- /*! 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;
- }
+ /*! Returns an iterator over the Interface1D vertices, pointing to the first vertex. */
+ virtual Interface0DIterator verticesBegin()
+ {
+ PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
+ return Interface0DIterator();
+ }
+
+ /*! Returns an iterator over the Interface1D vertices, pointing after the last vertex. */
+ virtual Interface0DIterator verticesEnd()
+ {
+ PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
+ return Interface0DIterator();
+ }
+
+ /*! 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)
+ {
+ PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
+ return Interface0DIterator();
+ }
+
+ /*! 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)
+ {
+ PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
+ return Interface0DIterator();
+ }
+
+ // Data access methods
+
+ /*! Returns the 2D length of the 1D element. */
+ virtual real getLength2D() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
+ return 0;
+ }
+
+ /*! Returns the Id of the 1D element. */
+ virtual Id getId() const
+ {
+ PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
+ return Id(0, 0);
+ }
+
+
+ // 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
+ {
+ PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
+ return Nature::NO_FEATURE;
+ }
+
+ /*! 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;
+ unsigned _timeStamp;
};
-#endif // INTERFACE1D_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 356e281be4b..5af618dd6f6 100644
--- a/source/blender/freestyle/intern/view_map/OccluderSource.cpp
+++ b/source/blender/freestyle/intern/view_map/OccluderSource.cpp
@@ -1,65 +1,73 @@
-//
-// Filename : OccluderSource.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2010-12-21
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/OccluderSource.cpp
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2010-12-21
+ */
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+#include <algorithm>
#include "OccluderSource.h"
-#include <algorithm>
-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();
}
-OccluderSource::~OccluderSource() {
-}
+OccluderSource::~OccluderSource() {}
-void OccluderSource::buildCachedPolygon() {
+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 ) {
+ 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();
+void OccluderSource::begin()
+{
+ vector<WShape*>& wshapes = wingedEdge.getWShapes();
currentShape = wshapes.begin();
shapesEnd = wshapes.end();
valid = false;
- if ( currentShape != shapesEnd ) {
+ if (currentShape != shapesEnd) {
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
currentFace = wFaces.begin();
facesEnd = wFaces.end();
- if ( currentFace != facesEnd ) {
+ if (currentFace != facesEnd) {
buildCachedPolygon();
valid = true;
}
@@ -67,14 +75,15 @@ void OccluderSource::begin() {
}
bool OccluderSource::next() {
- if ( valid ) {
+ if (valid) {
++currentFace;
- while ( currentFace == facesEnd ) {
+ while (currentFace == facesEnd) {
++currentShape;
- if ( currentShape == shapesEnd ) {
+ if (currentShape == shapesEnd) {
valid = false;
return false;
- } else {
+ }
+ else {
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
currentFace = wFaces.begin();
facesEnd = wFaces.end();
@@ -86,40 +95,47 @@ bool OccluderSource::next() {
return false;
}
-bool OccluderSource::isValid() {
+bool OccluderSource::isValid()
+{
// Or:
// return currentShapes != shapesEnd && currentFace != facesEnd;
return valid;
}
-WFace* OccluderSource::getWFace() {
+WFace *OccluderSource::getWFace()
+{
return valid ? *currentFace : NULL;
}
-Polygon3r OccluderSource::getCameraSpacePolygon() {
+Polygon3r OccluderSource::getCameraSpacePolygon()
+{
return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()), (*currentFace)->GetNormal());
}
-Polygon3r& OccluderSource::getGridSpacePolygon() {
+Polygon3r& OccluderSource::getGridSpacePolygon()
+{
return cachedPolygon;
}
-void OccluderSource::getOccluderProscenium(real proscenium[4]) {
+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() ) {
+ while (isValid()) {
GridHelpers::expandProscenium (proscenium, cachedPolygon);
next();
}
- cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << ")" << endl;
+ cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", "
+ << proscenium[3] << ")" << endl;
}
-real OccluderSource::averageOccluderArea() {
+real OccluderSource::averageOccluderArea()
+{
real area = 0.0;
unsigned numFaces = 0;
- for ( begin(); isValid(); next() ) {
+ for (begin(); isValid(); next()) {
Vec3r min, max;
cachedPolygon.getBBox(min, max);
area += (max[0] - min[0]) * (max[1] - min[1]);
@@ -128,5 +144,3 @@ real OccluderSource::averageOccluderArea() {
area /= numFaces;
return area;
}
-
-
diff --git a/source/blender/freestyle/intern/view_map/OccluderSource.h b/source/blender/freestyle/intern/view_map/OccluderSource.h
index d623cc63fed..14f8f54fa1a 100644
--- a/source/blender/freestyle/intern/view_map/OccluderSource.h
+++ b/source/blender/freestyle/intern/view_map/OccluderSource.h
@@ -1,53 +1,59 @@
-//
-// Filename : OccluderSource.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2010-12-21
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_OCCLUDER_SOURCE_H__
+#define __FREESTYLE_OCCLUDER_SOURCE_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/view_map/OccluderSource.h
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2010-12-21
+ */
-#ifndef OCCLUDERSOURCE_H
-#define OCCLUDERSOURCE_H
+#include "../geometry/GridHelpers.h"
#include "../winged_edge/WEdge.h"
-#include "../geometry/GridHelpers.h"
-class OccluderSource {
+class OccluderSource
+{
// Disallow copying and assignment
- OccluderSource (const OccluderSource& other);
- OccluderSource& operator= (const OccluderSource& other);
+ OccluderSource(const OccluderSource& other);
+ OccluderSource& operator=(const OccluderSource& other);
public:
- OccluderSource (const GridHelpers::Transform& transform, WingedEdge& we);
+ OccluderSource(const GridHelpers::Transform& transform, WingedEdge& we);
virtual ~OccluderSource();
void begin();
virtual bool next();
bool isValid();
- WFace* getWFace();
+ WFace *getWFace();
Polygon3r getCameraSpacePolygon();
Polygon3r& getGridSpacePolygon();
@@ -67,4 +73,4 @@ protected:
void buildCachedPolygon();
};
-#endif // OCCLUDERSOURCE_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 2e506da9ee9..1a15fc849a6 100644
--- a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
@@ -1,52 +1,57 @@
-//
-// Filename : Pow23GridDensityProvider.cpp
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-2-8
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-2-8
+ */
#include "Pow23GridDensityProvider.h"
-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);
}
-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);
-
+
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);
@@ -56,7 +61,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsig
Pow23GridDensityProvider::~Pow23GridDensityProvider () {}
-void Pow23GridDensityProvider::initialize (const real proscenium[4])
+void Pow23GridDensityProvider::initialize(const real proscenium[4])
{
float prosceniumWidth = (proscenium[1] - proscenium[0]);
float prosceniumHeight = (proscenium[3] - proscenium[2]);
@@ -71,10 +76,10 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
// Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1;
- if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
+ if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
}
- if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
+ if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
}
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
@@ -85,25 +90,26 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
}
Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFaces)
- : numFaces(numFaces)
+: numFaces(numFaces)
{
}
Pow23GridDensityProviderFactory::~Pow23GridDensityProviderFactory () {}
-auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
+auto_ptr<GridDensityProvider>
+Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, proscenium, numFaces));
}
-auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
+auto_ptr<GridDensityProvider>
+Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform)
{
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
}
-auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
}
-
-
diff --git a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
index c398a1643a4..0e26793cec7 100644
--- a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
@@ -1,67 +1,75 @@
-//
-// Filename : Pow23GridDensityProvider.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2011-2-8
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
+#define __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef POW23GRIDDENSITYPROVIDER_H
-#define POW23GRIDDENSITYPROVIDER_H
+/** \file blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2011-2-8
+ */
#include "GridDensityProvider.h"
-class Pow23GridDensityProvider : public GridDensityProvider {
+class Pow23GridDensityProvider : public GridDensityProvider
+{
// Disallow copying and assignment
- Pow23GridDensityProvider (const Pow23GridDensityProvider& other);
- Pow23GridDensityProvider& operator= (const Pow23GridDensityProvider& other);
+ 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, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform,
+ unsigned numFaces);
Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces);
- virtual ~Pow23GridDensityProvider ();
+ virtual ~Pow23GridDensityProvider();
protected:
unsigned numFaces;
private:
- void initialize (const real proscenium[4]);
+ void initialize(const real proscenium[4]);
};
-class Pow23GridDensityProviderFactory : public GridDensityProviderFactory {
+class Pow23GridDensityProviderFactory : public GridDensityProviderFactory
+{
public:
Pow23GridDensityProviderFactory(unsigned numFaces);
- ~Pow23GridDensityProviderFactory ();
+ ~Pow23GridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
+ auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
+
protected:
unsigned numFaces;
};
-#endif // POW23GRIDDENSITYPROVIDER_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 7a7d0a51d4b..104040fd2a5 100644
--- a/source/blender/freestyle/intern/view_map/Silhouette.cpp
+++ b/source/blender/freestyle/intern/view_map/Silhouette.cpp
@@ -1,370 +1,414 @@
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/Silhouette.cpp
+ * \ingroup freestyle
+ * \brief Classes to define a silhouette structure
+ * \author Stephane Grabli
+ * \date 25/03/2002
+ */
#include "Silhouette.h"
#include "ViewMap.h"
- /**********************************/
- /* */
- /* */
- /* SVertex */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* SVertex */
+/* */
+/* */
+/**********************************/
+
+Nature::VertexNature SVertex::getNature() const
+{
+ Nature::VertexNature nature = Nature::S_VERTEX;
+ if (_pViewVertex)
+ nature |= _pViewVertex->getNature();
+ return nature;
+}
+
+SVertex *SVertex::castToSVertex()
+{
+ return this;
+}
+
+ViewVertex *SVertex::castToViewVertex()
+{
+ return _pViewVertex;
+}
+
+NonTVertex *SVertex::castToNonTVertex()
+{
+ return dynamic_cast<NonTVertex*>(_pViewVertex);
+}
+
+TVertex *SVertex::castToTVertex()
+{
+ return dynamic_cast<TVertex*>(_pViewVertex);
+}
-Nature::VertexNature SVertex::getNature() const {
- Nature::VertexNature nature = Nature::S_VERTEX;
- if (_pViewVertex)
- nature |= _pViewVertex->getNature();
- return nature;
+float SVertex::shape_importance() const
+{
+ return shape()->importance();
}
-SVertex * SVertex::castToSVertex(){
- return this;
+#if 0
+Material SVertex::material() const
+{
+ return _Shape->material();
}
+#endif
-ViewVertex * SVertex::castToViewVertex(){
- return _pViewVertex;
+Id SVertex::shape_id() const
+{
+ return _Shape->getId();
}
-NonTVertex * SVertex::castToNonTVertex(){
- return dynamic_cast<NonTVertex*>(_pViewVertex);
+const SShape *SVertex::shape() const
+{
+ return _Shape;
}
-TVertex * SVertex::castToTVertex(){
- return dynamic_cast<TVertex*>(_pViewVertex);
+const int SVertex::qi() const
+{
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->qi();
}
-float SVertex::shape_importance() const
+occluder_container::const_iterator SVertex::occluders_begin() const
{
- return shape()->importance();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluders_begin();
}
-
-//Material SVertex::material() const {return _Shape->material();}
-Id SVertex::shape_id() const {return _Shape->getId();}
-const SShape * SVertex::shape() const {return _Shape;}
-const int SVertex::qi() const
+occluder_container::const_iterator SVertex::occluders_end() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->qi();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluders_end();
}
-occluder_container::const_iterator SVertex::occluders_begin() const
+bool SVertex::occluders_empty() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluders_begin();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluders_empty();
}
-occluder_container::const_iterator SVertex::occluders_end() const
+int SVertex::occluders_size() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluders_end();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluders_size();
}
-bool SVertex::occluders_empty() const
+const Polygon3r& SVertex::occludee() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluders_empty();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occludee();
}
-int SVertex::occluders_size() const
+const SShape *SVertex::occluded_shape() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluders_size();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occluded_shape();
}
-const Polygon3r& SVertex::occludee() const
+const bool SVertex::occludee_empty() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occludee();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->occludee_empty();
}
-const SShape* SVertex::occluded_shape() const
+real SVertex::z_discontinuity() const
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occluded_shape();
+ if (getNature() & Nature::T_VERTEX)
+ Exception::raiseException();
+ return (_FEdges[0])->z_discontinuity();
}
-const bool SVertex::occludee_empty() const
+FEdge *SVertex::fedge()
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->occludee_empty();
+ if (getNature() & Nature::T_VERTEX)
+ return NULL;
+ return _FEdges[0];
}
-real SVertex::z_discontinuity() const
+FEdge *SVertex::getFEdge(Interface0D& inter)
{
- if (getNature() & Nature::T_VERTEX)
- Exception::raiseException();
- return (_FEdges[0])->z_discontinuity();
+ 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;
}
-FEdge* SVertex::fedge()
+
+/**********************************/
+/* */
+/* */
+/* FEdge */
+/* */
+/* */
+/**********************************/
+
+
+int FEdge::viewedge_nature() const
{
- if (getNature() & Nature::T_VERTEX)
- return 0;
- return _FEdges[0];
+ return _ViewEdge->getNature();
}
-FEdge* SVertex::getFEdge(Interface0D& inter)
+#if 0
+float FEdge::viewedge_length() const
{
- FEdge * result = 0;
- 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;
-}
-
-
- /**********************************/
- /* */
- /* */
- /* FEdge */
- /* */
- /* */
- /**********************************/
-
-
-int FEdge::viewedge_nature() const {return _ViewEdge->getNature();}
-//float FEdge::viewedge_length() const {return _ViewEdge->viewedge_length();}
-const SShape* FEdge::occluded_shape() const
-{
- ViewShape * aShape = _ViewEdge->aShape();
- if(aShape == 0)
- return 0;
- return aShape->sshape();
-}
-
-float FEdge::shape_importance() const
-{
- return _VertexA->shape()->importance();
-}
-
-int FEdge::invisibility() const
-{
- return _ViewEdge->qi();
-}
-
-occluder_container::const_iterator FEdge::occluders_begin() const {return _ViewEdge->occluders_begin();}
-occluder_container::const_iterator FEdge::occluders_end() const {return _ViewEdge->occluders_end();}
-bool FEdge::occluders_empty() const {return _ViewEdge->occluders_empty();}
-int FEdge::occluders_size() const {return _ViewEdge->occluders_size();}
+ return _ViewEdge->viewedge_length();
+}
+#endif
+
+const SShape *FEdge::occluded_shape() const
+{
+ ViewShape *aShape = _ViewEdge->aShape();
+ if (aShape == 0)
+ return 0;
+ return aShape->sshape();
+}
+
+float FEdge::shape_importance() const
+{
+ return _VertexA->shape()->importance();
+}
+
+int FEdge::invisibility() const
+{
+ return _ViewEdge->qi();
+}
+
+occluder_container::const_iterator FEdge::occluders_begin() const
+{
+ return _ViewEdge->occluders_begin();
+}
+
+occluder_container::const_iterator FEdge::occluders_end() const
+{
+ return _ViewEdge->occluders_end();
+}
+
+bool FEdge::occluders_empty() const
+{
+ return _ViewEdge->occluders_empty();
+}
+
+int FEdge::occluders_size() const
+{
+ return _ViewEdge->occluders_size();
+}
+
const bool FEdge::occludee_empty() const
{
- return _ViewEdge->occludee_empty();
-}
-
-
-
-Id FEdge::shape_id() const
-{
- return _VertexA->shape()->getId();
-}
-const SShape* FEdge::shape() const
-{
- return _VertexA->shape();
-}
-
-real FEdge::z_discontinuity() const
-{
- if(!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER))
- {
- return 0;
- }
-
- 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;
-
- }
- // real result;
- // z_discontinuity_functor<SVertex> _functor;
-
- // Evaluate<SVertex,z_discontinuity_functor<SVertex> >(&_functor, iCombination, result )
- 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()));
-}
-
-
-//float FEdge::local_average_depth(int iCombination ) const
-//{
-//
-// float result;
-// local_average_depth_functor<SVertex> functor;
-// Evaluate(&functor, iCombination, result);
-//
-// return result;
-//}
-//float FEdge::local_depth_variance(int iCombination ) const
-//{
-// float result;
-//
-// local_depth_variance_functor<SVertex> functor;
-//
-// Evaluate(&functor, iCombination, result);
-//
-// return result;
-//}
-//
-//
-//real FEdge::local_average_density( float sigma, int iCombination) const
-//{
-// float result;
-//
-// density_functor<SVertex> functor(sigma);
-//
-// Evaluate(&functor, iCombination, 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 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;
-//}
-//
-//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;
-//}
-
- /**********************************/
- /* */
- /* */
- /* FEdgeSharp */
- /* */
- /* */
- /**********************************/
-
-//Material FEdge::material() const
-//{
-// return _VertexA->shape()->material();
-//}
-const FrsMaterial& FEdgeSharp::aFrsMaterial() const {
- return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
-}
-
-const FrsMaterial& FEdgeSharp::bFrsMaterial() const {
- return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
-}
-
- /**********************************/
- /* */
- /* */
- /* FEdgeSmooth */
- /* */
- /* */
- /**********************************/
-
-const FrsMaterial& FEdgeSmooth::frs_material() const {
- return _VertexA->shape()->frs_material(_FrsMaterialIndex);
+ return _ViewEdge->occludee_empty();
+}
+
+Id FEdge::shape_id() const
+{
+ return _VertexA->shape()->getId();
+}
+
+const SShape *FEdge::shape() const
+{
+ return _VertexA->shape();
+}
+
+real FEdge::z_discontinuity() const
+{
+ if (!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) {
+ return 0;
+ }
+
+ 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;
+ }
+
+#if 0
+ 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;
+
+ 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);
+
+ return result;
+}
+
+float FEdge::local_depth_variance(int iCombination ) const
+{
+ float result;
+
+ local_depth_variance_functor<SVertex> functor;
+
+ Evaluate(&functor, iCombination, result);
+
+ return result;
+}
+
+real FEdge::local_average_density( float sigma, int iCombination) const
+{
+ float result;
+
+ density_functor<SVertex> functor(sigma);
+
+ Evaluate(&functor, iCombination, 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 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;
+}
+
+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;
+}
+#endif
+
+/**********************************/
+/* */
+/* */
+/* FEdgeSharp */
+/* */
+/* */
+/**********************************/
+
+#if 0
+Material FEdge::material() const
+{
+ return _VertexA->shape()->material();
+}
+#endif
+
+const FrsMaterial& FEdgeSharp::aFrsMaterial() const
+{
+ return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
+}
+
+const FrsMaterial& FEdgeSharp::bFrsMaterial() const
+{
+ return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
+}
+
+/**********************************/
+/* */
+/* */
+/* FEdgeSmooth */
+/* */
+/* */
+/**********************************/
+
+const FrsMaterial& FEdgeSmooth::frs_material() const
+{
+ return _VertexA->shape()->frs_material(_FrsMaterialIndex);
}
diff --git a/source/blender/freestyle/intern/view_map/Silhouette.h b/source/blender/freestyle/intern/view_map/Silhouette.h
index 369267af8d9..2efe111add5 100644
--- a/source/blender/freestyle/intern/view_map/Silhouette.h
+++ b/source/blender/freestyle/intern/view_map/Silhouette.h
@@ -1,49 +1,59 @@
-//
-// Filename : Silhouette.h
-// Author(s) : Stephane Grabli
-// Purpose : Classes to define a silhouette structure
-// Date of creation : 25/03/2002
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_SILHOUETTE_H__
+#define __FREESTYLE_SILHOUETTE_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef SILHOUETTE_H
-# define SILHOUETTE_H
-
-# include "Interface0D.h"
-# include "Interface1D.h"
-# include <iostream>
-# include <string>
-# include <vector>
-# include <set>
-# include <float.h>
-# include "../system/FreestyleConfig.h"
-# include "../geometry/Geom.h"
-# include "../geometry/BBox.h"
-# include "../scene_graph/FrsMaterial.h"
-# include "../geometry/Polygon.h"
-# include "../system/Exception.h"
-# include "../winged_edge/Curvature.h"
+/** \file blender/freestyle/intern/view_map/Silhouette.h
+ * \ingroup freestyle
+ * \brief Classes to define a silhouette structure
+ * \author Stephane Grabli
+ * \date 25/03/2002
+ */
+
+#include <float.h>
+#include <iostream>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "Interface0D.h"
+#include "Interface1D.h"
+
+#include "../geometry/BBox.h"
+#include "../geometry/Geom.h"
+#include "../geometry/Polygon.h"
+
+#include "../scene_graph/FrsMaterial.h"
+
+#include "../system/Exception.h"
+#include "../system/FreestyleConfig.h"
+
+#include "../winged_edge/Curvature.h"
using namespace std;
using namespace Geometry;
@@ -51,13 +61,13 @@ using namespace Geometry;
class ViewShape;
typedef vector<ViewShape*> occluder_container;
- /**********************************/
- /* */
- /* */
- /* SVertex */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* SVertex */
+/* */
+/* */
+/**********************************/
class FEdge;
class ViewVertex;
@@ -67,574 +77,856 @@ class SShape;
class LIB_VIEW_MAP_EXPORT 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 Vec3f 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 Vec2f getPoint2D() const {
- return Vec2f((float)_Point2D.x(),(float)_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();
+ /*! 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 Vec3f 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 Vec2f getPoint2D() const
+ {
+ return Vec2f((float)_Point2D.x(), (float)_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;
+ 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.
- real _curvatureFredo;
- Vec2r _directionFredo;
- CurvatureInfo* _curvature_info;
+ 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.
+ real _curvatureFredo;
+ Vec2r _directionFredo;
+ 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;
- }
-
- /* 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;}
-
- /*! 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);}
- /* 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;
- }
- }
- }
+ /*! 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;
+ }
+
+ /* 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;
+ }
+
+ /*! 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);
+ }
+
+ /* 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 ;
- //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 ;
-
+ /* 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;
+#endif
};
- /**********************************/
- /* */
- /* */
- /* FEdge */
- /* */
- /* */
- /**********************************/
-
+/**********************************/
+/* */
+/* */
+/* FEdge */
+/* */
+/* */
+/**********************************/
class ViewEdge;
+
/*! Base Class for feature edges.
- * This FEdge can represent a silhouette, a crease,
- * a ridge/valley, a border or a suggestive contour.
- * For silhouettes, the FEdge is oriented
- * such as, the visible face lies on the left of the edge.
- * For borders, the FEdge is oriented
- * such as, the face lies on the left of the edge.
- * An FEdge can represent an initial edge of the mesh
- * or runs accross a face of the initial mesh depending
+ * This FEdge can represent a silhouette, a crease, a ridge/valley, a border or a suggestive contour.
+ * For silhouettes, the FEdge is oriented such as, the visible face lies on the left of the edge.
+ * For borders, the FEdge is oriented such as, the face lies on the left of the edge.
+ * An FEdge can represent an initial edge of the mesh or runs accross a face of the initial mesh depending
* on the smoothness or sharpness of the mesh.
- * This class is specialized into a smooth and a sharp
- * version since their properties slightly vary from
+ * This class is specialized into a smooth and a sharp version since their properties slightly vary from
* one to the other.
*/
class LIB_VIEW_MAP_EXPORT 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;
+ }
- /*! Returns the string "FEdge" . */
- virtual string getExactTypeName() const {
- return "FEdge";
- }
-
- // Data access methods
+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;
- /*! Returns the 2D length of the FEdge. */
- virtual real getLength2D() const {
- if (!_VertexA || !_VertexB)
- return 0;
- return (_VertexB->getPoint2D() - _VertexA->getPoint2D()).norm();
- }
+protected:
+ SVertex *_VertexA;
+ SVertex *_VertexB;
+ Id _Id;
+ Nature::EdgeNature _Nature;
+ //vector<Polygon3r> _Occluders; // visibility // NOT HANDLED BY THE COPY CONSTRUCTOR!!
- /*! Returns the Id of the FEdge. */
- virtual Id getId() const {
- return _Id;
- }
+ 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
-public:
+ Polygon3r _aFace; // The occluded face which lies on the right of a silhouette edge
+ Vec3r _occludeeIntersection;
+ bool _occludeeEmpty;
- // 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;
+ bool _isSmooth;
-protected:
- SVertex *_VertexA;
- SVertex *_VertexB;
- Id _Id;
- Nature::EdgeNature _Nature;
- //vector<Polygon3r> _Occluders; // visibility // NON GERE PAR LE 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 _isInImage;
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;
- }
- /*! 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;
- }
- /*! 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;
- 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();}
- //inline int invisibility() const {return _Occluders.size();}
- int invisibility() const ;
- //inline const vector<Polygon3r>& occluders() const {return _Occluders;}
- /*! 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 center2d() {return Vec3r((_VertexA->point2D()+_VertexB->point2D())/2.0);}
- // inline bool hasVisibilityPoint() const {return _hasVisibilityPoint;}
- // inline Vec3r visibilityPointA() const {return _VisibilityPointA;}
- // inline Vec3r visibilityPointB() const {return _VisibilityPointB;}
- 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; }
-
- /* 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 void AddOccluder(Polygon3r& iPolygon) {_Occluders.push_back(iPolygon);}
- /*! Sets the ViewEdge to which this FEdge belongs to. */
- inline void setViewEdge(ViewEdge *iViewEdge) {_ViewEdge = iViewEdge;}
- // 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 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; }
-
- /* 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 */
- /* 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 const bool occludee_empty() const {return _occludeeEmpty;}
- const bool occludee_empty() const ;
- real z_discontinuity() 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 {}
- int viewedge_nature() const ;
- //float viewedge_length() const ;
- inline Vec3r orientation2d() const {return Vec3r(_VertexB->point2d()-_VertexA->point2d());}
- inline Vec3r orientation3d() const {return Vec3r(_VertexB->point3d()-_VertexA->point3d());}
- // //inline real curvature2d() const {return viewedge()->curvature2d((_VertexA->point2d()+_VertexB->point2d())/2.0);}
- // inline Vec3r curvature2d_as_vector(int iCombination = 0) const ;
- // /* angle in degrees*/
- // inline real curvature2d_as_angle(int iCombination = 0) const ;
-
-
- // 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.f);
- /*! 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.f);
+ /*! 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;
+ }
+
+ /*! 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;
+ }
+
+ /*! 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;
+ 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();
+ }
+#endif
+
+ int invisibility() const;
+
+#if 0
+ 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;
+ }
+
+ inline Vec3r center3d()
+ {
+ return Vec3r((_VertexA->point3D() + _VertexB->point3D()) / 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;
+ }
+#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;
+ }
+
+ /* 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);
+ }
+#endif
+
+ /*! 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;
+ }
+#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;
+ }
+
+ /* 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;
+ }
+#endif
+
+ 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 {}
+#endif
+
+ int viewedge_nature() const;
+
+ //float viewedge_length() const;
+
+ inline Vec3r orientation2d() const
+ {
+ return Vec3r(_VertexB->point2d() - _VertexA->point2d());
+ }
+
+ 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 Vec3r curvature2d_as_vector(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);
};
//
@@ -644,828 +936,941 @@ 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;
- }
- return ((float)_edge->getLength2D());
- }
- virtual float u() const{
- if(_vertex == _edge->vertexA()){
- return 0;
- }
- return 1.0;
- }
- 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
// Iterator access (implementation)
-Interface0DIterator FEdge::verticesBegin() {
- Interface0DIterator ret(new FEdgeInternal::SVertexIterator(_VertexA, this));
- return ret;
+Interface0DIterator FEdge::verticesBegin()
+{
+ Interface0DIterator ret(new FEdgeInternal::SVertexIterator(_VertexA, this));
+ return ret;
}
-Interface0DIterator FEdge::verticesEnd() {
- Interface0DIterator ret(new FEdgeInternal::SVertexIterator(0, this));
- return ret;
+Interface0DIterator FEdge::verticesEnd()
+{
+ Interface0DIterator ret(new FEdgeInternal::SVertexIterator(0, this));
+ return ret;
}
-Interface0DIterator FEdge::pointsBegin(float t) {
- return verticesBegin();
+Interface0DIterator FEdge::pointsBegin(float t)
+{
+ return verticesBegin();
}
-Interface0DIterator FEdge::pointsEnd(float t) {
- return verticesEnd();
+Interface0DIterator FEdge::pointsEnd(float t)
+{
+ return verticesEnd();
}
-/*! Class defining a sharp FEdge. A Sharp FEdge
- * corresponds to an initial edge of the input mesh.
- * It can be a silhouette, a crease or a border.
- * If it is a crease edge, then it is borded
- * 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 defining a sharp FEdge. A Sharp FEdge corresponds to an initial edge of the input mesh.
+ * It can be a silhouette, a crease or a border. If it is a crease edge, then it is borded
+ * 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 LIB_VIEW_MAP_EXPORT 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;
-
+ 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;}
-
+ /*! 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 defining a smooth edge. This kind of edge typically
- * runs across a face of the input mesh. It can be
+/*! 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 LIB_VIEW_MAP_EXPORT FEdgeSmooth : public FEdge
{
protected:
- Vec3r _Normal;
- unsigned _FrsMaterialIndex;
- // bool _hasVisibilityPoint;
- // Vec3r _VisibilityPointA; // The edge on which the visibility will be computed represented
- // Vec3r _VisibilityPointB; // using its 2 extremity points A and B
- void * _Face; // In case of exact silhouette, Face is the WFace crossed by Fedge
- // NON GERE PAR LE COPY CONSTRUCTEUR
- bool _FaceMark;
+ 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
+#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=0;
- _FaceMark = false;
- _FrsMaterialIndex = 0;
- _isSmooth = true;
- }
- /*! Builds an FEdgeSmooth going from vA to vB. */
- inline FEdgeSmooth(SVertex *vA, SVertex *vB) : FEdge(vA, vB){
- _Face=0;
- _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;}
+ /*! 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;
+ }
};
- /**********************************/
- /* */
- /* */
- /* SShape */
- /* */
- /* */
- /**********************************/
-/*! Class to define a feature shape. It is the gathering
- * of feature elements from an identified input shape
- */
+/**********************************/
+/* */
+/* */
+/* SShape */
+/* */
+/* */
+/**********************************/
+
+
+/*! Class to define a feature shape. It is the gathering of feature elements from an identified input shape */
class LIB_VIEW_MAP_EXPORT 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;
- BBox<Vec3r> _BBox;
- vector<FrsMaterial> _FrsMaterials;
+ 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;
+ BBox<Vec3r> _BBox;
+ vector<FrsMaterial> _FrsMaterials;
- float _importance;
+ float _importance;
- ViewShape *_ViewShape;
+ 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 = 0;
-
- _importance = 0.f;
- _ViewShape = 0;
- }
- /*! Copy constructor */
- inline SShape(SShape& iBrother)
- {
- userdata = 0;
- _Id = iBrother._Id;
- _Name = iBrother._Name;
- _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());
- }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());
- }
- 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;
- if(x < XMin)
- XMin = x;
-
- // Y
- real y = vertex[1];
- if(y > YMax)
- YMax = y;
- if(y < YMin)
- YMin = y;
-
- // Z
- real z = vertex[2];
- if(z > ZMax)
- ZMax = z;
- 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;} // Get vertices list
- /*! Returns the list of FEdges of the Shape. */
- inline vector<FEdge*>& getEdgeList() {return _edgesList;} // Get edges list
- 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; }
-
- /* 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 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;}
+ /*! 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;
+ _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());
+ }
+ 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());
+ }
+ 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;
+ }
+
+ /* 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 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;
+ }
};
-#endif // 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 6327956ca80..06cbd85d863 100644
--- a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
+++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
@@ -1,163 +1,191 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
+ * \ingroup freestyle
+ * \brief Class to perform all geometric operations dedicated to silhouette. That, for example, implies that
+ * this geom engine has as member data the viewpoint, transformations, projections...
+ * \author Stephane Grabli
+ * \date 03/09/2002
+ */
#include "Silhouette.h"
#include "SilhouetteGeomEngine.h"
+
#include "../geometry/GeomUtils.h"
using namespace std;
-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}};
-real SilhouetteGeomEngine::_projectionMatrix[4][4] = {{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}};
-int SilhouetteGeomEngine::_viewport[4] = {1,1,1,1}; // the viewport
+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}
+};
+real SilhouetteGeomEngine::_projectionMatrix[4][4] = {
+ {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}
+};
+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}};
-real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {{1,0,0,0},
- {0,1,0,0},
- {0,0,1,0},
- {0,0,0,1}};
+
+real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {
+ {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}
+};
real SilhouetteGeomEngine::_znear = 0.0;
real SilhouetteGeomEngine::_zfar = 100.0;
-bool SilhouetteGeomEngine::_isOrthographicProjection = false;
+bool SilhouetteGeomEngine::_isOrthographicProjection = false;
-SilhouetteGeomEngine * SilhouetteGeomEngine::_pInstance = 0;
+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];
-
- for(i=0; i<4; i++){
- for(j=0; j<4; j++)
- {
- _modelViewMatrix[i][j] = iModelViewMatrix[j][i];
- _glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
- }
- }
+ 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++) {
+ _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++)
- {
- _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++){
- _viewport[i] = iViewport[i];
- }
- _Focal = iFocal;
+ for (i = 0; i < 4; i++) {
+ _viewport[i] = iViewport[i];
+ }
+ _Focal = iFocal;
_isOrthographicProjection = (iProjectionMatrix[3][3] != 0.0);
}
-void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
+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));
+void SilhouetteGeomEngine::retrieveViewport(int viewport[4])
+{
+ memcpy(viewport, _viewport, 4 * sizeof(int));
}
-//#define HUGE 1e9
+
+//#define HUGE 1.0e9
void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices)
{
- Vec3r newPoint;
- // real min=HUGE;
- // real max=-HUGE;
- vector<SVertex*>::iterator sv, svend;
- const real depth = _zfar - _znear;
- const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
-
- for(sv=ioVertices.begin(), svend=ioVertices.end();
- sv!=svend;
- sv++)
- {
- GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
- newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1
- (*sv)->setPoint2D(newPoint);
- //cerr << (*sv)->point2d().z() << " ";
- // real d=(*sv)->point2d()[2];
- // if (d>max) max =d;
- // if (d<min) min =d;
- }
- // for(sv=ioVertices.begin(), svend=ioVertices.end();
- // sv!=svend;
- // sv++)
- // {
- // Vec3r P((*sv)->point2d());
- // (*sv)->setPoint2D(Vec3r(P[0], P[1], 1.0-(P[2]-min)/(max-min)));
- // //cerr<<(*sv)->point2d()[2]<<" ";
- // }
+ Vec3r newPoint;
+#if 0
+ real min = HUGE;
+ real max = -HUGE;
+#endif
+ vector<SVertex*>::iterator sv, svend;
+ const real depth = _zfar - _znear;
+ const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
+
+ for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
+ GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
+ newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
+ (*sv)->setPoint2D(newPoint);
+#if 0
+ cerr << (*sv)->point2d().z() << " ";
+ real d = (*sv)->point2d()[2];
+ if (d > max)
+ max =d;
+ if (d < min)
+ min =d;
+#endif
+ }
+#if 0
+ for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
+ Vec3r P((*sv)->point2d());
+ (*sv)->setPoint2D(Vec3r(P[0], P[1], 1.0 - (P[2] - min) / (max - min)));
+ //cerr << (*sv)->point2d()[2] << " ";
+ }
+#endif
}
-void SilhouetteGeomEngine::ProjectSilhouette(SVertex* ioVertex)
+void SilhouetteGeomEngine::ProjectSilhouette(SVertex *ioVertex)
{
- Vec3r newPoint;
- // real min=HUGE;
- // real max=-HUGE;
- vector<SVertex*>::iterator sv, svend;
- const real depth = _zfar - _znear;
- const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
- GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
- newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1
- ioVertex->setPoint2D(newPoint);
+ Vec3r newPoint;
+#if 0
+ real min = HUGE;
+ real max = -HUGE;
+ vector<SVertex*>::iterator sv, svend;
+#endif
+ const real depth = _zfar - _znear;
+ const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
+ GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
+ newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
+ ioVertex->setPoint2D(newPoint);
}
real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
{
- if( _isOrthographicProjection )
+ if (_isOrthographicProjection)
return t;
- // we need to compute for each parameter t the corresponding
- // parameter T which gives the intersection in 3D.
+ // 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
@@ -184,44 +212,48 @@ real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
real m22 = _projectionMatrix[1][1];
real m23 = _projectionMatrix[1][2];
- if (fabs(ABc[0]) > 1e-6) {
-
+ 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) < 1e-6)
+ if (fabs(denom) < 1.0e-6)
goto iter;
Ic[0] = -beta * (Ir[0] + m13) / denom;
-// Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
-// Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
+#if 0
+ 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]) > 1e-6) {
-
+ }
+ 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) < 1e-6)
+ if (fabs(denom) < 1.0e-6)
goto iter;
Ic[1] = -beta * (Ir[1] + m23) / denom;
-// Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
-// Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
+#if 0
+ 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]) > 1e-6) {
+ }
+ 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 {
+ }
+ 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 = 1e-6;
+ 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);
@@ -235,15 +267,30 @@ iter: bool x_coords, less_than;
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; }
+ if (Pi[0] < Ii[0])
+ T_sta = T;
+ else
+ T_end = T;
}
- } else {
+ 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 (Pi[1] < Ii[1])
+ T_sta = T;
+ else
+ T_end = T;
+ }
+ else {
+ if (Pi[1] > Ii[1])
+ T_sta = T;
+ else
+ T_end = T;
}
}
}
@@ -258,15 +305,11 @@ iter: bool x_coords, less_than;
}
Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r& M)
-
{
-
- const real depth = _zfar - _znear;
- const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
- Vec3r newPoint;
- GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
- newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1
- return newPoint;
-
+ const real depth = _zfar - _znear;
+ const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
+ Vec3r newPoint;
+ GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
+ newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
+ return newPoint;
}
-
diff --git a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
index 5bd89f8a162..d6ee159fe88 100644
--- a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
+++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
@@ -1,41 +1,46 @@
-//
-// Filename : SilhouetteGeomEngine.h
-// Author(s) : Stephane Grabli
-// Purpose : Class to perform all geometric operations dedicated
-// to silhouette. That, for example, implies that
-// this geom engine has as member data the viewpoint,
-// transformations, projections...
-// Date of creation : 03/09/2002
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef SILHOUETTEGEOMENGINE_H
-# define SILHOUETTEGEOMENGINE_H
-
-# include <vector>
-# include "../system/FreestyleConfig.h"
-# include "../geometry/Geom.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
+#define __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
+
+/** \file blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
+ * \ingroup freestyle
+ * \brief Class to perform all geometric operations dedicated to silhouette. That, for example, implies that
+ * this geom engine has as member data the viewpoint, transformations, projections...
+ * \author Stephane Grabli
+ * \date 03/09/2002
+ */
+
+#include <vector>
+
+#include "../geometry/Geom.h"
+
+#include "../system/FreestyleConfig.h"
using namespace Geometry;
@@ -45,79 +50,87 @@ class FEdge;
class LIB_VIEW_MAP_EXPORT SilhouetteGeomEngine
{
private:
- static Vec3r _Viewpoint; // The viewpoint under which the silhouette has to be computed
- static real _translation[3];
- static real _modelViewMatrix[4][4]; // the model view matrix (_modelViewMatrix[i][j] means element of line i and column j)
- static real _projectionMatrix[4][4]; // the projection matrix (_projectionMatrix[i][j] means element of line i and column j)
- static real _transform[4][4]; // the global transformation from world to screen (projection included) (_transform[i][j] means element of line i and column j)
- static int _viewport[4]; // the viewport
- static real _Focal;
-
- static real _znear;
- static real _zfar;
-
- static real _glProjectionMatrix[4][4]; // GL style (column major) projection matrix
- static real _glModelViewMatrix[4][4]; // GL style (column major) model view matrix
-
-static bool _isOrthographicProjection;
-
-
- static SilhouetteGeomEngine *_pInstance;
+ // 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(0 == _pInstance)
- {
- _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);
+ /*! retrieves an instance on the singleton */
+ static SilhouetteGeomEngine *getInstance()
+ {
+ if(0 == _pInstance) {
+ _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);
};
-#endif // SILHOUETTEGEOMENGINE_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 c1647050d0d..1052965d472 100644
--- a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp
+++ b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp
@@ -1,36 +1,41 @@
-//
-// Filename : SphericalGrid.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2010-12-19
-//
-///////////////////////////////////////////////////////////////////////////////
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/SphericalGrid.cpp
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2010-12-19
+ */
-#include "SphericalGrid.h"
-
-#include <stdexcept>
#include <algorithm>
+#include <stdexcept>
+
+#include "SphericalGrid.h"
using namespace std;
@@ -42,11 +47,12 @@ using namespace std;
// 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) {
+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;
@@ -54,11 +60,14 @@ void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
boundary[3] = y + sizeY + epsilon;
}
-bool SphericalGrid::Cell::compareOccludersByShallowestPoint (const SphericalGrid::OccluderData* a, const SphericalGrid::OccluderData* b) {
+bool SphericalGrid::Cell::compareOccludersByShallowestPoint(const SphericalGrid::OccluderData *a,
+ const SphericalGrid::OccluderData *b)
+{
return a->shallowest < b->shallowest;
}
-void SphericalGrid::Cell::indexPolygons() {
+void SphericalGrid::Cell::indexPolygons()
+{
// Sort occluders by their shallowest points.
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
}
@@ -66,30 +75,29 @@ void SphericalGrid::Cell::indexPolygons() {
// 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);
- #if sphericalgridlogging == 1
- 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 SPHERICAL_GRID_LOGGING
+ 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();
}
-SphericalGrid::Iterator::~Iterator () {}
+SphericalGrid::Iterator::~Iterator() {}
// SphericalGrid
/////////////////
-SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI)
- : _viewpoint(viewpoint),
- _enableQI(enableQI)
+SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
+ Vec3r& viewpoint, bool enableQI)
+: _viewpoint(viewpoint), _enableQI(enableQI)
{
cout << "Generate Cell structure" << endl;
// Generate Cell structure
@@ -103,10 +111,10 @@ SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& densit
cout << "Ready to use SphericalGrid" << endl;
}
-SphericalGrid::~SphericalGrid () {
-}
+SphericalGrid::~SphericalGrid() {}
-void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap) {
+void SphericalGrid::assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap)
+{
_cellSize = density.cellSize();
_cellsX = density.cellsX();
_cellsY = density.cellsY();
@@ -115,20 +123,19 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
// 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 ) {
+ 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() ) {
+ 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 ) {
+ if (_cells[i * _cellsY + j] == NULL) {
// This is an uninitialized cell
-
real x, y, width, height;
x = _cellOrigin[0] + _cellSize * i;
@@ -145,22 +152,23 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
}
}
-void SphericalGrid::distributePolygons (OccluderSource& source) {
+void SphericalGrid::distributePolygons(OccluderSource& source)
+{
unsigned long nFaces = 0;
unsigned long nKeptFaces = 0;
- for ( source.begin(); source.isValid(); source.next() ) {
- OccluderData* occluder = NULL;
+ for (source.begin(); source.isValid(); source.next()) {
+ OccluderData *occluder = NULL;
try {
- if ( insertOccluder(source, occluder) ) {
+ 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
+ }
+ 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;
@@ -170,46 +178,53 @@ void SphericalGrid::distributePolygons (OccluderSource& source) {
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
}
-void SphericalGrid::reorganizeCells () {
+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 ) {
+ 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));
}
-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];
}
-bool SphericalGrid::orthographicProjection () const {
+bool SphericalGrid::orthographicProjection() const
+{
return false;
}
-const Vec3r& SphericalGrid::viewpoint() const {
+const Vec3r& SphericalGrid::viewpoint() const
+{
return _viewpoint;
}
-bool SphericalGrid::enableQI() const {
+bool SphericalGrid::enableQI() const
+{
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);
}
-Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) {
+Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M)
+{
Vec3r newPoint;
newPoint[0] = ::atan(M[0] / M[2]);
@@ -218,4 +233,3 @@ Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) {
return newPoint;
}
-
diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.h b/source/blender/freestyle/intern/view_map/SphericalGrid.h
index 55cdee19a80..0f369b4b686 100644
--- a/source/blender/freestyle/intern/view_map/SphericalGrid.h
+++ b/source/blender/freestyle/intern/view_map/SphericalGrid.h
@@ -1,78 +1,86 @@
-//
-// Filename : SphericalGrid.h
-// Author(s) : Alexander Beels
-// Purpose : Class to define a cell grid surrounding
-// the projected image of a scene
-// Date of creation : 2010-12-19
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef SPHERICALGRID_H
-#define SPHERICALGRID_H
-
-#define sphericalgridlogging 0
-
-// I would like to avoid using deque because including ViewMap.h and <deque> or <vector>
-// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
-// so it should be a safe fall-back.
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_SPHERICAL_GRID_H__
+#define __FREESTYLE_SPHERICAL_GRID_H__
+
+/** \file blender/freestyle/intern/view_map/SphericalGrid.h
+ * \ingroup freestyle
+ * \brief Class to define a cell grid surrounding the projected image of a scene
+ * \author Alexander Beels
+ * \date 2010-12-19
+ */
+
+#define SPHERICAL_GRID_LOGGING FALSE
+
+// I would like to avoid using deque because including ViewMap.h and <deque> or <vector> separately results in
+// redefinitions of identifiers. ViewMap.h already includes <vector> so it should be a safe fall-back.
//#include <vector>
//#include <deque>
+
+#include "GridDensityProvider.h"
+#include "OccluderSource.h"
#include "ViewMap.h"
-#include "../winged_edge/WEdge.h"
+
#include "../geometry/Polygon.h"
-#include "../system/PointerSequence.h"
#include "../geometry/BBox.h"
#include "../geometry/GridHelpers.h"
-#include "OccluderSource.h"
-#include "GridDensityProvider.h"
+
+#include "../system/PointerSequence.h"
+
+#include "../winged_edge/WEdge.h"
class SphericalGrid
{
public:
// Helper classes
- struct OccluderData {
+ 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;
+ // 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;
};
private:
- struct Cell {
+ struct Cell
+ {
// Can't store Cell in a vector without copy and assign
//Cell(const Cell& other);
- //Cell& operator= (const Cell& other);
+ //Cell& operator=(const Cell& other);
- explicit Cell ();
- ~Cell ();
+ explicit Cell();
+ ~Cell();
- static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b);
+ 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);
@@ -84,43 +92,37 @@ private:
};
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 {
+ /*! 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=1e-06);
- ~Iterator ();
- void initBeforeTarget ();
- void initAfterTarget ();
- void nextOccluder ();
- void nextOccludee ();
+ 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();
+ WFace *getWFace() const;
+ Polygon3r *getCameraSpacePolygon();
void reportDepth(Vec3r origin, Vec3r u, real t);
private:
bool testOccluder(bool wantOccludee);
void markCurrentOccludeeCandidate(real depth);
- Cell* _cell;
+ Cell *_cell;
Vec3r _target;
bool _foundOccludee;
real _occludeeDepth;
@@ -128,33 +130,35 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate;
};
- class Transform : public GridHelpers::Transform {
+ class Transform : public GridHelpers::Transform
+ {
public:
- explicit Transform ();
- explicit Transform (Transform& other);
- Vec3r operator() (const Vec3r& point) const;
+ 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);
+ SphericalGrid& operator=(const SphericalGrid& other);
+
public:
- explicit SphericalGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
+ 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
+ // 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);
+ Cell *findCell(const Vec3r& point);
// Accessors:
bool orthographicProjection() const;
@@ -176,51 +180,52 @@ private:
bool _enableQI;
};
-inline void SphericalGrid::Iterator::initBeforeTarget () {
+inline void SphericalGrid::Iterator::initBeforeTarget()
+{
_current = _cell->faces.begin();
- while ( _current != _cell->faces.end() && ! testOccluder(false) ) {
+ while (_current != _cell->faces.end() && !testOccluder(false)) {
++_current;
}
}
-inline void SphericalGrid::Iterator::initAfterTarget () {
- if ( _foundOccludee ) {
- #if sphericalgridlogging == 1
+inline void SphericalGrid::Iterator::initAfterTarget()
+{
+ if (_foundOccludee) {
+ #if SPHERICAL_GRID_LOGGING
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
#endif
_current = _occludeeCandidate;
return;
}
- #if sphericalgridlogging == 1
+ #if SPHERICAL_GRID_LOGGING
std::cout << "\tStarting occludee search from current position" << std::endl;
#endif
- while ( _current != _cell->faces.end() && ! testOccluder(true) ) {
+ while (_current != _cell->faces.end() && !testOccluder(true)) {
++_current;
}
}
-inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
+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.
+ 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 sphericalgridlogging == 1
+ #if SPHERICAL_GRID_LOGGING
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
- for ( unsigned i = 1; i < (*_current)->poly.getVertices().size(); ++i ) {
+ 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 sphericalgridlogging == 1
+ if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
+ #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
#endif
_current = _cell->faces.end();
@@ -230,16 +235,17 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
}
// Specific continue or stop conditions when searching for each type
- if ( wantOccludee ) {
- if ( (*_current)->deepest < _target[2] ) {
- #if sphericalgridlogging == 1
+ if (wantOccludee) {
+ if ((*_current)->deepest < _target[2]) {
+ #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
#endif
return false;
}
- } else {
- if ( (*_current)->shallowest > _target[2] ) {
- #if sphericalgridlogging == 1
+ }
+ else {
+ if ((*_current)->shallowest > _target[2]) {
+ #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
#endif
return true;
@@ -251,70 +257,73 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
// 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 sphericalgridlogging == 1
+ if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
+ #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
#endif
return false;
}
- // We've done all the corner cutting we can.
- // Let the caller work out whether or not
- // the geometry is correct.
+ // 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.
+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();
- #if sphericalgridlogging == 1
+ #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
#endif
- if ( depth > _target[2] ) {
- #if sphericalgridlogging == 1
+ if (depth > _target[2]) {
+ #if SPHERICAL_GRID_LOGGING
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 ) {
+ if (! _foundOccludee || _occludeeDepth > depth) {
markCurrentOccludeeCandidate(depth);
}
- } else {
- #if sphericalgridlogging == 1
+ }
+ else {
+ #if SPHERICAL_GRID_LOGGING
std::cout << std::endl;
#endif
}
}
-inline void SphericalGrid::Iterator::nextOccluder () {
- if ( _current != _cell->faces.end() ) {
+inline void SphericalGrid::Iterator::nextOccluder()
+{
+ if (_current != _cell->faces.end()) {
do {
++_current;
- } while ( _current != _cell->faces.end() && ! testOccluder(false) );
+ } while (_current != _cell->faces.end() && !testOccluder(false));
}
}
-inline void SphericalGrid::Iterator::nextOccludee () {
- if ( _current != _cell->faces.end() ) {
+inline void SphericalGrid::Iterator::nextOccludee()
+{
+ if (_current != _cell->faces.end()) {
do {
++_current;
- } while ( _current != _cell->faces.end() && ! testOccluder(true) );
+ } while (_current != _cell->faces.end() && !testOccluder(true));
}
}
-inline bool SphericalGrid::Iterator::validBeforeTarget () {
+inline bool SphericalGrid::Iterator::validBeforeTarget()
+{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
}
-inline bool SphericalGrid::Iterator::validAfterTarget () {
+inline bool SphericalGrid::Iterator::validAfterTarget()
+{
return _current != _cell->faces.end();
}
-inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
- #if sphericalgridlogging == 1
+inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth)
+{
+ #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
#endif
_occludeeCandidate = _current;
@@ -322,18 +331,18 @@ inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
_foundOccludee = true;
}
-inline WFace* SphericalGrid::Iterator::getWFace() const {
+inline WFace *SphericalGrid::Iterator::getWFace() const
+{
return (*_current)->face;
}
-inline Polygon3r* SphericalGrid::Iterator::getCameraSpacePolygon() {
+inline Polygon3r *SphericalGrid::Iterator::getCameraSpacePolygon()
+{
return &((*_current)->cameraSpacePolygon);
}
inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
- : poly(p),
- cameraSpacePolygon(source.getCameraSpacePolygon()),
- face(source.getWFace())
+: 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
@@ -343,17 +352,18 @@ inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygo
// 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 i = 0; i < 2; ++i ) {
+ for (unsigned int i = 0; i < 2; ++i) {
real t = cameraSpacePolygon.getVertices()[i].norm();
- if ( t > deepest ) {
+ if (t > deepest) {
deepest = t;
}
}
}
-inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
- if ( GridHelpers::insideProscenium (boundary, poly) ) {
- if ( occluder == NULL) {
+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);
@@ -362,7 +372,8 @@ inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3
}
}
-inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) {
+inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
+{
Polygon3r& poly(source.getGridSpacePolygon());
occluder = NULL;
@@ -373,9 +384,9 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
getCellCoordinates(bbMin, startX, startY);
getCellCoordinates(bbMax, endX, endY);
- for ( unsigned i = startX; i <= endX; ++i ) {
- for ( unsigned j = startY; j <= endY; ++j ) {
- if ( _cells[i * _cellsY + j] != NULL ) {
+ 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);
}
}
@@ -384,5 +395,4 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
return occluder != NULL;
}
-#endif // SPHERICALGRID_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 6b76c2512f0..e39181e335d 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
@@ -1,267 +1,298 @@
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/SteerbaleViewMap.cpp
+ * \ingroup freestyle
+ * \brief Convenient access to the steerable ViewMap to which any element of the ViewMap belongs to.
+ * \author Stephane Grabli
+ * \date 01/07/2003
+ */
+
+#include <math.h>
+//soc #include <qimage.h>
+//soc #include <qstring.h>
+#include <sstream>
#include "Silhouette.h"
#include "SteerableViewMap.h"
-#include "../image/ImagePyramid.h"
-#include "../image/Image.h"
-#include <math.h>
+
#include "../geometry/Geom.h"
-using namespace Geometry;
-//soc #include <qstring.h>
-//soc #include <qimage.h>
-#include <sstream>
+#include "../image/ImagePyramid.h"
+#include "../image/Image.h"
extern "C" {
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
}
-SteerableViewMap::SteerableViewMap(unsigned int nbOrientations){
- _nbOrientations = nbOrientations;
- _bound = cos(M_PI/(float)_nbOrientations);
- for(unsigned i=0; i<_nbOrientations; ++i){
- _directions.push_back(Vec2d(cos((float)i*M_PI/(float)_nbOrientations), sin((float)i*M_PI/(float)_nbOrientations)));
- }
- Build();
+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();
}
-void SteerableViewMap::Build(){
- _imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM
- memset((_imagesPyramids),0,(_nbOrientations+1)*sizeof(ImagePyramid*));
+void SteerableViewMap::Build()
+{
+ _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){
- _nbOrientations = iBrother._nbOrientations;
- unsigned 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+1;++i)
- _imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
+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 + 1; ++i)
+ _imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
}
-SteerableViewMap::~SteerableViewMap(){
- Clear();
+SteerableViewMap::~SteerableViewMap()
+{
+ Clear();
}
-void SteerableViewMap::Clear(){
- unsigned 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::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();
+void SteerableViewMap::Reset()
+{
+ Clear();
+ Build();
}
-double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i){
- double dotp = fabs(dir*_directions[i]);
- if(dotp < _bound)
- return 0;
- if(dotp>1)
- dotp = 1;
+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;
- 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;
- }
- Vec3r o2d3 = iFEdge->orientation2d();
- Vec2r o2d2(o2d3.x(), o2d3.y());
- real norm = o2d2.norm();
- if(norm < 1e-6){
- return res;
- }
- o2d2/=norm;
+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;
+ for (i = 0; i < _nbOrientations; ++i) {
+ res[i] = ComputeWeight(o2d2, i);
+ }
+ _mapping[id] = res;
+ return res;
}
-unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){
- Vec2f dir(orient);
- //soc unsigned res = 0;
- real norm = dir.norm();
- if(norm < 1e-6){
- return _nbOrientations+1;
- }
- dir/=norm;
- double maxw = 0.f;
- unsigned winner = _nbOrientations+1;
- for(unsigned i=0; i<_nbOrientations; ++i){
- double w = ComputeWeight(dir, i);
- if(w>maxw){
- maxw = w;
- winner = i;
- }
- }
- return winner;
+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;
}
-
-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.f;
- 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;
+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;
}
-void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma){
- for(unsigned 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;
- }
+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;
+ }
}
-float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y){
- ImagePyramid *pyramid = _imagesPyramids[iOrientation];
- if(pyramid==0){
- cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
- return 0;
- }
- if((x<0) || (x>=pyramid->width()) || (y<0) || (y>=pyramid->height()))
- return 0;
- //float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)*255.f;
- float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)/32.f; // 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.
- return v;
+float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y)
+{
+ ImagePyramid *pyramid = _imagesPyramids[iOrientation];
+ if (pyramid == 0) {
+ cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
+ return 0;
+ }
+ 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);
+float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y)
+{
+ return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y);
}
-unsigned int SteerableViewMap::getNumberOfPyramidLevels() const{
- if(_imagesPyramids[0])
- return _imagesPyramids[0]->getNumberOfLevels();
- return 0;
+unsigned int SteerableViewMap::getNumberOfPyramidLevels() const
+{
+ if (_imagesPyramids[0])
+ return _imagesPyramids[0]->getNumberOfLevels();
+ return 0;
}
-void SteerableViewMap::saveSteerableViewMap() const {
- for(unsigned 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);
+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 QString base("SteerableViewMap");
- string base("SteerableViewMap");
- stringstream filename;
-
- for(int j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ //soc
- float coeff = 1;//1/255.f; //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.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= PNG;
- IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 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; //100*255;//*pow(2,j);
- // QImage qtmp(ow, oh, 32);
- // for(unsigned y=0;y<oh;++y){
- // for(unsigned 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");
- // }
- //
- }
+ //soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
+ filename << base;
+ filename << i << "-" << j << ".png";
+ ibuf->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");
+ }
+#endif
+ }
}
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.h b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
index fe7c2493752..a4a67c3fa7e 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.h
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
@@ -1,38 +1,46 @@
-//
-// Filename : SteerbaleViewMap.h
-// Author(s) : Stephane Grabli
-// Purpose : Convenient access to the steerable ViewMap
-// to which any element of the ViewMap belongs to.
-// Date of creation : 01/07/2003
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-#ifndef STEERABLEVIEWMAP_H
-# define STEERABLEVIEWMAP_H
-
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_STEERABLE_VIEW_MAP_H__
+#define __FREESTYLE_STEERABLE_VIEW_MAP_H__
+
+/** \file blender/freestyle/intern/view_map/SteerbaleViewMap.h
+ * \ingroup freestyle
+ * \brief Convenient access to the steerable ViewMap to which any element of the ViewMap belongs to.
+ * \author Stephane Grabli
+ * \date 01/07/2003
+ */
+
#include <map>
-#include "../system/FreestyleConfig.h"
+
#include "../geometry/Geom.h"
+
+#include "../system/FreestyleConfig.h"
+
using namespace Geometry;
using namespace std;
@@ -40,114 +48,107 @@ using namespace std;
class FEdge;
class ImagePyramid;
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
+
+/*! 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 LIB_VIEW_MAP_EXPORT SteerableViewMap{
+class LIB_VIEW_MAP_EXPORT SteerableViewMap
+{
protected:
- map<unsigned int, double* > _mapping; // for each vector the list of nbOrientations weigths corresponding to its contributions to the nbOrientations directional maps
- unsigned _nbOrientations;
- ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM
+ // for each vector the list of nbOrientations weigths 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;
+ // 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 weigths 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 intersted 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 constituing 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.
- * \params 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.f);
-
- /*! 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 ;
+ 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 weigths 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 intersted 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 constituing 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.
+ * \params 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();
-
-
+ void Clear();
+ void Build();
};
-#endif // STEERABLEVIEWMAP_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 4cb48d6613e..f3ab3c6d94a 100644
--- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
@@ -1,736 +1,753 @@
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
+ * \ingroup freestyle
+ * \brief Class to build view edges and the underlying chains of feature edges...
+ * \author Stephane Grabli
+ * \date 27/10/2003
+ */
-#include "ViewMap.h"
+#include <list>
+
+#include "SilhouetteGeomEngine.h"
#include "ViewEdgeXBuilder.h"
+#include "ViewMap.h"
+
#include "../winged_edge/WXEdge.h"
-#include "SilhouetteGeomEngine.h"
-#include <list>
using namespace std;
-void ViewEdgeXBuilder::Init(ViewShape *oVShape){
- if(0 == oVShape)
- return;
-
- // for design conveniance, we store the current SShape.
- _pCurrentSShape = oVShape->sshape();
- if(0 == _pCurrentSShape)
- return;
-
- _pCurrentVShape = oVShape;
-
- // Reset previous data
- //--------------------
- if(!_SVertexMap.empty())
- _SVertexMap.clear();
+void ViewEdgeXBuilder::Init(ViewShape *oVShape)
+{
+ if (0 == oVShape)
+ return;
+
+ // for design conveniance, we store the current SShape.
+ _pCurrentSShape = oVShape->sshape();
+ if (0 == _pCurrentSShape)
+ return;
+
+ _pCurrentVShape = oVShape;
+
+ // 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){
- // Reinit structures
- Init(oVShape);
-
- ViewEdge *vedge ;
- // 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 = 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());
+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;
+ // 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 = 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){
- // 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 = 0;
- FEdge * fefirst = 0;
- FEdge * fe = 0;
- 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::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;
}
-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;
- OWXEdge currentWEdge = firstWEdge;
- list<OWXEdge> edgesChain;
+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;
+ 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 = 0;
- FEdge * fefirst = 0;
- FEdge * fe = 0;
- 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){
- WXFace *nextFace = 0;
- 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);
- if(sameNatureLayers.size() == 1) {// don't know
- // maybe should test whether this face has
- // also a vertex_edge configuration
- WXFaceLayer * winner = sameNatureLayers[0];
- // check face mark continuity
- if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
- return OWXFaceLayer(0,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(0 == nextFace)
- return OWXFaceLayer(0,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(0,true);
- vector<WXFaceLayer*> sameNatureLayers;
- nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
- if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face
- return OWXFaceLayer(0,true);
- else{
- WXFaceLayer * winner = sameNatureLayers[0];
- // check face mark continuity
- if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
- return OWXFaceLayer(0,true);
- if(woeend == winner->getSmoothEdge()->woea()->twin())
- return OWXFaceLayer(winner,true);
- else
- return OWXFaceLayer(winner,false);
- }
- }
- return OWXFaceLayer(0,true);
+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);
}
-OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer) {
- WXFace *previousFace = 0;
- 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(0,true);
- bool found = false;
- WVertex::face_iterator f=previousVertex->faces_begin();
- WVertex::face_iterator fend=previousVertex->faces_end();
- while((!found) && (f!=fend)){
- previousFace = dynamic_cast<WXFace*>(*f);
- if((0 != previousFace) && (previousFace!=iFaceLayer.fl->getFace())){
- vector<WXFaceLayer*> sameNatureLayers;
- previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
- if(sameNatureLayers.size() == 1) {// don't know
- // maybe should test whether this face has
- // also a vertex_edge configuration
- WXFaceLayer * winner = sameNatureLayers[0];
- // check face mark continuity
- if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
- return OWXFaceLayer(0,true);
- if(woebegin == winner->getSmoothEdge()->woeb()->twin())
- return OWXFaceLayer(winner,true);
- else
- return OWXFaceLayer(winner,false);
- }
- }
- ++f;
- }
- }else{
- previousFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin));
- if(0 == previousFace)
- return OWXFaceLayer(0,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(0,true);
- vector<WXFaceLayer*> sameNatureLayers;
- previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
- if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face
- return OWXFaceLayer(0,true);
- else{
- WXFaceLayer * winner = sameNatureLayers[0];
- // check face mark continuity
- if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
- return OWXFaceLayer(0,true);
- if(woebegin == winner->getSmoothEdge()->woeb()->twin())
- return OWXFaceLayer(winner,true);
- else
- return OWXFaceLayer(winner,false);
- }
- }
- return OWXFaceLayer(0,true);
+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);
}
-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() < 1e-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;
+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;
}
-bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer){
- if(0 == iFaceLayer)
- return true;
- if(iFaceLayer->userdata == 0)
- return false;
- return true;
+bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer)
+{
+ if (0 == 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){
- if(Nature::NO_FEATURE == iEdge.e->nature())
- return OWXEdge(0, true);
-
- WVertex *v;
- if(true == iEdge.order)
- v = iEdge.e->GetbVertex();
- else
- v = iEdge.e->GetaVertex();
-
- 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->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(0, true);
+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);
}
-OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge){
- if(Nature::NO_FEATURE == iEdge.e->nature())
- return OWXEdge(0, 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(0, true);
+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);
}
-FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe){
- SVertex *va, *vb;
- FEdgeSharp *fe;
- WXVertex *wxVA, *wxVB;
- if(iwe.order){
- wxVA = (WXVertex*)iwe.e->GetaVertex();
- wxVB = (WXVertex*)iwe.e->GetbVertex();
- }else{
- wxVA = (WXVertex*)iwe.e->GetbVertex();
- wxVB = (WXVertex*)iwe.e->GetaVertex();
- }
- // Make the 2 SVertex
- va = MakeSVertex(wxVA->GetVertex(), true);
- vb = MakeSVertex(wxVB->GetVertex(), 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
- // 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;
+FEdge *ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
+{
+ SVertex *va, *vb;
+ FEdgeSharp *fe;
+ WXVertex *wxVA, *wxVB;
+ if (iwe.order) {
+ wxVA = (WXVertex *)iwe.e->GetaVertex();
+ wxVB = (WXVertex *)iwe.e->GetbVertex();
+ }
+ else {
+ wxVA = (WXVertex *)iwe.e->GetbVertex();
+ wxVB = (WXVertex *)iwe.e->GetaVertex();
+ }
+ // Make the 2 SVertex
+ va = MakeSVertex(wxVA->GetVertex(), true);
+ vb = MakeSVertex(wxVB->GetVertex(), 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(0 == iEdge)
- return true;
- if(iEdge->userdata == 0)
- return false;
- return true;
+bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge)
+{
+ if (0 == iEdge)
+ return true;
+ if (iEdge->userdata == 0)
+ return false;
+ return true;
}
-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 *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 * 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 *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;
}
-ViewVertex * ViewEdgeXBuilder::MakeViewVertex(SVertex *iSVertex){
- ViewVertex *vva = iSVertex->viewvertex();
- if(vva != 0)
- return vva;
- vva = new NonTVertex(iSVertex);
- // Add the view vertex to the ViewShape svertex list:
- _pCurrentVShape->AddVertex(vva);
- return vva;
+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;
}
-
diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
index 744cc520b2b..2883919a852 100644
--- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
@@ -1,73 +1,87 @@
-//
-// Filename : ViewEdgeXBuilder.h
-// Author(s) : Stephane Grabli
-// Purpose : Class to build view edges and the underlying chains
-// of feature edges...
-// Date of creation : 27/10/2003
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef VIEWEDGEXBUILDER_H
-# define VIEWEDGEXBUILDER_H
-
-# include <map>
-# include <utility>
-# include <vector>
-
-// 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 "../system/FreestyleConfig.h"
-# include "../geometry/Geom.h"
-# include "Interface1D.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
+#define __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
+
+/** \file blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
+ * \ingroup freestyle
+ * \brief Class to build view edges and the underlying chains of feature edges...
+ * \author Stephane Grabli
+ * \date 27/10/2003
+ */
+
+#include <map>
+#include <utility>
+#include <vector>
+
+#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
+#endif
+
+#include "Interface1D.h"
+
+#include "../geometry/Geom.h"
+
+#include "../system/FreestyleConfig.h"
using namespace Geometry;
using namespace std;
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<1e-06);
- }
+struct epsilonEquals
+{
+ bool operator()(const Vec3r& v1, const Vec3r& v2) const
+ {
+ real norm = (v1 - v2).norm();
+ return (norm < 1.0e-06);
+ }
};
@@ -75,47 +89,81 @@ struct epsilonEquals{
typedef map<Vec3r , SVertex*> SVertexMap;
class WXFaceLayer;
+
/*! class to describe an oriented smooth edge */
-class OWXFaceLayer{
+class OWXFaceLayer
+{
public:
- WXFaceLayer * fl;
- bool order;
-
- OWXFaceLayer() {fl=0;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);
- }
+ 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 WXEdge;
+
/*! class to describe an oriented sharp edge */
-class OWXEdge{
+class OWXEdge
+{
public:
- WXEdge * e;
- bool order;
-
- OWXEdge() {e=0;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);
- }
+ 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 WOEdge;
@@ -126,93 +174,115 @@ class FEdge;
class ViewVertex;
class ViewEdge;
class ViewShape;
+
class LIB_VIEW_MAP_EXPORT ViewEdgeXBuilder
{
protected:
- int _currentViewId; // Id for view edges
- int _currentFId; // Id for FEdges
- int _currentSVertexId; // Id for SVertex
+ 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) ;
+ 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; }
+ /*! 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;
-};
+ /*! Init the view edges building */
+ virtual void Init(ViewShape *oVShape);
-#endif
+ // 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;
+};
+#endif // __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp
index e6c5d55f765..9f8b5e08200 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp
@@ -1,623 +1,690 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/ViewMap.cpp
+ * \ingroup freestyle
+ * \brief Classes to define a View Map (ViewVertex, ViewEdge, etc.)
+ * \author Stephane Grabli
+ * \date 03/09/2002
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+#include <float.h>
#include "ViewMap.h"
-#include "../geometry/GeomUtils.h"
-#include <float.h>
-#include "ViewMapIterators.h"
#include "ViewMapAdvancedIterators.h"
+#include "ViewMapIterators.h"
- /**********************************/
- /* */
- /* */
- /* ViewMap */
- /* */
- /* */
- /**********************************/
+#include "../geometry/GeomUtils.h"
-ViewMap * ViewMap::_pInstance = 0;
-
-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();
-
- for(vector<ViewShape*>::iterator vs=_VShapes.begin(),vsend=_VShapes.end();
- vs!=vsend;
- vs++)
- {
- delete (*vs);
- }
- _VShapes.clear();
-
- _FEdges.clear();
- _SVertices.clear();
- _VEdges.clear();
-}
-
-ViewShape * ViewMap::viewShape(unsigned id)
-{
- int index = _shapeIdToIndex[id];
- return _VShapes[ index ];
-}
-void ViewMap::AddViewShape(ViewShape *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 = 0;
- 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==0)
- return 0;
-
- return winner;
-}
-
-const ViewEdge * ViewMap::getClosestViewEdge(real x, real y) const
-{
- // find the closest of this candidates:
- real minDist = DBL_MAX;
- FEdge * winner = 0;
- 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==0)
- return 0;
-
- 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 != 0)
- return vva;
- // beacuse 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 0;
- }
- FEdge * fend(0), * fbegin(0);
- 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!=0) && (fend!=0))
- 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(0);
- fbegin->setPreviousEdge(0);
-
- // 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(0);
- fbegin->setPreviousEdge(0);
-
- // update new View Vertex:
- vva->AddOutgoingViewEdge(newVEdge);
- vva->AddIncomingViewEdge(ioEdge);
- // 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;
-}
-
-//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;
-//}
+/**********************************/
+/* */
+/* */
+/* ViewMap */
+/* */
+/* */
+/**********************************/
- /**********************************/
- /* */
- /* */
- /* TVertex */
- /* */
- /* */
- /**********************************/
+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();
+
+ for (vector<ViewShape*>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend; vs++) {
+ delete (*vs);
+ }
+ _VShapes.clear();
+
+ _FEdges.clear();
+ _SVertices.clear();
+ _VEdges.clear();
+}
+
+ViewShape *ViewMap::viewShape(unsigned id)
+{
+ int index = _shapeIdToIndex[id];
+ return _VShapes[ index ];
+}
+
+void ViewMap::AddViewShape(ViewShape *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);
+ }
+ }
+
+ 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(0), *fbegin(0);
+ 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!=0) && (fend!=0))
+ 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);
+ // 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;
+}
+#endif
+
+/**********************************/
+/* */
+/* */
+/* TVertex */
+/* */
+/* */
+/**********************************/
// 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;
-}
-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();
- while((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();
- while((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();
- while((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();
- while((dve!=dveend) && ViewEdgeComp(**dve, _BackEdgeB)){
- ++dve;
- }
- _sortedEdges.insert(dve, &_BackEdgeB);
- }
- else
- _sortedEdges.push_back(&_BackEdgeB);
+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);
+ }
+}
+
+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);
+ }
+}
+
+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);
+ }
+}
+
+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);
+ }
}
+
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());
-
- // 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);
+{
+ 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);
+#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());
-
- // 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);
-}
-
-ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesBegin() {
- return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
-}
-ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesEnd() {
- 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::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);
+#endif
+}
+
+ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesBegin()
+{
+ return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
}
- /**********************************/
- /* */
- /* */
- /* NonTVertex */
- /* */
- /* */
- /**********************************/
-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();
- while((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();
- while((dve!=dveend) && ViewEdgeComp(*dve, idve)){
- ++dve;
- }
- _ViewEdges.insert(dve, idve);
- }
- else
- _ViewEdges.push_back(idve);
+ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesEnd()
+{
+ 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());
+}
+
+/**********************************/
+/* */
+/* */
+/* NonTVertex */
+/* */
+/* */
+/**********************************/
+
+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);
+ }
+}
+
+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);
+ }
}
/*! 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());
+ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesBegin()
+{
+ return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
-ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesEnd() {
- return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
+
+ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesEnd()
+{
+ 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());
+
+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());
+}
+
+/**********************************/
+/* */
+/* */
+/* 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;
}
- /**********************************/
- /* */
- /* */
- /* ViewEdge */
- /* */
- /* */
- /**********************************/
-real ViewEdge::getLength2D() const
+//! view edge iterator
+ViewEdge::edge_iterator ViewEdge::ViewEdge_iterator()
{
- float length = 0.f;
- 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;
+ return edge_iterator(this);
}
+ViewEdge::const_edge_iterator ViewEdge::ViewEdge_iterator() const
+{
+ return const_edge_iterator((ViewEdge*)this);
+}
-//! view edge iterator
-ViewEdge::edge_iterator ViewEdge::ViewEdge_iterator() {return edge_iterator(this);}
-ViewEdge::const_edge_iterator ViewEdge::ViewEdge_iterator() const {return const_edge_iterator((ViewEdge*)this);}
//! feature edge iterator
-ViewEdge::fedge_iterator ViewEdge::fedge_iterator_begin() {return fedge_iterator(this->_FEdgeA, this->_FEdgeB);}
-ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_begin() const {return const_fedge_iterator(this->_FEdgeA, this->_FEdgeB);}
-ViewEdge::fedge_iterator ViewEdge::fedge_iterator_last() {return fedge_iterator(this->_FEdgeB, this->_FEdgeB);}
-ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_last() const {return const_fedge_iterator(this->_FEdgeB, this->_FEdgeB);}
-ViewEdge::fedge_iterator ViewEdge::fedge_iterator_end() {return fedge_iterator(0, this->_FEdgeB);}
-ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_end() const {return const_fedge_iterator(0, this->_FEdgeB);}
+ViewEdge::fedge_iterator ViewEdge::fedge_iterator_begin()
+{
+ return fedge_iterator(this->_FEdgeA, this->_FEdgeB);
+}
+
+ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_begin() const
+{
+ return const_fedge_iterator(this->_FEdgeA, this->_FEdgeB);
+}
+
+ViewEdge::fedge_iterator ViewEdge::fedge_iterator_last()
+{
+ return fedge_iterator(this->_FEdgeB, this->_FEdgeB);
+}
+
+ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_last() const
+{
+ return const_fedge_iterator(this->_FEdgeB, this->_FEdgeB);
+}
+
+ViewEdge::fedge_iterator ViewEdge::fedge_iterator_end()
+{
+ return fedge_iterator(0, this->_FEdgeB);
+}
+
+ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_end() const
+{
+ 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);}
-ViewEdge::vertex_iterator ViewEdge::vertices_begin() {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);}
-ViewEdge::vertex_iterator ViewEdge::vertices_last() {return vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);}
-ViewEdge::const_vertex_iterator ViewEdge::vertices_end() const {return const_vertex_iterator(0, _FEdgeB, 0);}
-ViewEdge::vertex_iterator ViewEdge::vertices_end() {return vertex_iterator(0, _FEdgeB, 0);}
+ViewEdge::const_vertex_iterator ViewEdge::vertices_begin() const
+{
+ return const_vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
+}
+ViewEdge::vertex_iterator ViewEdge::vertices_begin()
+{
+ return vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
+}
-Interface0DIterator ViewEdge::verticesBegin() {
- Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(this->_FEdgeA->vertexA(), this->_FEdgeA->vertexA(), 0, _FEdgeA, 0.f));
- return ret;
+ViewEdge::const_vertex_iterator ViewEdge::vertices_last() const
+{
+ return const_vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);
}
-Interface0DIterator ViewEdge::verticesEnd() {
- Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(0, this->_FEdgeA->vertexA(), _FEdgeB, 0, getLength2D()));
- return ret;
+ViewEdge::vertex_iterator ViewEdge::vertices_last()
+{
+ return vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);
}
-Interface0DIterator ViewEdge::pointsBegin(float t) {
- return verticesBegin();
+ViewEdge::const_vertex_iterator ViewEdge::vertices_end() const
+{
+ return const_vertex_iterator(0, _FEdgeB, 0);
}
-Interface0DIterator ViewEdge::pointsEnd(float t) {
- return verticesEnd();
+ViewEdge::vertex_iterator ViewEdge::vertices_end()
+{
+ 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 ViewEdge::verticesEnd()
+{
+ Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(NULL, this->_FEdgeA->vertexA(),
+ _FEdgeB, NULL, getLength2D()));
+ return ret;
+}
+
+Interface0DIterator ViewEdge::pointsBegin(float t)
+{
+ return verticesBegin();
+}
+
+Interface0DIterator ViewEdge::pointsEnd(float t)
+{
+ return verticesEnd();
+}
/**********************************/
/* */
@@ -627,77 +694,60 @@ Interface0DIterator ViewEdge::pointsEnd(float t) {
/* */
/**********************************/
-
ViewShape::~ViewShape()
{
- _Vertices.clear();
-
- if(!(_Edges.empty()))
- {
- for(vector<ViewEdge*>::iterator e=_Edges.begin(), eend=_Edges.end();
- e!=eend;
- e++)
- {
- delete (*e);
- }
- _Edges.clear();
- }
-
- if(0 != _SShape)
- {
- delete _SShape;
- _SShape = 0;
- }
-}
-
-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;
- }
- }
-}
-
-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;
- }
- }
+ _Vertices.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;
+ }
}
- /**********************************/
- /* */
- /* */
- /* ViewEdge */
- /* */
- /* */
- /**********************************/
+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;
+ }
+ }
+}
+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;
+ }
+ }
+}
+
+/**********************************/
+/* */
+/* */
+/* ViewEdge */
+/* */
+/* */
+/**********************************/
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);
}
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h
index d2d7a9a5341..e29b2ae7cd6 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.h
+++ b/source/blender/freestyle/intern/view_map/ViewMap.h
@@ -1,56 +1,64 @@
-//
-// Filename : ViewMap.h
-// Author(s) : Stephane Grabli
-// Purpose : Classes to define a View Map (ViewVertex, ViewEdge, etc.)
-// Date of creation : 03/09/2002
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef VIEWMAP_H
-# define VIEWMAP_H
-
-# include "Interface0D.h"
-# include "Interface1D.h"
-# include "Silhouette.h" // defines the embedding
-# include "../system/BaseIterator.h"
-# include "../system/FreestyleConfig.h"
-# include "../geometry/GeomUtils.h"
-# include <map>
-
- /**********************************/
- /* */
- /* */
- /* ViewMap */
- /* */
- /* */
- /**********************************/
-
-
-/* Density
- Mean area depth value
- distance to a point
- */
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_VIEW_MAP_H__
+#define __FREESTYLE_VIEW_MAP_H__
+
+/** \file blender/freestyle/intern/view_map/ViewMap.h
+ * \ingroup freestyle
+ * \brief Classes to define a View Map (ViewVertex, ViewEdge, etc.)
+ * \author Stephane Grabli
+ * \date 03/09/2002
+ */
+
+#include <map>
+
+#include "Interface0D.h"
+#include "Interface1D.h"
+#include "Silhouette.h" // defines the embedding
+
+#include "../geometry/GeomUtils.h"
+
+#include "../system/BaseIterator.h"
+#include "../system/FreestyleConfig.h"
+
+/**********************************/
+/* */
+/* */
+/* ViewMap */
+/* */
+/* */
+/**********************************/
+
+
+/* Density
+ * Mean area depth value
+ * distance to a point
+ */
class ViewVertex;
class ViewEdge;
@@ -58,500 +66,580 @@ class ViewShape;
class TVertex;
/*! Class defining the ViewMap.*/
-class LIB_VIEW_MAP_EXPORT ViewMap
+class LIB_VIEW_MAP_EXPORT 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;
+ 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;
- id_to_index_map _shapeIdToIndex; // 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.
+ 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 = 0;
- }
- /*! 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);
+ /*! 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);
};
- /**********************************/
- /* */
- /* */
- /* ViewVertex */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* ViewVertex */
+/* */
+/* */
+/**********************************/
class ViewEdge;
class SShape;
namespace ViewVertexInternal {
- class edge_const_traits;
- class edge_nonconst_traits;
- template<class Traits> class edge_iterator_base ;
- class orientedViewEdgeIterator;
+
+class edge_const_traits;
+class edge_nonconst_traits;
+template<class Traits> class edge_iterator_base;
+class orientedViewEdgeIterator;
+
} // end of namespace ViewEdgeInternal
-/*! 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
+
+/*! 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
* edge might change (nature, visibility, ...).
- * A ViewVertex can be of two kinds: a TVertex when
- * it corresponds to the intersection between two
- * ViewEdges or a 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.
+ * A ViewVertex can be of two kinds: a TVertex when it corresponds to the intersection between two ViewEdges or a
+ * 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 LIB_VIEW_MAP_EXPORT ViewVertex : public Interface0D
{
public: // Implementation of Interface0D
+ /*! Returns the string "ViewVertex". */
+ virtual string getExactTypeName() const
+ {
+ return "ViewVertex";
+ }
- /*! 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
+public:
+ friend class ViewShape;
+ typedef pair<ViewEdge*, bool> directedViewEdge; // if bool = true, the ViewEdge is incoming
- typedef vector<directedViewEdge> edges_container;
+ 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;
+ 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;
+ 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 = 0;_Nature = Nature::VIEW_VERTEX; }
- inline ViewVertex(Nature::VertexNature nature) {
- userdata = 0;
- _Nature = Nature::VIEW_VERTEX | nature;
- }
+ /*! 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 = 0;
- }
- /*! Cloning method. */
- virtual ViewVertex * duplicate() = 0;
-
+ /*! 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 *) {}
+ /*! 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.
- */
+ /* 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.
- */
+ /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) = 0;
-
};
- /**********************************/
- /* */
- /* */
- /* TVertex */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* TVertex */
+/* */
+/* */
+/**********************************/
-/*! class to define a T vertex, i.e. an intersection between
- * two edges.
+/*! class to define a T vertex, i.e. an intersection between two edges.
* It points towards 2 SVertex and 4 View edges.
* Among these ViewEdges, 2 are front and 2 are back.
* 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
+ * So, among the back edges, 1 is of invisibility n and the other of visibility n+1
*/
class LIB_VIEW_MAP_EXPORT TVertex : public ViewVertex
{
public:
- typedef vector<directedViewEdge*> edge_pointers_container;
-public: // Implementation of Interface0D
+ typedef vector<directedViewEdge*> edge_pointers_container;
- /*! 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 Vec3f 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 Vec2f 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
- /*! Cast the Interface0D in ViewVertex if it can be. */
- virtual ViewVertex * castToViewVertex(){
- return this;
- }
-
- /*! Cast the Interface0D in TVertex if it can be. */
- virtual TVertex * castToTVertex(){
- return this;
- }
+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 Vec3f 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 Vec2f 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)
-
+ 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 = 0;
- _BackSVertex = 0;
- _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);
- }
+ /*! 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;
- }
+ /*! 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 0;
- }
-
- 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 0;
- }
-
- /* 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) ;
+ /* 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);
};
- /**********************************/
- /* */
- /* */
- /* NonTVertex */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* NonTVertex */
+/* */
+/* */
+/**********************************/
// (non T vertex)
@@ -562,744 +650,949 @@ public:
class LIB_VIEW_MAP_EXPORT NonTVertex : public ViewVertex
{
public:
- typedef vector<directedViewEdge> edges_container;
+ 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 Vec3f 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 Vec2f 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;
- }
+ /*! 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 Vec3f 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 Vec2f 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;
+ SVertex *_SVertex;
+ edges_container _ViewEdges;
+
public:
- /*! Default constructor.*/
- inline NonTVertex() : ViewVertex(Nature::NON_T_VERTEX) { _SVertex = 0; }
- /*! Builds a NonTVertex from a SVertex. */
- inline NonTVertex(SVertex* iSVertex) : ViewVertex(Nature::NON_T_VERTEX)
- {
- _SVertex = iSVertex;
- _SVertex->setViewVertex(this);
- }
+ /*! 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;
- }
+ /*! 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) ;
+ /*! 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);
};
- /**********************************/
- /* */
- /* */
- /* ViewEdge */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* ViewEdge */
+/* */
+/* */
+/**********************************/
/* Geometry(normals...)
- Nature of edges
- 2D spaces (1or2, material, z...)
- Parent Shape
- 3D Shading, material
- Importance
- Occluders
- */
+ * Nature of edges
+ * 2D spaces (1or2, material, z...)
+ * Parent Shape
+ * 3D Shading, material
+ * Importance
+ * Occluders
+ */
class ViewShape;
namespace ViewEdgeInternal {
- template<class Traits> class edge_iterator_base ;
- template<class Traits> class fedge_iterator_base ;
- template<class Traits> class vertex_iterator_base ;
+
+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
-/*! Class defining a ViewEdge. A ViewEdge in an edge
- * of the image graph. it connnects two ViewVertex.
+/*! Class defining a ViewEdge. A ViewEdge in an edge of the image graph. it connnects two ViewVertex.
* It is made by connecting a set of FEdges.
*/
class LIB_VIEW_MAP_EXPORT 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;
- }
+ /*! 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:
+ 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;
- 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;
- ViewShape *_aShape; // 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 // NON GERE PAR LE COPY CONSTRUCTEUR
- int _qi;
- vector<ViewShape*> _Occluders;
- bool _isInImage;
-
- // tmp
- Id * _splittingId;
+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=0;
- __B=0;
- _FEdgeA = 0;
- _FEdgeB = 0;
- _ChainingTimeStamp = 0;
- _qi = 0;
- _aShape=0;
- userdata = 0;
- _splittingId = 0;
- _isInImage = true;
- }
- inline ViewEdge(ViewVertex* iA, ViewVertex *iB)
- {
- __A = iA;
- __B = iB;
- _FEdgeA = 0;
- _FEdgeB = 0;
- _Shape = 0;
- _ChainingTimeStamp = 0;
- _aShape = 0;
- _qi = 0;
- userdata = 0;
- _splittingId = 0;
- _isInImage = true;
- }
- inline ViewEdge(ViewVertex* iA, ViewVertex *iB, FEdge *iFEdgeA)
- {
- __A = iA;
- __B = iB;
- _FEdgeA = iFEdgeA;
- _FEdgeB = 0;
- _Shape = 0;
- _ChainingTimeStamp = 0;
- _aShape = 0;
- _qi = 0;
- userdata = 0;
- _splittingId = 0;
- _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;
- _aShape = 0;
- _qi = 0;
- userdata = 0;
- _splittingId = 0;
- _isInImage = true;
- UpdateFEdges(); // tells every FEdge between iFEdgeA and iFEdgeB that this is theit ViewEdge
- }
+ /*! 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 = 0;
- _Id = iBrother._Id;
- _ChainingTimeStamp = iBrother._ChainingTimeStamp;
- _aShape = iBrother._aShape;
- _qi = iBrother._qi;
- _splittingId = 0;
- _isInImage = iBrother._isInImage;
- iBrother.userdata = this;
- userdata = 0;
- }
- /*! Cloning method. */
- virtual ViewEdge * duplicate()
- {
- ViewEdge *clone = new ViewEdge(*this);
- return clone;
- }
+ /*! 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 != _aFace)
- // {
- // delete _aFace;
- // _aFace = 0;
- // }
- // 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,
- * 0 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 == 0)
- 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 */
-
- //inline Nature::EdgeNature viewedge_nature() const {return getNature();}
- //float viewedge_length() const ;
- /*! Returns the 2D length of the Viewedge. */
- real getLength2D() const;
- //inline Material material() const {return _FEdgeA->vertexA()->shape()->material();}
- 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 constituing 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 constituing 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.f);
- /*! 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.f);
+ /*! Destructor. */
+ virtual ~ViewEdge()
+ {
+#if 0
+ 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 */
+
+#if 0
+ inline Nature::EdgeNature viewedge_nature() const
+ {
+ return getNature();
+ }
+
+ float viewedge_length() const;
+#endif
+
+ /*! Returns the 2D length of the Viewedge. */
+ real getLength2D() const;
+
+#if 0
+ 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 constituing 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 constituing 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);
};
-
- /**********************************/
- /* */
- /* */
- /* ViewShape */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* ViewShape */
+/* */
+/* */
+/**********************************/
-/*! Class gathering the elements of the ViewMap (ViewVertex, ViewEdge)
- * that are issued from the same input shape.
- */
+/*! Class gathering the elements of the ViewMap (ViewVertex, ViewEdge) that are issued from the same input shape. */
class LIB_VIEW_MAP_EXPORT ViewShape
{
private:
- vector<ViewVertex*> _Vertices;
- vector<ViewEdge*> _Edges;
- SShape * _SShape;
-
+ 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 = 0; _SShape = 0;}
- /*! Builds a ViewShape from a SShape. */
- inline ViewShape(SShape *iSShape) {userdata = 0; _SShape = iSShape;}//_SShape->setViewShape(this);}
- /*! Copy constructor. */
- inline ViewShape(ViewShape& iBrother)
- {
- userdata = 0;
- 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:
- ;
- }
- }
-
- //-------------------------------------
- // 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 id. */
- inline const string& getName() const {return _SShape->getName();}
-
- /* 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);
+ /*! 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 id. */
+ inline const string& getName() const
+ {
+ return _SShape->getName();
+ }
+
+ /* 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);
};
-
/*
-
#############################################
#############################################
#############################################
@@ -1309,198 +1602,178 @@ public:
#############################################
#############################################
#############################################
-
*/
/* for inline functions */
-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);
- // Id id(vEdge->getId().getFirst(), vEdge->getId().getSecond()+1);
- // newVEdge->setId(vEdge->getId());
- // vEdge->setId(id);
-
- 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);
- }
- }
-}
-
- /**********************************/
- /* */
- /* */
- /* ViewEdge */
- /* */
- /* */
- /**********************************/
-
-
-// inline Vec3r ViewEdge::orientation2d(int iCombination) const
-// {
-// return edge_orientation2d_function<ViewEdge>(*this, iCombination);
-// }
-
-// inline Vec3r ViewEdge::orientation3d(int iCombination) const
-// {
-// return edge_orientation3d_function<ViewEdge>(*this, iCombination);
-// }
-
-// inline real ViewEdge::z_discontinuity(int iCombination) const
-// {
-// 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);
-// }
-
-// inline float ViewEdge::local_depth_variance(int iCombination) const
-// {
-// 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);
-// }
-
-inline const SShape * ViewEdge::occluded_shape() const
+void ViewShape::SplitEdge(FEdge *fe, const vector<TVertex*>& iViewVertices, vector<FEdge*>& ioNewEdges,
+ vector<ViewEdge*>& ioNewViewEdges)
{
- if(0 == _aShape)
- return 0;
- return _aShape->sshape();
-}
+ 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);
+#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);
+ }
+ }
+}
+
+/**********************************/
+/* */
+/* */
+/* ViewEdge */
+/* */
+/* */
+/**********************************/
+
+#if 0
+inline Vec3r ViewEdge::orientation2d(int iCombination) const
+{
+ return edge_orientation2d_function<ViewEdge>(*this, iCombination);
+}
+
+inline Vec3r ViewEdge::orientation3d(int iCombination) const
+{
+ return edge_orientation3d_function<ViewEdge>(*this, iCombination);
+}
+
+inline real ViewEdge::z_discontinuity(int iCombination) const
+{
+ 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);
+}
-// inline Vec3r ViewEdge::curvature2d_as_vector(int iCombination) const
-// {
-// return curvature2d_as_vector_edge_function<ViewEdge>(*this, iCombination);
-// }
+inline float ViewEdge::local_depth_variance(int iCombination) const
+{
+ 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);
+}
+#endif
-// inline real ViewEdge::curvature2d_as_angle(int iCombination) const
-// {
-// return curvature2d_as_angle_edge_function<ViewEdge>(*this, iCombination);
-// }
+inline const SShape * ViewEdge::occluded_shape() const
+{
+ 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);
+}
+
+inline real ViewEdge::curvature2d_as_angle(int iCombination) const
+{
+ return curvature2d_as_angle_edge_function<ViewEdge>(*this, iCombination);
+}
+#endif
-#endif // VIEWMAP_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 adffc46ec74..ff6557b7d86 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
@@ -1,691 +1,789 @@
-//
-// Filename : ViewMapAdvancedIterators.h
-// Author(s) : Stephane Grabli
-// Purpose : Iterators used to iterate over the various elements of the ViewMap
-// These iterators can't be exported to python.
-// Date of creation : 01/07/2003
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef VIEWMAPADVANCEDITERATORS_H
-# define VIEWMAPADVANCEDITERATORS_H
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
+#define __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
+
+/** \file blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
+ * \ingroup freestyle
+ * \brief Iterators used to iterate over the various elements of the ViewMap.
+ * These iterators can't be exported to python.
+ * \author Stephane Grabli
+ * \date 01/07/2003
+ */
#include "ViewMap.h"
-#include "../system/Iterator.h" //soc
-
- /**********************************/
- /* */
- /* */
- /* ViewMap */
- /* */
- /* */
- /**********************************/
-
- /**********************************/
- /* */
- /* */
- /* ViewVertex */
- /* */
- /* */
- /**********************************/
-
-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_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 ;
- };
-
+
+#include "../system/Iterator.h" //soc
+
+/**********************************/
+/* */
+/* */
+/* ViewMap */
+/* */
+/* */
+/**********************************/
+
+/**********************************/
+/* */
+/* */
+/* ViewVertex */
+/* */
+/* */
+/**********************************/
+
+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_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;
-
- // mutable value_type _tvertex_iter;
- // value_type _feA;
- // value_type _feB;
- // value_type _beA;
- // value_type _beB;
-
- // Non TVertex attributes
- edges_container_iterator _begin;
- edges_container_iterator _end;
- edges_container_iterator _nontvertex_iter;
-
- typedef IteratorBase<Traits,InputIteratorTag_Traits> parent_class;
-
- public:
- inline edge_iterator_base() : parent_class() {}
- 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)
- {
- // _feA = iBrother._feA;
- // _feB = iBrother._feB;
- // _beA = iBrother._beA;
- // _beB = iBrother._beB;
- // _tvertex_iter = iBrother._tvertex_iter;
- _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)
- {
- // _feA = iBrother._feA;
- // _feB = iBrother._feB;
- // _beA = iBrother._beA;
- // _beB = iBrother._beB;
- // _tvertex_iter = iBrother._tvertex_iter;
- _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:
- // 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(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
- virtual Self& operator++() // operator corresponding to ++i
- {
- increment();
- return *this;
- }
- virtual Self operator++(int) // opérateur correspondant à i++
- { // c.a.d qui renvoie la valeur *puis* incrémente.
- Self tmp = *this; // C'est pour cela qu'on stocke la valeur
- increment(); // dans un temporaire.
- 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;
- // // 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
- // // 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;
- // }
- }
- else
- ++_nontvertex_iter;
- }
- };
-
- }
- /**********************************/
- /* */
- /* */
- /* ViewEdge */
- /* */
- /* */
- /**********************************/
+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;
+#endif
+
+ // Non TVertex attributes
+ edges_container_iterator _begin;
+ edges_container_iterator _end;
+ edges_container_iterator _nontvertex_iter;
+
+ typedef IteratorBase<Traits,InputIteratorTag_Traits> parent_class;
+
+public:
+ inline edge_iterator_base() : parent_class() {}
+
+ 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) {
+#if 0
+ _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) {
+#if 0
+ _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:
+#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;
+ }
+#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) // opérateur correspondant à i++
+ {
+ 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 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;
+ }
+ }
+};
+
+} // ViewVertexInternal namespace
+
+/**********************************/
+/* */
+/* */
+/* ViewEdge */
+/* */
+/* */
+/**********************************/
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
- inline Self& operator++() // operator corresponding to ++i
- {
- //++_ViewEdge->getTimeStamp();
- increment();
- return *this;
- }
- inline Self operator++(int) // opérateur correspondant à i++
- { // c.a.d qui renvoie la valeur *puis* incrémente.
- //++_ViewEdge->getTimeStamp();
- Self tmp = *this; // C'est pour cela qu'on stocke la valeur
- increment(); // dans un temporaire.
- return tmp;
- }
- inline Self& operator--() // operator corresponding to ++i
- {
- //++_ViewEdge->getTimeStamp();
- decrement();
- return *this;
- }
- inline Self operator--(int) // opérateur correspondant à i++
- { // c.a.d qui renvoie la valeur *puis* incrémente.
- //++_ViewEdge->getTimeStamp();
- Self tmp = *this; // C'est pour cela qu'on stocke la valeur
- decrement(); // dans un temporaire.
- 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
- inline Self& operator++() // operator corresponding to ++i
- {
- increment();
- return *this;
- }
- inline Self operator++(int) // opérateur correspondant à i++
- { // c.a.d qui renvoie la valeur *puis* incrémente.
- Self tmp = *this; // C'est pour cela qu'on stocke la valeur
- increment(); // dans un temporaire.
- return tmp;
- }
- inline Self& operator--() // operator corresponding to ++i
- {
- decrement();
- return *this;
- }
- inline Self operator--(int) // opérateur correspondant à i++
- { // c.a.d qui renvoie la valeur *puis* incrémente.
- Self tmp = *this; // C'est pour cela qu'on stocke la valeur
- decrement(); // dans un temporaire.
- 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
- inline Self& operator++() // operator corresponding to ++i
- {
- increment();
- return *this;
- }
- inline Self operator++(int) // opérateur correspondant à i++
- { // c.a.d qui renvoie la valeur *puis* incrémente.
- Self tmp = *this; // C'est pour cela qu'on stocke la valeur
- increment(); // dans un temporaire.
- return tmp;
- }
- inline Self& operator--() // operator corresponding to ++i
- {
- decrement();
- return *this;
- }
- inline Self operator--(int) // opérateur correspondant à i++
- { // c.a.d qui renvoie la valeur *puis* incrémente.
- Self tmp = *this; // C'est pour cela qu'on stocke la valeur
- decrement(); // dans un temporaire.
- 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(0 == _NextFEdge)
- {
- _SVertex = 0;
- return;
- }
-
- _SVertex = _NextFEdge->vertexB();
- _PreviousFEdge = _NextFEdge;
- _NextFEdge = _NextFEdge->nextEdge();
-
- }
- virtual void decrement()
- {
- // if(0 == _SVertex)
- // {
- // _SVertex = _PreviousFEdge->vertexB();
- // return;
- // }
- if(0 == _PreviousFEdge)
- {
- _SVertex = 0;
- return;
- }
- _SVertex = _PreviousFEdge->vertexA();
- _NextFEdge = _PreviousFEdge;
- _PreviousFEdge = _PreviousFEdge->previousEdge();
- }
- };
-
-
+/*!----------------------*/
+/*! 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() {}
+};
+
+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
+ }
+};
+
+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()
+ {
+#if 0
+ if (!_SVertex) {
+ _SVertex = _PreviousFEdge->vertexB();
+ return;
+ }
+#endif
+ if (!_PreviousFEdge) {
+ _SVertex = NULL;
+ return;
+ }
+ _SVertex = _PreviousFEdge->vertexA();
+ _NextFEdge = _PreviousFEdge;
+ _PreviousFEdge = _PreviousFEdge->previousEdge();
+ }
+};
+
} // end of namespace ViewEdgeInternal
-#endif // VIEWMAPADVANCEDITERATORS_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 d503daa3696..84cd166dca0 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -1,828 +1,827 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+ * \ingroup freestyle
+ * \brief Class to build silhouette edges from a Winged-Edge structure
+ * \author Stephane Grabli
+ * \date 25/03/2002
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#include "ViewMapBuilder.h"
#include <algorithm>
-#include <stdexcept>
#include <memory>
-#include "../winged_edge/WFillGrid.h"
-#include "../../FRS_freestyle.h"
-#include "../geometry/GeomUtils.h"
-#include "../geometry/GridHelpers.h"
+#include <stdexcept>
+
+#include "FRS_freestyle.h"
+
#include "BoxGrid.h"
-#include "SphericalGrid.h"
-#include "OccluderSource.h"
#include "CulledOccluderSource.h"
#include "HeuristicGridDensityProviderFactory.h"
+#include "OccluderSource.h"
+#include "SphericalGrid.h"
+#include "ViewMapBuilder.h"
+
+#include "../geometry/GridHelpers.h"
+#include "../geometry/GeomUtils.h"
+
+#include "../winged_edge/WFillGrid.h"
-#define logging 0
+#define LOGGING FALSE
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& edge, vector<WVertex*>& faceVertices)
+static void findOccludee(FEdge *fe, G& grid, I& occluders, real epsilon, WFace **oaWFace,
+ Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices)
{
- WFace *face = 0;
- if(fe->isSmooth()){
- FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe);
- face = (WFace*)fes->face();
- }
- WFace * oface;
- bool skipFace;
-
- WVertex::incoming_edge_iterator ie;
-
- *oaWFace = 0;
- 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 > 0
- 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, edge, p->getNormal(), d, t, epsilon)) {
-#if logging > 0
-cout << "\t\tRejecting occluder for target coincidence." << endl;
-#endif
- continue;
- }
- }
-
- if(p->rayIntersect(A, v, t, t_u, t_v))
- {
-#if logging > 0
-cout << "\t\tRay " << A << " * " << v << " intersects at time " << t << endl;
-#endif
-#if logging > 0
-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 logging > 0
-cout << "\t\tIs occludee" << endl;
-#endif
- }
- }
+ 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
+ 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, edge, p->getNormal(), d, t, epsilon))
+ {
+ #if LOGGING
+ cout << "\t\tRejecting occluder for target coincidence." << endl;
+ #endif
+ continue;
+ }
+ }
- occluders.reportDepth(A, v, t);
- }
+ if (p->rayIntersect(A, v, t, t_u, t_v)) {
+ #if LOGGING
+ 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 LOGGING
+ cout << "\t\tIs occludee" << endl;
+ #endif
+ }
+ }
+ }
- }
-
- if(noIntersection)
- *oaWFace = 0;
- }
+ occluders.reportDepth(A, v, t);
+ }
+ }
+
+ if (noIntersection)
+ *oaWFace = NULL;
+ }
}
template <typename G, typename I>
-static void findOccludee(FEdge *fe, G& grid, real epsilon, ViewEdge* ve, WFace** oaFace)
+static void findOccludee(FEdge *fe, G& grid, real epsilon, ViewEdge *ve, WFace **oaFace)
{
- Vec3r A;
- Vec3r edge;
- Vec3r origin;
- A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
- edge = Vec3r((fe)->vertexB()->point3D()-(fe)->vertexA()->point3D());
- 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 = 0;
- if(fe->isSmooth()) {
- FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe);
- face = (WFace*)fes->face();
- }
-
- if(0 != face) {
- face->RetrieveVertexList(faceVertices);
- }
-
- I occluders(grid, A, epsilon);
- findOccludee<G, I>(fe, grid, occluders, epsilon, oaFace, u, A, origin, edge, faceVertices);
+ Vec3r A;
+ Vec3r edge;
+ Vec3r origin;
+ A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
+ edge = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
+ 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, edge, 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)
+static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon, ViewEdge *ve, WFace **oaWFace,
+ set<ViewShape*> *foundOccluders)
{
- int qi = 0;
-
- Vec3r center;
- Vec3r edge;
- Vec3r origin;
-
- center = fe->center3d();
- edge = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
- 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 = 0;
- 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 > 0
- 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
+ int qi = 0;
-#if logging > 0
- 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());
- 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());
-#endif
-
- if(0 != face)
- {
-#if logging > 0
-cout << "\t\tDetermining face adjacency...";
-#endif
- skipFace = false;
-
- if(face == oface) {
-#if logging > 0
-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) {
-#if logging > 0
-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, edge, p->getNormal(), d, t, epsilon)) {
-#if logging > 0
-cout << "\t\tRejecting occluder for target coincidence." << endl;
-#endif
- continue;
- }
- }
+ Vec3r center;
+ Vec3r edge;
+ Vec3r origin;
-#if logging > 0
+ center = fe->center3d();
+ edge = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
+ origin = Vec3r(fe->vertexA()->point3D());
- 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;
+ 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
+ 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());
+ 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());
+ #endif
+
+ if (face)
+ {
+ #if LOGGING
+ cout << "\t\tDetermining face adjacency...";
+ #endif
+ skipFace = false;
+
+ if (face == oface) {
+ #if LOGGING
+ cout << " Rejecting occluder for face concurrency." << endl;
+ #endif
+ continue;
+ }
-#endif
- if(p->rayIntersect(center, u, t, t_u, t_v))
- {
-#if logging > 0
-cout << "\t\tRay " << center << " * " << u << " intersects at time " << t << " (raylength is " << raylength << ")" << endl;
-#endif
-#if logging > 0
-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 logging > 0
-cout << "\t\tIs occluder" << endl;
-#endif
- if ( foundOccluders != NULL ) {
- ViewShape *vshape = viewMap->viewShape(oface->GetVertex(0)->shape()->GetId());
- foundOccluders->insert(vshape);
- }
+ for (vector<WVertex*>::iterator fv = faceVertices.begin(), fvend = faceVertices.end(); fv != fvend; ++fv) {
+ if ((*fv)->isBoundary())
+ continue;
- ++qi;
+ 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
+ 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, edge, p->getNormal(), d, t, epsilon)) {
+ #if LOGGING
+ cout << "\t\tRejecting occluder for target coincidence." << endl;
+ #endif
+ continue;
+ }
+ }
- if(! grid.enableQI())
- break;
- }
+ #if LOGGING
+ 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 LOGGING
+ 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 LOGGING
+ 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);
+ occluders.reportDepth(center, u, t);
+ }
+ }
}
- }
- // Find occludee
- findOccludee<G, I>(fe, grid, occluders, epsilon, oaWFace, u, center, origin, edge, faceVertices);
+ // Find occludee
+ findOccludee<G, I>(fe, grid, occluders, epsilon, oaWFace, u, center, origin, edge, faceVertices);
- return qi;
+ return qi;
}
-// computeCumulativeVisibility returns the lowest x such that the majority
-// of FEdges have QI <= x
+// computeCumulativeVisibility returns the lowest x such that the majority of FEdges have QI <= x
//
-// This was probably the original intention of the "normal" algorithm
-// on which computeDetailedVisibility is based. But because the "normal"
-// algorithm chooses the most popular QI, without considering any other
-// values, a ViewEdge with FEdges having QIs of 0, 21, 22, 23, 24 and 25
-// will end up having a total QI of 0, even though most of the FEdges are
-// heavily occluded. computeCumulativeVisibility will treat this case as
-// a QI of 22 because 3 out of 6 occluders have QI <= 22.
+// This was probably the original intention of the "normal" algorithm on which computeDetailedVisibility is based.
+// But because the "normal" algorithm chooses the most popular QI, without considering any other values, a ViewEdge
+// with FEdges having QIs of 0, 21, 22, 23, 24 and 25 will end up having a total QI of 0, even though most of the
+// 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)
{
- vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
-
- FEdge * fe, *festart;
- int nSamples = 0;
- vector<WFace*> wFaces;
- WFace *wFace = 0;
- 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 > 0
-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);
-#if logging > 0
-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.
- 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 > 0
-cout << "\tqiMajority: " << qiMajority << endl;
-#endif
+ vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
- 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)) {
- tmpQI = computeVisibility<G, I>(ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders); //ARB: change &wFace to wFace and use reference in called function
-#if logging > 0
-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<G, I>(fe, grid, epsilon, *ve, &wFace); //ARB: change &wFace to wFace and use reference in called function
-#if logging > 0
-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);
-#if logging > 0
-cout << "\tFound occludee" << endl;
-#endif
- } else {
- fe->setOccludeeEmpty(true);
- }
-
- ++nSamples;
- fe = fe->nextEdge();
- }
- while((maxCard < qiMajority) && (0!=fe) && (fe!=festart));
-#if logging > 0
-cout << "\tFinished with " << nSamples << " samples, maxCard = " << maxCard << endl;
-#endif
+ 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
+ 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);
+ #if LOGGING
+ cout << "\tCulled." << endl;
+ #endif
+ continue;
+ }
- // 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
- // 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 > 0
-cout << "\tConclusion: QI = " << maxIndex << ", " << (*ve)->occluders_size() << " occluders." << endl;
-#endif
- // occludee --
- if(!wFaces.empty())
- {
- if(wFaces.size() <= (float)nSamples/2.f)
- {
- (*ve)->setaShape(0);
- }
- else
- {
- ViewShape *vshape = ioViewMap->viewShape((*wFaces.begin())->GetVertex(0)->shape()->GetId());
- (*ve)->setaShape(vshape);
- }
- }
-
- wFaces.clear();
- }
+ // 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.
+ 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
+ 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);
+ #if LOGGING
+ 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);
+ #if LOGGING
+ 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);
+ #if LOGGING
+ cout << "\tFound occludee" << endl;
+ #endif
+ }
+ else {
+ fe->setOccludeeEmpty(true);
+ }
+
+ ++nSamples;
+ fe = fe->nextEdge();
+ } while ((maxCard < qiMajority) && (fe) && (fe != festart));
+
+ #if LOGGING
+ 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));
+ }
+ #if LOGGING
+ 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();
+ }
}
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 = 0;
- 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 > 0
-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);
-#if logging > 0
-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.
- 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 > 0
-cout << "\tqiMajority: " << qiMajority << endl;
-#endif
+ vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
- 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)) {
- tmpQI = computeVisibility<G, I>(ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders); //ARB: change &wFace to wFace and use reference in called function
-#if logging > 0
-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<G, I>(fe, grid, epsilon, *ve, &wFace); //ARB: change &wFace to wFace and use reference in called function
-#if logging > 0
-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);
-#if logging > 0
-cout << "\tFound occludee" << endl;
-#endif
- } else {
- fe->setOccludeeEmpty(true);
- }
-
- ++nSamples;
- fe = fe->nextEdge();
- }
- while((maxCard < qiMajority) && (0!=fe) && (fe!=festart));
-#if logging > 0
-cout << "\tFinished with " << nSamples << " samples, maxCard = " << maxCard << endl;
-#endif
+ 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
+ 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);
+ #if LOGGING
+ cout << "\tCulled." << endl;
+ #endif
+ continue;
+ }
- // 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 > 0
-cout << "\tConclusion: QI = " << maxIndex << ", " << (*ve)->occluders_size() << " occluders." << endl;
-#endif
- // occludee --
- if(!wFaces.empty())
- {
- if(wFaces.size() <= (float)nSamples/2.f)
- {
- (*ve)->setaShape(0);
- }
- else
- {
- ViewShape *vshape = ioViewMap->viewShape((*wFaces.begin())->GetVertex(0)->shape()->GetId());
- (*ve)->setaShape(vshape);
- }
- }
-
- wFaces.clear();
- }
+ // 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.
+ 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
+ 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);
+ #if LOGGING
+ 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);
+ #if LOGGING
+ 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);
+ #if LOGGING
+ cout << "\tFound occludee" << endl;
+ #endif
+ }
+ else {
+ fe->setOccludeeEmpty(true);
+ }
+
+ ++nSamples;
+ fe = fe->nextEdge();
+ } while ((maxCard < qiMajority) && (fe) && (fe != festart));
+
+ #if LOGGING
+ 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));
+ }
+ #if LOGGING
+ 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();
+ }
}
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 = 0;
- 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 != NULL && 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.
- 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 == NULL || ! fe->isInImage() ) {
- fe = fe->nextEdge();
- continue;
- }
- if (even_test)
- {
- if((maxCard < qiMajority)) {
- tmpQI = computeVisibility<G, I>(ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders); //ARB: change &wFace to wFace and use reference in called function
-
- //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<G, I>(fe, grid, epsilon, *ve, &wFace); //ARB: change &wFace to wFace and use reference in called function
- }
-
- 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) && (0!=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.
+ 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>
@@ -830,14 +829,13 @@ static void computeVeryFastVisibility(ViewMap *ioViewMap, G& grid, real epsilon)
{
vector<ViewEdge*>& vedges = ioViewMap->ViewEdges();
- FEdge* fe;
+ FEdge *fe;
unsigned qi = 0;
- WFace* wFace = 0;
+ WFace *wFace = 0;
- for(vector<ViewEdge*>::iterator ve=vedges.begin(), veend=vedges.end(); ve!=veend; ve++)
- {
+ for (vector<ViewEdge*>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
// Find an edge to test
- if ( ! (*ve)->isInImage() ) {
+ if (!(*ve)->isInImage()) {
// This view edge has been proscenium culled
(*ve)->setQI(255);
(*ve)->setaShape(0);
@@ -845,16 +843,13 @@ static void computeVeryFastVisibility(ViewMap *ioViewMap, G& grid, real epsilon)
}
fe = (*ve)->fedgeA();
// Find a FEdge inside the occluder proscenium to test for visibility
- FEdge* festart = fe;
- while ( fe != NULL && ! fe->isInImage() ) {
+ FEdge *festart = fe;
+ while (fe && !fe->isInImage() && fe != festart) {
fe = fe->nextEdge();
- if ( fe == festart ) {
- break;
- }
}
// Test edge
- if ( fe == NULL || ! fe->isInImage() ) {
+ if (!fe || !fe->isInImage()) {
// There are no occludable FEdges on this ViewEdge
// This should be impossible.
cout << "View Edge in viewport without occludable FEdges: " << (*ve)->getId() << endl;
@@ -862,80 +857,81 @@ static void computeVeryFastVisibility(ViewMap *ioViewMap, G& grid, real epsilon)
// Treat this edge as fully visible with no occludee
qi = 0;
wFace = NULL;
- } else {
+ }
+ else {
qi = computeVisibility<G, I>(ioViewMap, fe, grid, epsilon, *ve, &wFace, NULL);
}
// Store test results
- if(wFace)
- {
+ if (wFace) {
vector<Vec3r> vertices;
- for ( int i = 0, numEdges = wFace->numberOfEdges(); i < numEdges; ++i ) {
+ 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;
+ 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
- {
+ }
+ else {
(*ve)->setaShape(0);
}
(*ve)->setQI(qi);
- }
-
+ }
}
-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]);
- size[i] += size[i]/10.0; // let make the grid 1/10 bigger to avoid numerical errors while computing triangles/cells intersections
- if(size[i]==0){
- 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();
+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]);
+ size[i] += size[i]/10.0; // let make the grid 1/10 bigger to avoid numerical errors while computing triangles/cells intersections
+ if (size[i] == 0) {
+ 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 = new ViewMap;
- _currentId = 1;
- _currentFId = 0;
- _currentSVertexId = 0;
-
- // Builds initial view edges
- computeInitialViewEdges(we);
-
- // Detects cusps
- computeCusps(_ViewMap);
-
- // Compute intersections
- ComputeIntersections(_ViewMap, sweep_line, epsilon);
-
- // Compute visibility
- ComputeEdgesVisibility(_ViewMap, we, bbox, sceneNumFaces, iAlgo, epsilon);
-
- return _ViewMap;
+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;
+
+ // Builds initial view edges
+ computeInitialViewEdges(we);
+
+ // Detects cusps
+ computeCusps(_ViewMap);
+
+ // Compute intersections
+ ComputeIntersections(_ViewMap, sweep_line, epsilon);
+
+ // Compute visibility
+ ComputeEdgesVisibility(_ViewMap, we, bbox, sceneNumFaces, iAlgo, epsilon);
+
+ 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]));
}
-static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
+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());
@@ -944,20 +940,21 @@ static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
return GeomUtils::intersect2dSeg2dArea (min, max, A, B);
}
-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] );
+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]);
}
-void ViewMapBuilder::CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4], bool extensiveFEdgeSearch) {
+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.
+ // This avoids the complications of trying to delete edges from the ViewMap.
- // Non-displayable view edges will be skipped over during
- // visibility calculation.
+ // 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,
+ // 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
@@ -966,34 +963,30 @@ void ViewMapBuilder::CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], r
prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
cout << "Proscenium culling:" << endl;
- cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2] << ", " << viewProscenium[3] << "]"<< 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
+
+ // 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
+ // 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.
+ // 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++) {
+ 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.
+ // 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
@@ -1005,27 +998,26 @@ void ViewMapBuilder::CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], r
// 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.
+ // 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()) ) {
+ // 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 {
+ }
+ else {
real d = distance2D(fe->center2d(), prosceniumOrigin);
// If center point is closer to viewport origin than current target
- if ( bestOccluderTarget == NULL || d < bestOccluderDistance ) {
+ if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
// Then store as bestOccluderTarget
bestOccluderDistance = d;
bestOccluderTarget = fe;
@@ -1034,33 +1026,35 @@ void ViewMapBuilder::CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], r
}
// If feature edge crosses the view proscenium
- if ( ! (*ve)->isInImage() && crossesProscenium(viewProscenium, fe) ) {
+ 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() ) );
+ } 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 != NULL && fe != festart ) {
+ 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 ) {
+ // 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] ) {
+ if (point[0] < occluderProscenium[0]) {
occluderProscenium[0] = point[0];
- } else if ( point[0] > occluderProscenium[1] ) {
+ }
+ else if (point[0] > occluderProscenium[1]) {
occluderProscenium[1] = point[0];
}
- if ( point[1] < occluderProscenium[2] ) {
+ if (point[1] < occluderProscenium[2]) {
occluderProscenium[2] = point[1];
- } else if ( point[1] > occluderProscenium[3] ) {
+ }
+ else if (point[1] > occluderProscenium[3]) {
occluderProscenium[3] = point[1];
}
// Use bestOccluderTarget for visibility determination
@@ -1078,22 +1072,18 @@ void ViewMapBuilder::CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], r
// 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 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() ) {
+ for (ve = ioViewMap->ViewEdges().begin(), veend = ioViewMap->ViewEdges().end(); ve != veend; ve++) {
+ if (!(*ve)->isInImage()) {
continue;
}
// For each feature edge,
@@ -1101,255 +1091,257 @@ void ViewMapBuilder::CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], r
FEdge *fe = festart;
do {
// If not (already) visible and center point inside occluder proscenium,
- if ( ! fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d()) ) {
+ if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
// Use the feature edge for visibility determination
fe->setIsInImage(true);
}
fe = fe->nextEdge();
- } while ( fe != NULL && fe != festart );
+ } while (fe && fe != festart);
}
}
}
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->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);
-
- _pViewEdgeBuilder->setCurrentViewId(_currentId); // we want to number the view edges in a unique way for the while scene.
- _pViewEdgeBuilder->setCurrentFId(_currentFId); // we want to number the feature edges in a unique way for the while scene.
- _pViewEdgeBuilder->setCurrentSVertexId(_currentFId); // we want to number the SVertex in a unique way for the while scene.
- _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->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 = 0;
- 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!=0)
- 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!=0)
- cusp->setNature(cusp->getNature()|Nature::CUSP);
- }
- }
- fe = fe->nextEdge();
- }while((fe!=0) && (fe!=fefirst));
- }
- for(ve=newVEdges.begin(), veend=newVEdges.end();
- ve!=veend;
- ++ve){
- (*ve)->viewShape()->AddEdge(*ve);
- vedges.push_back(*ve);
- }
+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);
+ }
}
-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)
{
auto_ptr<GridHelpers::Transform> transform;
auto_ptr<OccluderSource> source;
- if ( _orthographicProjection ) {
+ if (_orthographicProjection) {
transform.reset(new BoxGrid::Transform);
- } else {
+ }
+ else {
transform.reset(new SphericalGrid::Transform);
}
- if ( cull ) {
+ if (cull) {
source.reset(new CulledOccluderSource(*transform, we, *ioViewMap, true));
- } else {
+ }
+ else {
source.reset(new OccluderSource(*transform, we));
}
auto_ptr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
- if ( _orthographicProjection ) {
+ if (_orthographicProjection) {
BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
computeCumulativeVisibility<BoxGrid, BoxGrid::Iterator>(ioViewMap, grid, epsilon, _pRenderMonitor);
- } else {
+ }
+ 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)
{
auto_ptr<GridHelpers::Transform> transform;
auto_ptr<OccluderSource> source;
- if ( _orthographicProjection ) {
+ if (_orthographicProjection) {
transform.reset(new BoxGrid::Transform);
- } else {
+ }
+ else {
transform.reset(new SphericalGrid::Transform);
}
- if ( cull ) {
+ if (cull) {
source.reset(new CulledOccluderSource(*transform, we, *ioViewMap, true));
- } else {
+ }
+ else {
source.reset(new OccluderSource(*transform, we));
}
auto_ptr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
- if ( _orthographicProjection ) {
+ if (_orthographicProjection) {
BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
computeDetailedVisibility<BoxGrid, BoxGrid::Iterator>(ioViewMap, grid, epsilon, _pRenderMonitor);
- } else {
+ }
+ 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)
{
- switch(iAlgo)
- {
- case ray_casting:
- cout << "Using ordinary ray casting" << endl;
- BuildGrid(we, bbox, sceneNumFaces);
- ComputeRayCastingVisibility(ioViewMap, epsilon);
- break;
- case ray_casting_fast:
- cout << "Using fast ray casting" << endl;
- BuildGrid(we, bbox, sceneNumFaces);
- ComputeFastRayCastingVisibility(ioViewMap, epsilon);
- break;
- case ray_casting_very_fast:
- cout << "Using very fast ray casting" << endl;
- BuildGrid(we, bbox, sceneNumFaces);
- ComputeVeryFastRayCastingVisibility(ioViewMap, epsilon);
- break;
- case ray_casting_culled_adaptive_traditional:
- 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:
- 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:
- 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:
- 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:
+ cout << "Using ordinary ray casting" << endl;
+ BuildGrid(we, bbox, sceneNumFaces);
+ ComputeRayCastingVisibility(ioViewMap, epsilon);
+ break;
+ case ray_casting_fast:
+ cout << "Using fast ray casting" << endl;
+ BuildGrid(we, bbox, sceneNumFaces);
+ ComputeFastRayCastingVisibility(ioViewMap, epsilon);
+ break;
+ case ray_casting_very_fast:
+ cout << "Using very fast ray casting" << endl;
+ BuildGrid(we, bbox, sceneNumFaces);
+ ComputeVeryFastRayCastingVisibility(ioViewMap, epsilon);
+ break;
+ case ray_casting_culled_adaptive_traditional:
+ 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:
+ 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:
+ 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:
+ 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;
@@ -1357,977 +1349,913 @@ 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 = 0;
- 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 > 0
-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;
-#if logging > 0
-cout << "\tqiMajority: " << qiMajority << endl;
-#endif
+ 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;
+ }
- 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 > 0
-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++);
-#if logging > 0
-cout << "\tFEdge: occludee only (" << (aFace != NULL ? "found" : "not found") << ")" << endl;
-#endif
- }
-
- if(aFace) {
- fe->setaFace(*aFace);
- aFaces.push_back(aFace);
- fe->setOccludeeEmpty(false);
-#if logging > 0
-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) && (0!=fe) && (fe!=festart));
-#if logging > 0
-cout << "\tFinished with " << nSamples << " samples, maxCard = " << maxCard << endl;
-#endif
+ 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
+ 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;
+ #if LOGGING
+ 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++);
+
+ #if LOGGING
+ 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;
+ }
- // ViewEdge
- // qi --
- (*ve)->setQI(maxIndex);
- // occluders --
- for(set<ViewShape*>::iterator o=occluders.begin(), oend=occluders.end();
- o!=oend;
- ++o)
- (*ve)->AddOccluder((*o));
-#if logging > 0
-cout << "\tConclusion: QI = " << maxIndex << ", " << (*ve)->occluders_size() << " occluders." << endl;
-#endif
- // occludee --
- if(!aFaces.empty())
- {
- if(aFaces.size() <= (float)nSamples/2.f)
- {
- (*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();
- }
+ 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
+ cout << "\tFEdge: occludee only (" << (aFace != NULL ? "found" : "not found") << ")" << endl;
+ #endif
+ }
+
+ if (aFace) {
+ fe->setaFace(*aFace);
+ aFaces.push_back(aFace);
+ fe->setOccludeeEmpty(false);
+ #if LOGGING
+ 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));
+ #if LOGGING
+ 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));
+ #if LOGGING
+ 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();
+ }
}
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 = 0;
- 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) && (0!=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;
- // 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)
- (*ve)->setaShape(vshape);
- }
- }
-
- //(*ve)->setaFace(aFace);
-
- if(progressBarDisplay) {
- counter--;
- if (counter <= 0) {
- counter = progressBarStep;
- _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
- }
- }
- aFaces.clear();
- }
+ 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)
+#endif
+ (*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 = 0;
- 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& edge, vector<WVertex*>& faceVertices)
+void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
+ Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices)
{
- WFace *face = 0;
- 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 = 0;
- 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(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
- {
- if(GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, 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 = 0;
- }
+ 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, edge, 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 edge;
- Vec3r origin;
- A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D())/2.0);
- edge = Vec3r((fe)->vertexB()->point3D()-(fe)->vertexA()->point3D());
- 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 = 0;
- if(fe->isSmooth()){
- FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe);
- face = (WFace*)fes->face();
- }
- if(0 != face)
- face->RetrieveVertexList(faceVertices);
-
- return FindOccludee(fe,iGrid, epsilon, oaPolygon, timestamp,
- u, A, origin, edge, faceVertices);
+ OccludersSet occluders;
+
+ Vec3r A;
+ Vec3r edge;
+ Vec3r origin;
+ A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
+ edge = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
+ 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, edge, 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 edge;
- Vec3r origin;
-
- center = fe->center3d();
- edge = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
- 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;
- }
-
-
- // 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 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();
- //cout << "grid origin " << iGrid->getOrigin().x() << "," << iGrid->getOrigin().y() << "," << iGrid->getOrigin().z() << endl;
- //cout << "center " << center.x() << "," << center.y() << "," << center.z() << endl;
-
- iGrid->castRay(center, vp, occluders, timestamp);
-
- WFace *face = 0;
- 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 > 1
-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;
-
-#if logging > 1
-cout << "\t\tp: " << ((*p)->getVertices())[0] << ((*p)->getVertices())[1] << ((*p)->getVertices())[2] << ", norm: " << (*p)->getNormal() << endl;
-#endif
+ OccludersSet occluders;
+ int qi = 0;
+
+ Vec3r center;
+ Vec3r edge;
+ Vec3r origin;
+
+ center = fe->center3d();
+ edge = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
+ 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 != face)
- {
-#if logging > 1
-cout << "\t\tDetermining face adjacency...";
-#endif
- skipFace = false;
-
- if(face == oface) {
-#if logging > 1
-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) {
-#if logging > 1
-cout << " Rejecting occluder for face adjacency." << endl;
+#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;
+ }
#endif
- continue;
- }
+
+ Vec3r vp;
+ if (_orthographicProjection) {
+ vp = Vec3r(center.x(), center.y(), _viewpoint.z());
}
- else
- {
- // check whether the edge and the polygon plane are coincident:
- //-------------------------------------------------------------
- //first let us compute the plane equation.
-
- if(GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, normal, d, t, epsilon)) {
-#if logging > 1
-cout << "\t\tRejecting occluder for target coincidence." << endl;
+ else {
+ vp = Vec3r(_viewpoint);
+ }
+ Vec3r u(vp - center);
+ real raylength = u.norm();
+ u.normalize();
+#if 0
+ cout << "grid origin " << iGrid->getOrigin().x() << "," << iGrid->getOrigin().y() << ","
+ << iGrid->getOrigin().z() << endl;
+ cout << "center " << center.x() << "," << center.y() << "," << center.z() << endl;
#endif
- continue;
- }
+
+ 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
+ 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;
+
+ #if LOGGING
+ cout << "\t\tp: " << ((*p)->getVertices())[0] << ((*p)->getVertices())[1] << ((*p)->getVertices())[2]
+ << ", norm: " << (*p)->getNormal() << endl;
+ #endif
+
+ if (face) {
+ #if LOGGING
+ cout << "\t\tDetermining face adjacency...";
+ #endif
+ skipFace = false;
+
+ if (face == oface) {
+ #if LOGGING
+ cout << " Rejecting occluder for face concurrency." << endl;
+ #endif
+ continue;
+ }
- if((*p)->rayIntersect(center, u, t, t_u, t_v))
- {
-#if logging > 1
-cout << "\t\tRay " << vp << " * " << u << " intersects at time " << t << " (raylength is " << raylength << ")" << endl;
-#endif
-#if logging > 1
-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 logging > 1
-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;
- }
+ 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
+ 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, edge, normal, d, t, epsilon)) {
+ #if LOGGING
+ cout << "\t\tRejecting occluder for target coincidence." << endl;
+ #endif
+ continue;
+ }
+ }
+
+ if ((*p)->rayIntersect(center, u, t, t_u, t_v)) {
+ #if LOGGING
+ 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 LOGGING
+ 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, edge, origin, faceVertices);
+ // Find occludee
+ FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, center, edge, origin, faceVertices);
- return qi;
+ return qi;
}
void ViewMapBuilder::ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo, real epsilon)
{
- switch(iAlgo)
- {
- case sweep_line:
- ComputeSweepLineIntersections(ioViewMap, epsilon);
- break;
- default:
- break;
- }
- 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;
- }
- }
+ switch (iAlgo) {
+ case sweep_line:
+ ComputeSweepLineIntersections(ioViewMap, epsilon);
+ break;
+ default:
+ break;
+ }
+ 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;
+ }
+ }
}
-struct less_SVertex2D : public binary_function<SVertex*, SVertex*, bool>
+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;
- }
+ 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 Segment<FEdge*, Vec3r> segment;
typedef Intersection<segment> intersection;
-struct less_Intersection : public binary_function<intersection*, intersection*, bool>
+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;
- }
+ 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>
+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();
-
- if((!(((f1)->getNature() & Nature::SILHOUETTE) || ((f1)->getNature() & Nature::BORDER))) && (!(((f2)->getNature() & Nature::SILHOUETTE) || ((f2)->getNature() & Nature::BORDER))))
- return false;
-
- return true;
- }
+ silhouette_binary_rule() : binary_rule<segment,segment>() {}
+
+ 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;
+ }
+
+ 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();
- // 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;
- // }
-
- 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;
+ vector<SVertex*>& svertices = ioViewMap->SVertices();
+ bool progressBarDisplay = false;
+ unsigned sVerticesSize = svertices.size();
+ unsigned fEdgesSize = ioViewMap->FEdges().size();
+#if 0
+ 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;
#if 0
- 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 -- b1 %e, %e\n", a1[0], a1[1], b1[0], b1[1]);
- printf("a2 %e, %e -- b2 %e, %e\n", a2[0], a2[1], b2[0], 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 -- B1 %e, %e, %e\n", A1[0], A1[1], A1[2], B1[0], B1[1], B1[2]);
- printf("A2 %e, %e, %e -- B2 %e, %e, %e\n", A2[0], A2[1], A2[2], B2[0], B2[1], B2[2]);
- }
+ 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 -- b1 %e, %e\n", a1[0], a1[1], b1[0], b1[1]);
+ printf("a2 %e, %e -- b2 %e, %e\n", a2[0], a2[1], b2[0], 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 -- B1 %e, %e, %e\n", A1[0], A1[1], A1[2], B1[0], B1[1], B1[2]);
+ printf("A2 %e, %e, %e -- B2 %e, %e, %e\n", A2[0], A2[1], A2[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) {
+ 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;
- _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;
- }
- }
-}
+ 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;
+ }
+ }
+}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
index a41df92062e..2d5d24a0ffe 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
@@ -1,248 +1,257 @@
-//
-// Filename : ViewMapBuilder.h
-// Author(s) : Stephane Grabli
-// Purpose : Class to build silhouette edges from a
-// Winged-Edge structure
-// Date of creation : 25/03/2002
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef VIEWMAPBUILDER_H
-# define VIEWMAPBUILDER_H
-
-# include "Silhouette.h"
-# include <vector>
-# include "../system/FreestyleConfig.h"
-# include "../geometry/Geom.h"
-# include "../scene_graph/NodeGroup.h"
-# include "../winged_edge/WXEdge.h"
-# include "../geometry/GeomUtils.h"
-# include "../geometry/Grid.h"
-# include "../system/ProgressBar.h"
-# include "../system/RenderMonitor.h"
-# include "../geometry/SweepLine.h"
-# include "ViewMap.h"
-# include "SilhouetteGeomEngine.h"
-# include "../scene_graph/TriangleRep.h"
-# include "../winged_edge/WEdge.h"
-# include "ViewEdgeXBuilder.h"
-# include "../system/TimeUtils.h"
-# include "GridDensityProvider.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_VIEW_MAP_BUILDER_H__
+#define __FREESTYLE_VIEW_MAP_BUILDER_H__
+
+/** \file blender/freestyle/intern/view_map/ViewMapBuilder.h
+ * \ingroup freestyle
+ * \brief Class to build silhouette edges from a Winged-Edge structure
+ * \author Stephane Grabli
+ * \date 25/03/2002
+ */
+
+#include <vector>
+
+#include "GridDensityProvider.h"
+#include "Silhouette.h"
+#include "SilhouetteGeomEngine.h"
+#include "ViewEdgeXBuilder.h"
+#include "ViewMap.h"
+
+#include "../geometry/Geom.h"
+#include "../geometry/GeomUtils.h"
+#include "../geometry/Grid.h"
+#include "../geometry/SweepLine.h"
+
+#include "../scene_graph/NodeGroup.h"
+#include "../scene_graph/TriangleRep.h"
+
+#include "../system/FreestyleConfig.h"
+#include "../system/ProgressBar.h"
+#include "../system/RenderMonitor.h"
+#include "../system/TimeUtils.h"
+
+#include "../winged_edge/WEdge.h"
+#include "../winged_edge/WXEdge.h"
using namespace Geometry;
class LIB_VIEW_MAP_EXPORT 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;
- ViewMap * _ViewMap; // result
- //SilhouetteGeomEngine _GeomEngine;
- ProgressBar *_pProgressBar;
- RenderMonitor *_pRenderMonitor;
- Vec3r _viewpoint;
- bool _orthographicProjection;
- Grid* _Grid;
- ViewEdgeXBuilder *_pViewEdgeBuilder;
- bool _EnableQI;
- double _epsilon;
+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;
- // tmp values:
- int _currentId;
- int _currentFId;
- int _currentSVertexId;
-
+ inline ViewMapBuilder()
+ {
+ _pProgressBar = NULL;
+ _pRenderMonitor = NULL;
+ _Grid = NULL;
+ _currentId = 1;
+ _currentFId = 0;
+ _currentSVertexId = 0;
+ _pViewEdgeBuilder = new ViewEdgeXBuilder;
+ _EnableQI = true;
+ }
-public:
+ 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);
- 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 = 0;
- _pRenderMonitor = 0;
- _Grid = 0;
- _currentId = 1;
- _currentFId = 0;
- _currentSVertexId = 0;
- _pViewEdgeBuilder = new ViewEdgeXBuilder;
- _EnableQI = true;
- }
-
- inline ~ViewMapBuilder()
- {
- if(_pViewEdgeBuilder){
- delete _pViewEdgeBuilder;
- _pViewEdgeBuilder = 0;
- }
- }
-
- /* 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=1e-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=1e-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;}
+ /*! 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);
- /*! Computes intersections on all edges of the scene using a sweep line
- * algorithm*/
- void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1e-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=1e-6);
- void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
- void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-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& edge, vector<WVertex*>& faceVertices);
+ 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& edge, vector<WVertex*>& faceVertices);
};
-#endif // VIEWMAPBUILDER_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 210bb3b8750..978272848ec 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
@@ -1,1245 +1,1258 @@
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/view_map/ViewMapIO.cpp
+ * \ingroup freestyle
+ * \brief Functions to manage I/O for the view map
+ * \author Emmanuel Turquin
+ * \date 09/01/2003
+ */
#include "ViewMapIO.h"
#ifdef IRIX
-# define WRITE(n) Internal::write<sizeof((n))>(out, (const char*)(&(n)))
-# define READ(n) Internal::read<sizeof((n))>(in, (char*)(&(n)))
+# define WRITE(n) Internal::write<sizeof((n))>(out, (const char *)(&(n)))
+# define READ(n) Internal::read<sizeof((n))>(in, (char *)(&(n)))
#else
-# define WRITE(n) out.write((const char*)(&(n)), sizeof((n)))
-# define READ(n) in.read((char*)(&(n)), sizeof((n)))
+# define WRITE(n) out.write((const char *)(&(n)), sizeof((n)))
+# define READ(n) in.read((char *)(&(n)), sizeof((n)))
#endif
-#define WRITE_IF_NON_NULL(ptr) if ((ptr) == NULL) { WRITE(ZERO); } else { WRITE((ptr)->userdata); }
-#define READ_IF_NON_NULL(ptr, array) READ(tmp); if (tmp == ZERO) { (ptr) = NULL; } else { (ptr) = (array)[tmp]; }
+#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
namespace ViewMapIO {
- namespace Internal {
+namespace Internal {
- ViewMap* g_vm;
+ViewMap* g_vm;
- //////////////////// 'load' Functions ////////////////////
+//////////////////// '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;
+inline int load(istream& in, Polygon3r& p)
+{
+ unsigned tmp;
+
+ // Id
READ(tmp);
- v[1] = tmp;
+ p.setId(tmp);
+
+ // vertices (List)
+ vector<Vec3r> tmp_vec;
+ Vec3r v;
READ(tmp);
- v[2] = tmp;
- }
- return 0;
- }
+ 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)
- inline
- int load(istream& in, Polygon3r& p) {
+ return 0;
+}
- unsigned tmp;
+inline int load(istream& in, FrsMaterial& m)
+{
+ float tmp_array[4];
+ int i;
- // Id
- READ(tmp);
- p.setId(tmp);
+ // 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]);
- // vertices (List)
- vector<Vec3r> tmp_vec;
- Vec3r v;
- READ(tmp);
- for (unsigned 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) {
-
- 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) {
-
- 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);
- }
+ // 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]);
- // 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) {
-
- if (!fe)
- return 1;
-
- bool b;
-
- FEdgeSmooth *fesmooth = 0;
- FEdgeSharp * fesharp = 0;
- 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);
-
- // hasVisibilityPoint
- // bool b;
- // READ(b);
- // fe->setHasVisibilityPoint(b);
-
- Vec3r v;
- unsigned int matindex;
-
- // VisibilityPointA
- // load(in, v);
- // fe->setVisibilityPointA(v);
-
- // VisibilityPointB
- // load(in, v);
- // fe->setVisibilityPointB(v);
-
- 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) {
-
- 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) {
-
- 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;
+ // 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)
+{
+ 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);
- ViewShape* vso;
- for (unsigned i = 0; i < size; i++) {
- READ_IF_NON_NULL(vso, g_vm->ViewShapes());
- ve->AddOccluder(vso);
- }
- }
+ for (i = 0; i < size; i++) {
+ FEdge *fe;
+ READ_IF_NON_NULL(fe, g_vm->FEdges());
+ vs->sshape()->AddChain(fe);
+ }
- return 0;
- }
+ // -> 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);
+ }
- static int load(istream& in, ViewVertex* vv) {
+ // ViewVertices (List)
+ READ(size);
+ for (i = 0; i < size; i++) {
+ ViewVertex *vv;
+ READ_IF_NON_NULL(vv, g_vm->ViewVertices());
+ vs->AddVertex(vv);
+ }
- if (!vv)
- return 1;
+ return 0;
+}
- 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);
+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);
- tv->setId(Id(id1, id2));
+ fe->setId(Id(id1, id2));
- // FrontSVertex
- SVertex* fsv;
- READ_IF_NON_NULL(fsv, g_vm->SVertices());
- tv->setFrontSVertex(fsv);
+ // Nature
+ Nature::EdgeNature nature;
+ READ(nature);
+ fe->setNature(nature);
- // 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());
+#if 0 // hasVisibilityPoint
+ bool b;
READ(b);
- tv->setFrontEdgeA(fea, b);
+ fe->setHasVisibilityPoint(b);
+#endif
- // FrontEdgeB
- ViewEdge* feb;
- READ_IF_NON_NULL(feb, g_vm->ViewEdges());
- READ(b);
- tv->setFrontEdgeB(feb, b);
+ Vec3r v;
+ unsigned int matindex;
- // BackEdgeA
- ViewEdge* bea;
- READ_IF_NON_NULL(bea, g_vm->ViewEdges());
- READ(b);
- tv->setBackEdgeA(bea, b);
+#if 0
+ // VisibilityPointA
+ load(in, v);
+ fe->setVisibilityPointA(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;
- // BackEdgeB
- ViewEdge* beb;
- READ_IF_NON_NULL(beb, g_vm->ViewEdges());
+ // aFace
+ load(in, p);
+ fe->setaFace(p);
+
+ // occludeeEmpty
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;
+ fe->setOccludeeEmpty(b);
+
+ // occludeeIntersection
+ load(in, v);
+ fe->setOccludeeIntersection(v);
+
+ return 0;
+}
+
+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);
- ViewEdge* ve;
- for (unsigned i = 0; i < size; i++) {
- READ_IF_NON_NULL(ve, g_vm->ViewEdges());
- READ(b);
- ntv->AddViewEdge(ve, b);
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ unsigned 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);
+ }
+
+ // min & max
+ // Do not need to be saved
+
+ return 0;
+}
+
+inline int save(ostream& out, const FrsMaterial& m)
+{
+ unsigned i;
+
+ // Diffuse
+ for (i = 0; i < 4; i++)
+ WRITE(m.diffuse()[i]);
+
+ // Specular
+ for (i = 0; i < 4; i++)
+ WRITE(m.specular()[i]);
+
+ // Ambient
+ for (i = 0; i < 4; i++)
+ WRITE(m.ambient()[i]);
+
+ // Emission
+ for (i = 0; i < 4; i++)
+ WRITE(m.emission()[i]);
+
+ // Shininess
+ float shininess = m.shininess();
+ WRITE(shininess);
+
+ return 0;
+}
+
+static int save(ostream& out, ViewShape *vs)
+{
+ if (!vs || !vs->sshape()) {
+ cerr << "Warning: null ViewShape" << endl;
+ return 1;
}
- }
-
- return 0;
- }
- //////////////////// 'save' Functions ////////////////////
+ unsigned tmp;
- inline
- int save(ostream& out, const Vec3r& v) {
+ // SShape
- if (Options::getFlags() & Options::FLOAT_VECTORS) {
- float tmp;
+ // -> 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);
- tmp = v[0];
+ // -> 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);
- tmp = v[1];
+ 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);
- tmp = v[2];
+ 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);
- } else {
- Vec3r::value_type tmp;
+ for (vector<ViewEdge*>::const_iterator i4 = vs->edges().begin(); i4 != vs->edges().end(); i4++)
+ WRITE_IF_NON_NULL(*i4);
- tmp = v[0];
+ // ViewVertices (List)
+ tmp = vs->vertices().size();
WRITE(tmp);
- tmp = v[1];
+ 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)
+{
+ if (!fe) {
+ cerr << "Warning: null FEdge" << endl;
+ return 1;
+ }
+
+ 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);
+
+ // Nature
+ Nature::EdgeNature nature = fe->getNature();
+ WRITE(nature);
+
+ bool b;
+
+#if 0
+ // hasVisibilityPoint
+ b = fe->hasVisibilityPoint();
+ WRITE(b);
+
+ // VisibilityPointA
+ save(out, fe->visibilityPointA());
+
+ // 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;
+}
+
+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);
- tmp = v[2];
+ for (i = sv->normals().begin(); i != sv->normals().end(); i++)
+ save(out, *i);
+
+ // FEdges (List)
+ tmp = sv->fedges().size();
WRITE(tmp);
- }
- return 0;
- }
-
-
- inline
- int save(ostream& out, const Polygon3r& p) {
-
- unsigned 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);
- }
-
- // min & max
- // Do not need to be saved
-
- return 0;
- }
-
-
- inline
- int save(ostream& out, const FrsMaterial& m) {
-
- unsigned i;
-
- // Diffuse
- for (i = 0; i < 4; i++)
- WRITE(m.diffuse()[i]);
-
- // Specular
- for (i = 0; i < 4; i++)
- WRITE(m.specular()[i]);
-
- // Ambient
- for (i = 0; i < 4; i++)
- WRITE(m.ambient()[i]);
-
- // Emission
- for (i = 0; i < 4; i++)
- WRITE(m.emission()[i]);
-
- // Shininess
- float shininess = m.shininess();
- WRITE(shininess);
-
- return 0;
- }
-
-
- 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 size = vs->sshape()->frs_materials().size();
- WRITE(size);
- for(unsigned 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) {
-
- if (!fe) {
- cerr << "Warning: null FEdge" << endl;
- return 1;
- }
-
- 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);
-
- // Nature
- Nature::EdgeNature nature = fe->getNature();
- WRITE(nature);
-
- bool b;
-
- // hasVisibilityPoint
- // b = fe->hasVisibilityPoint();
- // WRITE(b);
-
- // VisibilityPointA
- // save(out, fe->visibilityPointA());
- //
- // // VisibilityPointB
- // save(out, fe->visibilityPointB());
-
- 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) {
-
- 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) {
-
- if (!ve) {
- cerr << "Warning: null ViewEdge" << endl;
- return 1;
- }
-
- unsigned tmp;
-
- // Id
- Id::id_type id = ve->getId().getFirst();
- WRITE(id);
- id = ve->getId().getSecond();
- WRITE(id);
+ for (vector<FEdge*>::const_iterator j = sv->fedges_begin(); j != sv->fedges_end(); j++)
+ WRITE_IF_NON_NULL(*j);
- // Nature
- Nature::EdgeNature nature = ve->getNature();
- WRITE(nature);
+ return 0;
+}
- // QI
- unsigned qi = ve->qi();
- WRITE(qi);
- // Shape
- WRITE_IF_NON_NULL(ve->shape());
+static int save(ostream& out, ViewEdge *ve)
+{
+ if (!ve) {
+ cerr << "Warning: null ViewEdge" << endl;
+ return 1;
+ }
+
+ unsigned tmp;
- // aShape
- WRITE_IF_NON_NULL(ve->aShape());
-
- // FEdgeA
- WRITE_IF_NON_NULL(ve->fedgeA());
-
- // FEdgeB
- WRITE_IF_NON_NULL(ve->fedgeB());
-
- // A
- WRITE_IF_NON_NULL(ve->A());
-
- // 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));
- }
-
- return 0;
- }
-
-
- 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();
+ Id::id_type id = ve->getId().getFirst();
WRITE(id);
- id = tv->getId().getSecond();
+ id = ve->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();
+ // Nature
+ Nature::EdgeNature nature = ve->getNature();
+ WRITE(nature);
+
+ // QI
+ unsigned qi = ve->qi();
+ WRITE(qi);
+
+ // Shape
+ WRITE_IF_NON_NULL(ve->shape());
+
+ // aShape
+ WRITE_IF_NON_NULL(ve->aShape());
+
+ // FEdgeA
+ WRITE_IF_NON_NULL(ve->fedgeA());
+
+ // FEdgeB
+ WRITE_IF_NON_NULL(ve->fedgeB());
+
+ // A
+ WRITE_IF_NON_NULL(ve->A());
+
+ // 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));
+ }
+
+ return 0;
+}
+
+
+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;
+}
+
+} // End of namespace Internal
+
+
+//////////////////// "Public" 'load' and 'save' functions ////////////////////
+
+#define SET_PROGRESS(n) \
+ if (pb) { \
+ pb->setProgress((n)); \
+ } (void)0
+
+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 informations 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 + 1; 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 + 1; 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);
+ }
+#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;
+}
+
+
+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 = (void *)i0;
+ vm->ViewShapes()[i0]->sshape()->userdata = (void *)i0;
+ }
+ for (unsigned int i1 = 0; i1 < vm->FEdges().size(); i1++)
+ vm->FEdges()[i1]->userdata = (void *)i1;
+ for (unsigned int i2 = 0; i2 < vm->SVertices().size(); i2++)
+ vm->SVertices()[i2]->userdata = (void *)i2;
+ for (unsigned int i3 = 0; i3 < vm->ViewEdges().size(); i3++)
+ vm->ViewEdges()[i3]->userdata = (void *)i3;
+ for (unsigned int i4 = 0; i4 < vm->ViewVertices().size(); i4++)
+ vm->ViewVertices()[i4]->userdata = (void *)i4;
+
+ // Write the current options
+ unsigned char flags = Options::getFlags();
+ WRITE(flags);
+
+ // Write the size of the five lists (with some extra informations 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);
- vector<ViewVertex::directedViewEdge>::const_iterator i = ntv->viewedges().begin();
- for ( ; i != ntv->viewedges().end(); i++){
- WRITE_IF_NON_NULL(i->first);
- WRITE(i->second);
+ 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);
}
- } else {
- cerr << "Warning: unexpected ViewVertex nature" << endl;
- return 1;
- }
-
- return 0;
- }
-
- } // End of namespace Internal
-
-
- //////////////////// "Public" 'load' and 'save' functions ////////////////////
-
-#define SET_PROGRESS(n) if (pb) pb->setProgress((n))
-
- 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 informations 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+1;
- fe_rle2 = fe_rle1, READ(fe_rle1)) {
- if (b) {
- for (unsigned i = fe_rle2; i < fe_rle1; i++) {
- FEdgeSmooth * fes = new FEdgeSmooth;
- vm->AddFEdge(fes);
- }
- b = !b;
- }
- else if (!b) {
- for (unsigned 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+1;
- vv_rle2 = vv_rle1, READ(vv_rle1)) {
- if (nature & Nature::T_VERTEX) {
- for (unsigned 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 i = vv_rle2; i < vv_rle1; i++) {
- NonTVertex* ntv = new NonTVertex();
- vm->AddViewVertex(ntv);
- }
- nature = Nature::T_VERTEX;
- }
- }
- }
-
- for (unsigned i0 = 0; i0 < vs_s; i0++) {
- SShape* ss = new SShape();
- ViewShape* vs = new ViewShape();
- vs->setSShape(ss);
- ss->setViewShape(vs);
- vm->AddViewShape(vs);
- }
- // for (unsigned i1 = 0; i1 < fe_s; i1++) {
- // FEdge* fe = new FEdge();
- // vm->AddFEdge(fe);
- // }
- for (unsigned i2 = 0; i2 < sv_s; i2++) {
- SVertex* sv = new SVertex();
- vm->AddSVertex(sv);
- }
- for (unsigned 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 i4=0;i4<map_s;++i4){
- READ(id);
- READ(index);
- vm->shapeIdToIndexMap()[id] = index;
- }
-
- return err;
- }
-
-
- 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 i0 = 0; i0 < vm->ViewShapes().size(); i0++) {
- vm->ViewShapes()[i0]->userdata = (void*)i0;
- vm->ViewShapes()[i0]->sshape()->userdata = (void*)i0;
- }
- for (unsigned i1 = 0; i1 < vm->FEdges().size(); i1++)
- vm->FEdges()[i1]->userdata = (void*)i1;
- for (unsigned i2 = 0; i2 < vm->SVertices().size(); i2++)
- vm->SVertices()[i2]->userdata = (void*)i2;
- for (unsigned i3 = 0; i3 < vm->ViewEdges().size(); i3++)
- vm->ViewEdges()[i3]->userdata = (void*)i3;
- for (unsigned i4 = 0; i4 < vm->ViewVertices().size(); i4++)
- vm->ViewVertices()[i4]->userdata = (void*)i4;
-
- // Write the current options
- unsigned char flags = Options::getFlags();
- WRITE(flags);
-
- // Write the size of the five lists (with some extra informations 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 i = 0; i < size; i++) {
- while (i < size && (vm->FEdges()[i]->isSmooth() == b))
- i++;
- if (i < size) {
- WRITE(i);
- b = !b;
+ // 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);
}
- }
- 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 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;
+
+ // Reset 'userdata' members
+ for (vector<ViewShape*>::const_iterator j0 = vm->ViewShapes().begin(); j0 != vm->ViewShapes().end(); j0++) {
+ (*j0)->userdata = NULL;
+ (*j0)->sshape()->userdata = NULL;
}
- }
- 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 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 = 0;
- (*j0)->sshape()->userdata = 0;
- }
- for (vector<FEdge*>::const_iterator j1 = vm->FEdges().begin();
- j1 != vm->FEdges().end(); j1++)
- (*j1)->userdata = 0;
- for (vector<SVertex*>::const_iterator j2 = vm->SVertices().begin();
- j2 != vm->SVertices().end(); j2++)
- (*j2)->userdata = 0;
- for (vector<ViewEdge*>::const_iterator j3 = vm->ViewEdges().begin();
- j3 != vm->ViewEdges().end(); j3++)
- (*j3)->userdata = 0;
- for (vector<ViewVertex*>::const_iterator j4 = vm->ViewVertices().begin();
- j4 != vm->ViewVertices().end(); j4++)
- (*j4)->userdata = 0;
- SET_PROGRESS(6);
-
- return err;
- }
-
-
- //////////////////// Options ////////////////////
-
- namespace Options {
-
- namespace Internal {
-
- static unsigned char g_flags = 0;
- static string g_models_path;
-
- } // End of namespace Internal
-
- void setFlags(const unsigned char flags) {
- Internal::g_flags = flags;
- }
-
- void addFlags(const unsigned char flags) {
- Internal::g_flags |= flags;
- }
-
- void rmFlags(const unsigned char flags) {
- Internal::g_flags &= ~flags;
- }
-
- unsigned char getFlags() {
- return Internal::g_flags;
- }
-
- void setModelsPath(const string& path) {
- Internal::g_models_path = path;
- }
-
- string getModelsPath() {
- return Internal::g_models_path;
- }
-
- }; // End of namepace Options
+ 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 {
+
+namespace Internal {
+
+static unsigned char g_flags = 0;
+static string g_models_path;
+
+} // End of namespace Internal
+
+void setFlags(const unsigned char flags)
+{
+ Internal::g_flags = flags;
+}
+
+void addFlags(const unsigned char flags)
+{
+ Internal::g_flags |= flags;
+}
+
+void rmFlags(const unsigned char flags)
+{
+ Internal::g_flags &= ~flags;
+}
+
+unsigned char getFlags()
+{
+ return Internal::g_flags;
+}
+
+void setModelsPath(const string& path)
+{
+ Internal::g_models_path = path;
+}
+
+string getModelsPath()
+{
+ return Internal::g_models_path;
+}
+
+} // End of namepace Options
} // End of namespace ViewMapIO
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.h b/source/blender/freestyle/intern/view_map/ViewMapIO.h
index 185841a90ec..44521f03317 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIO.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapIO.h
@@ -1,116 +1,129 @@
-//
-// Filename : ViewMapIO.h
-// Author(s) : Emmanuel Turquin
-// Purpose : Functions to manage I/O for the view map
-// Date of creation : 09/01/2003
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef VIEWMAPIO_H
-# define VIEWMAPIO_H
-
-# include "ViewMap.h"
-# include <fstream>
-# include <string>
-# include "../system/FreestyleConfig.h"
-# include "../system/ProgressBar.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_VIEW_MAP_IO_H__
+#define __FREESTYLE_VIEW_MAP_IO_H__
+
+/** \file blender/freestyle/intern/view_map/ViewMapIO.h
+ * \ingroup freestyle
+ * \brief Functions to manage I/O for the view map
+ * \author Emmanuel Turquin
+ * \date 09/01/2003
+ */
+
+#include <fstream>
+#include <string>
+
+#include "ViewMap.h"
+
+#include "../system/FreestyleConfig.h"
+#include "../system/ProgressBar.h"
namespace ViewMapIO {
- static const unsigned ZERO = UINT_MAX;
-
- LIB_VIEW_MAP_EXPORT
- int load(istream& in, ViewMap* vm, ProgressBar* pb = NULL);
-
- LIB_VIEW_MAP_EXPORT
- int save(ostream& out, ViewMap* vm, ProgressBar* pb = NULL);
-
- namespace Options {
-
- static const unsigned char FLOAT_VECTORS = 1;
- static const unsigned char NO_OCCLUDERS = 2;
-
- LIB_VIEW_MAP_EXPORT
- void setFlags(const unsigned char flags);
-
- LIB_VIEW_MAP_EXPORT
- void addFlags(const unsigned char flags);
-
- LIB_VIEW_MAP_EXPORT
- void rmFlags(const unsigned char flags);
-
- LIB_VIEW_MAP_EXPORT
- unsigned char getFlags();
-
- LIB_VIEW_MAP_EXPORT
- void setModelsPath(const string& path);
-
- LIB_VIEW_MAP_EXPORT
- string getModelsPath();
-
- }; // End of namepace Options
-
-# ifdef IRIX
-
- namespace Internal {
-
- template <unsigned S>
- ostream& write(ostream& out, const char* str) {
- out.put(str[S - 1]);
- return write<S - 1>(out, str);
- }
-
- template<>
- ostream& write<1>(ostream& out, const char* str) {
- return out.put(str[0]);
- }
-
- template<>
- ostream& write<0>(ostream& out, const char*) {
- return out;
- }
-
- template <unsigned S>
- istream& read(istream& in, char* str) {
- in.get(str[S - 1]);
- return read<S - 1>(in, str);
- }
-
- template<>
- istream& read<1>(istream& in, char* str) {
- return in.get(str[0]);
- }
-
- template<>
- istream& read<0>(istream& in, char*) {
- return in;
- }
-
- } // End of namespace Internal
-
-# endif // IRIX
+static const unsigned ZERO = UINT_MAX;
+
+LIB_VIEW_MAP_EXPORT
+int load(istream& in, ViewMap *vm, ProgressBar *pb = NULL);
+
+LIB_VIEW_MAP_EXPORT
+int save(ostream& out, ViewMap *vm, ProgressBar *pb = NULL);
+
+namespace Options {
+
+static const unsigned char FLOAT_VECTORS = 1;
+static const unsigned char NO_OCCLUDERS = 2;
+
+LIB_VIEW_MAP_EXPORT
+void setFlags(const unsigned char flags);
+
+LIB_VIEW_MAP_EXPORT
+void addFlags(const unsigned char flags);
+
+LIB_VIEW_MAP_EXPORT
+void rmFlags(const unsigned char flags);
+
+LIB_VIEW_MAP_EXPORT
+unsigned char getFlags();
+
+LIB_VIEW_MAP_EXPORT
+void setModelsPath(const string& path);
+
+LIB_VIEW_MAP_EXPORT
+string getModelsPath();
+
+}; // End of namepace Options
+
+#ifdef IRIX
+
+namespace Internal {
+
+template <unsigned S>
+ostream& write(ostream& out, const char *str)
+{
+ out.put(str[S - 1]);
+ return write<S - 1>(out, str);
+}
+
+template<>
+ostream& write<1>(ostream& out, const char *str)
+{
+ return out.put(str[0]);
+}
+
+template<>
+ostream& write<0>(ostream& out, const char*)
+{
+ return out;
+}
+
+template <unsigned S>
+istream& read(istream& in, char *str)
+{
+ in.get(str[S - 1]);
+ return read<S - 1>(in, str);
+}
+
+template<>
+istream& read<1>(istream& in, char *str)
+{
+ return in.get(str[0]);
+}
+
+template<>
+istream& read<0>(istream& in, char*)
+{
+ return in;
+}
+
+} // End of namespace Internal
+
+#endif // IRIX
} // End of namespace ViewMapIO
-#endif // VIEWMAPIO_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 7ef2fe5fbe0..78c09c863cc 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIterators.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapIterators.h
@@ -1,381 +1,402 @@
-//
-// Filename : ViewMapIterators.h
-// Author(s) : Stephane Grabli
-// Purpose : Iterators used to iterate over the various elements
-// of the ViewMap
-// Date of creation : 01/07/2003
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_VIEW_MAP_ITERATORS_H__
+#define __FREESTYLE_VIEW_MAP_ITERATORS_H__
+
+/** \file blender/freestyle/intern/view_map/ViewMapIterators.h
+ * \ingroup freestyle
+ * \brief Iterators used to iterate over the various elements of the ViewMap
+ * \author Stephane Grabli
+ * \date 01/07/2003
+ */
+#include "ViewMap.h"
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+#include "../system/Iterator.h" //soc
-#ifndef VIEWMAPITERATORS_H
-# define VIEWMAPITERATORS_H
-#include "ViewMap.h"
-#include "../system/Iterator.h" //soc
+/**********************************/
+/* */
+/* */
+/* ViewMap */
+/* */
+/* */
+/**********************************/
+
+/**********************************/
+/* */
+/* */
+/* ViewVertex */
+/* */
+/* */
+/**********************************/
+
+namespace ViewVertexInternal {
+
+/*! Class representing an iterator over oriented ViewEdges around a ViewVertex. This iterator allows a CCW iteration
+ * (in the image plane).
+ * 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;
+ }
+};
+
+} // ViewVertexInternal namespace
- /**********************************/
- /* */
- /* */
- /* ViewMap */
- /* */
- /* */
- /**********************************/
-
- /**********************************/
- /* */
- /* */
- /* ViewVertex */
- /* */
- /* */
- /**********************************/
-
-namespace ViewVertexInternal{
-
- /*! Class representing an iterator over oriented ViewEdges
- * around a ViewVertex. This iterator allows a CCW iteration
- * (in the image plane).
- * 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()".
- */
- virtual orientedViewEdgeIterator& operator++() // operator corresponding to ++i
- {
- increment();
- return *this;
- }
- /*! Increments.In the scripting language, call
- * "increment()".
- */
- virtual orientedViewEdgeIterator operator++(int) // opérateur correspondant à i++
- { // c.a.d qui renvoie la valeur *puis* incrémente.
- orientedViewEdgeIterator tmp = *this; // C'est pour cela qu'on stocke la valeur
- increment(); // dans un temporaire.
- 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;
- }
- };
-
- }
- /**********************************/
- /* */
- /* */
- /* ViewEdge */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* ViewEdge */
+/* */
+/* */
+/**********************************/
namespace ViewEdgeInternal {
+
//
// SVertexIterator
//
/////////////////////////////////////////////////
- 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 = 0;
- 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 = 0;
- 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
+};
//
@@ -383,167 +404,171 @@ namespace ViewEdgeInternal {
//
///////////////////////////////////////////////////////////
- /*! Base class for iterators over ViewEdges of the ViewMap Graph.
- * Basically the "increment()" operator of this class should
- * be able to take the decision of "where" (on which ViewEdge) to go
- * when pointing on a given ViewEdge.
- * ::Caution::: the dereferencing operator returns a *pointer* to
- * the pointed ViewEdge.
- */
+/*! Base class for iterators over ViewEdges of the ViewMap Graph.
+ * Basically the "increment()" operator of this class should be able to take the decision of "where" (on which
+ * 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 = 0, 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);
- }
+ /*! 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;
+ bool _orientation;
+ ViewEdge *_edge;
+ ViewEdge *_begin;
};
} // end of namespace ViewEdgeInternal
-#endif // VIEWMAPITERATORS_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 6041f527d17..d1adc55d3ac 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
@@ -1,36 +1,49 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/view_map/ViewMapTesselator.cpp
+ * \ingroup freestyle
+ * \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
+ * \author Stephane Grabli
+ * \date 26/03/2002
+ */
#include "ViewMapTesselator.h"
-NodeGroup* ViewMapTesselator::Tesselate(ViewMap *iViewMap)
+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 *)
+NodeGroup *ViewMapTesselator::Tesselate(WShape *)
{
- return NULL;
+ return NULL;
}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
index 0177dc630b8..c1ed7e3926a 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
@@ -1,44 +1,50 @@
-//
-// Filename : ViewMapTesselator.h
-// Author(s) : Stephane Grabli
-// Purpose : Class to build a Node Tree designed to be displayed
-// from a Silhouette View Map structure.
-// Date of creation : 26/03/2002
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef VIEWMAPTESSELATOR_H
-# define VIEWMAPTESSELATOR_H
-
-# include "Silhouette.h"
-# include "ViewMap.h"
-# include "../scene_graph/NodeShape.h"
-# include "../winged_edge/WEdge.h"
-# include "../scene_graph/NodeGroup.h"
-# include "../scene_graph/LineRep.h"
-# include "../scene_graph/OrientedLineRep.h"
-# include "../scene_graph/VertexRep.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_VIEW_MAP_TESSELATOR_H__
+#define __FREESTYLE_VIEW_MAP_TESSELATOR_H__
+
+/** \file blender/freestyle/intern/view_map/ViewMapTesselator.h
+ * \ingroup freestyle
+ * \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
+ * \author Stephane Grabli
+ * \date 26/03/2002
+ */
+
+#include "Silhouette.h"
+#include "ViewMap.h"
+
+#include "../scene_graph/LineRep.h"
+#include "../scene_graph/NodeShape.h"
+#include "../scene_graph/NodeGroup.h"
+#include "../scene_graph/OrientedLineRep.h"
+#include "../scene_graph/VertexRep.h"
+
+#include "../winged_edge/WEdge.h"
class NodeShape;
class NodeGroup;
@@ -48,68 +54,83 @@ class WShape;
class LIB_VIEW_MAP_EXPORT 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
- * 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;}
+ 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;
-
+ virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
+
private:
- Nature::EdgeNature _nature;
- FrsMaterial _FrsMaterial;
- bool _overloadFrsMaterial;
+ Nature::EdgeNature _nature;
+ FrsMaterial _FrsMaterial;
+ bool _overloadFrsMaterial;
};
/*! Class to tesselate the 2D projected silhouette */
class ViewMapTesselator2D : public ViewMapTesselator
{
public:
- inline ViewMapTesselator2D() : ViewMapTesselator() {}
- virtual ~ViewMapTesselator2D() {}
+ inline ViewMapTesselator2D() : ViewMapTesselator() {}
+ virtual ~ViewMapTesselator2D() {}
protected:
- virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
- {
- iLine->AddVertex(v->point2D());
- }
+ virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
+ {
+ iLine->AddVertex(v->point2D());
+ }
};
/*! Class to tesselate the 3D silhouette */
class ViewMapTesselator3D : public ViewMapTesselator
{
public:
- inline ViewMapTesselator3D() : ViewMapTesselator() {}
- virtual ~ViewMapTesselator3D() {}
+ inline ViewMapTesselator3D() : ViewMapTesselator() {}
+ virtual ~ViewMapTesselator3D() {}
protected:
- virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
- {
- iLine->AddVertex(v->point3D());
- }
+ virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
+ {
+ iLine->AddVertex(v->point3D());
+ }
};
//
@@ -118,79 +139,73 @@ protected:
///////////////////////////////////////////////
template<class ViewEdgesIterator>
-NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
+NodeGroup *ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
{
- NodeGroup *group = new NodeGroup;
- NodeShape *tshape = new NodeShape;
- group->AddChild(tshape);
- //tshape->frs_material().setDiffuse(0.f, 0.f, 0.f, 1.f);
- tshape->setFrsMaterial(_FrsMaterial);
-
- LineRep* line;
-
-
- 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++)
- {
- // if((*c)->qi() > 0){
- // continue;
- // }
- // if(!((*c)->nature() & (_nature)))
- // continue;
- //
- firstEdge = (*c)->fedgeA();
-
- // if(firstEdge->invisibility() > 0)
- // continue;
-
- 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;
+ 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;
+
+ 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++) {
+#if 0
+ if ((*c)->qi() > 0) {
+ continue;
+ }
+ if (!((*c)->nature() & (_nature))) {
+ continue;
+ }
+#endif
+ firstEdge = (*c)->fedgeA();
+
+#if 0
+ 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;
}
-#endif // VIEWMAPTESSELATOR_H
+#endif // __FREESTYLE_VIEW_MAP_TESSELATOR_H__
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
index ce8fc5b98fa..acefe1aa5fc 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
@@ -1,646 +1,642 @@
-/* GTS - Library for the manipulation of triangulated surfaces
- * Copyright (C) 1999-2002 Ray Jones, Stéphane Popinet
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is:
+ * GTS - Library for the manipulation of triangulated surfaces
+ * Copyright (C) 1999 Stephane Popinet
+ * and:
+ * OGF/Graphite: Geometry and Graphics Programming Library + Utilities
+ * Copyright (C) 2000-2003 Bruno Levy
+ * Contact: Bruno Levy levy@loria.fr
+ * ISA Project
+ * LORIA, INRIA Lorraine,
+ * Campus Scientifique, BP 239
+ * 54506 VANDOEUVRE LES NANCY CEDEX
+ * FRANCE
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
*/
+/** \file blender/freestyle/intern/winged_edge/Curvature.cpp
+ * \ingroup freestyle
+ * \brief GTS - Library for the manipulation of triangulated surfaces
+ * \author Stephane Popinet
+ * \date 1999
+ * \brief OGF/Graphite: Geometry and Graphics Programming Library + Utilities
+ * \author Bruno Levy
+ * \date 2000-2003
+ */
+
+#include <assert.h>
#include <cstdlib> // for malloc and free
-#include "Curvature.h"
#include <math.h>
-#include <assert.h>
-#include "WEdge.h"
-#include "../system/FreestyleConfig.h"
-#include "../geometry/normal_cycle.h"
#include <set>
#include <stack>
-static bool angle_obtuse (WVertex * v, WFace * f)
+#include "Curvature.h"
+#include "WEdge.h"
+
+#include "../geometry/normal_cycle.h"
+
+#include "../system/FreestyleConfig.h"
+
+static bool angle_obtuse(WVertex *v, WFace *f)
{
- WOEdge * e;
- f->getOppositeEdge (v, e);
-
- Vec3r vec1(e->GetaVertex()->GetVertex()-v->GetVertex());
- Vec3r vec2(e->GetbVertex()->GetVertex()-v->GetVertex());
- return ((vec1 * vec2) < 0);
+ WOEdge *e;
+ f->getOppositeEdge(v, e);
+
+ Vec3r vec1(e->GetaVertex()->GetVertex()-v->GetVertex());
+ Vec3r vec2(e->GetbVertex()->GetVertex()-v->GetVertex());
+ return ((vec1 * vec2) < 0);
}
// FIXME
// WVvertex is useless but kept for history reasons
-static bool triangle_obtuse (WVertex*, WFace * f)
+static bool triangle_obtuse(WVertex *, WFace *f)
{
- bool b=false;
- for (int i=0; i<3; i++)
- b = b ||
- ((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i+1)%3]->GetVec()) < 0);
- return b;
+ bool b = false;
+ for (int i = 0; i < 3; i++)
+ b = b || ((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i + 1) % 3]->GetVec()) < 0);
+ return b;
}
-static real cotan (WVertex * vo, WVertex * v1, WVertex * v2)
+static real cotan(WVertex *vo, WVertex *v1, WVertex *v2)
{
- /* cf. Appendix B of [Meyer et al 2002] */
- real udotv, denom;
-
- Vec3r u(v1->GetVertex()- vo->GetVertex());
- Vec3r v(v2->GetVertex()- vo->GetVertex());
+ /* cf. Appendix B of [Meyer et al 2002] */
+ real udotv, denom;
- udotv = u * v;
- denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
+ Vec3r u(v1->GetVertex() - vo->GetVertex());
+ Vec3r v(v2->GetVertex() - vo->GetVertex());
- /* denom can be zero if u==v. Returning 0 is acceptable, based on
- * the callers of this function below. */
- if (denom == 0.0) return (0.0);
+ udotv = u * v;
+ denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
- return (udotv / denom);
+ /* denom can be zero if u==v. Returning 0 is acceptable, based on the callers of this function below. */
+ if (denom == 0.0)
+ return 0.0;
+ return (udotv / denom);
}
-static real angle_from_cotan (WVertex * vo, WVertex * v1, WVertex * v2)
+static real angle_from_cotan(WVertex *vo, WVertex *v1, WVertex *v2)
{
- /* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */
- real udotv, denom;
+ /* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */
+ real udotv, denom;
- Vec3r u (v1->GetVertex()-vo->GetVertex());
- Vec3r v(v2->GetVertex()-vo->GetVertex());
+ Vec3r u (v1->GetVertex() - vo->GetVertex());
+ Vec3r v(v2->GetVertex() - vo->GetVertex());
- udotv = u * v;
- denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
+ udotv = u * v;
+ denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
- /* Note: I assume this is what they mean by using atan2 (). -Ray Jones */
+ /* Note: I assume this is what they mean by using atan2(). -Ray Jones */
- /* tan = denom/udotv = y/x (see man page for atan2) */
- return (fabs (atan2 (denom, udotv)));
+ /* tan = denom/udotv = y/x (see man page for atan2) */
+ return (fabs(atan2(denom, udotv)));
}
-/**
- * gts_vertex_mean_curvature_normal:
- * @v: a #WVertex.
- * @s: a #GtsSurface.
- * @Kh: the Mean Curvature Normal at @v.
+/*! gts_vertex_mean_curvature_normal:
+ * @v: a #WVertex.
+ * @s: a #GtsSurface.
+ * @Kh: the Mean Curvature Normal at @v.
*
- * Computes the Discrete Mean Curvature Normal approximation at @v.
- * The mean curvature at @v is half the magnitude of the vector @Kh.
+ * Computes the Discrete Mean Curvature Normal approximation at @v.
+ * The mean curvature at @v is half the magnitude of the vector @Kh.
*
- * Note: the normal computed is not unit length, and may point either
- * into or out of the surface, depending on the curvature at @v. It
- * is the responsibility of the caller of the function to use the mean
- * curvature normal appropriately.
+ * Note: the normal computed is not unit length, and may point either into or out of the surface, depending on
+ * the curvature at @v. It is the responsibility of the caller of the function to use the mean curvature normal
+ * appropriately.
*
- * This approximation is from the paper:
- * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds
- * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr
- * VisMath '02, Berlin (Germany)
- * http://www-grail.usc.edu/pubs.html
+ * This approximation is from the paper:
+ * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds
+ * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr
+ * VisMath '02, Berlin (Germany)
+ * http://www-grail.usc.edu/pubs.html
*
- * Returns: %TRUE if the operator could be evaluated, %FALSE if the
- * evaluation failed for some reason (@v is boundary or is the
- * endpoint of a non-manifold edge.)
+ * Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is
+ * boundary or is the endpoint of a non-manifold edge.)
*/
-bool gts_vertex_mean_curvature_normal (WVertex * v, Vec3r &Kh)
+bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh)
{
real area = 0.0;
- if (!v) return false;
+ if (!v)
+ return false;
/* this operator is not defined for boundary edges */
- if (v->isBoundary()) return false;
-
- WVertex::incoming_edge_iterator itE;
-
- for (itE=v->incoming_edges_begin();
- itE!=v->incoming_edges_end(); itE++)
- area+=(*itE)->GetaFace()->getArea();
-
- Kh=Vec3r(0.0, 0.0, 0.0);
-
- for (itE=v->incoming_edges_begin();
- itE!=v->incoming_edges_end(); itE++)
- {
- WOEdge * e = (*itE)->getPrevOnFace();
- //if ((e->GetaVertex()==v) || (e->GetbVertex()==v)) cerr<< "BUG ";
+ if (v->isBoundary())
+ return false;
- WVertex * v1 = e->GetaVertex();
- WVertex * v2 = e->GetbVertex();
- real temp;
-
- temp = cotan (v1, v, v2);
- Kh = Vec3r(Kh+temp*(v2->GetVertex()-v->GetVertex()));
+ WVertex::incoming_edge_iterator itE;
- temp = cotan (v2, v, v1);
- Kh = Vec3r(Kh+temp*(v1->GetVertex()-v->GetVertex()));
- }
- if (area > 0.0)
- {
- Kh[0] /= 2*area;
- Kh[1] /= 2*area;
- Kh[2] /= 2*area;
- }
- else return false;
+ for (itE=v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
+ area += (*itE)->GetaFace()->getArea();
+
+ Kh = Vec3r(0.0, 0.0, 0.0);
+
+ for (itE=v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
+ WOEdge *e = (*itE)->getPrevOnFace();
+#if 0
+ if ((e->GetaVertex() == v) || (e->GetbVertex() == v))
+ cerr<< "BUG ";
+#endif
+ WVertex *v1 = e->GetaVertex();
+ WVertex *v2 = e->GetbVertex();
+ real temp;
+
+ temp = cotan(v1, v, v2);
+ Kh = Vec3r(Kh + temp * (v2->GetVertex() - v->GetVertex()));
+
+ temp = cotan(v2, v, v1);
+ Kh = Vec3r(Kh + temp * (v1->GetVertex() - v->GetVertex()));
+ }
+ if (area > 0.0) {
+ Kh[0] /= 2 * area;
+ Kh[1] /= 2 * area;
+ Kh[2] /= 2 * area;
+ }
+ else {
+ return false;
+ }
return true;
}
-/**
- * gts_vertex_gaussian_curvature:
- * @v: a #WVertex.
- * @s: a #GtsSurface.
- * @Kg: the Discrete Gaussian Curvature approximation at @v.
+/*! gts_vertex_gaussian_curvature:
+ * @v: a #WVertex.
+ * @s: a #GtsSurface.
+ * @Kg: the Discrete Gaussian Curvature approximation at @v.
*
- * Computes the Discrete Gaussian Curvature approximation at @v.
+ * Computes the Discrete Gaussian Curvature approximation at @v.
*
- * This approximation is from the paper:
- * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds
- * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr
- * VisMath '02, Berlin (Germany)
- * http://www-grail.usc.edu/pubs.html
+ * This approximation is from the paper:
+ * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds
+ * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr
+ * VisMath '02, Berlin (Germany)
+ * http://www-grail.usc.edu/pubs.html
*
- * Returns: %TRUE if the operator could be evaluated, %FALSE if the
- * evaluation failed for some reason (@v is boundary or is the
- * endpoint of a non-manifold edge.)
+ * Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is
+ * boundary or is the endpoint of a non-manifold edge.)
*/
-bool gts_vertex_gaussian_curvature (WVertex * v, real * Kg)
+bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg)
{
real area = 0.0;
real angle_sum = 0.0;
- if (!v) return false;
- if (!Kg) return false;
+ if (!v)
+ return false;
+ if (!Kg)
+ return false;
+
+ /* this operator is not defined for boundary edges */
+ if (v->isBoundary()) {
+ *Kg = 0.0;
+ return false;
+ }
- /* this operator is not defined for boundary edges */
- if (v->isBoundary()) {*Kg=0.0 ;return false;}
-
WVertex::incoming_edge_iterator itE;
- for (itE=v->incoming_edges_begin();
- itE!=v->incoming_edges_end(); itE++)
- area+=(*itE)->GetaFace()->getArea();
-
- for (itE=v->incoming_edges_begin();
- itE!=v->incoming_edges_end(); itE++)
- {
- WOEdge * e = (*itE)->getPrevOnFace();
- WVertex * v1 = e->GetaVertex();
- WVertex * v2 = e->GetbVertex();
- angle_sum += angle_from_cotan (v, v1, v2);
- }
-
- *Kg = (2.0*M_PI - angle_sum)/area;
+ for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
+ area += (*itE)->GetaFace()->getArea();
+
+ for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
+ WOEdge *e = (*itE)->getPrevOnFace();
+ WVertex *v1 = e->GetaVertex();
+ WVertex *v2 = e->GetbVertex();
+ angle_sum += angle_from_cotan(v, v1, v2);
+ }
+
+ *Kg = (2.0 * M_PI - angle_sum) / area;
return true;
}
-/**
- * gts_vertex_principal_curvatures:
- * @Kh: mean curvature.
- * @Kg: Gaussian curvature.
- * @K1: first principal curvature.
- * @K2: second principal curvature.
+/*! gts_vertex_principal_curvatures:
+ * @Kh: mean curvature.
+ * @Kg: Gaussian curvature.
+ * @K1: first principal curvature.
+ * @K2: second principal curvature.
*
- * Computes the principal curvatures at a point given the mean and
- * Gaussian curvatures at that point.
+ * Computes the principal curvatures at a point given the mean and Gaussian curvatures at that point.
*
- * The mean curvature can be computed as one-half the magnitude of the
- * vector computed by gts_vertex_mean_curvature_normal().
+ * The mean curvature can be computed as one-half the magnitude of the vector computed by
+ * gts_vertex_mean_curvature_normal().
*
- * The Gaussian curvature can be computed with
- * gts_vertex_gaussian_curvature().
+ * The Gaussian curvature can be computed with gts_vertex_gaussian_curvature().
*/
-void gts_vertex_principal_curvatures (real Kh, real Kg,
- real * K1, real * K2)
+void gts_vertex_principal_curvatures (real Kh, real Kg, real *K1, real *K2)
{
- real temp = Kh*Kh - Kg;
+ real temp = Kh * Kh - Kg;
- if (!K1) return;
- if (!K1) return;
+ if (!K1 || !K2)
+ return;
- if (temp < 0.0) temp = 0.0;
- temp = sqrt (temp);
- *K1 = Kh + temp;
- *K2 = Kh - temp;
+ if (temp < 0.0)
+ temp = 0.0;
+ temp = sqrt (temp);
+ *K1 = Kh + temp;
+ *K2 = Kh - temp;
}
/* from Maple */
-static void linsolve (real m11, real m12, real b1,
- real m21, real m22, real b2,
- real * x1, real * x2)
+static void linsolve(real m11, real m12, real b1, real m21, real m22, real b2, real *x1, real *x2)
{
- real temp;
+ real temp;
- temp = 1.0 / (m21*m12 - m11*m22);
- *x1 = (m12*b2 - m22*b1)*temp;
- *x2 = (m11*b2 - m21*b1)*temp;
+ temp = 1.0 / (m21 * m12 - m11 * m22);
+ *x1 = (m12 * b2 - m22 * b1) * temp;
+ *x2 = (m11 * b2 - m21 * b1) * temp;
}
-
+
/* from Maple - largest eigenvector of [a b; b c] */
-static void eigenvector (real a, real b, real c,
- Vec3r e)
+static void eigenvector(real a, real b, real c, Vec3r e)
{
- if (b == 0.0) {
- e[0] = 0.0;
- } else {
- e[0] = -(c - a - sqrt (c*c - 2*a*c + a*a + 4*b*b))/(2*b);
- }
- e[1] = 1.0;
- e[2] = 0.0;
+ if (b == 0.0) {
+ e[0] = 0.0;
+ }
+ else {
+ e[0] = -(c - a - sqrt(c * c - 2 * a * c + a * a + 4 * b * b)) / (2 * b);
+ }
+ e[1] = 1.0;
+ e[2] = 0.0;
}
-/**
- * gts_vertex_principal_directions:
- * @v: a #WVertex.
- * @s: a #GtsSurface.
- * @Kh: mean curvature normal (a #Vec3r).
- * @Kg: Gaussian curvature (a real).
- * @e1: first principal curvature direction (direction of largest curvature).
- * @e2: second principal curvature direction.
+/*! gts_vertex_principal_directions:
+ * @v: a #WVertex.
+ * @s: a #GtsSurface.
+ * @Kh: mean curvature normal (a #Vec3r).
+ * @Kg: Gaussian curvature (a real).
+ * @e1: first principal curvature direction (direction of largest curvature).
+ * @e2: second principal curvature direction.
*
- * Computes the principal curvature directions at a point given @Kh
- * and @Kg, the mean curvature normal and Gaussian curvatures at that
- * point, computed with gts_vertex_mean_curvature_normal() and
- * gts_vertex_gaussian_curvature(), respectively.
+ * Computes the principal curvature directions at a point given @Kh and @Kg, the mean curvature normal and
+ * Gaussian curvatures at that point, computed with gts_vertex_mean_curvature_normal() and
+ * gts_vertex_gaussian_curvature(), respectively.
*
- * Note that this computation is very approximate and tends to be
- * unstable. Smoothing of the surface or the principal directions may
- * be necessary to achieve reasonable results.
+ * Note that this computation is very approximate and tends to be unstable. Smoothing of the surface or the principal
+ * directions may be necessary to achieve reasonable results.
*/
-void gts_vertex_principal_directions (WVertex * v,
- Vec3r Kh, real Kg,
- Vec3r &e1, Vec3r &e2)
+void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2)
{
- Vec3r N;
- real normKh;
-
- Vec3r basis1, basis2, d, eig;
- real ve2, vdotN;
- real aterm_da, bterm_da, cterm_da, const_da;
- real aterm_db, bterm_db, cterm_db, const_db;
- real a, b, c;
- real K1, K2;
- real *weights, *kappas, *d1s, *d2s;
- int edge_count;
- real err_e1, err_e2;
- int e;
- WVertex::incoming_edge_iterator itE;
-
- /* compute unit normal */
- normKh = Kh.norm();
-
- if (normKh > 0.0) {
- Kh.normalize();
- } else {
- /* This vertex is a point of zero mean curvature (flat or saddle
- * point). Compute a normal by averaging the adjacent triangles
- */
- N[0] = N[1] = N[2] = 0.0;
-
- for (itE=v->incoming_edges_begin();
- itE!=v->incoming_edges_end(); itE++)
- N=Vec3r(N+(*itE)->GetaFace()->GetNormal());
- real normN = N.norm();
- if (normN <= 0.0)
- return;
- N.normalize();
- }
-
-
- /* construct a basis from N: */
- /* set basis1 to any component not the largest of N */
- basis1[0] = basis1[1] = basis1[2] = 0.0;
- if (fabs (N[0]) > fabs (N[1]))
- basis1[1] = 1.0;
- else
- basis1[0] = 1.0;
-
- /* make basis2 orthogonal to N */
- basis2 = (N ^ basis1);
- basis2.normalize();
-
- /* make basis1 orthogonal to N and basis2 */
- basis1 = (N ^ basis2);
- basis1.normalize();
-
- aterm_da = bterm_da = cterm_da = const_da = 0.0;
- aterm_db = bterm_db = cterm_db = const_db = 0.0;
- int nb_edges=v->GetEdges().size();
-
- weights = (real *) malloc (sizeof (real)*nb_edges);
- kappas = (real*) malloc (sizeof (real)*nb_edges);
- d1s = (real*) malloc (sizeof (real)*nb_edges);
- d2s = (real*) malloc (sizeof (real)*nb_edges);
- edge_count = 0;
-
- for (itE=v->incoming_edges_begin();
- itE!=v->incoming_edges_end(); itE++)
- {
- WOEdge * e;
- WFace * f1, * f2;
- real weight, kappa, d1, d2;
- Vec3r vec_edge;
- if (! *itE) continue;
- e = *itE;
-
- /* since this vertex passed the tests in
- * gts_vertex_mean_curvature_normal(), this should be true. */
- //g_assert (gts_edge_face_number (e, s) == 2);
-
- /* identify the two triangles bordering e in s */
- f1=e->GetaFace();
- f2=e->GetbFace();
-
- /* We are solving for the values of the curvature tensor
- * B = [ a b ; b c ].
- * The computations here are from section 5 of [Meyer et al 2002].
- *
- * The first step is to calculate the linear equations governing
- * the values of (a,b,c). These can be computed by setting the
- * derivatives of the error E to zero (section 5.3).
- *
- * Since a + c = norm(Kh), we only compute the linear equations
- * for dE/da and dE/db. (NB: [Meyer et al 2002] has the
- * equation a + b = norm(Kh), but I'm almost positive this is
- * incorrect.)
- *
- * Note that the w_ij (defined in section 5.2) are all scaled by
- * (1/8*A_mixed). We drop this uniform scale factor because the
- * solution of the linear equations doesn't rely on it.
- *
- * The terms of the linear equations are xterm_dy with x in
- * {a,b,c} and y in {a,b}. There are also const_dy terms that are
- * the constant factors in the equations.
- */
-
- /* find the vector from v along edge e */
- vec_edge=Vec3r(-1*e->GetVec());
-
- ve2 = vec_edge.squareNorm();
- vdotN = vec_edge * N;
-
- /* section 5.2 - There is a typo in the computation of kappa. The
- * edges should be x_j-x_i.
- */
- kappa = 2.0 * vdotN / ve2;
-
- /* section 5.2 */
-
- /* I don't like performing a minimization where some of the
- * weights can be negative (as can be the case if f1 or f2 are
- * obtuse). To ensure all-positive weights, we check for
- * obtuseness. */
- weight = 0.0;
- if (! triangle_obtuse(v, f1)) {
- weight += ve2 *
- cotan (f1->GetNextOEdge(e->twin())->GetbVertex(),
- e->GetaVertex(), e->GetbVertex()) / 8.0;
- } else {
- if (angle_obtuse (v, f1)) {
- weight += ve2 * f1->getArea() / 4.0;
- } else {
- weight += ve2 * f1->getArea() / 8.0;
- }
- }
-
- if (! triangle_obtuse(v, f2)) {
- weight += ve2 *
- cotan (f2->GetNextOEdge(e)->GetbVertex(),
- e->GetaVertex(), e->GetbVertex()) / 8.0;
- } else {
- if (angle_obtuse (v, f2)) {
- weight += ve2 * f1->getArea() / 4.0;
- } else {
- weight += ve2 * f1->getArea() / 8.0;
- }
- }
-
- /* projection of edge perpendicular to N (section 5.3) */
- d[0] = vec_edge[0] - vdotN * N[0];
- d[1] = vec_edge[1] - vdotN * N[1];
- d[2] = vec_edge[2] - vdotN * N[2];
- d.normalize();
-
- /* not explicit in the paper, but necessary. Move d to 2D basis. */
- d1 = d * basis1;
- d2 = d * basis2;
-
- /* store off the curvature, direction of edge, and weights for later use */
- weights[edge_count] = weight;
- kappas[edge_count] = kappa;
- d1s[edge_count] = d1;
- d2s[edge_count] = d2;
- edge_count++;
-
- /* Finally, update the linear equations */
- aterm_da += weight * d1 * d1 * d1 * d1;
- bterm_da += weight * d1 * d1 * 2 * d1 * d2;
- cterm_da += weight * d1 * d1 * d2 * d2;
- const_da += weight * d1 * d1 * (- kappa);
-
- aterm_db += weight * d1 * d2 * d1 * d1;
- bterm_db += weight * d1 * d2 * 2 * d1 * d2;
- cterm_db += weight * d1 * d2 * d2 * d2;
- const_db += weight * d1 * d2 * (- kappa);
-
- }
-
- /* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */
- aterm_da -= cterm_da;
- const_da += cterm_da * normKh;
-
- aterm_db -= cterm_db;
- const_db += cterm_db * normKh;
-
- /* check for solvability of the linear system */
- if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) &&
- ((const_da != 0.0) || (const_db != 0.0))) {
- linsolve (aterm_da, bterm_da, -const_da,
- aterm_db, bterm_db, -const_db,
- &a, &b);
-
- c = normKh - a;
-
- eigenvector (a, b, c, eig);
- } else {
- /* region of v is planar */
- eig[0] = 1.0;
- eig[1] = 0.0;
- }
-
- /* Although the eigenvectors of B are good estimates of the
- * principal directions, it seems that which one is attached to
- * which curvature direction is a bit arbitrary. This may be a bug
- * in my implementation, or just a side-effect of the inaccuracy of
- * B due to the discrete nature of the sampling.
- *
- * To overcome this behavior, we'll evaluate which assignment best
- * matches the given eigenvectors by comparing the curvature
- * estimates computed above and the curvatures calculated from the
- * discrete differential operators. */
-
- gts_vertex_principal_curvatures (0.5 * normKh, Kg, &K1, &K2);
-
- err_e1 = err_e2 = 0.0;
- /* loop through the values previously saved */
- for (e = 0; e < edge_count; e++) {
- real weight, kappa, d1, d2;
- real temp1, temp2;
- real delta;
-
- weight = weights[e];
- kappa = kappas[e];
- d1 = d1s[e];
- d2 = d2s[e];
-
- temp1 = fabs (eig[0] * d1 + eig[1] * d2);
- temp1 = temp1 * temp1;
- temp2 = fabs (eig[1] * d1 - eig[0] * d2);
- temp2 = temp2 * temp2;
-
- /* err_e1 is for K1 associated with e1 */
- delta = K1 * temp1 + K2 * temp2 - kappa;
- err_e1 += weight * delta * delta;
-
- /* err_e2 is for K1 associated with e2 */
- delta = K2 * temp1 + K1 * temp2 - kappa;
- err_e2 += weight * delta * delta;
- }
- free (weights);
- free (kappas);
- free (d1s);
- free (d2s);
-
- /* rotate eig by a right angle if that would decrease the error */
- if (err_e2 < err_e1) {
- real temp = eig[0];
-
- eig[0] = eig[1];
- eig[1] = -temp;
- }
-
- e1[0] = eig[0] * basis1[0] + eig[1] * basis2[0];
- e1[1] = eig[0] * basis1[1] + eig[1] * basis2[1];
- e1[2] = eig[0] * basis1[2] + eig[1] * basis2[2];
- e1.normalize();
-
- /* make N,e1,e2 a right handed coordinate sytem */
- e2 = N ^ e1;
- e2.normalize();
+ Vec3r N;
+ real normKh;
+
+ Vec3r basis1, basis2, d, eig;
+ real ve2, vdotN;
+ real aterm_da, bterm_da, cterm_da, const_da;
+ real aterm_db, bterm_db, cterm_db, const_db;
+ real a, b, c;
+ real K1, K2;
+ real *weights, *kappas, *d1s, *d2s;
+ int edge_count;
+ real err_e1, err_e2;
+ int e;
+ WVertex::incoming_edge_iterator itE;
+
+ /* compute unit normal */
+ normKh = Kh.norm();
+
+ if (normKh > 0.0) {
+ Kh.normalize();
+ }
+ else {
+ /* This vertex is a point of zero mean curvature (flat or saddle point). Compute a normal by averaging
+ * the adjacent triangles
+ */
+ N[0] = N[1] = N[2] = 0.0;
+
+ for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
+ N = Vec3r(N + (*itE)->GetaFace()->GetNormal());
+ real normN = N.norm();
+ if (normN <= 0.0)
+ return;
+ N.normalize();
+ }
+
+ /* construct a basis from N: */
+ /* set basis1 to any component not the largest of N */
+ basis1[0] = basis1[1] = basis1[2] = 0.0;
+ if (fabs (N[0]) > fabs (N[1]))
+ basis1[1] = 1.0;
+ else
+ basis1[0] = 1.0;
+
+ /* make basis2 orthogonal to N */
+ basis2 = (N ^ basis1);
+ basis2.normalize();
+
+ /* make basis1 orthogonal to N and basis2 */
+ basis1 = (N ^ basis2);
+ basis1.normalize();
+
+ aterm_da = bterm_da = cterm_da = const_da = 0.0;
+ aterm_db = bterm_db = cterm_db = const_db = 0.0;
+ int nb_edges=v->GetEdges().size();
+
+ weights = (real *)malloc(sizeof (real) * nb_edges);
+ kappas = (real *)malloc(sizeof (real) * nb_edges);
+ d1s = (real *)malloc(sizeof (real) * nb_edges);
+ d2s = (real *)malloc(sizeof (real) * nb_edges);
+ edge_count = 0;
+
+ for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
+ WOEdge *e;
+ WFace *f1, *f2;
+ real weight, kappa, d1, d2;
+ Vec3r vec_edge;
+ if (!*itE)
+ continue;
+ e = *itE;
+
+ /* since this vertex passed the tests in gts_vertex_mean_curvature_normal(), this should be true. */
+ //g_assert(gts_edge_face_number (e, s) == 2);
+
+ /* identify the two triangles bordering e in s */
+ f1 = e->GetaFace();
+ f2 = e->GetbFace();
+
+ /* We are solving for the values of the curvature tensor
+ * B = [ a b ; b c ].
+ * The computations here are from section 5 of [Meyer et al 2002].
+ *
+ * The first step is to calculate the linear equations governing the values of (a,b,c). These can be computed
+ * by setting the derivatives of the error E to zero (section 5.3).
+ *
+ * Since a + c = norm(Kh), we only compute the linear equations for dE/da and dE/db. (NB: [Meyer et al 2002]
+ * has the equation a + b = norm(Kh), but I'm almost positive this is incorrect).
+ *
+ * Note that the w_ij (defined in section 5.2) are all scaled by (1/8*A_mixed). We drop this uniform scale
+ * factor because the solution of the linear equations doesn't rely on it.
+ *
+ * The terms of the linear equations are xterm_dy with x in {a,b,c} and y in {a,b}. There are also const_dy
+ * terms that are the constant factors in the equations.
+ */
+
+ /* find the vector from v along edge e */
+ vec_edge = Vec3r(-1 * e->GetVec());
+
+ ve2 = vec_edge.squareNorm();
+ vdotN = vec_edge * N;
+
+ /* section 5.2 - There is a typo in the computation of kappa. The edges should be x_j-x_i. */
+ kappa = 2.0 * vdotN / ve2;
+
+ /* section 5.2 */
+
+ /* I don't like performing a minimization where some of the weights can be negative (as can be the case
+ * if f1 or f2 are obtuse). To ensure all-positive weights, we check for obtuseness. */
+ weight = 0.0;
+ if (!triangle_obtuse(v, f1)) {
+ weight += ve2 * cotan(f1->GetNextOEdge(e->twin())->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
+ }
+ else {
+ if (angle_obtuse(v, f1)) {
+ weight += ve2 * f1->getArea() / 4.0;
+ }
+ else {
+ weight += ve2 * f1->getArea() / 8.0;
+ }
+ }
+
+ if (!triangle_obtuse(v, f2)) {
+ weight += ve2 * cotan (f2->GetNextOEdge(e)->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
+ }
+ else {
+ if (angle_obtuse(v, f2)) {
+ weight += ve2 * f1->getArea() / 4.0;
+ }
+ else {
+ weight += ve2 * f1->getArea() / 8.0;
+ }
+ }
+
+ /* projection of edge perpendicular to N (section 5.3) */
+ d[0] = vec_edge[0] - vdotN * N[0];
+ d[1] = vec_edge[1] - vdotN * N[1];
+ d[2] = vec_edge[2] - vdotN * N[2];
+ d.normalize();
+
+ /* not explicit in the paper, but necessary. Move d to 2D basis. */
+ d1 = d * basis1;
+ d2 = d * basis2;
+
+ /* store off the curvature, direction of edge, and weights for later use */
+ weights[edge_count] = weight;
+ kappas[edge_count] = kappa;
+ d1s[edge_count] = d1;
+ d2s[edge_count] = d2;
+ edge_count++;
+
+ /* Finally, update the linear equations */
+ aterm_da += weight * d1 * d1 * d1 * d1;
+ bterm_da += weight * d1 * d1 * 2 * d1 * d2;
+ cterm_da += weight * d1 * d1 * d2 * d2;
+ const_da += weight * d1 * d1 * (-kappa);
+
+ aterm_db += weight * d1 * d2 * d1 * d1;
+ bterm_db += weight * d1 * d2 * 2 * d1 * d2;
+ cterm_db += weight * d1 * d2 * d2 * d2;
+ const_db += weight * d1 * d2 * (-kappa);
+ }
+
+ /* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */
+ aterm_da -= cterm_da;
+ const_da += cterm_da * normKh;
+
+ aterm_db -= cterm_db;
+ const_db += cterm_db * normKh;
+
+ /* check for solvability of the linear system */
+ if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) && ((const_da != 0.0) || (const_db != 0.0))) {
+ linsolve(aterm_da, bterm_da, -const_da, aterm_db, bterm_db, -const_db, &a, &b);
+
+ c = normKh - a;
+
+ eigenvector(a, b, c, eig);
+ }
+ else {
+ /* region of v is planar */
+ eig[0] = 1.0;
+ eig[1] = 0.0;
+ }
+
+ /* Although the eigenvectors of B are good estimates of the principal directions, it seems that which one is
+ * attached to which curvature direction is a bit arbitrary. This may be a bug in my implementation, or just
+ * a side-effect of the inaccuracy of B due to the discrete nature of the sampling.
+ *
+ * To overcome this behavior, we'll evaluate which assignment best matches the given eigenvectors by comparing
+ * the curvature estimates computed above and the curvatures calculated from the discrete differential operators.
+ */
+
+ gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2);
+
+ err_e1 = err_e2 = 0.0;
+ /* loop through the values previously saved */
+ for (e = 0; e < edge_count; e++) {
+ real weight, kappa, d1, d2;
+ real temp1, temp2;
+ real delta;
+
+ weight = weights[e];
+ kappa = kappas[e];
+ d1 = d1s[e];
+ d2 = d2s[e];
+
+ temp1 = fabs (eig[0] * d1 + eig[1] * d2);
+ temp1 = temp1 * temp1;
+ temp2 = fabs (eig[1] * d1 - eig[0] * d2);
+ temp2 = temp2 * temp2;
+
+ /* err_e1 is for K1 associated with e1 */
+ delta = K1 * temp1 + K2 * temp2 - kappa;
+ err_e1 += weight * delta * delta;
+
+ /* err_e2 is for K1 associated with e2 */
+ delta = K2 * temp1 + K1 * temp2 - kappa;
+ err_e2 += weight * delta * delta;
+ }
+ free (weights);
+ free (kappas);
+ free (d1s);
+ free (d2s);
+
+ /* rotate eig by a right angle if that would decrease the error */
+ if (err_e2 < err_e1) {
+ real temp = eig[0];
+
+ eig[0] = eig[1];
+ eig[1] = -temp;
+ }
+
+ e1[0] = eig[0] * basis1[0] + eig[1] * basis2[0];
+ e1[1] = eig[0] * basis1[1] + eig[1] * basis2[1];
+ e1[2] = eig[0] * basis1[2] + eig[1] * basis2[2];
+ e1.normalize();
+
+ /* make N,e1,e2 a right handed coordinate sytem */
+ e2 = N ^ e1;
+ e2.normalize();
}
namespace OGF {
- inline static real angle(WOEdge * h) {
- const Vec3r& n1 = h->GetbFace()->GetNormal();
- const Vec3r& n2 = h->GetaFace()->GetNormal();
- const Vec3r v = h->getVec3r();
- real sine = (n1 ^ n2) * v / v.norm() ;
- if(sine >= 1.0) {
- return M_PI / 2.0 ;
- }
- if(sine <= -1.0) {
- return -M_PI / 2.0 ;
- }
- return ::asin(sine) ;
- }
-
- // precondition1: P is inside the sphere
- // precondition2: P,V points to the outside of
- // the sphere (i.e. OP.V > 0)
- static bool sphere_clip_vector(
- const Vec3r& O, real r,
- const Vec3r& P, Vec3r& V
- ) {
-
- Vec3r W = P - O ;
- real a = V.squareNorm() ;
- real b = 2.0 * V * W ;
- real c = W.squareNorm() - r*r ;
- real delta = b*b - 4*a*c ;
- if(delta < 0) {
- // Should not happen, but happens sometimes (numerical precision)
- return true ;
- }
- real t = - b + ::sqrt(delta) / (2.0 * a) ;
- if(t < 0.0) {
- // Should not happen, but happens sometimes (numerical precision)
- return true ;
- }
- if(t >= 1.0) {
- // Inside the sphere
- return false ;
- }
-
- V[0] = (t * V.x()) ;
- V[1] = (t * V.y()) ;
- V[2] = (t * V.z()) ;
-
- return true ;
- }
-
- // TODO: check optimizations:
- // use marking ? (measure *timings* ...)
- void compute_curvature_tensor(
- WVertex* start, real radius, NormalCycle& nc
- ) {
- // in case we have a non-manifold vertex, skip it...
- if(start->isBoundary())
- return;
-
- std::set<WVertex*> vertices ;
- const Vec3r& O = start->GetVertex() ;
- std::stack<WVertex*> S ;
- S.push(start) ;
- vertices.insert(start) ;
- while(!S.empty()) {
- WVertex* v = S.top() ;
- S.pop() ;
- if(v->isBoundary())
- continue;
- const Vec3r& P = v->GetVertex() ;
- WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin();
- WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end();
- for(;woeit!=woeitend; ++woeit){
- WOEdge *h = *woeit;
- if((v == start) || h->GetVec() * (O - P) > 0.0) {
- Vec3r V(-1 * h->GetVec());
- bool isect = sphere_clip_vector(O, radius, P, V) ;
- assert (h->GetOwner()->GetNumberOfOEdges() == 2); // Because otherwise v->isBoundary() would be true
- nc.accumulate_dihedral_angle(V, h->GetAngle()) ;
-
- if(!isect) {
- WVertex* w = h->GetaVertex() ;
- if(vertices.find(w) == vertices.end()) {
- vertices.insert(w) ;
- S.push(w) ;
- }
- }
- }
- }
- }
- }
-
-
- void compute_curvature_tensor_one_ring(
- WVertex* start, NormalCycle& nc
- ) {
- // in case we have a non-manifold vertex, skip it...
- if(start->isBoundary())
- return;
-
- WVertex::incoming_edge_iterator woeit = start->incoming_edges_begin();
- WVertex::incoming_edge_iterator woeitend = start->incoming_edges_end();
- for(;woeit!=woeitend; ++woeit){
- WOEdge *h = (*woeit)->twin();
- nc.accumulate_dihedral_angle(h->GetVec(), h->GetAngle()) ;
- WOEdge *hprev = h->getPrevOnFace();
- nc.accumulate_dihedral_angle(hprev->GetVec(), hprev->GetAngle()) ;
- }
- }
+inline static real angle(WOEdge *h)
+{
+ const Vec3r& n1 = h->GetbFace()->GetNormal();
+ const Vec3r& n2 = h->GetaFace()->GetNormal();
+ const Vec3r v = h->getVec3r();
+ real sine = (n1 ^ n2) * v / v.norm();
+ if (sine >= 1.0) {
+ return M_PI / 2.0;
+ }
+ if (sine <= -1.0) {
+ return -M_PI / 2.0;
+ }
+ return ::asin(sine);
+}
+
+// precondition1: P is inside the sphere
+// precondition2: P,V points to the outside of the sphere (i.e. OP.V > 0)
+static bool sphere_clip_vector(const Vec3r& O, real r, const Vec3r& P, Vec3r& V)
+{
+ Vec3r W = P - O;
+ real a = V.squareNorm();
+ real b = 2.0 * V * W;
+ real c = W.squareNorm() - r * r;
+ real delta = b * b - 4 * a * c;
+ if (delta < 0) {
+ // Should not happen, but happens sometimes (numerical precision)
+ return true;
+ }
+ real t = - b + ::sqrt(delta) / (2.0 * a);
+ if (t < 0.0) {
+ // Should not happen, but happens sometimes (numerical precision)
+ return true;
+ }
+ if (t >= 1.0) {
+ // Inside the sphere
+ return false;
+ }
+
+ V[0] = (t * V.x());
+ V[1] = (t * V.y());
+ V[2] = (t * V.z());
+
+ return true;
+}
+
+// TODO: check optimizations:
+// use marking ? (measure *timings* ...)
+void compute_curvature_tensor(WVertex *start, real radius, NormalCycle& nc)
+{
+ // in case we have a non-manifold vertex, skip it...
+ if(start->isBoundary())
+ return;
+
+ std::set<WVertex*> vertices;
+ const Vec3r& O = start->GetVertex();
+ std::stack<WVertex*> S;
+ S.push(start);
+ vertices.insert(start);
+ while (!S.empty()) {
+ WVertex *v = S.top();
+ S.pop();
+ if (v->isBoundary())
+ continue;
+ const Vec3r& P = v->GetVertex();
+ WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin();
+ WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end();
+ for (; woeit != woeitend; ++woeit) {
+ WOEdge *h = *woeit;
+ if ((v == start) || h->GetVec() * (O - P) > 0.0) {
+ Vec3r V(-1 * h->GetVec());
+ bool isect = sphere_clip_vector(O, radius, P, V);
+ assert (h->GetOwner()->GetNumberOfOEdges() == 2); // Because otherwise v->isBoundary() would be true
+ nc.accumulate_dihedral_angle(V, h->GetAngle());
+
+ if (!isect) {
+ WVertex *w = h->GetaVertex();
+ if (vertices.find(w) == vertices.end()) {
+ vertices.insert(w);
+ S.push(w);
+ }
+ }
+ }
+ }
+ }
}
+
+void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc)
+{
+ // in case we have a non-manifold vertex, skip it...
+ if (start->isBoundary())
+ return;
+
+ WVertex::incoming_edge_iterator woeit = start->incoming_edges_begin();
+ WVertex::incoming_edge_iterator woeitend = start->incoming_edges_end();
+ for (; woeit != woeitend; ++woeit) {
+ WOEdge *h = (*woeit)->twin();
+ nc.accumulate_dihedral_angle(h->GetVec(), h->GetAngle());
+ WOEdge *hprev = h->getPrevOnFace();
+ nc.accumulate_dihedral_angle(hprev->GetVec(), hprev->GetAngle());
+ }
+}
+
+} // OGF namespace
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.h b/source/blender/freestyle/intern/winged_edge/Curvature.h
index b14a5a38337..20450dbdb38 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.h
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.h
@@ -1,29 +1,59 @@
-
-/* GTS - Library for the manipulation of triangulated surfaces
- * Copyright (C) 1999 Stéphane Popinet
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is:
+ * GTS - Library for the manipulation of triangulated surfaces
+ * Copyright (C) 1999 Stephane Popinet
+ * and:
+ * OGF/Graphite: Geometry and Graphics Programming Library + Utilities
+ * Copyright (C) 2000-2003 Bruno Levy
+ * Contact: Bruno Levy levy@loria.fr
+ * ISA Project
+ * LORIA, INRIA Lorraine,
+ * Campus Scientifique, BP 239
+ * 54506 VANDOEUVRE LES NANCY CEDEX
+ * FRANCE
+ *
+ * Contributor(s): none yet.
*
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __CURVATURE_H__
-#define __CURVATURE_H__
+#ifndef __FREESTYLE_CURVATURE_H__
+#define __FREESTYLE_CURVATURE_H__
+
+/** \file blender/freestyle/intern/winged_edge/Curvature.h
+ * \ingroup freestyle
+ * \brief GTS - Library for the manipulation of triangulated surfaces
+ * \author Stephane Popinet
+ * \date 1999
+ * \brief OGF/Graphite: Geometry and Graphics Programming Library + Utilities
+ * \author Bruno Levy
+ * \date 2000-2003
+ */
+
+#include "../geometry/Geom.h"
+
+#include "../system/FreestyleConfig.h"
+#include "../system/Precision.h"
-# include "../system/FreestyleConfig.h"
-# include "../system/Precision.h"
-# include "../geometry/Geom.h"
using namespace Geometry;
class WVertex;
@@ -31,126 +61,83 @@ class WVertex;
class LIB_WINGED_EDGE_EXPORT CurvatureInfo
{
public:
-
- CurvatureInfo()
- {
- K1 = 0.0;
- K2 = 0.0;
- e1 = Vec3r(0.0,0.0,0.0);
- e2 = Vec3r(0.0,0.0,0.0);
- Kr = 0.0;
- dKr = 0.0;
- er = Vec3r(0.0,0.0,0.0);
- }
-
- CurvatureInfo(const CurvatureInfo& iBrother){
- K1 = iBrother.K1;
- K2 = iBrother.K2;
- e1 = iBrother.e1;
- e2 = iBrother.e2;
- Kr = iBrother.Kr;
- dKr = iBrother.dKr;
- er = iBrother.er;
- }
-
- CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t) {
- K1 = ca.K1 + t * (cb.K1 - ca.K1);
- K2 = ca.K2 + t * (cb.K2 - ca.K2);
- e1 = ca.e1 + t * (cb.e1 - ca.e1);
- e2 = ca.e2 + t * (cb.e2 - ca.e2);
- Kr = ca.Kr + t * (cb.Kr - ca.Kr);
- dKr = ca.dKr + t * (cb.dKr - ca.dKr);
- er = ca.er + t * (cb.er - ca.er);
- }
-
- real K1; // maximum curvature
- real K2; // minimum curvature
- Vec3r e1; // maximum curvature direction
- Vec3r e2; // minimum curvature direction
- real Kr; // radial curvature
- real dKr; // radial curvature
- Vec3r er; // radial curvature direction
+ CurvatureInfo()
+ {
+ K1 = 0.0;
+ K2 = 0.0;
+ e1 = Vec3r(0.0, 0.0, 0.0);
+ e2 = Vec3r(0.0, 0.0, 0.0);
+ Kr = 0.0;
+ dKr = 0.0;
+ er = Vec3r(0.0, 0.0, 0.0);
+ }
+
+ CurvatureInfo(const CurvatureInfo& iBrother)
+ {
+ K1 = iBrother.K1;
+ K2 = iBrother.K2;
+ e1 = iBrother.e1;
+ e2 = iBrother.e2;
+ Kr = iBrother.Kr;
+ dKr = iBrother.dKr;
+ er = iBrother.er;
+ }
+
+ CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t)
+ {
+ K1 = ca.K1 + t * (cb.K1 - ca.K1);
+ K2 = ca.K2 + t * (cb.K2 - ca.K2);
+ e1 = ca.e1 + t * (cb.e1 - ca.e1);
+ e2 = ca.e2 + t * (cb.e2 - ca.e2);
+ Kr = ca.Kr + t * (cb.Kr - ca.Kr);
+ dKr = ca.dKr + t * (cb.dKr - ca.dKr);
+ er = ca.er + t * (cb.er - ca.er);
+ }
+
+ real K1; // maximum curvature
+ real K2; // minimum curvature
+ Vec3r e1; // maximum curvature direction
+ Vec3r e2; // minimum curvature direction
+ real Kr; // radial curvature
+ real dKr; // radial curvature
+ Vec3r er; // radial curvature direction
};
-class Face_Curvature_Info{
+class Face_Curvature_Info
+{
public:
- Face_Curvature_Info() {}
- ~Face_Curvature_Info(){
- for(vector<CurvatureInfo*>::iterator ci=vec_curvature_info.begin(), ciend=vec_curvature_info.end();
- ci!=ciend;
- ++ci){
- delete (*ci);
- }
- vec_curvature_info.clear();
- }
- vector<CurvatureInfo *> vec_curvature_info;
+ Face_Curvature_Info() {}
+
+ ~Face_Curvature_Info()
+ {
+ for (vector<CurvatureInfo*>::iterator ci = vec_curvature_info.begin(), ciend = vec_curvature_info.end();
+ ci != ciend;
+ ++ci)
+ {
+ delete (*ci);
+ }
+ vec_curvature_info.clear();
+ }
+
+ vector<CurvatureInfo *> vec_curvature_info;
};
-bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal (WVertex * v,
- Vec3r &n);
+bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &n);
-bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature (WVertex * v,
- real * Kg);
+bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature(WVertex *v, real *Kg);
-void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures (real Kh,
- real Kg,
- real * K1,
- real * K2);
+void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2);
-void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions (WVertex * v,
- Vec3r Kh,
- real Kg,
- Vec3r &e1,
- Vec3r &e2);
-
-/*
- * OGF/Graphite: Geometry and Graphics Programming Library + Utilities
- * Copyright (C) 2000-2003 Bruno Levy
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * If you modify this software, you should include a notice giving the
- * name of the person performing the modification, the date of modification,
- * and the reason for such modification.
- *
- * Contact: Bruno Levy
- *
- * levy@loria.fr
- *
- * ISA Project
- * LORIA, INRIA Lorraine,
- * Campus Scientifique, BP 239
- * 54506 VANDOEUVRE LES NANCY CEDEX
- * FRANCE
- *
- * Note that the GNU General Public License does not permit incorporating
- * the Software into proprietary programs.
- */
- namespace OGF {
+void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2);
- class NormalCycle ;
+namespace OGF {
- void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor(
- WVertex* start, double radius, NormalCycle& nc
- ) ;
+class NormalCycle ;
- void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(
- WVertex* start, NormalCycle& nc
- ) ;
- }
+void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( WVertex *start, double radius, NormalCycle& nc);
+void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc);
-#endif /* __CURVATURE_H__ */
+} // OGF namespace
+#endif /* __FREESTYLE_CURVATURE_H__ */
diff --git a/source/blender/freestyle/intern/winged_edge/Nature.h b/source/blender/freestyle/intern/winged_edge/Nature.h
index 62171fae111..0ce64f3f1cb 100644
--- a/source/blender/freestyle/intern/winged_edge/Nature.h
+++ b/source/blender/freestyle/intern/winged_edge/Nature.h
@@ -1,79 +1,79 @@
-//
-// Filename : Nature.h
-// Author(s) : Emmanuel Turquin
-// Purpose : Different natures for both vertices and edges
-// Date of creation : 01/07/2003
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-#ifndef NATURE_H
-# define NATURE_H
+#ifndef __FREESTYLE_NATURE_H__
+#define __FREESTYLE_NATURE_H__
-/*! \file Nature.h
- * Definitions of Natures of the ViewMap's elements
+/** \file blender/freestyle/intern/winged_edge/Nature.h
+ * \ingroup freestyle
+ * \brief Different natures for both vertices and edges
+ * \author Emmanuel Turquin
+ * \date 01/07/2003
*/
-/*! Namespace gathering the different possible
- * natures of 0D and 1D elements of the ViewMap
- */
+/*! Namespace gathering the different possible natures of 0D and 1D elements of the ViewMap */
namespace Nature {
-
- typedef unsigned short VertexNature;
- /*! true for any 0D element */
- static const VertexNature POINT = 0; // 0
- /*! true for SVertex */
- static const VertexNature S_VERTEX = (1 << 0); // 1
- /*! true for ViewVertex */
- static const VertexNature VIEW_VERTEX = (1 << 1); // 2
- /*! true for NonTVertex */
- static const VertexNature NON_T_VERTEX = (1 << 2); // 4
- /*! true for TVertex */
- static const VertexNature T_VERTEX = (1 << 3); // 8
- /*! true for CUSP */
- static const VertexNature CUSP = (1 << 4); // 16
+/* XXX Why not using enums??? */
+
+typedef unsigned short VertexNature;
+/*! true for any 0D element */
+static const VertexNature POINT = 0; // 0
+/*! true for SVertex */
+static const VertexNature S_VERTEX = (1 << 0); // 1
+/*! true for ViewVertex */
+static const VertexNature VIEW_VERTEX = (1 << 1); // 2
+/*! true for NonTVertex */
+static const VertexNature NON_T_VERTEX = (1 << 2); // 4
+/*! true for TVertex */
+static const VertexNature T_VERTEX = (1 << 3); // 8
+/*! true for CUSP */
+static const VertexNature CUSP = (1 << 4); // 16
- typedef unsigned short EdgeNature;
- /*! true for non feature edges (always false for 1D elements of the ViewMap) */
- static const EdgeNature NO_FEATURE = 0; // 0
- /*! true for silhouettes */
- static const EdgeNature SILHOUETTE = (1 << 0); // 1
- /*! true for borders */
- static const EdgeNature BORDER = (1 << 1); // 2
- /*! true for creases */
- static const EdgeNature CREASE = (1 << 2); // 4
- /*! true for ridges */
- static const EdgeNature RIDGE = (1 << 3); // 8
- /*! true for valleys */
- static const EdgeNature VALLEY = (1 << 4); // 16
- /*! true for suggestive contours */
- static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32
- /*! true for material boundaries */
- static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64
- /*! true for user-defined edge marks */
- static const EdgeNature EDGE_MARK = (1 << 7); // 128
+typedef unsigned short EdgeNature;
+/*! true for non feature edges (always false for 1D elements of the ViewMap) */
+static const EdgeNature NO_FEATURE = 0; // 0
+/*! true for silhouettes */
+static const EdgeNature SILHOUETTE = (1 << 0); // 1
+/*! true for borders */
+static const EdgeNature BORDER = (1 << 1); // 2
+/*! true for creases */
+static const EdgeNature CREASE = (1 << 2); // 4
+/*! true for ridges */
+static const EdgeNature RIDGE = (1 << 3); // 8
+/*! true for valleys */
+static const EdgeNature VALLEY = (1 << 4); // 16
+/*! true for suggestive contours */
+static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32
+/*! true for material boundaries */
+static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64
+/*! true for user-defined edge marks */
+static const EdgeNature EDGE_MARK = (1 << 7); // 128
} // end of namespace Nature
-#endif // NATURE_H
+#endif // __FREESTYLE_NATURE_H__
diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.cpp b/source/blender/freestyle/intern/winged_edge/WEdge.cpp
index 6ef99186a2c..6201d23f9bf 100644
--- a/source/blender/freestyle/intern/winged_edge/WEdge.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp
@@ -1,752 +1,713 @@
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/winged_edge/WEdge.cpp
+ * \ingroup freestyle
+ * \brief Classes to define a Winged Edge data structure.
+ * \author Stephane Grabli
+ * \date 18/02/2002
+ */
#include <iostream>
+
#include "WEdge.h"
/*! Temporary structures */
class vertexdata
{
public:
- WVertex *_copy;
+ WVertex *_copy;
};
class oedgedata
{
public:
- WOEdge *_copy;
+ WOEdge *_copy;
};
class edgedata
{
public:
- WEdge *_copy;
+ WEdge *_copy;
};
class facedata
{
public:
- WFace *_copy;
+ WFace *_copy;
};
- /**********************************/
- /* */
- /* */
- /* WVertex */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WVertex *
+ * *
+ * *
+ **********************************/
WVertex::WVertex(WVertex& iBrother)
{
- _Id = iBrother._Id;
- _Vertex = iBrother._Vertex;
- _EdgeList = iBrother._EdgeList;
-
- _Shape = iBrother._Shape;
- _Smooth = iBrother._Smooth;
- _Border = iBrother._Border;
- userdata = NULL;
- iBrother.userdata = new vertexdata;
- ((vertexdata*)(iBrother.userdata))->_copy = this;
+ _Id = iBrother._Id;
+ _Vertex = iBrother._Vertex;
+ _EdgeList = iBrother._EdgeList;
+
+ _Shape = iBrother._Shape;
+ _Smooth = iBrother._Smooth;
+ _Border = iBrother._Border;
+ userdata = NULL;
+ iBrother.userdata = new vertexdata;
+ ((vertexdata *)(iBrother.userdata))->_copy = this;
}
-WVertex* WVertex::duplicate()
+WVertex *WVertex::duplicate()
{
- WVertex *clone = new WVertex(*this);
- return clone;
+ WVertex *clone = new WVertex(*this);
+ return clone;
}
-
-WOEdge* WVertex::incoming_edge_iterator::operator*()
-
-{
- return _current;
+WOEdge *WVertex::incoming_edge_iterator::operator*()
+{
+ return _current;
}
-void WVertex::incoming_edge_iterator::increment(){
- WOEdge *twin = _current->twin();
- if(!twin){
- // we reached a hole
- _current = 0;
- return;
- }
- WOEdge *next = twin->getPrevOnFace();
- if(next == _begin){
- next = 0;
- }
- _current = next;
+
+void WVertex::incoming_edge_iterator::increment()
+{
+ WOEdge *twin = _current->twin();
+ if (!twin) {
+ // we reached a hole
+ _current = 0;
+ return;
+ }
+ WOEdge *next = twin->getPrevOnFace();
+ if (next == _begin) {
+ next = NULL;
+ }
+ _current = next;
}
-WFace* WVertex::face_iterator::operator*(){
- WOEdge * woedge = *_edge_it;
- if(woedge == 0)
- return 0;
- return (woedge)->GetbFace();
+WFace *WVertex::face_iterator::operator*()
+{
+ WOEdge *woedge = *_edge_it;
+ if (!woedge)
+ return NULL;
+ return (woedge)->GetbFace();
}
-//bool WVertex::isBoundary () const{
-// return _Border;
-//}
+#if 0
+bool WVertex::isBoundary () const
+{
+ return _Border;
+}
+#endif
bool WVertex::isBoundary ()
{
- if(_Border == 1)
- return true;
- else if(_Border == 0)
- return false;
-
+ if (_Border == 1)
+ return true;
+ else if (_Border == 0)
+ return false;
+
vector<WEdge *>::const_iterator it;
- for(it=_EdgeList.begin(); it!=_EdgeList.end(); it++){
- if((*it)->GetNumberOfOEdges() == 1){
- _Border = 1;
- return true;
- }
- }
- //if (!(*it)->GetaOEdge()->GetaFace()) return true;
- _Border = 0;
+ for (it = _EdgeList.begin(); it != _EdgeList.end(); it++) {
+ if ((*it)->GetNumberOfOEdges() == 1) {
+ _Border = 1;
+ return true;
+ }
+ }
+#if 0
+ if (!(*it)->GetaOEdge()->GetaFace())
+ return true;
+#endif
+ _Border = 0;
return false;
}
-void WVertex::AddEdge(WEdge *iEdge) {
- _EdgeList.push_back(iEdge);
+void WVertex::AddEdge(WEdge *iEdge)
+{
+ _EdgeList.push_back(iEdge);
}
-WVertex::incoming_edge_iterator WVertex::incoming_edges_begin(){
- WOEdge *begin;
- WEdge * wedge = _EdgeList.front();
- WOEdge* aOEdge = wedge->GetaOEdge();
- if(aOEdge->GetbVertex() == this)
- begin = aOEdge;
- else
- begin = _EdgeList.front()->GetbOEdge();
- return incoming_edge_iterator(this, begin, begin);
+WVertex::incoming_edge_iterator WVertex::incoming_edges_begin()
+{
+ WOEdge *begin;
+ WEdge *wedge = _EdgeList.front();
+ WOEdge *aOEdge = wedge->GetaOEdge();
+ if (aOEdge->GetbVertex() == this)
+ begin = aOEdge;
+ else
+ begin = _EdgeList.front()->GetbOEdge();
+ return incoming_edge_iterator(this, begin, begin);
+}
+
+WVertex::incoming_edge_iterator WVertex::incoming_edges_end()
+{
+ WOEdge *begin;
+ WOEdge *aOEdge = _EdgeList.front()->GetaOEdge();
+ if (aOEdge->GetbVertex() == this)
+ begin = aOEdge;
+ else
+ begin = _EdgeList.front()->GetbOEdge();
+ return incoming_edge_iterator(this, begin, 0);
}
-WVertex::incoming_edge_iterator WVertex::incoming_edges_end(){
- WOEdge *begin;
- WOEdge* aOEdge = _EdgeList.front()->GetaOEdge();
- if(aOEdge->GetbVertex() == this)
- begin = aOEdge;
- else
- begin = _EdgeList.front()->GetbOEdge();
- return incoming_edge_iterator(this, begin, 0);
+#if 0
+WOEdge **WVertex::incoming_edge_iterator::operator->()
+{
+ WOEdge **ppaOEdge = (*_iter)->GetaOEdge();
+ if (aOEdge->GetbVertex() == _vertex) {
+ return ppaOEdge;
+ }
+ else {
+ WOEdge *bOEdge = (*_iter)->GetbOEdge();
+ return &bOEdge;
+ }
}
-//WOEdge** WVertex::incoming_edge_iterator::operator->()
-//{
-// WOEdge ** ppaOEdge = (*_iter)->GetaOEdge();
-// if(aOEdge->GetbVertex() == _vertex)
-// return ppaOEdge;
-// else
-// {
-// WOEdge *bOEdge = (*_iter)->GetbOEdge();
-// return &bOEdge;
-// }
-//
-//}
- /**********************************/
- /* */
- /* */
- /* WOEdge */
- /* */
- /* */
- /**********************************/
+#endif
+
+/**********************************
+ * *
+ * *
+ * WOEdge *
+ * *
+ * *
+ **********************************/
WOEdge::WOEdge(WOEdge& iBrother)
{
- _paVertex = iBrother.GetaVertex();
- _pbVertex = iBrother.GetbVertex();
- _paFace = iBrother.GetaFace();
- _pbFace = iBrother.GetbFace();
- _pOwner = iBrother.GetOwner();
- userdata = NULL;
- iBrother.userdata = new oedgedata;
- ((oedgedata*)(iBrother.userdata))->_copy = this;
-
- _vec = iBrother._vec;
- _angle = iBrother._angle;
+ _paVertex = iBrother.GetaVertex();
+ _pbVertex = iBrother.GetbVertex();
+ _paFace = iBrother.GetaFace();
+ _pbFace = iBrother.GetbFace();
+ _pOwner = iBrother.GetOwner();
+ userdata = NULL;
+ iBrother.userdata = new oedgedata;
+ ((oedgedata *)(iBrother.userdata))->_copy = this;
+
+ _vec = iBrother._vec;
+ _angle = iBrother._angle;
}
-WOEdge * WOEdge::duplicate()
+WOEdge *WOEdge::duplicate()
{
- WOEdge *clone = new WOEdge(*this);
- return clone;
+ WOEdge *clone = new WOEdge(*this);
+ return clone;
}
-Vec3r
-WOEdge::getVec3r ()
+Vec3r WOEdge::getVec3r ()
{
- return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex());
-}
+ return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex());
+}
-WOEdge * WOEdge::twin ()
+WOEdge *WOEdge::twin ()
{
- return GetOwner()->GetOtherOEdge(this);
+ return GetOwner()->GetOtherOEdge(this);
}
-WOEdge *
-WOEdge::getPrevOnFace()
+WOEdge *WOEdge::getPrevOnFace()
{
return _pbFace->GetPrevOEdge(this);
}
- /**********************************/
- /* */
- /* */
- /* WEdge */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WEdge *
+ * *
+ * *
+ **********************************/
WEdge::WEdge(WEdge& iBrother)
{
- _paOEdge = NULL;
- _pbOEdge = NULL;
- WOEdge *aoedge = iBrother.GetaOEdge();
- WOEdge *boedge = iBrother.GetbOEdge();
- userdata = NULL;
-
- if(NULL != aoedge)
- //_paOEdge = new WOEdge(*aoedge);
- _paOEdge = aoedge->duplicate();
- if(NULL != boedge)
- //_pbOEdge = new WOEdge(*boedge);
- _pbOEdge = boedge->duplicate();
-
- _nOEdges = iBrother.GetNumberOfOEdges();
- _Id = iBrother.GetId();
- iBrother.userdata = new edgedata;
- ((edgedata*)(iBrother.userdata))->_copy = this;
+ _paOEdge = NULL;
+ _pbOEdge = NULL;
+ WOEdge *aoedge = iBrother.GetaOEdge();
+ WOEdge *boedge = iBrother.GetbOEdge();
+ userdata = NULL;
+
+ if (aoedge)
+ //_paOEdge = new WOEdge(*aoedge);
+ _paOEdge = aoedge->duplicate();
+ if (boedge)
+ //_pbOEdge = new WOEdge(*boedge);
+ _pbOEdge = boedge->duplicate();
+
+ _nOEdges = iBrother.GetNumberOfOEdges();
+ _Id = iBrother.GetId();
+ iBrother.userdata = new edgedata;
+ ((edgedata *)(iBrother.userdata))->_copy = this;
}
-WEdge * WEdge::duplicate()
+WEdge *WEdge::duplicate()
{
- WEdge *clone = new WEdge(*this);
- return clone;
+ WEdge *clone = new WEdge(*this);
+ return clone;
}
- /**********************************/
- /* */
- /* */
- /* WFace */
- /* */
- /* */
- /**********************************/
-
+/**********************************
+ * *
+ * *
+ * WFace *
+ * *
+ * *
+ **********************************/
WFace::WFace(WFace& iBrother)
{
- _OEdgeList = iBrother.getEdgeList();
- _Normal = iBrother.GetNormal();
- _VerticesNormals = iBrother._VerticesNormals;
- _VerticesTexCoords = iBrother._VerticesTexCoords;
- _Id = iBrother.GetId();
- _FrsMaterialIndex = iBrother._FrsMaterialIndex;
- _Mark = iBrother._Mark;
- userdata = NULL;
- iBrother.userdata = new facedata;
- ((facedata*)(iBrother.userdata))->_copy = this;
+ _OEdgeList = iBrother.getEdgeList();
+ _Normal = iBrother.GetNormal();
+ _VerticesNormals = iBrother._VerticesNormals;
+ _VerticesTexCoords = iBrother._VerticesTexCoords;
+ _Id = iBrother.GetId();
+ _FrsMaterialIndex = iBrother._FrsMaterialIndex;
+ _Mark = iBrother._Mark;
+ userdata = NULL;
+ iBrother.userdata = new facedata;
+ ((facedata *)(iBrother.userdata))->_copy = this;
}
-WFace * WFace::duplicate()
+WFace *WFace::duplicate()
{
- WFace * clone = new WFace(*this);
- return clone;
+ WFace *clone = new WFace(*this);
+ return clone;
}
-const FrsMaterial& WFace::frs_material() {
- return getShape()->frs_material(_FrsMaterialIndex);
+const FrsMaterial& WFace::frs_material()
+{
+ return getShape()->frs_material(_FrsMaterialIndex);
}
-WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
-{
- // First check whether the same oriented edge already exists
- // or not:
- vector<WEdge *>& v1Edges = v1->GetEdges();
- for(vector<WEdge*>::iterator it1=v1Edges.begin(), end=v1Edges.end();
- it1!=end;
- it1++)
- {
-
- WEdge *we=(*it1);
-
- WOEdge *woea = we->GetaOEdge();
-
- if((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2))
- //if((*it1)->GetbVertex() == v2)
- {
- // The oriented edge already exists
- cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
- // Adds the edge to the face
- //AddEdge((*it1)->GetaOEdge());
- AddEdge(woea);
- (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1);
- //sets these vertices as border:
- v1->setBorder(true);
- v2->setBorder(true);
- //return (*it1)->GetaOEdge();
- return woea;
- }
-
- WOEdge *woeb = we->GetbOEdge();
- if((woeb != 0) && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2))
-
- //if((*it1)->GetbVertex() == v2)
-
- {
- // The oriented edge already exists
- cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
- // Adds the edge to the face
- //AddEdge((*it1)->GetaOEdge());
- AddEdge(woeb);
- (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1);
- //sets these vertices as border:
- v1->setBorder(true);
- v2->setBorder(true);
- //return (*it1)->GetaOEdge();
- return woeb;
- }
- }
-
- // the oriented edge we're about to build
- WOEdge *pOEdge = new WOEdge;
-
- WEdge * edge; // The edge containing the oriented edge.
-
- // checks whether this edge already exists or not
- // If it exists, it points outward v2
-
- bool exist = false;
- WOEdge *pInvertEdge = NULL; // The inverted edge if it exists
- vector<WEdge *>& v2Edges = v2->GetEdges();
- vector<WEdge *>::iterator it;
- for(it=v2Edges.begin(); it!=v2Edges.end(); it++)
- {
- if((*it)->GetbVertex() == v1)
- {
- // The invert edge already exists
- exist = true;
- pInvertEdge = (*it)->GetaOEdge();
- break;
- }
- }
-
- //DEBUG:
-
-
- if(true == exist) // The invert edge already exists
- {
- // Retrieves the corresponding edge
- edge = pInvertEdge->GetOwner();
-
- // Sets the a Face (retrieved from pInvertEdge
- pOEdge->setaFace(pInvertEdge->GetbFace());
-
- // Updates the invert edge:
- pInvertEdge->setaFace(this);
- }
- else // The invert edge does not exist yet
- {
- // we must create a new edge
- //edge = new WEdge;
- edge = instanciateEdge();
-
- // updates the a,b vertex edges list:
- v1->AddEdge(edge);
- v2->AddEdge(edge);
-
- }
-
- pOEdge->setOwner(edge);
- // Add the vertices:
- pOEdge->setaVertex(v1);
- pOEdge->setbVertex(v2);
-
- // Debug:
- if(v1->GetId() == v2->GetId())
- cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl;
-
- edge->AddOEdge(pOEdge);
- //edge->setNumberOfOEdges(edge->GetNumberOfOEdges()+1);
-
- // Add this face (the b face)
- pOEdge->setbFace(this);
-
- // Adds the edge to the face
- AddEdge(pOEdge);
-
- return pOEdge;
+WOEdge *WFace::MakeEdge(WVertex *v1, WVertex *v2)
+{
+ // First check whether the same oriented edge already exists or not:
+ vector<WEdge *>& v1Edges = v1->GetEdges();
+ for (vector<WEdge*>::iterator it1 = v1Edges.begin(), end = v1Edges.end(); it1 != end; it1++) {
+ WEdge *we = (*it1);
+ WOEdge *woea = we->GetaOEdge();
+
+ //if ((*it1)->GetbVertex() == v2) {
+ if ((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) {
+ // The oriented edge already exists
+ cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
+ // Adds the edge to the face
+ //AddEdge((*it1)->GetaOEdge());
+ AddEdge(woea);
+ (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1);
+ //sets these vertices as border:
+ v1->setBorder(true);
+ v2->setBorder(true);
+ //return (*it1)->GetaOEdge();
+ return woea;
+ }
+
+ WOEdge *woeb = we->GetbOEdge();
+ //if ((*it1)->GetbVertex() == v2)
+ if (woeb && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2)) {
+ // The oriented edge already exists
+ cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
+ // Adds the edge to the face
+ //AddEdge((*it1)->GetaOEdge());
+ AddEdge(woeb);
+ (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1);
+ //sets these vertices as border:
+ v1->setBorder(true);
+ v2->setBorder(true);
+ //return (*it1)->GetaOEdge();
+ return woeb;
+ }
+ }
+
+ // the oriented edge we're about to build
+ WOEdge *pOEdge = new WOEdge;
+ // The edge containing the oriented edge.
+ WEdge *edge;
+
+ // checks whether this edge already exists or not
+ // If it exists, it points outward v2
+ bool exist = false;
+ WOEdge *pInvertEdge = NULL; // The inverted edge if it exists
+ vector<WEdge *>& v2Edges = v2->GetEdges();
+ vector<WEdge *>::iterator it;
+ for (it = v2Edges.begin(); it != v2Edges.end(); it++) {
+ if ((*it)->GetbVertex() == v1) {
+ // The invert edge already exists
+ exist = true;
+ pInvertEdge = (*it)->GetaOEdge();
+ break;
+ }
+ }
+
+ //DEBUG:
+ if (true == exist) { // The invert edge already exists
+ // Retrieves the corresponding edge
+ edge = pInvertEdge->GetOwner();
+
+ // Sets the a Face (retrieved from pInvertEdge
+ pOEdge->setaFace(pInvertEdge->GetbFace());
+
+ // Updates the invert edge:
+ pInvertEdge->setaFace(this);
+ }
+ else { // The invert edge does not exist yet
+ // we must create a new edge
+ //edge = new WEdge;
+ edge = instanciateEdge();
+
+ // updates the a,b vertex edges list:
+ v1->AddEdge(edge);
+ v2->AddEdge(edge);
+ }
+
+ pOEdge->setOwner(edge);
+ // Add the vertices:
+ pOEdge->setaVertex(v1);
+ pOEdge->setbVertex(v2);
+
+ // Debug:
+ if (v1->GetId() == v2->GetId())
+ cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl;
+
+ edge->AddOEdge(pOEdge);
+ //edge->setNumberOfOEdges(edge->GetNumberOfOEdges() + 1);
+
+ // Add this face (the b face)
+ pOEdge->setbFace(this);
+
+ // Adds the edge to the face
+ AddEdge(pOEdge);
+
+ return pOEdge;
}
-bool
-WFace::getOppositeEdge (const WVertex *v, WOEdge* &e)
+bool WFace::getOppositeEdge (const WVertex *v, WOEdge *&e)
{
- if (_OEdgeList.size()!=3) return false;
+ if (_OEdgeList.size() != 3)
+ return false;
vector<WOEdge *>::iterator it;
- e=NULL;
- for(it=_OEdgeList.begin(); it!=_OEdgeList.end(); it++)
- if ((*it)->GetaVertex()==v) e=*it;
- if (!e) return false;
- e=NULL;
- for(it=_OEdgeList.begin(); it!=_OEdgeList.end(); it++)
- if (((*it)->GetaVertex()!=v) && ((*it)->GetbVertex()!=v)) e=*it;
- if (!e) return false;
- else return true;
+ e = NULL;
+ for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) {
+ if ((*it)->GetaVertex() == v)
+ e = *it;
+ }
+ if (!e)
+ return false;
+ e = NULL;
+ for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) {
+ if (((*it)->GetaVertex() != v) && ((*it)->GetbVertex() != v))
+ e = *it;
+ }
+ if (!e)
+ return false;
+ else
+ return true;
}
-real
-WFace::getArea ()
+real WFace::getArea ()
{
vector<WOEdge *>::iterator it;
- Vec3r origin=(*(_OEdgeList.begin()))->GetaVertex()->GetVertex();
- it=_OEdgeList.begin();
- real a=0;
- for (it=it++; it!=_OEdgeList.end(); it++) {
- Vec3r v1=Vec3r((*it)->GetaVertex()->GetVertex() - origin);
- Vec3r v2=Vec3r((*it)->GetbVertex()->GetVertex() - origin);
- a += (v1 ^ v2).norm() / 2.0;
+ Vec3r origin = (*(_OEdgeList.begin()))->GetaVertex()->GetVertex();
+ it = _OEdgeList.begin();
+ real a = 0;
+ for (it = it++; it != _OEdgeList.end(); it++) {
+ Vec3r v1 = Vec3r((*it)->GetaVertex()->GetVertex() - origin);
+ Vec3r v2 = Vec3r((*it)->GetbVertex()->GetVertex() - origin);
+ a += (v1 ^ v2).norm() / 2.0;
}
return a;
}
-WOEdge*
-WFace::GetPrevOEdge(WOEdge* iOEdge)
- {
- vector<WOEdge*>::iterator woe,woend, woefirst;
- woefirst = _OEdgeList.begin();
- woend=_OEdgeList.end();
- WOEdge *prev =*woefirst;
- woe=woefirst;
- woe++;
- for(;
- woe!=woend;
- woe++)
- {
- if((*woe) == iOEdge)
- return prev;
- prev= *woe;
+WOEdge *WFace::GetPrevOEdge(WOEdge* iOEdge)
+{
+ vector<WOEdge *>::iterator woe, woend, woefirst;
+ woefirst = _OEdgeList.begin();
+ woend = _OEdgeList.end();
+ WOEdge *prev = *woefirst;
+ woe = woefirst;
+ ++woe;
+ for (; woe != woend; woe++) {
+ if ((*woe) == iOEdge)
+ return prev;
+ prev = *woe;
}
- // We left the loop. That means that the first
- // OEdge was the good one:
- if((*woefirst)==iOEdge)
- return prev;
+ // We left the loop. That means that the first OEdge was the good one:
+ if ((*woefirst) == iOEdge)
+ return prev;
- return NULL;
- }
+ return NULL;
+}
-WShape * WFace::getShape()
+WShape *WFace::getShape()
{
- return GetVertex(0)->shape();
+ return GetVertex(0)->shape();
}
- /**********************************/
- /* */
- /* */
- /* WShape */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WShape *
+ * *
+ * *
+ **********************************/
LIB_WINGED_EDGE_EXPORT
unsigned WShape::_SceneCurrentId = 0;
-WShape * WShape::duplicate()
+WShape *WShape::duplicate()
{
- WShape *clone = new WShape(*this);
- return clone;
+ WShape *clone = new WShape(*this);
+ return clone;
}
WShape::WShape(WShape& iBrother)
{
- _Id = iBrother.GetId();
- _Name = iBrother._Name;
- _FrsMaterials = iBrother._FrsMaterials;
- _meanEdgeSize = iBrother._meanEdgeSize;
- iBrother.bbox(_min, _max);
- vector<WVertex*>& vertexList = iBrother.getVertexList();
- vector<WVertex*>::iterator v=vertexList.begin(), vend=vertexList.end();
- for(;
- v!=vend;
- v++)
- {
- //WVertex *newVertex = new WVertex(*(*v));
- WVertex *newVertex = (*v)->duplicate();
-
- newVertex->setShape(this);
- AddVertex(newVertex);
- }
-
- vector<WEdge*>& edgeList = iBrother.getEdgeList();
- vector<WEdge*>::iterator e=edgeList.begin(), eend=edgeList.end();
- for(;
- e!=eend;
- e++)
- {
- //WEdge *newEdge = new WEdge(*(*e));
- WEdge *newEdge = (*e)->duplicate();
- AddEdge(newEdge);
- }
-
- vector<WFace*>& faceList = iBrother.GetFaceList();
- vector<WFace*>::iterator f=faceList.begin(), fend=faceList.end();
- for(;
- f!=fend;
- f++)
- {
- //WFace *newFace = new WFace(*(*f));
- WFace *newFace = (*f)->duplicate();
- AddFace(newFace);
- }
-
- // update all pointed addresses thanks to the newly created objects:
- vend=_VertexList.end();
- for(v=_VertexList.begin();
- v!=vend;
- v++)
- {
- const vector<WEdge*>& vedgeList = (*v)->GetEdges();
- vector<WEdge*> newvedgelist;
- unsigned int i;
- for(i=0; i<vedgeList.size(); i++)
- {
- WEdge *current = vedgeList[i];
- edgedata * currentvedata = (edgedata*)current->userdata;
- newvedgelist.push_back(currentvedata->_copy);
- }
- (*v)->setEdges(newvedgelist);
- }
-
- eend = _EdgeList.end();
- for(e=_EdgeList.begin();
- e!=eend;
- e++)
- {
- // update aOedge:
- WOEdge *aoEdge = (*e)->GetaOEdge();
- aoEdge->setaVertex(((vertexdata*)(aoEdge->GetaVertex()->userdata))->_copy);
- aoEdge->setbVertex(((vertexdata*)(aoEdge->GetbVertex()->userdata))->_copy);
- if(NULL != aoEdge->GetaFace())
- aoEdge->setaFace(((facedata*)(aoEdge->GetaFace()->userdata))->_copy);
- aoEdge->setbFace(((facedata*)(aoEdge->GetbFace()->userdata))->_copy);
- aoEdge->setOwner(((edgedata*)(aoEdge->GetOwner()->userdata))->_copy);
- // update bOedge:
-
- WOEdge *boEdge = (*e)->GetbOEdge();
- if(boEdge != 0)
- {
- boEdge->setaVertex(((vertexdata*)(boEdge->GetaVertex()->userdata))->_copy);
- boEdge->setbVertex(((vertexdata*)(boEdge->GetbVertex()->userdata))->_copy);
- if(NULL != boEdge->GetaFace())
- boEdge->setaFace(((facedata*)(boEdge->GetaFace()->userdata))->_copy);
- boEdge->setbFace(((facedata*)(boEdge->GetbFace()->userdata))->_copy);
- boEdge->setOwner(((edgedata*)(boEdge->GetOwner()->userdata))->_copy);
- }
- }
-
- fend = _FaceList.end();
- for(f=_FaceList.begin();
- f!=fend;
- f++)
- {
- unsigned i;
- const vector<WOEdge*>& oedgeList = (*f)->getEdgeList();
- vector<WOEdge*> newoedgelist;
-
- unsigned n = oedgeList.size();
- for(i=0; i<n; i++)
- {
- WOEdge *current = oedgeList[i];
- oedgedata * currentoedata = (oedgedata*)current->userdata;
- newoedgelist.push_back(currentoedata->_copy);
- //oedgeList[i] = currentoedata->_copy;
- //oedgeList[i] = ((oedgedata*)(oedgeList[i]->userdata))->_copy;
- }
- (*f)->setEdgeList(newoedgelist);
- }
-
- // Free all memory (arghh!)
- // Vertex
- vend = iBrother.getVertexList().end();
- for(v=iBrother.getVertexList().begin();
- v!=vend;
- v++)
- {
- delete (vertexdata*)((*v)->userdata);
- (*v)->userdata = NULL;
- }
-
- // Edges and OEdges:
- eend = iBrother.getEdgeList().end();
- for(e=iBrother.getEdgeList().begin();
- e!=eend;
- e++)
- {
- delete (edgedata*)((*e)->userdata);
- (*e)->userdata = NULL;
- // OEdge a :
- delete (oedgedata*)((*e)->GetaOEdge()->userdata);
- (*e)->GetaOEdge()->userdata = NULL;
- // OEdge b:
- WOEdge* oedgeb = (*e)->GetbOEdge();
- if(NULL != oedgeb)
- {
- delete (oedgedata*)(oedgeb->userdata);
- oedgeb->userdata = NULL;
- }
- }
- // Faces
- fend = iBrother.GetFaceList().end();
- for(f=iBrother.GetFaceList().begin();
- f!=fend;
- f++)
- {
- delete (facedata*)((*f)->userdata);
- (*f)->userdata = NULL;
- }
-}
+ _Id = iBrother.GetId();
+ _Name = iBrother._Name;
+ _FrsMaterials = iBrother._FrsMaterials;
+ _meanEdgeSize = iBrother._meanEdgeSize;
+ iBrother.bbox(_min, _max);
+ vector<WVertex *>& vertexList = iBrother.getVertexList();
+ vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end();
+ for (; v != vend; ++v) {
+ //WVertex *newVertex = new WVertex(*(*v));
+ WVertex *newVertex = (*v)->duplicate();
+
+ newVertex->setShape(this);
+ AddVertex(newVertex);
+ }
-WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
-{
- // allocate the new face
- WFace *face = instanciateFace();
+ vector<WEdge *>& edgeList = iBrother.getEdgeList();
+ vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end();
+ for (; e != eend; ++e) {
+ //WEdge *newEdge = new WEdge(*(*e));
+ WEdge *newEdge = (*e)->duplicate();
+ AddEdge(newEdge);
+ }
- WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face);
- if (0 == result) {
- delete face;
- return 0;
- }
- return result;
-}
+ vector<WFace *>& faceList = iBrother.GetFaceList();
+ vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end();
+ for (; f != fend; ++f) {
+ //WFace *newFace = new WFace(*(*f));
+ WFace *newFace = (*f)->duplicate();
+ AddFace(newFace);
+ }
-WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
-{
- // allocate the new face
- WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial);
+ // update all pointed addresses thanks to the newly created objects:
+ vend = _VertexList.end();
+ for (v = _VertexList.begin(); v != vend; ++v) {
+ const vector<WEdge *>& vedgeList = (*v)->GetEdges();
+ vector<WEdge *> newvedgelist;
+ unsigned int i;
+ for (i = 0; i < vedgeList.size(); i++) {
+ WEdge *current = vedgeList[i];
+ edgedata *currentvedata = (edgedata *)current->userdata;
+ newvedgelist.push_back(currentvedata->_copy);
+ }
+ (*v)->setEdges(newvedgelist);
+ }
+
+ eend = _EdgeList.end();
+ for (e = _EdgeList.begin(); e != eend; ++e) {
+ // update aOedge:
+ WOEdge *aoEdge = (*e)->GetaOEdge();
+ aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy);
+ aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy);
+ if (aoEdge->GetaFace())
+ aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy);
+ aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy);
+ aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy);
+
+ // update bOedge:
+ WOEdge *boEdge = (*e)->GetbOEdge();
+ if (boEdge) {
+ boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy);
+ boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy);
+ if (boEdge->GetaFace())
+ boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy);
+ boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy);
+ boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy);
+ }
+ }
- if(0 == face)
+ fend = _FaceList.end();
+ for (f = _FaceList.begin(); f != fend; ++f) {
+ unsigned int i;
+ const vector<WOEdge *>& oedgeList = (*f)->getEdgeList();
+ vector<WOEdge *> newoedgelist;
+
+ unsigned int n = oedgeList.size();
+ for (i = 0; i < n; i++) {
+ WOEdge *current = oedgeList[i];
+ oedgedata *currentoedata = (oedgedata *)current->userdata;
+ newoedgelist.push_back(currentoedata->_copy);
+ //oedgeList[i] = currentoedata->_copy;
+ //oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy;
+ }
+ (*f)->setEdgeList(newoedgelist);
+ }
- return 0;
+ // Free all memory (arghh!)
+ // Vertex
+ vend = iBrother.getVertexList().end();
+ for (v = iBrother.getVertexList().begin(); v != vend; ++v) {
+ delete (vertexdata *)((*v)->userdata);
+ (*v)->userdata = NULL;
+ }
- // set the list of per-vertex normals
- face->setNormalList(iNormalsList);
- // set the list of per-vertex tex coords
- face->setTexCoordsList(iTexCoordsList);
+ // Edges and OEdges:
+ eend = iBrother.getEdgeList().end();
+ for (e = iBrother.getEdgeList().begin(); e != eend; ++e) {
+ delete (edgedata *)((*e)->userdata);
+ (*e)->userdata = NULL;
+ // OEdge a:
+ delete (oedgedata *)((*e)->GetaOEdge()->userdata);
+ (*e)->GetaOEdge()->userdata = NULL;
+ // OEdge b:
+ WOEdge *oedgeb = (*e)->GetbOEdge();
+ if (oedgeb) {
+ delete (oedgedata *)(oedgeb->userdata);
+ oedgeb->userdata = NULL;
+ }
+ }
- return face;
+ // Faces
+ fend = iBrother.GetFaceList().end();
+ for (f = iBrother.GetFaceList().begin(); f != fend; ++f) {
+ delete (facedata *)((*f)->userdata);
+ (*f)->userdata = NULL;
+ }
}
-WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial, WFace *face)
+WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
{
+ // allocate the new face
+ WFace *face = instanciateFace();
- int id = _FaceList.size();
-
- face->setFrsMaterialIndex(iMaterial);
-
- // Check whether we have a degenerated face:
-
- // LET'S HACK IT FOR THE TRIANGLE CASE:
-
- if(3 == iVertexList.size())
-
- {
-
- if((iVertexList[0] == iVertexList[1])
-
- || (iVertexList[0] == iVertexList[2])
-
- || (iVertexList[2] == iVertexList[1]))
-
- {
-
- cerr << "Warning: degenerated triangle detected, correcting" << endl;
- return 0;
-
- }
+ WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face);
+ if (!result)
+ delete face;
+ return result;
+}
- }
+WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
+ vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
+{
+ // allocate the new face
+ WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial);
- vector<WVertex*>::iterator it;
+ if (!face)
+ return NULL;
- // compute the face normal (v1v2 ^ v1v3)
- WVertex *v1, *v2, *v3;
- it = iVertexList.begin();
- v1 = *it;
- it++;
- v2 = *it;
- it++;
- v3 = *it;
+ // set the list of per-vertex normals
+ face->setNormalList(iNormalsList);
+ // set the list of per-vertex tex coords
+ face->setTexCoordsList(iTexCoordsList);
- Vec3r vector1(v2->GetVertex()-v1->GetVertex());
- Vec3r vector2(v3->GetVertex()-v1->GetVertex());
+ return face;
+}
- Vec3r normal(vector1 ^ vector2);
- normal.normalize();
- face->setNormal(normal);
+WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial,
+ WFace *face)
+{
+ int id = _FaceList.size();
- vector<bool>::iterator mit = iFaceEdgeMarksList.begin();
- face->setMark(*mit);
- mit++;
+ face->setFrsMaterialIndex(iMaterial);
- // vertex pointers used to build each edge
- vector<WVertex*>::iterator va, vb;
+ // Check whether we have a degenerated face:
- va = iVertexList.begin();
- vb = va;
- for(; va != iVertexList.end(); va = vb)
- {
- vb++;
- // Adds va to the vertex list:
- //face->AddVertex(*va);
+ // LET'S HACK IT FOR THE TRIANGLE CASE:
- WOEdge * oedge;
- if(*va == iVertexList.back())
- oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge
- else
- oedge = face->MakeEdge(*va, *vb);
+ if (3 == iVertexList.size()) {
+ if ((iVertexList[0] == iVertexList[1]) ||
+ (iVertexList[0] == iVertexList[2]) ||
+ (iVertexList[2] == iVertexList[1])) {
+ cerr << "Warning: degenerated triangle detected, correcting" << endl;
+ return NULL;
+ }
+ }
+ vector<WVertex *>::iterator it;
- if(oedge == 0)
- return 0;
+ // compute the face normal (v1v2 ^ v1v3)
+ WVertex *v1, *v2, *v3;
+ it = iVertexList.begin();
+ v1 = *it;
+ it++;
+ v2 = *it;
+ it++;
+ v3 = *it;
+ Vec3r vector1(v2->GetVertex() - v1->GetVertex());
+ Vec3r vector2(v3->GetVertex() - v1->GetVertex());
- WEdge *edge = oedge->GetOwner();
- if(1 == edge->GetNumberOfOEdges())
- {
- // means that we just created a new edge and that we must add it to the
- // shape's edges list
- edge->setId(_EdgeList.size());
- AddEdge(edge);
- // compute the mean edge value:
- _meanEdgeSize += edge->GetaOEdge()->GetVec().norm();
- }
+ Vec3r normal(vector1 ^ vector2);
+ normal.normalize();
+ face->setNormal(normal);
- edge->setMark(*mit);
+ vector<bool>::iterator mit = iFaceEdgeMarksList.begin();
+ face->setMark(*mit);
mit++;
- }
- // Add the face to the shape's faces list:
- face->setId(id);
- AddFace(face);
+ // vertex pointers used to build each edge
+ vector<WVertex *>::iterator va, vb;
+
+ va = iVertexList.begin();
+ vb = va;
+ for (; va != iVertexList.end(); va = vb) {
+ ++vb;
+ // Adds va to the vertex list:
+ //face->AddVertex(*va);
+
+ WOEdge *oedge;
+ if (*va == iVertexList.back())
+ oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge
+ else
+ oedge = face->MakeEdge(*va, *vb);
+
+ if (!oedge)
+ return NULL;
+
+ WEdge *edge = oedge->GetOwner();
+ if (1 == edge->GetNumberOfOEdges()) {
+ // means that we just created a new edge and that we must add it to the shape's edges list
+ edge->setId(_EdgeList.size());
+ AddEdge(edge);
+ // compute the mean edge value:
+ _meanEdgeSize += edge->GetaOEdge()->GetVec().norm();
+ }
+
+ edge->setMark(*mit);
+ ++mit;
+ }
+
+ // Add the face to the shape's faces list:
+ face->setId(id);
+ AddFace(face);
- return face;
-}
+ return face;
+} \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h
index dc920448add..be9181329d6 100644
--- a/source/blender/freestyle/intern/winged_edge/WEdge.h
+++ b/source/blender/freestyle/intern/winged_edge/WEdge.h
@@ -1,991 +1,1344 @@
-//
-// Filename : WEdge.h
-// Author(s) : Stephane Grabli
-// Purpose : Classes to define a Winged Edge data structure.
-// Date of creation : 18/02/2002
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef WEDGE_H
-# define WEDGE_H
-
-# include <vector>
-# include <iterator>
-# include <math.h>
-# include "../system/FreestyleConfig.h"
-# include "../geometry/Geom.h"
-# include "../scene_graph/FrsMaterial.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_W_EDGE_H__
+#define __FREESTYLE_W_EDGE_H__
+
+/** \file blender/freestyle/intern/winged_edge/WEdge.h
+ * \ingroup freestyle
+ * \brief Classes to define a Winged Edge data structure.
+ * \author Stephane Grabli
+ * \date 18/02/2002
+ */
+
+#include <iterator>
+#include <math.h>
+#include <vector>
+
+#include "../geometry/Geom.h"
+
+#include "../scene_graph/FrsMaterial.h"
+
+#include "../system/FreestyleConfig.h"
using namespace std;
using namespace Geometry;
- /**********************************/
- /* */
- /* */
- /* WVertex */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WVertex *
+ * *
+ * *
+ **********************************/
class WOEdge;
class WEdge;
class WShape;
class WFace;
+
class LIB_WINGED_EDGE_EXPORT WVertex
{
protected:
- int _Id; // an identificator
- Vec3r _Vertex;
- vector<WEdge*> _EdgeList;
- WShape * _Shape; // the shape to which the vertex belongs
- bool _Smooth; // flag to indicate whether the Vertex belongs to a smooth edge or not
- int _Border; // 1 -> border, 0 -> no border, -1 -> not set
-
-public:
- void * userdata; // designed to store specific user data
- inline WVertex(const Vec3r &v) {_Id = 0; _Vertex = v; userdata = NULL; _Shape = NULL;_Smooth=true;_Border=-1;}
- /*! Copy constructor */
- WVertex(WVertex& iBrother);
- virtual WVertex * duplicate();
- virtual ~WVertex() {}
-
- /*! accessors */
- inline Vec3r& GetVertex() {return _Vertex;}
- inline vector<WEdge*>& GetEdges() {return _EdgeList;}
- inline int GetId() {return _Id;}
- inline WShape * shape() const {return _Shape;}
- inline bool isSmooth() const {return _Smooth;}
- bool isBoundary();
-
- /*! modifiers */
- inline void setVertex(const Vec3r& v) {_Vertex = v;}
- inline void setEdges(const vector<WEdge *>& iEdgeList) {_EdgeList = iEdgeList;}
- inline void setId(int id) {_Id = id;}
- inline void setShape(WShape *iShape) {_Shape = iShape;}
- inline void setSmooth(bool b) {_Smooth = b;}
- inline void setBorder(bool b) {if(b) _Border= 1; else _Border = 0;}
-
- /*! Adds an edge to the edges list */
- void AddEdge(WEdge *iEdge) ;
-
- virtual void ResetUserData() {userdata = 0;}
-
-
+ int _Id; // an identificator
+ Vec3r _Vertex;
+ vector<WEdge*> _EdgeList;
+ WShape *_Shape; // the shape to which the vertex belongs
+ bool _Smooth; // flag to indicate whether the Vertex belongs to a smooth edge or not
+ int _Border; // 1 -> border, 0 -> no border, -1 -> not set
public:
+ void *userdata; // designed to store specific user data
+ inline WVertex(const Vec3r &v)
+ {
+ _Id = 0;
+ _Vertex = v;
+ userdata = NULL;
+ _Shape = NULL;
+ _Smooth = true;
+ _Border = -1;
+ }
+
+ /*! Copy constructor */
+ WVertex(WVertex& iBrother);
+ virtual WVertex *duplicate();
+ virtual ~WVertex() {}
+
+ /*! accessors */
+ inline Vec3r& GetVertex()
+ {
+ return _Vertex;
+ }
+
+ inline vector<WEdge*>& GetEdges()
+ {
+ return _EdgeList;
+ }
+
+ inline int GetId()
+ {
+ return _Id;
+ }
+
+ inline WShape *shape() const
+ {
+ return _Shape;
+ }
+
+ inline bool isSmooth() const
+ {
+ return _Smooth;
+ }
+
+ bool isBoundary();
+
+ /*! modifiers */
+ inline void setVertex(const Vec3r& v)
+ {
+ _Vertex = v;
+ }
+
+ inline void setEdges(const vector<WEdge *>& iEdgeList)
+ {
+ _EdgeList = iEdgeList;
+ }
+
+ inline void setId(int id)
+ {
+ _Id = id;
+ }
+
+ inline void setShape(WShape *iShape)
+ {
+ _Shape = iShape;
+ }
+
+ inline void setSmooth(bool b)
+ {
+ _Smooth = b;
+ }
+
+ inline void setBorder(bool b)
+ {
+ if (b)
+ _Border = 1;
+ else
+ _Border = 0;
+ }
+
+ /*! Adds an edge to the edges list */
+ void AddEdge(WEdge *iEdge);
+
+ virtual void ResetUserData()
+ {
+ userdata = NULL;
+ }
-
-
- /*! Iterator to iterate over a vertex incoming edges in the CCW order*/
-# if defined(__GNUC__) && (__GNUC__ < 3)
- class incoming_edge_iterator : public input_iterator<WOEdge*,ptrdiff_t>
-# else
- class LIB_WINGED_EDGE_EXPORT incoming_edge_iterator : public iterator<input_iterator_tag, WOEdge*,ptrdiff_t>
-# endif
- {
- private:
- WVertex *_vertex;
- //
- WOEdge *_begin;
- WOEdge *_current;
-
- public:
-# if defined(__GNUC__) && (__GNUC__ < 3)
- inline incoming_edge_iterator() : input_iterator<WOEdge*,ptrdiff_t>() {}
-# else
- inline incoming_edge_iterator() : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>() {}
-# endif
- virtual ~incoming_edge_iterator() {}; //soc
-
- protected:
- friend class WVertex;
- inline incoming_edge_iterator(
- WVertex *iVertex,
- WOEdge * iBegin,
- WOEdge * iCurrent)
-# if defined(__GNUC__) && (__GNUC__ < 3)
- : input_iterator<WOEdge*,ptrdiff_t>()
-# else
- : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>()
-# endif
- {
- _vertex = iVertex;
- _begin = iBegin;
- _current = iCurrent;
- }
-
- public:
- inline incoming_edge_iterator(const incoming_edge_iterator& iBrother)
-# if defined(__GNUC__) && (__GNUC__ < 3)
- : input_iterator<WOEdge*,ptrdiff_t>(iBrother)
-# else
- : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>(iBrother)
-# endif
- {
- _vertex = iBrother._vertex;
- _begin = iBrother._begin;
- _current = iBrother._current;
- }
-
- public:
- // operators
- virtual incoming_edge_iterator& operator++() // operator corresponding to ++i
- {
- increment();
- return *this;
- }
- virtual incoming_edge_iterator operator++(int) // operator corresponding to i++
- {
- incoming_edge_iterator tmp = *this;
- increment();
- return tmp;
- }
-
- // comparibility
- virtual bool operator!=(const incoming_edge_iterator& b) const
- {
- return ((_current) != (b._current));
- }
-
- virtual bool operator==(const incoming_edge_iterator& b) const
- {
- return ((_current)== (b._current));
- }
-
- // dereferencing
- virtual WOEdge* operator*();
- //virtual WOEdge** operator->();
- protected:
- virtual void increment();
- };
-
-
- /*! Iterator to iterate over a vertex faces in the CCW order */
-# if defined(__GNUC__) && (__GNUC__ < 3)
- class face_iterator : public input_iterator<WFace*,ptrdiff_t>
-# else
- class LIB_WINGED_EDGE_EXPORT face_iterator : public iterator<input_iterator_tag, WFace*,ptrdiff_t>
-# endif
- {
- private:
- incoming_edge_iterator _edge_it;
-
- public:
-# if defined(__GNUC__) && (__GNUC__ < 3)
- inline face_iterator() : input_iterator<WFace*,ptrdiff_t>() {}
-# else
- inline face_iterator() : iterator<input_iterator_tag, WFace*,ptrdiff_t>() {}
-# endif
- virtual ~face_iterator() {}; //soc
-
- protected:
- friend class WVertex;
- inline face_iterator(
- incoming_edge_iterator it)
-# if defined(__GNUC__) && (__GNUC__ < 3)
- : input_iterator<WFace*,ptrdiff_t>()
-# else
- : iterator<input_iterator_tag, WFace*,ptrdiff_t>()
-# endif
- {
- _edge_it = it;
- }
-
- public:
- inline face_iterator(const face_iterator& iBrother)
-# if defined(__GNUC__) && (__GNUC__ < 3)
- : input_iterator<WFace*,ptrdiff_t>(iBrother)
-# else
- : iterator<input_iterator_tag, WFace*,ptrdiff_t>(iBrother)
-# endif
- {
- _edge_it = iBrother._edge_it;
- }
-
- public:
- // operators
- virtual face_iterator& operator++() // operator corresponding to ++i
- {
- increment();
- return *this;
- }
- virtual face_iterator operator++(int) // operator corresponding to i++
- {
- face_iterator tmp = *this;
- increment();
- return tmp;
- }
-
- // comparibility
- virtual bool operator!=(const face_iterator& b) const
- {
- return ((_edge_it) != (b._edge_it));
- }
-
- virtual bool operator==(const face_iterator& b) const
- {
- return ((_edge_it)== (b._edge_it));
- }
-
- // dereferencing
- virtual WFace* operator*();
- //virtual WOEdge** operator->();
- protected:
- inline void increment(){
- ++_edge_it;
- }
- };
+public:
+ /*! Iterator to iterate over a vertex incoming edges in the CCW order*/
+#if defined(__GNUC__) && (__GNUC__ < 3)
+ class incoming_edge_iterator : public input_iterator<WOEdge *, ptrdiff_t>
+#else
+ class LIB_WINGED_EDGE_EXPORT incoming_edge_iterator
+ : public iterator<input_iterator_tag, WOEdge *, ptrdiff_t>
+#endif
+ {
+ private:
+ WVertex *_vertex;
+ //
+ WOEdge *_begin;
+ WOEdge *_current;
+
+ public:
+#if defined(__GNUC__) && (__GNUC__ < 3)
+ inline incoming_edge_iterator() : input_iterator<WOEdge *, ptrdiff_t>() {}
+#else
+ inline incoming_edge_iterator() : iterator<input_iterator_tag, WOEdge *, ptrdiff_t>() {}
+#endif
+ virtual ~incoming_edge_iterator() {}; //soc
+
+ protected:
+ friend class WVertex;
+ inline incoming_edge_iterator(WVertex *iVertex, WOEdge *iBegin, WOEdge *iCurrent)
+#if defined(__GNUC__) && (__GNUC__ < 3)
+ : input_iterator<WOEdge *, ptrdiff_t>()
+#else
+ : iterator<input_iterator_tag, WOEdge *, ptrdiff_t>()
+#endif
+ {
+ _vertex = iVertex;
+ _begin = iBegin;
+ _current = iCurrent;
+ }
+
+ public:
+ inline incoming_edge_iterator(const incoming_edge_iterator& iBrother)
+#if defined(__GNUC__) && (__GNUC__ < 3)
+ : input_iterator<WOEdge *, ptrdiff_t>(iBrother)
+#else
+ : iterator<input_iterator_tag, WOEdge *, ptrdiff_t>(iBrother)
+#endif
+ {
+ _vertex = iBrother._vertex;
+ _begin = iBrother._begin;
+ _current = iBrother._current;
+ }
+
+ public:
+ // operators
+ // operator corresponding to ++i
+ virtual incoming_edge_iterator& operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ // operator corresponding to i++
+ virtual incoming_edge_iterator operator++(int)
+ {
+ incoming_edge_iterator tmp = *this;
+ increment();
+ return tmp;
+ }
+
+ // comparibility
+ virtual bool operator!=(const incoming_edge_iterator& b) const
+ {
+ return ((_current) != (b._current));
+ }
+
+ virtual bool operator==(const incoming_edge_iterator& b) const
+ {
+ return ((_current)== (b._current));
+ }
+
+ // dereferencing
+ virtual WOEdge *operator*();
+ //virtual WOEdge **operator->();
+ protected:
+ virtual void increment();
+ };
+
+ /*! Iterator to iterate over a vertex faces in the CCW order */
+#if defined(__GNUC__) && (__GNUC__ < 3)
+ class face_iterator : public input_iterator<WFace *, ptrdiff_t>
+#else
+ class LIB_WINGED_EDGE_EXPORT face_iterator : public iterator<input_iterator_tag, WFace *, ptrdiff_t>
+#endif
+ {
+ private:
+ incoming_edge_iterator _edge_it;
+
+ public:
+#if defined(__GNUC__) && (__GNUC__ < 3)
+ inline face_iterator() : input_iterator<WFace *, ptrdiff_t>() {}
+#else
+ inline face_iterator() : iterator<input_iterator_tag, WFace *, ptrdiff_t>() {}
+#endif
+ virtual ~face_iterator() {}; //soc
+
+ protected:
+ friend class WVertex;
+ inline face_iterator(incoming_edge_iterator it)
+#if defined(__GNUC__) && (__GNUC__ < 3)
+ : input_iterator<WFace *, ptrdiff_t>()
+#else
+ : iterator<input_iterator_tag, WFace *, ptrdiff_t>()
+#endif
+ {
+ _edge_it = it;
+ }
+
+ public:
+ inline face_iterator(const face_iterator& iBrother)
+#if defined(__GNUC__) && (__GNUC__ < 3)
+ : input_iterator<WFace *, ptrdiff_t>(iBrother)
+#else
+ : iterator<input_iterator_tag, WFace *, ptrdiff_t>(iBrother)
+#endif
+ {
+ _edge_it = iBrother._edge_it;
+ }
+
+ public:
+ // operators
+ // operator corresponding to ++i
+ virtual face_iterator& operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ // operator corresponding to i++
+ virtual face_iterator operator++(int)
+ {
+ face_iterator tmp = *this;
+ increment();
+ return tmp;
+ }
+
+ // comparibility
+ virtual bool operator!=(const face_iterator& b) const
+ {
+ return ((_edge_it) != (b._edge_it));
+ }
+
+ virtual bool operator==(const face_iterator& b) const
+ {
+ return ((_edge_it)== (b._edge_it));
+ }
+
+ // dereferencing
+ virtual WFace *operator*();
+ //virtual WOEdge **operator->();
+
+ protected:
+ inline void increment()
+ {
+ ++_edge_it;
+ }
+ };
public:
- /*! iterators access */
- virtual incoming_edge_iterator incoming_edges_begin();
- virtual incoming_edge_iterator incoming_edges_end() ;
-
- virtual face_iterator faces_begin() {
- return face_iterator(incoming_edges_begin());
- }
- virtual face_iterator faces_end() {
- return face_iterator(incoming_edges_end());
- }
+ /*! iterators access */
+ virtual incoming_edge_iterator incoming_edges_begin();
+ virtual incoming_edge_iterator incoming_edges_end();
+
+ virtual face_iterator faces_begin()
+ {
+ return face_iterator(incoming_edges_begin());
+ }
+
+ virtual face_iterator faces_end()
+ {
+ return face_iterator(incoming_edges_end());
+ }
};
- /**********************************/
- /* */
- /* */
- /* WOEdge */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WOEdge *
+ * *
+ * *
+ **********************************/
+
class WFace;
class WEdge;
class LIB_WINGED_EDGE_EXPORT WOEdge
{
protected:
- // WOEdge *_paCWEdge; // edge reached when traveling clockwise on aFace from the edge
- // WOEdge *_pbCWEdge; // edge reached when traveling clockwise on bFace from the edge
- // WOEdge *_paCCWEdge; // edge reached when traveling counterclockwise on aFace from the edge
- // WOEdge *_pbCCWEdge; // edge reached when traveling counterclockwise on bFace from the edge
- WVertex *_paVertex; // starting vertex
- WVertex *_pbVertex; // ending vertex
- WFace *_paFace; // when following the edge, face on the right
- WFace *_pbFace; // when following the edge, face on the left
- WEdge *_pOwner; // Edge
-
- Vec3r _vec;
- real _angle;
+#if 0
+ WOEdge *_paCWEdge; // edge reached when traveling clockwise on aFace from the edge
+ WOEdge *_pbCWEdge; // edge reached when traveling clockwise on bFace from the edge
+ WOEdge *_paCCWEdge; // edge reached when traveling counterclockwise on aFace from the edge
+ WOEdge *_pbCCWEdge; // edge reached when traveling counterclockwise on bFace from the edge
+#endif
+ WVertex *_paVertex; // starting vertex
+ WVertex *_pbVertex; // ending vertex
+ WFace *_paFace; // when following the edge, face on the right
+ WFace *_pbFace; // when following the edge, face on the left
+ WEdge *_pOwner; // Edge
+
+ Vec3r _vec;
+ real _angle;
public:
-
- void *userdata;
- inline WOEdge()
- {
- // _paCWEdge = NULL;
- // _pbCWEdge = NULL;
- // _paCCWEdge = NULL;
- // _pbCCWEdge = NULL;
- _paVertex = NULL;
- _pbVertex = NULL;
- _paFace = NULL;
- _pbFace = NULL;
- _pOwner = NULL;
- userdata = NULL;
- }
- virtual ~WOEdge() {}; //soc
-
- /*! copy constructor */
- WOEdge(WOEdge& iBrother);
- virtual WOEdge * duplicate();
-
- /*! accessors */
- // inline WOEdge *GetaCWEdge() {return _paCWEdge;}
- // inline WOEdge *GetbCWEdge() {return _pbCWEdge;}
- // inline WOEdge *GetaCCWEdge() {return _paCCWEdge;}
- // inline WOEdge *GetbCCWEdge() {return _pbCCWEdge;}
- inline WVertex *GetaVertex() {return _paVertex;}
- inline WVertex *GetbVertex() {return _pbVertex;}
- inline WFace *GetaFace() {return _paFace;}
- inline WFace *GetbFace() {return _pbFace;}
- inline WEdge *GetOwner() {return _pOwner;}
-
- inline const Vec3r& GetVec() { return _vec; }
- inline const real GetAngle() { return _angle; }
-
-
- /*! modifiers */
- // inline void SetaCWEdge(WOEdge *pe) {_paCWEdge = pe;}
- // inline void SetbCWEdge(WOEdge *pe) {_pbCWEdge = pe;}
- // inline void SetaCCWEdge(WOEdge *pe) {_paCCWEdge = pe;}
- // inline void SetbCCCWEdge(WOEdge *pe) {_pbCCWEdge = pe;}
- inline void setVecAndAngle();
- inline void setaVertex(WVertex *pv) {_paVertex = pv; setVecAndAngle(); }
- inline void setbVertex(WVertex *pv) {_pbVertex = pv; setVecAndAngle(); }
- inline void setaFace(WFace *pf) {_paFace = pf; setVecAndAngle(); }
- inline void setbFace(WFace *pf) {_pbFace = pf; setVecAndAngle(); }
- inline void setOwner(WEdge *pe) {_pOwner = pe;}
-
- /*! Retrieves the list of edges in CW order */
- inline void RetrieveCWOrderedEdges(vector<WEdge*>& oEdges);
- /*! returns the vector between the two vertices */
- Vec3r getVec3r ();
- WOEdge * twin ();
- WOEdge * getPrevOnFace();
- virtual void ResetUserData() {userdata = 0;}
+ void *userdata;
+
+ inline WOEdge()
+ {
+#if 0
+ _paCWEdge = NULL;
+ _pbCWEdge = NULL;
+ _paCCWEdge = NULL;
+ _pbCCWEdge = NULL;
+#endif
+ _paVertex = NULL;
+ _pbVertex = NULL;
+ _paFace = NULL;
+ _pbFace = NULL;
+ _pOwner = NULL;
+ userdata = NULL;
+ }
+
+ virtual ~WOEdge() {}; //soc
+
+ /*! copy constructor */
+ WOEdge(WOEdge& iBrother);
+ virtual WOEdge *duplicate();
+
+ /*! accessors */
+#if 0
+ inline WOEdge *GetaCWEdge()
+ {
+ return _paCWEdge;
+ }
+
+ inline WOEdge *GetbCWEdge()
+ {
+ return _pbCWEdge;
+ }
+
+ inline WOEdge *GetaCCWEdge()
+ {
+ return _paCCWEdge;
+ }
+
+ inline WOEdge *GetbCCWEdge()
+ {
+ return _pbCCWEdge;
+ }
+#endif
+
+ inline WVertex *GetaVertex()
+ {
+ return _paVertex;
+ }
+
+ inline WVertex *GetbVertex()
+ {
+ return _pbVertex;
+ }
+
+ inline WFace *GetaFace()
+ {
+ return _paFace;
+ }
+
+ inline WFace *GetbFace()
+ {
+ return _pbFace;
+ }
+
+ inline WEdge *GetOwner()
+ {
+ return _pOwner;
+ }
+
+ inline const Vec3r& GetVec()
+ {
+ return _vec;
+ }
+
+ inline const real GetAngle()
+ {
+ return _angle;
+ }
+
+
+ /*! modifiers */
+#if 0
+ inline void SetaCWEdge(WOEdge *pe)
+ {
+ _paCWEdge = pe;
+ }
+
+ inline void SetbCWEdge(WOEdge *pe)
+ {
+ _pbCWEdge = pe;
+ }
+
+ inline void SetaCCWEdge(WOEdge *pe)
+ {
+ _paCCWEdge = pe;
+ }
+
+ inline void SetbCCCWEdge(WOEdge *pe)
+ {
+ _pbCCWEdge = pe;
+ }
+#endif
+
+ inline void setVecAndAngle();
+
+ inline void setaVertex(WVertex *pv)
+ {
+ _paVertex = pv;
+ setVecAndAngle();
+ }
+
+ inline void setbVertex(WVertex *pv)
+ {
+ _pbVertex = pv;
+ setVecAndAngle();
+ }
+
+ inline void setaFace(WFace *pf)
+ {
+ _paFace = pf;
+ setVecAndAngle();
+ }
+
+ inline void setbFace(WFace *pf)
+ {
+ _pbFace = pf;
+ setVecAndAngle();
+ }
+
+ inline void setOwner(WEdge *pe)
+ {
+ _pOwner = pe;
+ }
+
+ /*! Retrieves the list of edges in CW order */
+ inline void RetrieveCWOrderedEdges(vector<WEdge*>& oEdges);
+
+ /*! returns the vector between the two vertices */
+ Vec3r getVec3r ();
+ WOEdge *twin ();
+ WOEdge *getPrevOnFace();
+
+ virtual void ResetUserData()
+ {
+ userdata = NULL;
+ }
};
- /**********************************/
- /* */
- /* */
- /* WEdge */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WEdge *
+ * *
+ * *
+ **********************************/
class LIB_WINGED_EDGE_EXPORT WEdge
{
protected:
- WOEdge *_paOEdge; // first oriented edge
- WOEdge *_pbOEdge; // second oriented edge
- int _nOEdges; // number of oriented edges associated with this edge. (1 means border edge)
- bool _Mark; // user-specified edge mark for feature edge detection
- int _Id; // Identifier for the edge
-
+ WOEdge *_paOEdge; // first oriented edge
+ WOEdge *_pbOEdge; // second oriented edge
+ int _nOEdges; // number of oriented edges associated with this edge. (1 means border edge)
+ bool _Mark; // user-specified edge mark for feature edge detection
+ int _Id; // Identifier for the edge
+
public:
- void * userdata; // designed to store specific user data
- inline WEdge()
- {
- _paOEdge = NULL;
- _pbOEdge = NULL;
- _nOEdges = 0;
- userdata = NULL;
- }
-
- inline WEdge(WOEdge *iOEdge)
- {
- _paOEdge = iOEdge;
- _pbOEdge = NULL;
- _nOEdges = 1;
- userdata = NULL;
- }
-
- inline WEdge(WOEdge *iaOEdge, WOEdge *ibOEdge)
- {
- _paOEdge = iaOEdge;
- _pbOEdge = ibOEdge;
- _nOEdges = 2;
- userdata = NULL;
- }
-
- /*! Copy constructor */
- WEdge(WEdge& iBrother);
- virtual WEdge * duplicate();
-
- virtual ~WEdge()
- {
- if(NULL != _paOEdge)
- {
- delete _paOEdge;
- _paOEdge = NULL;
- }
-
- if(NULL != _pbOEdge)
- {
- delete _pbOEdge;
- _pbOEdge = NULL;
- }
- }
-
- /*! checks whether two WEdge have a common vertex.
- * Returns a pointer on the common vertex if it exists,
- * NULL otherwise.
- */
- static inline WVertex* CommonVertex(WEdge *iEdge1, WEdge* iEdge2)
- {
- if((NULL == iEdge1) || (NULL == iEdge2))
- return NULL;
-
- WVertex *wv1 = iEdge1->GetaOEdge()->GetaVertex();
- WVertex *wv2 = iEdge1->GetaOEdge()->GetbVertex();
- WVertex *wv3 = iEdge2->GetaOEdge()->GetaVertex();
- WVertex *wv4 = iEdge2->GetaOEdge()->GetbVertex();
-
- if((wv1 == wv3) || (wv1 == wv4))
- {
- return wv1;
- }
- else if((wv2 == wv3) || (wv2 == wv4))
- {
- return wv2;
- }
-
- return NULL;
- }
- /*! accessors */
- inline WOEdge * GetaOEdge() {return _paOEdge;}
- inline WOEdge * GetbOEdge() {return _pbOEdge;}
- inline int GetNumberOfOEdges() {return _nOEdges;}
- inline bool GetMark() {return _Mark;}
- inline int GetId() {return _Id;}
- inline WVertex * GetaVertex() {return _paOEdge->GetaVertex();}
- inline WVertex * GetbVertex() {return _paOEdge->GetbVertex();}
- inline WFace * GetaFace() {return _paOEdge->GetaFace();}
- inline WFace * GetbFace() {return _paOEdge->GetbFace();}
- inline WOEdge* GetOtherOEdge(WOEdge* iOEdge)
- {
- if(iOEdge == _paOEdge)
- return _pbOEdge;
- else
- return _paOEdge;
- }
-
- /*! modifiers */
- inline void setaOEdge(WOEdge *iEdge) {_paOEdge = iEdge;}
- inline void setbOEdge(WOEdge *iEdge) {_pbOEdge = iEdge;}
- inline void AddOEdge(WOEdge *iEdge)
- {
- if(NULL == _paOEdge)
- {
- _paOEdge = iEdge;
- _nOEdges++;
- return;
- }
- if(NULL == _pbOEdge)
- {
- _pbOEdge = iEdge;
- _nOEdges++;
- return;
- }
- }
- inline void setNumberOfOEdges(int n) {_nOEdges = n;}
- inline void setMark(bool mark) {_Mark = mark;}
- inline void setId(int id) {_Id = id;}
- virtual void ResetUserData() {userdata = 0;}
+ void *userdata; // designed to store specific user data
+
+ inline WEdge()
+ {
+ _paOEdge = NULL;
+ _pbOEdge = NULL;
+ _nOEdges = 0;
+ userdata = NULL;
+ }
+
+ inline WEdge(WOEdge *iOEdge)
+ {
+ _paOEdge = iOEdge;
+ _pbOEdge = NULL;
+ _nOEdges = 1;
+ userdata = NULL;
+ }
+
+ inline WEdge(WOEdge *iaOEdge, WOEdge *ibOEdge)
+ {
+ _paOEdge = iaOEdge;
+ _pbOEdge = ibOEdge;
+ _nOEdges = 2;
+ userdata = NULL;
+ }
+
+ /*! Copy constructor */
+ WEdge(WEdge& iBrother);
+ virtual WEdge *duplicate();
+
+ virtual ~WEdge()
+ {
+ if (_paOEdge) {
+ delete _paOEdge;
+ _paOEdge = NULL;
+ }
+
+ if (_pbOEdge) {
+ delete _pbOEdge;
+ _pbOEdge = NULL;
+ }
+ }
+
+ /*! checks whether two WEdge have a common vertex.
+ * Returns a pointer on the common vertex if it exists, NULL otherwise.
+ */
+ static inline WVertex *CommonVertex(WEdge *iEdge1, WEdge *iEdge2)
+ {
+ if (!iEdge1 || !iEdge2)
+ return NULL;
+
+ WVertex *wv1 = iEdge1->GetaOEdge()->GetaVertex();
+ WVertex *wv2 = iEdge1->GetaOEdge()->GetbVertex();
+ WVertex *wv3 = iEdge2->GetaOEdge()->GetaVertex();
+ WVertex *wv4 = iEdge2->GetaOEdge()->GetbVertex();
+
+ if ((wv1 == wv3) || (wv1 == wv4)) {
+ return wv1;
+ }
+ else if ((wv2 == wv3) || (wv2 == wv4)) {
+ return wv2;
+ }
+ return NULL;
+ }
+
+ /*! accessors */
+ inline WOEdge *GetaOEdge()
+ {
+ return _paOEdge;
+ }
+
+ inline WOEdge *GetbOEdge()
+ {
+ return _pbOEdge;
+ }
+
+ inline int GetNumberOfOEdges()
+ {
+ return _nOEdges;
+ }
+
+ inline bool GetMark()
+ {
+ return _Mark;
+ }
+
+ inline int GetId()
+ {
+ return _Id;
+ }
+
+ inline WVertex *GetaVertex()
+ {
+ return _paOEdge->GetaVertex();
+ }
+
+ inline WVertex *GetbVertex()
+ {
+ return _paOEdge->GetbVertex();
+ }
+
+ inline WFace *GetaFace()
+ {
+ return _paOEdge->GetaFace();
+ }
+
+ inline WFace *GetbFace()
+ {
+ return _paOEdge->GetbFace();
+ }
+
+ inline WOEdge *GetOtherOEdge(WOEdge *iOEdge) {
+ if (iOEdge == _paOEdge)
+ return _pbOEdge;
+ else
+ return _paOEdge;
+ }
+
+ /*! modifiers */
+ inline void setaOEdge(WOEdge *iEdge)
+ {
+ _paOEdge = iEdge;
+ }
+
+ inline void setbOEdge(WOEdge *iEdge)
+ {
+ _pbOEdge = iEdge;
+ }
+
+ inline void AddOEdge(WOEdge *iEdge)
+ {
+ if (!_paOEdge) {
+ _paOEdge = iEdge;
+ _nOEdges++;
+ return;
+ }
+ if (!_pbOEdge) {
+ _pbOEdge = iEdge;
+ _nOEdges++;
+ return;
+ }
+ }
+
+ inline void setNumberOfOEdges(int n)
+ {
+ _nOEdges = n;
+ }
+
+ inline void setMark(bool mark)
+ {
+ _Mark = mark;
+ }
+
+ inline void setId(int id)
+ {
+ _Id = id;
+ }
+
+ virtual void ResetUserData()
+ {
+ userdata = NULL;
+ }
};
- /**********************************/
- /* */
- /* */
- /* WFace */
- /* */
- /* */
- /**********************************/
+
+/**********************************
+ * *
+ * *
+ * WFace *
+ * *
+ * *
+ **********************************/
class LIB_WINGED_EDGE_EXPORT WFace
{
protected:
- vector<WOEdge *> _OEdgeList; // list of oriented edges of bording the face
- Vec3r _Normal; // normal to the face
- vector<Vec3r> _VerticesNormals; // in case there is a normal per vertex.
- // The normal number i corresponds to the
- // aVertex of the oedge number i, for that face
- vector<Vec2r> _VerticesTexCoords;
+ vector<WOEdge *> _OEdgeList; // list of oriented edges of bording the face
+ Vec3r _Normal; // normal to the face
+ // in case there is a normal per vertex.
+ // The normal number i corresponds to the aVertex of the oedge number i, for that face
+ vector<Vec3r> _VerticesNormals;
+ vector<Vec2r> _VerticesTexCoords;
- int _Id;
- unsigned _FrsMaterialIndex;
- bool _Mark; // Freestyle face mark (if true, feature edges on this face are ignored)
+ int _Id;
+ unsigned _FrsMaterialIndex;
+ bool _Mark; // Freestyle face mark (if true, feature edges on this face are ignored)
public:
- void *userdata;
- inline WFace() {userdata = NULL;_FrsMaterialIndex = 0;}
- /*! copy constructor */
- WFace(WFace& iBrother);
- virtual WFace * duplicate();
- virtual ~WFace() {}
-
- /*! accessors */
- inline const vector<WOEdge*>& getEdgeList() {return _OEdgeList;}
- inline WOEdge * GetOEdge(int i) {return _OEdgeList[i];}
- inline Vec3r& GetNormal() {return _Normal;}
- inline int GetId() {return _Id;}
- inline unsigned frs_materialIndex() const {return _FrsMaterialIndex;}
- inline bool GetMark() const {return _Mark;}
- const FrsMaterial& frs_material() ;
-
- /*! The vertex of index i corresponds to the a vertex
- * of the edge of index i
- */
- inline WVertex* GetVertex(unsigned int index)
- {
- // if(index >= _OEdgeList.size())
- // return NULL;
- return _OEdgeList[index]->GetaVertex();
- }
- /*! returns the index at which iVertex is stored in the
- * array.
- * returns -1 if iVertex doesn't belong to the face.
- */
- inline int GetIndex(WVertex *iVertex){
- int index = 0;
- for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end();
- woe!=woend;
- woe++){
- if((*woe)->GetaVertex() == iVertex)
- return index;
- ++index;
- }
- return -1;
- }
- inline void RetrieveVertexList(vector<WVertex*>& oVertices)
- {
- for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end();
- woe!=woend;
- woe++)
- {
- oVertices.push_back((*woe)->GetaVertex());
- }
- }
- inline void RetrieveBorderFaces(vector<const WFace*>& oWFaces)
- {
- for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end();
- woe!=woend;
- woe++)
- {
- WFace *af;
- if(NULL != (af = (*woe)->GetaFace()))
- oWFaces.push_back(af);
- }
- }
- inline WFace * GetBordingFace(int index)
- {
- // if(index >= _OEdgeList.size())
- // return 0;
- return _OEdgeList[index]->GetaFace();
- }
- inline WFace * GetBordingFace(WOEdge *iOEdge)
- {
- return iOEdge->GetaFace();
- }
- inline vector<Vec3r>& GetPerVertexNormals()
- {
- return _VerticesNormals;
- }
- inline vector<Vec2r>& GetPerVertexTexCoords()
- {
- return _VerticesTexCoords;
- }
- /*! Returns the normal of the vertex of index index */
- inline Vec3r& GetVertexNormal(int index)
- {
- return _VerticesNormals[index];
- }
- /*! Returns the tex coords of the vertex of index index */
- inline Vec2r& GetVertexTexCoords(int index)
- {
- return _VerticesTexCoords[index];
- }
- /*! Returns the normal of the vertex iVertex for that face */
- inline Vec3r& GetVertexNormal(WVertex *iVertex)
- {
- int i = 0;
- int index = 0;
- for(vector<WOEdge*>::const_iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end();
- woe!=woend;
- woe++)
- {
- if((*woe)->GetaVertex() == iVertex)
- {
- index = i;
- break;
- }
- ++i;
- }
-
- return _VerticesNormals[index];
- }
- inline WOEdge* GetNextOEdge(WOEdge* iOEdge)
- {
- bool found = false;
- vector<WOEdge*>::iterator woe,woend, woefirst;
- woefirst = _OEdgeList.begin();
- for(woe=woefirst,woend=_OEdgeList.end();
- woe!=woend;
- woe++)
- {
- if(true == found)
- return (*woe);
-
- if((*woe) == iOEdge)
- {
- found = true;
- }
- }
-
- // We left the loop. That means that the first
- // OEdge was the good one:
- if(found)
- return (*woefirst);
-
- return NULL;
- }
- WOEdge* GetPrevOEdge(WOEdge* iOEdge);
-
- inline int numberOfEdges() const { return _OEdgeList.size();}
- inline int numberOfVertices() const { return _OEdgeList.size();}
- /*! Returns true if the face has one ot its edge which is a border
- * edge
- */
- inline bool isBorder() const
- {
- for(vector<WOEdge*>::const_iterator woe=_OEdgeList.begin(), woeend=_OEdgeList.end();
- woe!=woeend;
- ++woe)
- {
- if((*woe)->GetOwner()->GetbOEdge() == 0)
- return true;
- }
- return false;
- }
- /*! modifiers */
- inline void setEdgeList(const vector<WOEdge*>& iEdgeList) {_OEdgeList = iEdgeList;}
- inline void setNormal(const Vec3r& iNormal) {_Normal = iNormal;}
- inline void setNormalList(const vector<Vec3r>& iNormalsList) {_VerticesNormals = iNormalsList;}
- inline void setTexCoordsList(const vector<Vec2r>& iTexCoordsList) {_VerticesTexCoords = iTexCoordsList;}
- inline void setId(int id) {_Id = id;}
- inline void setFrsMaterialIndex(unsigned iMaterialIndex) {_FrsMaterialIndex = iMaterialIndex;}
- inline void setMark(bool iMark) {_Mark = iMark;}
-
- /*! designed to build a specialized WEdge
- * for use in MakeEdge
- */
- virtual WEdge * instanciateEdge() const {return new WEdge;}
-
- /*! Builds an oriented edge
- * Returns the built edge.
- * v1, v2
- * Vertices at the edge's extremities
- * The edge is oriented from v1 to v2.
- */
- virtual WOEdge * MakeEdge(WVertex *v1, WVertex *v2);
-
- /*! Adds an edge to the edges list */
- inline void AddEdge(WOEdge *iEdge) {_OEdgeList.push_back(iEdge);}
-
- /*! For triangles, returns the edge opposite to the vertex in e.
- returns flase if the face is not a triangle or if the vertex is not found*/
- bool getOppositeEdge (const WVertex *v, WOEdge* &e);
-
- /*! compute the area of the face */
- real getArea ();
-
- WShape * getShape() ;
- virtual void ResetUserData() {userdata = 0;}
+ void *userdata;
+ inline WFace()
+ {
+ userdata = NULL;
+ _FrsMaterialIndex = 0;
+ }
+
+ /*! copy constructor */
+ WFace(WFace& iBrother);
+ virtual WFace *duplicate();
+ virtual ~WFace() {}
+
+ /*! accessors */
+ inline const vector<WOEdge*>& getEdgeList()
+ {
+ return _OEdgeList;
+ }
+
+ inline WOEdge *GetOEdge(int i)
+ {
+ return _OEdgeList[i];
+ }
+
+ inline Vec3r& GetNormal()
+ {
+ return _Normal;
+ }
+
+ inline int GetId()
+ {
+ return _Id;
+ }
+
+ inline unsigned frs_materialIndex() const
+ {
+ return _FrsMaterialIndex;
+ }
+
+ inline bool GetMark() const
+ {
+ return _Mark;
+ }
+
+ const FrsMaterial& frs_material();
+
+ /*! The vertex of index i corresponds to the a vertex of the edge of index i */
+ inline WVertex *GetVertex(unsigned int index)
+ {
+#if 0
+ if (index >= _OEdgeList.size())
+ return NULL;
+#endif
+ return _OEdgeList[index]->GetaVertex();
+ }
+
+ /*! returns the index at which iVertex is stored in the array.
+ * returns -1 if iVertex doesn't belong to the face.
+ */
+ inline int GetIndex(WVertex *iVertex)
+ {
+ int index = 0;
+ for (vector<WOEdge*>::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) {
+ if ((*woe)->GetaVertex() == iVertex)
+ return index;
+ ++index;
+ }
+ return -1;
+ }
+
+ inline void RetrieveVertexList(vector<WVertex *>& oVertices)
+ {
+ for (vector<WOEdge *>::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) {
+ oVertices.push_back((*woe)->GetaVertex());
+ }
+ }
+
+ inline void RetrieveBorderFaces(vector<const WFace *>& oWFaces)
+ {
+ for (vector<WOEdge *>::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) {
+ WFace *af;
+ if ((af = (*woe)->GetaFace()))
+ oWFaces.push_back(af);
+ }
+ }
+
+ inline WFace *GetBordingFace(int index)
+ {
+#if 0
+ if (index >= _OEdgeList.size())
+ return NULL;
+#endif
+ return _OEdgeList[index]->GetaFace();
+ }
+
+ inline WFace *GetBordingFace(WOEdge *iOEdge)
+ {
+ return iOEdge->GetaFace();
+ }
+
+ inline vector<Vec3r>& GetPerVertexNormals()
+ {
+ return _VerticesNormals;
+ }
+
+ inline vector<Vec2r>& GetPerVertexTexCoords()
+ {
+ return _VerticesTexCoords;
+ }
+
+ /*! Returns the normal of the vertex of index index */
+ inline Vec3r& GetVertexNormal(int index)
+ {
+ return _VerticesNormals[index];
+ }
+
+ /*! Returns the tex coords of the vertex of index index */
+ inline Vec2r& GetVertexTexCoords(int index)
+ {
+ return _VerticesTexCoords[index];
+ }
+
+ /*! Returns the normal of the vertex iVertex for that face */
+ inline Vec3r& GetVertexNormal(WVertex *iVertex)
+ {
+ int i = 0;
+ int index = 0;
+ for (vector<WOEdge *>::const_iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end(); woe != woend; woe++) {
+ if ((*woe)->GetaVertex() == iVertex) {
+ index = i;
+ break;
+ }
+ ++i;
+ }
+
+ return _VerticesNormals[index];
+ }
+
+ inline WOEdge *GetNextOEdge(WOEdge *iOEdge)
+ {
+ bool found = false;
+ vector<WOEdge *>::iterator woe, woend, woefirst;
+ woefirst = _OEdgeList.begin();
+ for (woe = woefirst, woend = _OEdgeList.end(); woe != woend; ++woe) {
+ if (found)
+ return (*woe);
+
+ if ((*woe) == iOEdge) {
+ found = true;
+ }
+ }
+
+ // We left the loop. That means that the first OEdge was the good one:
+ if (found)
+ return (*woefirst);
+
+ return NULL;
+ }
+
+ WOEdge *GetPrevOEdge(WOEdge *iOEdge);
+
+ inline int numberOfEdges() const
+ {
+ return _OEdgeList.size();
+ }
+
+ inline int numberOfVertices() const
+ {
+ return _OEdgeList.size();
+ }
+
+ /*! Returns true if the face has one ot its edge which is a border edge */
+ inline bool isBorder() const
+ {
+ for (vector<WOEdge*>::const_iterator woe = _OEdgeList.begin(), woeend = _OEdgeList.end();
+ woe != woeend;
+ ++woe)
+ {
+ if ((*woe)->GetOwner()->GetbOEdge() == 0)
+ return true;
+ }
+ return false;
+ }
+
+ /*! modifiers */
+ inline void setEdgeList(const vector<WOEdge *>& iEdgeList)
+ {
+ _OEdgeList = iEdgeList;
+ }
+
+ inline void setNormal(const Vec3r& iNormal)
+ {
+ _Normal = iNormal;
+ }
+
+ inline void setNormalList(const vector<Vec3r>& iNormalsList)
+ {
+ _VerticesNormals = iNormalsList;
+ }
+
+ inline void setTexCoordsList(const vector<Vec2r>& iTexCoordsList)
+ {
+ _VerticesTexCoords = iTexCoordsList;
+ }
+
+ inline void setId(int id)
+ {
+ _Id = id;
+ }
+
+ inline void setFrsMaterialIndex(unsigned iMaterialIndex)
+ {
+ _FrsMaterialIndex = iMaterialIndex;
+ }
+
+ inline void setMark(bool iMark)
+ {
+ _Mark = iMark;
+ }
+
+ /*! designed to build a specialized WEdge for use in MakeEdge */
+ virtual WEdge *instanciateEdge() const
+ {
+ return new WEdge;
+ }
+
+ /*! Builds an oriented edge
+ * Returns the built edge.
+ * v1, v2
+ * Vertices at the edge's extremities
+ * The edge is oriented from v1 to v2.
+ */
+ virtual WOEdge *MakeEdge(WVertex *v1, WVertex *v2);
+
+ /*! Adds an edge to the edges list */
+ inline void AddEdge(WOEdge *iEdge)
+ {
+ _OEdgeList.push_back(iEdge);
+ }
+
+ /*! For triangles, returns the edge opposite to the vertex in e.
+ * returns flase if the face is not a triangle or if the vertex is not found
+ */
+ bool getOppositeEdge (const WVertex *v, WOEdge* &e);
+
+ /*! compute the area of the face */
+ real getArea ();
+
+ WShape *getShape();
+ virtual void ResetUserData()
+ {
+ userdata = NULL;
+ }
};
- /**********************************/
- /* */
- /* */
- /* WShape */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WShape *
+ * *
+ * *
+ **********************************/
class LIB_WINGED_EDGE_EXPORT WShape
{
protected:
- vector<WVertex*> _VertexList;
- vector<WEdge*> _EdgeList;
- vector<WFace*> _FaceList;
- int _Id;
- string _Name;
- static unsigned _SceneCurrentId;
- Vec3r _min;
- Vec3r _max;
- vector<FrsMaterial> _FrsMaterials;
- real _meanEdgeSize;
+ vector<WVertex *> _VertexList;
+ vector<WEdge *> _EdgeList;
+ vector<WFace *> _FaceList;
+ int _Id;
+ string _Name;
+ static unsigned _SceneCurrentId;
+ Vec3r _min;
+ Vec3r _max;
+ vector<FrsMaterial> _FrsMaterials;
+ real _meanEdgeSize;
public:
- inline WShape() {_meanEdgeSize = 0;_Id = _SceneCurrentId; _SceneCurrentId++;}
- /*! copy constructor */
- WShape(WShape& iBrother);
- virtual WShape * duplicate();
- virtual ~WShape()
- {
- if(_EdgeList.size() != 0)
- {
- vector<WEdge *>::iterator e;
- for(e=_EdgeList.begin(); e!=_EdgeList.end(); e++)
- {
- delete (*e);
- }
- _EdgeList.clear();
- }
-
- if(_VertexList.size() != 0)
- {
- vector<WVertex *>::iterator v;
- for(v=_VertexList.begin(); v!=_VertexList.end(); v++)
- {
- delete (*v);
- }
- _VertexList.clear();
- }
-
- if(_FaceList.size() != 0)
- {
- vector<WFace *>::iterator f;
- for(f=_FaceList.begin(); f!=_FaceList.end(); f++)
- {
- delete (*f);
- }
- _FaceList.clear();
- }
- }
-
- /*! accessors */
- inline vector<WEdge *>& getEdgeList() {return _EdgeList;}
- inline vector<WVertex*>& getVertexList() {return _VertexList;}
- inline vector<WFace*>& GetFaceList() {return _FaceList;}
- inline unsigned GetId() {return _Id;}
- inline void bbox(Vec3r& min, Vec3r& max) {min=_min; max=_max;}
- inline const FrsMaterial& frs_material(unsigned i) const {return _FrsMaterials[i];}
- inline const vector<FrsMaterial>& frs_materials() const {return _FrsMaterials;}
- inline const real getMeanEdgeSize() const {return _meanEdgeSize;}
- inline const string& getName() const {return _Name;}
- /*! modifiers */
- static inline void setCurrentId(const unsigned id) { _SceneCurrentId = id; }
- inline void setEdgeList(const vector<WEdge*>& iEdgeList) {_EdgeList = iEdgeList;}
- inline void setVertexList(const vector<WVertex*>& iVertexList) {_VertexList = iVertexList;}
- inline void setFaceList(const vector<WFace*>& iFaceList) {_FaceList = iFaceList;}
- inline void setId(int id) {_Id = id;}
- inline void setBBox(const Vec3r& min, const Vec3r& max) {_min = min; _max=max;}
- inline void setFrsMaterial(const FrsMaterial& frs_material, unsigned i) {_FrsMaterials[i]=frs_material;}
- inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials) {_FrsMaterials = iMaterials;}
- inline void setName(const string& name) {_Name = name;}
-
- /*! designed to build a specialized WFace
- * for use in MakeFace
- */
- virtual WFace * instanciateFace() const {return new WFace;}
-
- /*! adds a new face to the shape
- * returns the built face.
- * iVertexList
- * List of face's vertices. These vertices are
- * not added to the WShape vertex list; they are
- * supposed to be already stored when calling MakeFace.
- * The order in which the vertices are stored in the list
- * determines the face's edges orientation and (so) the
- * face orientation.
- * iMaterialIndex
- * The material index for this face
- */
- virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
-
- /*! adds a new face to the shape. The difference with
- * the previous method is that this one is designed
- * to build a WingedEdge structure for which there are
- * per vertex normals, opposed to per face normals.
- * returns the built face.
- * iVertexList
- * List of face's vertices. These vertices are
- * not added to the WShape vertex list; they are
- * supposed to be already stored when calling MakeFace.
- * The order in which the vertices are stored in the list
- * determines the face's edges orientation and (so) the
- * face orientation.
- * iMaterialIndex
- * The materialIndex for this face
- * iNormalsList
- * The list of normals, iNormalsList[i] corresponding to the
- * normal of the vertex iVertexList[i] for that face.
- * iTexCoordsList
- * The list of tex coords, iTexCoordsList[i] corresponding to the
- * normal of the vertex iVertexList[i] for that face.
- */
- virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
-
- inline void AddEdge(WEdge *iEdge) {_EdgeList.push_back(iEdge);}
- inline void AddFace(WFace* iFace) {_FaceList.push_back(iFace);}
- inline void AddVertex(WVertex *iVertex) {iVertex->setShape(this); _VertexList.push_back(iVertex);}
-
- inline void ResetUserData()
- {
- for(vector<WVertex*>::iterator v=_VertexList.begin(),vend=_VertexList.end();
- v!=vend;
- v++)
- {
- (*v)->ResetUserData();
- }
-
- for(vector<WEdge*>::iterator e=_EdgeList.begin(),eend=_EdgeList.end();
- e!=eend;
- e++)
- {
- (*e)->ResetUserData();
- // manages WOEdge:
- WOEdge *oe = (*e)->GetaOEdge();
- if(oe != NULL)
- oe->ResetUserData();
- oe = (*e)->GetbOEdge();
- if(oe != NULL)
- oe->ResetUserData();
- }
-
- for(vector<WFace*>::iterator f=_FaceList.begin(),fend=_FaceList.end();
- f!=fend;
- f++)
- {
- (*f)->ResetUserData();
- }
-
- }
-
- inline void ComputeBBox()
- {
- _min = _VertexList[0]->GetVertex();
- _max = _VertexList[0]->GetVertex();
-
- Vec3r v;
- for(vector<WVertex*>::iterator wv=_VertexList.begin(), wvend=_VertexList.end();
- wv!=wvend;
- wv++)
- {
- for(unsigned int i=0; i<3; i++)
- {
- v = (*wv)->GetVertex();
- if(v[i] < _min[i])
- _min[i] = v[i];
- if(v[i] > _max[i])
- _max[i] = v[i];
- }
- }
- }
-
- inline real ComputeMeanEdgeSize(){
- _meanEdgeSize = _meanEdgeSize/(_EdgeList.size());
- return _meanEdgeSize;
- }
+ inline WShape()
+ {
+ _meanEdgeSize = 0;
+ _Id = _SceneCurrentId;
+ _SceneCurrentId++;
+ }
+
+ /*! copy constructor */
+ WShape(WShape& iBrother);
+ virtual WShape *duplicate();
+
+ virtual ~WShape()
+ {
+ if (_EdgeList.size() != 0) {
+ vector<WEdge *>::iterator e;
+ for (e = _EdgeList.begin(); e != _EdgeList.end(); ++e) {
+ delete (*e);
+ }
+ _EdgeList.clear();
+ }
+
+ if (_VertexList.size() != 0) {
+ vector<WVertex *>::iterator v;
+ for (v = _VertexList.begin(); v != _VertexList.end(); ++v) {
+ delete (*v);
+ }
+ _VertexList.clear();
+ }
+
+ if (_FaceList.size() != 0) {
+ vector<WFace *>::iterator f;
+ for (f = _FaceList.begin(); f != _FaceList.end(); ++f) {
+ delete (*f);
+ }
+ _FaceList.clear();
+ }
+ }
+
+ /*! accessors */
+ inline vector<WEdge *>& getEdgeList()
+ {
+ return _EdgeList;
+ }
+
+ inline vector<WVertex *>& getVertexList()
+ {
+ return _VertexList;
+ }
+
+ inline vector<WFace *>& GetFaceList()
+ {
+ return _FaceList;
+ }
+
+ inline unsigned GetId()
+ {
+ return _Id;
+ }
+
+ inline void bbox(Vec3r& min, Vec3r& max)
+ {
+ min = _min;
+ max = _max;
+ }
+
+ inline const FrsMaterial& frs_material(unsigned i) const
+ {
+ return _FrsMaterials[i];
+ }
+
+ inline const vector<FrsMaterial>& frs_materials() const
+ {
+ return _FrsMaterials;
+ }
+
+ inline const real getMeanEdgeSize() const
+ {
+ return _meanEdgeSize;
+ }
+
+ inline const string& getName() const
+ {
+ return _Name;
+ }
+
+ /*! modifiers */
+ static inline void setCurrentId(const unsigned id)
+ {
+ _SceneCurrentId = id;
+ }
+
+ inline void setEdgeList(const vector<WEdge *>& iEdgeList)
+ {
+ _EdgeList = iEdgeList;
+ }
+
+ inline void setVertexList(const vector<WVertex *>& iVertexList)
+ {
+ _VertexList = iVertexList;
+ }
+
+ inline void setFaceList(const vector<WFace *>& iFaceList)
+ {
+ _FaceList = iFaceList;
+ }
+
+ inline void setId(int id)
+ {
+ _Id = id;
+ }
+
+ inline void setBBox(const Vec3r& min, const Vec3r& max)
+ {
+ _min = min;
+ _max = max;
+ }
+
+ inline void setFrsMaterial(const FrsMaterial& frs_material, unsigned i)
+ {
+ _FrsMaterials[i] = frs_material;
+ }
+
+ inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials)
+ {
+ _FrsMaterials = iMaterials;
+ }
+
+ inline void setName(const string& name)
+ {
+ _Name = name;
+ }
+
+ /*! designed to build a specialized WFace for use in MakeFace */
+ virtual WFace *instanciateFace() const
+ {
+ return new WFace;
+ }
+
+ /*! adds a new face to the shape
+ * returns the built face.
+ * iVertexList
+ * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be
+ * already stored when calling MakeFace.
+ * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the
+ * face orientation.
+ * iMaterialIndex
+ * The material index for this face
+ */
+ virtual WFace *MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
+
+ /*! adds a new face to the shape. The difference with the previous method is that this one is designed
+ * to build a WingedEdge structure for which there are per vertex normals, opposed to per face normals.
+ * returns the built face.
+ * iVertexList
+ * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be
+ * already stored when calling MakeFace.
+ * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the
+ * face orientation.
+ * iMaterialIndex
+ * The materialIndex for this face
+ * iNormalsList
+ * The list of normals, iNormalsList[i] corresponding to the normal of the vertex iVertexList[i] for that face.
+ * iTexCoordsList
+ * The list of tex coords, iTexCoordsList[i] corresponding to the normal of the vertex iVertexList[i] for
+ * that face.
+ */
+ virtual WFace *MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
+ vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
+
+ inline void AddEdge(WEdge *iEdge)
+ {
+ _EdgeList.push_back(iEdge);
+ }
+
+ inline void AddFace(WFace *iFace)
+ {
+ _FaceList.push_back(iFace);
+ }
+
+ inline void AddVertex(WVertex *iVertex)
+ {
+ iVertex->setShape(this);
+ _VertexList.push_back(iVertex);
+ }
+
+ inline void ResetUserData()
+ {
+ for (vector<WVertex *>::iterator v = _VertexList.begin(), vend = _VertexList.end(); v != vend; v++) {
+ (*v)->ResetUserData();
+ }
+
+ for (vector<WEdge *>::iterator e = _EdgeList.begin(), eend = _EdgeList.end(); e != eend; e++) {
+ (*e)->ResetUserData();
+ // manages WOEdge:
+ WOEdge *oe = (*e)->GetaOEdge();
+ if (oe)
+ oe->ResetUserData();
+ oe = (*e)->GetbOEdge();
+ if (oe)
+ oe->ResetUserData();
+ }
+
+ for (vector<WFace *>::iterator f = _FaceList.begin(), fend = _FaceList.end(); f != fend; f++) {
+ (*f)->ResetUserData();
+ }
+ }
+
+ inline void ComputeBBox()
+ {
+ _min = _VertexList[0]->GetVertex();
+ _max = _VertexList[0]->GetVertex();
+
+ Vec3r v;
+ for (vector<WVertex *>::iterator wv = _VertexList.begin(), wvend = _VertexList.end(); wv != wvend; wv++) {
+ for (unsigned int i = 0; i < 3; i++) {
+ v = (*wv)->GetVertex();
+ if (v[i] < _min[i])
+ _min[i] = v[i];
+ if (v[i] > _max[i])
+ _max[i] = v[i];
+ }
+ }
+ }
+
+ inline real ComputeMeanEdgeSize()
+ {
+ _meanEdgeSize = _meanEdgeSize / _EdgeList.size();
+ return _meanEdgeSize;
+ }
protected:
- /*! Builds the face passed as argument (which as already been allocated)
- * iVertexList
- * List of face's vertices. These vertices are
- * not added to the WShape vertex list; they are
- * supposed to be already stored when calling MakeFace.
- * The order in which the vertices are stored in the list
- * determines the face's edges orientation and (so) the
- * face orientation.
- * iMaterialIndex
- * The material index for this face
- * face
- * The Face that is filled in
- */
- virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex, WFace *face);
+ /*! Builds the face passed as argument (which as already been allocated)
+ * iVertexList
+ * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be
+ * already stored when calling MakeFace.
+ * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the
+ * face orientation.
+ * iMaterialIndex
+ * The material index for this face
+ * face
+ * The Face that is filled in
+ */
+ virtual WFace *MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex,
+ WFace *face);
};
- /**********************************/
- /* */
- /* */
- /* WingedEdge */
- /* */
- /* */
- /**********************************/
-
-class WingedEdge {
-
- public:
+/**********************************
+ * *
+ * *
+ * WingedEdge *
+ * *
+ * *
+ **********************************/
- WingedEdge() {}
-
- ~WingedEdge() {
- clear();
- }
-
- void clear() {
- for (vector<WShape*>::iterator it = _wshapes.begin();
- it != _wshapes.end();
- it++)
- delete *it;
- _wshapes.clear();
- }
-
- void addWShape(WShape* wshape) {
- _wshapes.push_back(wshape);
- }
-
- vector<WShape*>& getWShapes() {
- return _wshapes;
- }
-
- private:
-
- vector<WShape*> _wshapes;
+class WingedEdge
+{
+public:
+ WingedEdge() {}
+
+ ~WingedEdge()
+ {
+ clear();
+ }
+
+ void clear()
+ {
+ for (vector<WShape *>::iterator it = _wshapes.begin(); it != _wshapes.end(); it++)
+ delete *it;
+ _wshapes.clear();
+ }
+
+ void addWShape(WShape *wshape)
+ {
+ _wshapes.push_back(wshape);
+ }
+
+ vector<WShape *>& getWShapes()
+ {
+ return _wshapes;
+ }
+
+private:
+ vector<WShape *> _wshapes;
};
/*
-
- #############################################
- #############################################
- #############################################
- ###### ######
- ###### I M P L E M E N T A T I O N ######
- ###### ######
- #############################################
- #############################################
- #############################################
-
+
+#############################################
+#############################################
+#############################################
+###### ######
+###### I M P L E M E N T A T I O N ######
+###### ######
+#############################################
+#############################################
+#############################################
+
*/
/* for inline functions */
-void WOEdge::RetrieveCWOrderedEdges(vector<WEdge*>& oEdges)
+void WOEdge::RetrieveCWOrderedEdges(vector<WEdge *>& oEdges)
{
-
- WOEdge *currentOEdge = this;
- do
- {
- WOEdge* nextOEdge = currentOEdge->GetbFace()->GetNextOEdge(currentOEdge);
- oEdges.push_back(nextOEdge->GetOwner());
- currentOEdge = nextOEdge->GetOwner()->GetOtherOEdge(nextOEdge);
-
- } while((currentOEdge != NULL) && (currentOEdge->GetOwner() != GetOwner()));
+ WOEdge *currentOEdge = this;
+ do {
+ WOEdge *nextOEdge = currentOEdge->GetbFace()->GetNextOEdge(currentOEdge);
+ oEdges.push_back(nextOEdge->GetOwner());
+ currentOEdge = nextOEdge->GetOwner()->GetOtherOEdge(nextOEdge);
+ } while (currentOEdge && (currentOEdge->GetOwner() != GetOwner()));
}
-inline void WOEdge::setVecAndAngle() {
- if ( _paVertex != NULL && _pbVertex != NULL ) {
- _vec = _pbVertex->GetVertex() - _paVertex->GetVertex();
- if ( _paFace != NULL && _pbFace != NULL ) {
- real sine = (_pbFace->GetNormal() ^ _paFace->GetNormal()) * _vec / _vec.norm() ;
- if(sine >= 1.0) {
- _angle = M_PI / 2.0 ;
- return;
- }
- if(sine <= -1.0) {
- _angle = -M_PI / 2.0 ;
- return;
- }
- _angle = ::asin(sine);
- }
- }
+inline void WOEdge::setVecAndAngle()
+{
+ if (_paVertex && _pbVertex) {
+ _vec = _pbVertex->GetVertex() - _paVertex->GetVertex();
+ if (_paFace && _pbFace) {
+ real sine = (_pbFace->GetNormal() ^ _paFace->GetNormal()) * _vec / _vec.norm();
+ if (sine >= 1.0) {
+ _angle = M_PI / 2.0;
+ return;
+ }
+ if (sine <= -1.0) {
+ _angle = -M_PI / 2.0;
+ return;
+ }
+ _angle = ::asin(sine);
+ }
+ }
}
-#endif // WEDGE_H
+#endif // __FREESTYLE_W_EDGE_H__ \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp b/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp
index 7d0a2d3c561..8b446791efc 100644
--- a/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp
@@ -1,60 +1,68 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/winged_edge/WFillGrid.cpp
+ * \ingroup freestyle
+ * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
+ * \author Emmanuel Turquin
+ * \author Stephane Grabli
+ * \date 03/05/2003
+ */
#include "WEdge.h"
#include "WFillGrid.h"
-void WFillGrid::fillGrid() {
- if (!_winged_edge || !_grid)
- return;
-
- vector<WShape*> wshapes = _winged_edge->getWShapes();
- vector<WVertex*> fvertices;
- vector<Vec3r> vectors;
- vector<WFace*> faces;
-
- for (vector<WShape*>::const_iterator it = wshapes.begin();
- it != wshapes.end();
- it++) {
- faces = (*it)->GetFaceList();
-
- for (vector<WFace*>::const_iterator f = faces.begin();
- f != faces.end();
- f++) {
- (*f)->RetrieveVertexList(fvertices);
-
- for (vector<WVertex*>::const_iterator wv = fvertices.begin();
- wv != fvertices.end();
- wv++)
- vectors.push_back(Vec3r((*wv)->GetVertex()));
-
- // occluder will be deleted by the grid
- Polygon3r *occluder =
- new Polygon3r(vectors, (*f)->GetNormal());
- occluder->setId(_polygon_id++);
- occluder->userdata = (void*)(*f);
- _grid->insertOccluder(occluder);
- vectors.clear();
- fvertices.clear();
- }
- faces.clear();
- }
-}
+void WFillGrid::fillGrid()
+{
+ if (!_winged_edge || !_grid)
+ return;
+
+ vector<WShape *> wshapes = _winged_edge->getWShapes();
+ vector<WVertex *> fvertices;
+ vector<Vec3r> vectors;
+ vector<WFace *> faces;
+
+ for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) {
+ faces = (*it)->GetFaceList();
+
+ for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) {
+ (*f)->RetrieveVertexList(fvertices);
+
+ for (vector<WVertex*>::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv)
+ vectors.push_back(Vec3r((*wv)->GetVertex()));
+
+ // occluder will be deleted by the grid
+ Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal());
+ occluder->setId(_polygon_id++);
+ occluder->userdata = (void *)(*f);
+ _grid->insertOccluder(occluder);
+ vectors.clear();
+ fvertices.clear();
+ }
+ faces.clear();
+ }
+} \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.h b/source/blender/freestyle/intern/winged_edge/WFillGrid.h
index 2ebbc2f359a..223c5a786d8 100644
--- a/source/blender/freestyle/intern/winged_edge/WFillGrid.h
+++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.h
@@ -1,80 +1,88 @@
-//
-// Filename : WFillGrid.h
-// Author(s) : Stephane Grabli
-// Emmanuel Turquin
-// Purpose : Class to fill in a grid from a SceneGraph
-// (uses only the WingedEdge structures)
-// Date of creation : 03/05/2003
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_W_FILL_GRID_H__
+#define __FREESTYLE_W_FILL_GRID_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/winged_edge/WFillGrid.h
+ * \ingroup freestyle
+ * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
+ * \author Emmanuel Turquin
+ * \author Stephane Grabli
+ * \date 03/05/2003
+ */
-#ifndef W_FILL_GRID_H
-# define W_FILL_GRID_H
+#include "WEdge.h"
-# include "../geometry/Grid.h"
-# include "../geometry/Polygon.h"
-# include "WEdge.h"
+#include "../geometry/Grid.h"
+#include "../geometry/Polygon.h"
class LIB_WINGED_EDGE_EXPORT WFillGrid
{
public:
+ inline WFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
+ {
+ _winged_edge = winged_edge;
+ _grid = grid;
+ _polygon_id = 0;
+ }
- inline WFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) {
- _winged_edge = winged_edge;
- _grid = grid;
- _polygon_id = 0;
- }
+ virtual ~WFillGrid() {}
- virtual ~WFillGrid() {}
+ void fillGrid();
- void fillGrid();
+ /*! Accessors */
+ WingedEdge *getWingedEdge()
+ {
+ return _winged_edge;
+ }
- /*! Accessors */
- WingedEdge* getWingedEdge() {
- return _winged_edge;
- }
+ Grid *getGrid()
+ {
+ return _grid;
+ }
- Grid* getGrid() {
- return _grid;
- }
+ /*! Modifiers */
+ void setWingedEdge(WingedEdge *winged_edge)
+ {
+ if (winged_edge)
+ _winged_edge = winged_edge;
+ }
- /*! Modifiers */
- void setWingedEdge(WingedEdge* winged_edge) {
- if (winged_edge)
- _winged_edge = winged_edge;
- }
-
- void setGrid(Grid* grid) {
- if (grid)
- _grid = grid;
- }
+ void setGrid(Grid *grid)
+ {
+ if (grid)
+ _grid = grid;
+ }
private:
-
- Grid* _grid;
- WingedEdge* _winged_edge;
- unsigned _polygon_id;
+ Grid *_grid;
+ WingedEdge *_winged_edge;
+ unsigned _polygon_id;
};
-#endif // WS_FILL_GRID_H
+#endif // __FREESTYLE_W_FILL_GRID_H__ \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp b/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp
index 55fa418d4f5..3504a8ab179 100644
--- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp
@@ -1,60 +1,67 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/winged_edge/WSFillGrid.cpp
+ * \ingroup freestyle
+ * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
+ * \author Stephane Grabli
+ * \date 03/05/2003
+ */
#include "WEdge.h"
#include "WSFillGrid.h"
-void WSFillGrid::fillGrid() {
- if (!_winged_edge || !_grid)
- return;
-
- vector<WShape*> wshapes = _winged_edge->getWShapes();
- vector<WVertex*> fvertices;
- vector<Vec3r> vectors;
- vector<WFace*> faces;
-
- for (vector<WShape*>::const_iterator it = wshapes.begin();
- it != wshapes.end();
- it++) {
- faces = (*it)->GetFaceList();
-
- for (vector<WFace*>::const_iterator f = faces.begin();
- f != faces.end();
- f++) {
- (*f)->RetrieveVertexList(fvertices);
-
- for (vector<WVertex*>::const_iterator wv = fvertices.begin();
- wv != fvertices.end();
- wv++)
- vectors.push_back(Vec3r((*wv)->GetVertex()));
-
- // occluder will be deleted by the grid
- Polygon3r *occluder =
- new Polygon3r(vectors, (*f)->GetNormal());
- occluder->setId(_polygon_id++);
- occluder->userdata = (void*)(*f);
- _grid->insertOccluder(occluder);
- vectors.clear();
- fvertices.clear();
- }
- faces.clear();
- }
-}
+void WSFillGrid::fillGrid()
+{
+ if (!_winged_edge || !_grid)
+ return;
+
+ vector<WShape *> wshapes = _winged_edge->getWShapes();
+ vector<WVertex *> fvertices;
+ vector<Vec3r> vectors;
+ vector<WFace *> faces;
+
+ for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) {
+ faces = (*it)->GetFaceList();
+
+ for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) {
+ (*f)->RetrieveVertexList(fvertices);
+
+ for (vector<WVertex*>::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv)
+ vectors.push_back(Vec3r((*wv)->GetVertex()));
+
+ // occluder will be deleted by the grid
+ Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal());
+ occluder->setId(_polygon_id++);
+ occluder->userdata = (void *)(*f);
+ _grid->insertOccluder(occluder);
+ vectors.clear();
+ fvertices.clear();
+ }
+ faces.clear();
+ }
+} \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
index 2ea5bc6c621..55bedd83cce 100644
--- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
+++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
@@ -1,79 +1,87 @@
-//
-// Filename : WSFillGrid.h
-// Author(s) : Stephane Grabli
-// Purpose : Class to fill in a grid from a SceneGraph
-// (uses only the WingedEdge structures)
-// Date of creation : 03/05/2003
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __FREESTYLE_WS_FILL_GRID_H__
+#define __FREESTYLE_WS_FILL_GRID_H__
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/** \file blender/freestyle/intern/winged_edge/WSFillGrid.h
+ * \ingroup freestyle
+ * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
+ * \author Stephane Grabli
+ * \date 03/05/2003
+ */
-#ifndef WS_FILL_GRID_H
-# define WS_FILL_GRID_H
+#include "WEdge.h"
-# include "../geometry/Grid.h"
-# include "../geometry/Polygon.h"
-# include "WEdge.h"
+#include "../geometry/Grid.h"
+#include "../geometry/Polygon.h"
class LIB_WINGED_EDGE_EXPORT WSFillGrid
{
public:
+ inline WSFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
+ {
+ _winged_edge = winged_edge;
+ _grid = grid;
+ _polygon_id = 0;
+ }
- inline WSFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) {
- _winged_edge = winged_edge;
- _grid = grid;
- _polygon_id = 0;
- }
+ virtual ~WSFillGrid() {}
- virtual ~WSFillGrid() {}
+ void fillGrid();
- void fillGrid();
+ /*! Accessors */
+ WingedEdge *getWingedEdge()
+ {
+ return _winged_edge;
+ }
- /*! Accessors */
- WingedEdge* getWingedEdge() {
- return _winged_edge;
- }
+ Grid *getGrid()
+ {
+ return _grid;
+ }
- Grid* getGrid() {
- return _grid;
- }
+ /*! Modifiers */
+ void setWingedEdge(WingedEdge *winged_edge)
+ {
+ if (winged_edge)
+ _winged_edge = winged_edge;
+ }
- /*! Modifiers */
- void setWingedEdge(WingedEdge* winged_edge) {
- if (winged_edge)
- _winged_edge = winged_edge;
- }
-
- void setGrid(Grid* grid) {
- if (grid)
- _grid = grid;
- }
+ void setGrid(Grid *grid)
+ {
+ if (grid)
+ _grid = grid;
+ }
private:
-
- Grid* _grid;
- WingedEdge* _winged_edge;
- unsigned _polygon_id;
+ Grid *_grid;
+ WingedEdge *_winged_edge;
+ unsigned _polygon_id;
};
-#endif // WS_FILL_GRID_H
+#endif // __FREESTYLE_WS_FILL_GRID_H__ \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp
index d238749570c..fed9a1588bb 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp
@@ -1,296 +1,298 @@
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/winged_edge/WXEdge.cpp
+ * \ingroup freestyle
+ * \brief Classes to define an Extended Winged Edge data structure.
+ * \author Stephane Grabli
+ * \date 26/10/2003
+ */
#include "WXEdge.h"
- /**********************************/
- /* */
- /* */
- /* WXFace */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WXFace *
+ * *
+ * *
+ **********************************/
-unsigned int WXFaceLayer::Get0VertexIndex() const {
- int i = 0;
- int nEdges = _pWXFace->numberOfEdges();
- for(i=0; i<nEdges; ++i){
- if(_DotP[i] == 0){
- return i;
- }
- }
- return -1;
+unsigned int WXFaceLayer::Get0VertexIndex() const
+{
+ int i = 0;
+ int nEdges = _pWXFace->numberOfEdges();
+ for (i = 0; i < nEdges; ++i) {
+ if (_DotP[i] == 0) {
+ return i;
+ }
+ }
+ return -1;
}
-unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{
- int i = 0;
- int nEdges = _pWXFace->numberOfEdges();
- for(i=0; i<nEdges; ++i){
- if((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)){
- return i;
- }
- }
- return -1;
+unsigned int WXFaceLayer::GetSmoothEdgeIndex() const
+{
+ int i = 0;
+ int nEdges = _pWXFace->numberOfEdges();
+ for (i = 0; i < nEdges; ++i) {
+ if ((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)) {
+ return i;
+ }
+ }
+ return -1;
}
-void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){
- int i = 0;
- int nEdges = _pWXFace->numberOfEdges();
- for(i=0; i<nEdges; ++i){
- if(_DotP[i]*_DotP[(i+1)%nEdges] < 0){
- // we got one
- oCuspEdges.push_back(i);
- }
- }
+void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges)
+{
+ int i = 0;
+ int nEdges = _pWXFace->numberOfEdges();
+ for (i = 0; i < nEdges; ++i) {
+ if (_DotP[i] * _DotP[(i + 1) % nEdges] < 0) {
+ // we got one
+ oCuspEdges.push_back(i);
+ }
+ }
}
-
-WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
- // if the smooth edge has already been
- // built: exit
- if(0 != _pSmoothEdge)
- return _pSmoothEdge;
- real ta, tb;
- WOEdge *woea(0), *woeb(0);
- bool ok = false;
- vector<int> cuspEdgesIndices;
- int indexStart, indexEnd;
- unsigned nedges = _pWXFace->numberOfEdges();
- if(_nNullDotP == nedges){
- _pSmoothEdge = 0;
- return _pSmoothEdge;
- }
- if((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)){
- // that means that we have a smooth edge that starts from
- // an edge and ends at an edge
- //-----------------------------
- // We retrieve the 2 edges for which we have
- // opposite signs for each extremity
- RetrieveCuspEdgesIndices(cuspEdgesIndices);
- if(cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges
- return 0;
-
- // let us determine which cusp edge corresponds to the starting:
- // We can do that because we defined that
- // a silhouette edge had the back facing part on its right.
- // So if the WOEdge woea is such that woea[0].dotp > 0 and
- // woea[1].dotp < 0, it is the starting edge.
- //-------------------------------------------
-
- if(_DotP[cuspEdgesIndices[0]] > 0){
- woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
- woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
- indexStart = cuspEdgesIndices[0];
- indexEnd = cuspEdgesIndices[1];
- }else{
- woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
- woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
- indexStart = cuspEdgesIndices[1];
- indexEnd = cuspEdgesIndices[0];
- }
-
- // Compute the interpolation:
- ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]);
- tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]);
- ok = true;
- }else if(_nNullDotP == 1){
- // that means that we have exactly one of the
- // 2 extremities of our silhouette edge is
- // a vertex of the mesh
- if((_nPosDotP == 2) || (_nPosDotP == 0)){
- _pSmoothEdge = 0;
- return _pSmoothEdge;
- }
- RetrieveCuspEdgesIndices(cuspEdgesIndices);
- // We should have only one EdgeCusp:
- if(cuspEdgesIndices.size() != 1){
- cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl;
- _pSmoothEdge = 0;
- return 0;
- }
- unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
- unsigned nedges = _pWXFace->numberOfEdges();
- if(_DotP[cuspEdgesIndices[0]] > 0){
- woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
- woeb = _pWXFace->GetOEdge(index0);
- indexStart = cuspEdgesIndices[0];
- ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]);
- tb = 0.0;
- }else{
- woea = _pWXFace->GetOEdge(index0);
- woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
- indexEnd = cuspEdgesIndices[0];
- ta = 0.0;
- tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]);
- }
- ok = true;
- }else if(_nNullDotP == 2){
- // that means that the silhouette edge
- // is an edge of the mesh
- int index = GetSmoothEdgeIndex();
- if(!_pWXFace->front()) {// is it in the right order ?
- // the order of the WOEdge index is wrong
- woea = _pWXFace->GetOEdge((index+1)%nedges);
- woeb = _pWXFace->GetOEdge((index-1)%nedges);
- ta = 0;
- tb = 1;
- ok = true;
- }else{
- // here it's not good, our edge is a single point -> skip that face
- ok = false;
- // the order of the WOEdge index is good
- // woea = _pWXFace->GetOEdge((index-1)%nedges);
- // woeb = _pWXFace->GetOEdge((index+1)%nedges);
- // ta = 1;
- // tb = 0;
- }
- }
- if(ok){
- _pSmoothEdge = new WXSmoothEdge;
- _pSmoothEdge->setWOeA(woea);
- _pSmoothEdge->setWOeB(woeb);
- _pSmoothEdge->setTa(ta);
- _pSmoothEdge->setTb(tb);
- if(_Nature & Nature::SILHOUETTE){
- if(_nNullDotP != 2){
- if(_DotP[_ClosestPointIndex] + 0.01 > 0)
- _pSmoothEdge->setFront(true);
- else
- _pSmoothEdge->setFront(false);
- }
- }
- }
-
- // check bording edges to see if they have different dotp values
- // in bording faces.
- // for(int i=0; i<numberOfEdges(); i++)
- // {
- // WSFace * bface = (WSFace*)GetBordingFace(i);
- // if(bface != 0)
- // {
- // if((front())^(bface->front())) // fA->front XOR fB->front (true if one is 0 and the other is 1)
- // {
- // // that means that the edge i of the face is
- // // a silhouette edge
- // // TESTER D'ABORD SI LE EXACTSILHOUETTEEDGE N'A PAS
- // // ETE CONSTRUIT SUR L'AUTRE FACE.(1 suffit)
- // if(0 != ((WSExactFace*)bface)->exactSilhouetteEdge())
- // {
- // // that means that this silhouette edge has already been built
- // return ((WSExactFace*)bface)->exactSilhouetteEdge();
- // }
- // // Else we must build it
- // WOEdge *woea, *woeb;
- // real ta, tb;
- // if(!front()) // is it in the right order ?
- // {
- // // the order of the WOEdge index is wrong
- // woea = _OEdgeList[(i+1)%numberOfEdges()];
- // if(0 == i)
- // woeb = _OEdgeList[numberOfEdges()-1];
- // else
- // woeb = _OEdgeList[(i-1)];
- // ta = 0;
- // tb = 1;
- // }
- // else
- // {
- // // the order of the WOEdge index is good
- // if(0 == i)
- // woea = _OEdgeList[numberOfEdges()-1];
- // else
- // woea = _OEdgeList[(i-1)];
- // woeb = _OEdgeList[(i+1)%numberOfEdges()];
- // ta = 1;
- // tb = 0;
- // }
- //
- // _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
- // _pSmoothEdge->setWOeA(woea);
- // _pSmoothEdge->setWOeA(woeb);
- // _pSmoothEdge->setTa(ta);
- // _pSmoothEdge->setTb(tb);
- //
- // return _pSmoothEdge;
- // }
- // }
- //}
- return _pSmoothEdge;
+
+WXSmoothEdge *WXFaceLayer::BuildSmoothEdge()
+{
+ // if the smooth edge has already been built: exit
+ if (_pSmoothEdge)
+ return _pSmoothEdge;
+ real ta, tb;
+ WOEdge *woea(0), *woeb(0);
+ bool ok = false;
+ vector<int> cuspEdgesIndices;
+ int indexStart, indexEnd;
+ unsigned nedges = _pWXFace->numberOfEdges();
+ if (_nNullDotP == nedges) {
+ _pSmoothEdge = NULL;
+ return _pSmoothEdge;
+ }
+ if ((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)) {
+ // that means that we have a smooth edge that starts from an edge and ends at an edge
+ //-----------------------------
+ // We retrieve the 2 edges for which we have opposite signs for each extremity
+ RetrieveCuspEdgesIndices(cuspEdgesIndices);
+ if (cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges
+ return 0;
+
+ // let us determine which cusp edge corresponds to the starting:
+ // We can do that because we defined that a silhouette edge had the back facing part on its right.
+ // So if the WOEdge woea is such that woea[0].dotp > 0 and woea[1].dotp < 0, it is the starting edge.
+ //-------------------------------------------
+
+ if (_DotP[cuspEdgesIndices[0]] > 0) {
+ woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
+ woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
+ indexStart = cuspEdgesIndices[0];
+ indexEnd = cuspEdgesIndices[1];
+ }
+ else {
+ woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
+ woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
+ indexStart = cuspEdgesIndices[1];
+ indexEnd = cuspEdgesIndices[0];
+ }
+
+ // Compute the interpolation:
+ ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
+ tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
+ ok = true;
+ }
+ else if (_nNullDotP == 1) {
+ // that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex of the mesh
+ if ((_nPosDotP == 2) || (_nPosDotP == 0)) {
+ _pSmoothEdge = NULL;
+ return _pSmoothEdge;
+ }
+ RetrieveCuspEdgesIndices(cuspEdgesIndices);
+ // We should have only one EdgeCusp:
+ if (cuspEdgesIndices.size() != 1) {
+ cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl;
+ _pSmoothEdge = NULL;
+ return NULL;
+ }
+ unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
+ unsigned nedges = _pWXFace->numberOfEdges();
+ if (_DotP[cuspEdgesIndices[0]] > 0) {
+ woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
+ woeb = _pWXFace->GetOEdge(index0);
+ indexStart = cuspEdgesIndices[0];
+ ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
+ tb = 0.0;
+ }
+ else {
+ woea = _pWXFace->GetOEdge(index0);
+ woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
+ indexEnd = cuspEdgesIndices[0];
+ ta = 0.0;
+ tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
+ }
+ ok = true;
+ }
+ else if (_nNullDotP == 2) {
+ // that means that the silhouette edge is an edge of the mesh
+ int index = GetSmoothEdgeIndex();
+ if (!_pWXFace->front()) { // is it in the right order ?
+ // the order of the WOEdge index is wrong
+ woea = _pWXFace->GetOEdge((index + 1) % nedges);
+ woeb = _pWXFace->GetOEdge((index - 1) % nedges);
+ ta = 0;
+ tb = 1;
+ ok = true;
+ }
+ else {
+ // here it's not good, our edge is a single point -> skip that face
+ ok = false;
+#if 0
+ // the order of the WOEdge index is good
+ woea = _pWXFace->GetOEdge((index - 1) % nedges);
+ woeb = _pWXFace->GetOEdge((index + 1) % nedges);
+ ta = 1;
+ tb = 0;
+#endif
+ }
+ }
+ if (ok) {
+ _pSmoothEdge = new WXSmoothEdge;
+ _pSmoothEdge->setWOeA(woea);
+ _pSmoothEdge->setWOeB(woeb);
+ _pSmoothEdge->setTa(ta);
+ _pSmoothEdge->setTb(tb);
+ if (_Nature & Nature::SILHOUETTE) {
+ if (_nNullDotP != 2) {
+ if (_DotP[_ClosestPointIndex] + 0.01 > 0)
+ _pSmoothEdge->setFront(true);
+ else
+ _pSmoothEdge->setFront(false);
+ }
+ }
+ }
+
+#if 0
+ // check bording edges to see if they have different dotp values in bording faces.
+ for (int i = 0; i < numberOfEdges(); i++) {
+ WSFace *bface = (WSFace *)GetBordingFace(i);
+ if (bface) {
+ if ((front()) ^ (bface->front())) { // fA->front XOR fB->front (true if one is 0 and the other is 1)
+ // that means that the edge i of the face is a silhouette edge
+ // CHECK FIRST WHETHER THE EXACTSILHOUETTEEDGE HAS NOT YET BEEN BUILT ON THE OTHER FACE (1 is enough).
+ if (((WSExactFace *)bface)->exactSilhouetteEdge()) {
+ // that means that this silhouette edge has already been built
+ return ((WSExactFace *)bface)->exactSilhouetteEdge();
+ }
+ // Else we must build it
+ WOEdge *woea, *woeb;
+ real ta, tb;
+ if (!front()) { // is it in the right order ?
+ // the order of the WOEdge index is wrong
+ woea = _OEdgeList[(i + 1) % numberOfEdges()];
+ if (0 == i)
+ woeb = _OEdgeList[numberOfEdges() - 1];
+ else
+ woeb = _OEdgeList[(i - 1)];
+ ta = 0;
+ tb = 1;
+ }
+ else {
+ // the order of the WOEdge index is good
+ if (0 == i)
+ woea = _OEdgeList[numberOfEdges() - 1];
+ else
+ woea = _OEdgeList[(i - 1)];
+ woeb = _OEdgeList[(i + 1) % numberOfEdges()];
+ ta = 1;
+ tb = 0;
+ }
+
+ _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
+ _pSmoothEdge->setWOeA(woea);
+ _pSmoothEdge->setWOeA(woeb);
+ _pSmoothEdge->setTa(ta);
+ _pSmoothEdge->setTb(tb);
+
+ return _pSmoothEdge;
+ }
+ }
+ }
+#endif
+ return _pSmoothEdge;
}
-
+
void WXFace::ComputeCenter()
{
- vector<WVertex*> iVertexList;
- RetrieveVertexList(iVertexList);
- Vec3r center;
- for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
- wv!=wvend;
- wv++)
- {
- center += (*wv)->GetVertex();
- }
- center /= (real)iVertexList.size();
- setCenter(center);
+ vector<WVertex *> iVertexList;
+ RetrieveVertexList(iVertexList);
+ Vec3r center;
+ for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
+ center += (*wv)->GetVertex();
+ }
+ center /= (real)iVertexList.size();
+ setCenter(center);
}
- /**********************************/
- /* */
- /* */
- /* WXShape */
- /* */
- /* */
- /**********************************/
-
+/**********************************
+ * *
+ * *
+ * WXShape *
+ * *
+ * *
+ **********************************/
-WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
+WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
{
- WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
- if(0 == face)
- return 0;
-
- Vec3r center;
- for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
- wv!=wvend;
- wv++)
- {
- center += (*wv)->GetVertex();
- }
- center /= (real)iVertexList.size();
- ((WXFace*)face)->setCenter(center);
+ WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
+ if (!face)
+ return NULL;
- return face;
+ Vec3r center;
+ for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
+ center += (*wv)->GetVertex();
+ }
+ center /= (real)iVertexList.size();
+ ((WXFace *)face)->setCenter(center);
+
+ return face;
}
-WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
+WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
+ vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
{
- WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
-
- // Vec3r center;
- // for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
- // wv!=wvend;
- // wv++)
- // {
- // center += (*wv)->GetVertex();
- // }
- // center /= (real)iVertexList.size();
- // ((WSFace*)face)->setCenter(center);
+ WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
- return face;
-}
+#if 0
+ Vec3r center;
+ for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
+ center += (*wv)->GetVertex();
+ }
+ center /= (real)iVertexList.size();
+ ((WSFace *)face)->setCenter(center);
+#endif
+ return face;
+} \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h
index c51b6a84a98..9f3522e4e70 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdge.h
+++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h
@@ -1,582 +1,809 @@
-//
-// Filename : WXEdge.h
-// Author(s) : Stephane Grabli
-// Purpose : Classes to define an Extended Winged Edge data structure.
-// Date of creation : 26/10/2003
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef WXEDGE_H
-# define WXEDGE_H
-
-# include "WEdge.h"
-# include "Nature.h"
-# include "Curvature.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_WX_EDGE_H__
+#define __FREESTYLE_WX_EDGE_H__
+
+/** \file blender/freestyle/intern/winged_edge/WXEdge.h
+ * \ingroup freestyle
+ * \brief Classes to define an Extended Winged Edge data structure.
+ * \author Stephane Grabli
+ * \date 26/10/2003
+ */
+
+#include "Curvature.h"
+#include "Nature.h"
+#include "WEdge.h"
typedef Nature::EdgeNature WXNature;
- /**********************************/
- /* */
- /* */
- /* WXVertex */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WXVertex *
+ * *
+ * *
+ **********************************/
class WXVertex : public WVertex
-{
+{
private:
- // Curvature info
- CurvatureInfo *_curvatures;
+ // Curvature info
+ CurvatureInfo *_curvatures;
public:
- inline WXVertex(const Vec3r &v)
- : WVertex(v)
- {_curvatures = 0;}
- /*! Copy constructor */
- WXVertex(WXVertex& iBrother)
- : WVertex(iBrother)
- {_curvatures = new CurvatureInfo(*iBrother._curvatures);}
- virtual WVertex * duplicate()
- {
- WXVertex *clone = new WXVertex(*this);
- return clone;
- }
- virtual ~WXVertex() {if(_curvatures) delete _curvatures;}
- virtual void Reset() {if(_curvatures) _curvatures->Kr = 0.0;}
- inline void setCurvatures(CurvatureInfo *ci) {_curvatures = ci;}
-
- inline bool isFeature();
- inline CurvatureInfo* curvatures() {return _curvatures;}
-
+ inline WXVertex(const Vec3r &v) : WVertex(v)
+ {
+ _curvatures = NULL;
+ }
+
+ /*! Copy constructor */
+ WXVertex(WXVertex& iBrother) : WVertex(iBrother)
+ {
+ _curvatures = new CurvatureInfo(*iBrother._curvatures);
+ }
+
+ virtual WVertex *duplicate()
+ {
+ WXVertex *clone = new WXVertex(*this);
+ return clone;
+ }
+
+ virtual ~WXVertex()
+ {
+ if (_curvatures)
+ delete _curvatures;
+ }
+
+ virtual void Reset()
+ {
+ if (_curvatures)
+ _curvatures->Kr = 0.0;
+ }
+
+ inline void setCurvatures(CurvatureInfo *ci)
+ {
+ _curvatures = ci;
+ }
+
+ inline bool isFeature();
+
+ inline CurvatureInfo *curvatures()
+ {
+ return _curvatures;
+ }
};
+/**********************************
+ * *
+ * *
+ * WXEdge *
+ * *
+ * *
+ **********************************/
- /**********************************/
- /* */
- /* */
- /* WXEdge */
- /* */
- /* */
- /**********************************/
class WXEdge : public WEdge
{
private:
- WXNature _nature; // flag to indicate whether the edge is a silhouette edge or not
- int _order; // 0: the order doesn't matter. 1: the order is the orginal one. -1: the order is not good
- bool _front; // a front facing edge is an edge for which the bording face which is the nearest
- // from the viewpoint is front. A back facing edge is the opposite.
-
+ // flag to indicate whether the edge is a silhouette edge or not
+ WXNature _nature;
+ // 0: the order doesn't matter. 1: the order is the orginal one. -1: the order is not good
+ int _order;
+ // A front facing edge is an edge for which the bording face which is the nearest from the viewpoint is front.
+ // A back facing edge is the opposite.
+ bool _front;
+
public:
- inline WXEdge()
- : WEdge(){
- _nature = Nature::NO_FEATURE;
- _front = false;
- _order=0;
- }
-
- inline WXEdge(WOEdge *iOEdge)
- : WEdge(iOEdge)
- { _nature = Nature::NO_FEATURE;_front = false;_order=0;}
-
- inline WXEdge(WOEdge *iaOEdge, WOEdge *ibOEdge)
- : WEdge(iaOEdge, ibOEdge)
- { _nature = Nature::NO_FEATURE;_front = false;_order=0;}
-
- /*! Copy constructor */
- inline WXEdge(WXEdge& iBrother)
- : WEdge(iBrother)
- {_nature = iBrother.nature();_front = iBrother._front;_order = iBrother._order;}
- virtual WEdge * duplicate()
- {
- WXEdge *clone = new WXEdge(*this);
- return clone;
- }
-
- virtual ~WXEdge()
- {}
-
- virtual void Reset(){
- _nature = _nature & ~Nature::SILHOUETTE;
- _nature = _nature & ~Nature::SUGGESTIVE_CONTOUR;
- }
-
- /*! accessors */
- inline WXNature nature() {return _nature;}
- inline bool front() {return _front;}
- inline int order() const {return _order;}
-
- /*! modifiers */
- inline void setFront(bool iFront) {_front = iFront;}
- inline void setNature(WXNature iNature) {_nature = iNature;}
- inline void AddNature(WXNature iNature) {_nature = _nature|iNature;}
- inline void setOrder(int i) {_order = i;}
-
+ inline WXEdge() : WEdge()
+ {
+ _nature = Nature::NO_FEATURE;
+ _front = false;
+ _order = 0;
+ }
+
+ inline WXEdge(WOEdge *iOEdge) : WEdge(iOEdge)
+ {
+ _nature = Nature::NO_FEATURE;
+ _front = false;
+ _order = 0;
+ }
+
+ inline WXEdge(WOEdge *iaOEdge, WOEdge *ibOEdge) : WEdge(iaOEdge, ibOEdge)
+ {
+ _nature = Nature::NO_FEATURE;
+ _front = false;
+ _order = 0;
+ }
+
+ /*! Copy constructor */
+ inline WXEdge(WXEdge& iBrother) : WEdge(iBrother)
+ {
+ _nature = iBrother.nature();
+ _front = iBrother._front;
+ _order = iBrother._order;
+ }
+
+ virtual WEdge *duplicate()
+ {
+ WXEdge *clone = new WXEdge(*this);
+ return clone;
+ }
+
+ virtual ~WXEdge() {}
+
+ virtual void Reset()
+ {
+ _nature = _nature & ~Nature::SILHOUETTE;
+ _nature = _nature & ~Nature::SUGGESTIVE_CONTOUR;
+ }
+
+ /*! accessors */
+ inline WXNature nature()
+ {
+ return _nature;
+ }
+
+ inline bool front()
+ {
+ return _front;
+ }
+
+ inline int order() const
+ {
+ return _order;
+ }
+
+ /*! modifiers */
+ inline void setFront(bool iFront)
+ {
+ _front = iFront;
+ }
+
+ inline void setNature(WXNature iNature)
+ {
+ _nature = iNature;
+ }
+
+ inline void AddNature(WXNature iNature)
+ {
+ _nature = _nature | iNature;
+ }
+
+ inline void setOrder(int i)
+ {
+ _order = i;
+ }
};
- /**********************************/
- /* */
- /* */
- /* WXFace */
- /* */
- /* */
- /**********************************/
+/**********************************
+ * *
+ * *
+ * WXFace *
+ * *
+ * *
+ **********************************/
/*! Class to store a smooth edge (i.e Hertzman & Zorin smooth silhouette edges) */
-class WXSmoothEdge{
+class WXSmoothEdge
+{
public:
- typedef enum{
- EDGE_EDGE,
- VERTEX_EDGE,
- EDGE_VERTEX
- } Configuration;
-
- WOEdge *_woea; // Oriented edge from which the silhouette edge starts
- WOEdge *_woeb; // Oriented edge where the silhouette edge ends
- real _ta; // The silhouette starting point's coordinates are : _woea[0]+ta*(_woea[1]-_woea[0])
- real _tb; // The silhouette ending point's coordinates are : _woeb[0]+ta*(_woeb[1]-_woeb[0])
- bool _front;
- Configuration _config;
-
- WXSmoothEdge(){
- _woea = 0;
- _woeb = 0;
- _ta = 0;
- _tb = 0;
- _front = false;
- _config = EDGE_EDGE;
- }
- WXSmoothEdge(const WXSmoothEdge& iBrother){
- _woea = iBrother._woea;
- _woeb = iBrother._woeb;
- _ta = iBrother._ta;
- _tb = iBrother._tb;
- _config = iBrother._config;
- _front = iBrother._front;
- }
- ~WXSmoothEdge() {}
-
- inline WOEdge * woea() {return _woea;}
- inline WOEdge * woeb() {return _woeb;}
- inline real ta() const {return _ta;}
- inline real tb() const {return _tb;}
- inline bool front() const {return _front;}
- inline Configuration configuration() const {return _config;}
-
- /*! modifiers */
- inline void setWOeA(WOEdge *iwoea) {_woea = iwoea;}
- inline void setWOeB(WOEdge *iwoeb) {_woeb = iwoeb;}
- inline void setTa(real ta) {_ta = ta;}
- inline void setTb(real tb) {_tb = tb;}
- inline void setFront(bool iFront) {_front = iFront;}
- inline void setConfiguration(Configuration iConf) {_config = iConf;}
-
+ typedef enum {
+ EDGE_EDGE,
+ VERTEX_EDGE,
+ EDGE_VERTEX,
+ } Configuration;
+
+ WOEdge *_woea; // Oriented edge from which the silhouette edge starts
+ WOEdge *_woeb; // Oriented edge where the silhouette edge ends
+ real _ta; // The silhouette starting point's coordinates are : _woea[0]+ta*(_woea[1]-_woea[0])
+ real _tb; // The silhouette ending point's coordinates are : _woeb[0]+ta*(_woeb[1]-_woeb[0])
+ bool _front;
+ Configuration _config;
+
+ WXSmoothEdge()
+ {
+ _woea = NULL;
+ _woeb = NULL;
+ _ta = 0;
+ _tb = 0;
+ _front = false;
+ _config = EDGE_EDGE;
+ }
+
+ WXSmoothEdge(const WXSmoothEdge& iBrother)
+ {
+ _woea = iBrother._woea;
+ _woeb = iBrother._woeb;
+ _ta = iBrother._ta;
+ _tb = iBrother._tb;
+ _config = iBrother._config;
+ _front = iBrother._front;
+ }
+
+ ~WXSmoothEdge() {}
+
+ inline WOEdge *woea()
+ {
+ return _woea;
+ }
+
+ inline WOEdge *woeb()
+ {
+ return _woeb;
+ }
+
+ inline real ta() const
+ {
+ return _ta;
+ }
+
+ inline real tb() const
+ {
+ return _tb;
+ }
+
+ inline bool front() const
+ {
+ return _front;
+ }
+
+ inline Configuration configuration() const
+ {
+ return _config;
+ }
+
+ /*! modifiers */
+ inline void setWOeA(WOEdge *iwoea)
+ {
+ _woea = iwoea;
+ }
+
+ inline void setWOeB(WOEdge *iwoeb)
+ {
+ _woeb = iwoeb;
+ }
+
+ inline void setTa(real ta)
+ {
+ _ta = ta;
+ }
+
+ inline void setTb(real tb)
+ {
+ _tb = tb;
+ }
+
+ inline void setFront(bool iFront)
+ {
+ _front = iFront;
+ }
+
+ inline void setConfiguration(Configuration iConf)
+ {
+ _config = iConf;
+ }
};
-/* Class to store a value per vertex and a smooth edge.
- * The WXFace stores a list of these
+
+/* Class to store a value per vertex and a smooth edge.
+ * The WXFace stores a list of these
*/
class WXFace;
-class LIB_WINGED_EDGE_EXPORT WXFaceLayer{
+
+class LIB_WINGED_EDGE_EXPORT WXFaceLayer
+{
public:
- void * userdata;
- WXFace * _pWXFace;
- vector<real> _DotP;// in case of silhouette: the values obtained when computing the normal-view direction
- // dot product. _DotP[i] is this value for the vertex i for that
- // face.
- WXSmoothEdge * _pSmoothEdge;
- WXNature _Nature;
-
- //oldtmp values
- unsigned _nPosDotP; // count the number of positive dot products for vertices.
- // if this number is != 0 and !=_DotP.size() -> it is a silhouette fac
-
- unsigned _nNullDotP; // count the number of null dot products for vertices.
- unsigned _ClosestPointIndex;
- bool _viewDependant;
-
- WXFaceLayer(WXFace *iFace, WXNature iNature, bool viewDependant){
- _pWXFace = iFace;
- _pSmoothEdge = 0;
- _nPosDotP = 0;
- _nNullDotP=0;
- _Nature = iNature;
- _viewDependant = viewDependant;
- userdata = 0;
- }
- WXFaceLayer(const WXFaceLayer& iBrother){
- _pWXFace = iBrother._pWXFace;
- _pSmoothEdge = 0;
- _DotP = iBrother._DotP;
- _nPosDotP = iBrother._nPosDotP;
- _nNullDotP = iBrother._nNullDotP;
- _Nature = iBrother._Nature;
- if(0 != iBrother._pSmoothEdge)
- {
- _pSmoothEdge = new WXSmoothEdge(*(iBrother._pSmoothEdge));
- }
- _viewDependant = iBrother._viewDependant;
- userdata = 0;
- }
- virtual ~WXFaceLayer() {
- if(!_DotP.empty())
- _DotP.clear();
- if(0 != _pSmoothEdge){
- delete _pSmoothEdge;
- _pSmoothEdge = 0;
- }
- }
- inline const real dotP(int i) const {return _DotP[i];}
- inline unsigned nPosDotP() const {return _nPosDotP;}
- inline unsigned nNullDotP() const {return _nNullDotP;}
- inline int closestPointIndex() const {return _ClosestPointIndex;}
- inline Nature::EdgeNature nature() const {return _Nature;}
- inline bool hasSmoothEdge() const {if(_pSmoothEdge) return true; return false;}
- inline WXFace * getFace() {return _pWXFace;}
- inline WXSmoothEdge * getSmoothEdge() {return _pSmoothEdge;}
- inline bool isViewDependant() const {return _viewDependant;}
- inline void setClosestPointIndex(int iIndex) {_ClosestPointIndex = iIndex;}
-
- inline void removeSmoothEdge() {
- if(!_DotP.empty())
- _DotP.clear();
- if (_pSmoothEdge) {
- delete _pSmoothEdge;
- _pSmoothEdge = 0;
- }
- }
-
- /*! If one of the face layer vertex has a DotP equal
- * to 0, this method returns the vertex where it happens
- */
- unsigned int Get0VertexIndex() const ;
-
- /*! In case one of the edge of the triangle
- * is a smooth edge, this method
- * allows to retrieve the concerned edge
- */
- unsigned int GetSmoothEdgeIndex() const;
- /*! retrieves the edges of the triangle for which
- * the signs are different (a null value is not considered) for the dotp
- * values at each edge extrimity
- */
- void RetrieveCuspEdgesIndices(vector<int>& oCuspEdges);
- WXSmoothEdge * BuildSmoothEdge();
- inline void setDotP(const vector<real>& iDotP) {_DotP = iDotP;}
- inline void PushDotP(real iDotP) {
- _DotP.push_back(iDotP);
- if(iDotP > 0)
- ++_nPosDotP;
- if(iDotP == 0)
- ++_nNullDotP;
- }
- inline void ReplaceDotP(unsigned int index, real newDotP){
- _DotP[index] = newDotP;
- updateDotPInfos();
- }
- inline void updateDotPInfos() {
- _nPosDotP = 0;
- _nNullDotP = 0;
- for(vector<real>::iterator d=_DotP.begin(), dend=_DotP.end();
- d!=dend;
- ++d){
- if((*d) > 0)
- ++_nPosDotP;
- if((*d) == 0)
- ++_nNullDotP;
- }
- }
+ void *userdata;
+ WXFace *_pWXFace;
+ // in case of silhouette: the values obtained when computing the normal-view direction dot product. _DotP[i] is
+ // this value for the vertex i for that face.
+ vector<real> _DotP;
+ WXSmoothEdge *_pSmoothEdge;
+ WXNature _Nature;
+
+ //oldtmp values
+ // count the number of positive dot products for vertices.
+ // if this number is != 0 and !=_DotP.size() -> it is a silhouette fac
+ unsigned _nPosDotP;
+
+ unsigned _nNullDotP; // count the number of null dot products for vertices.
+ unsigned _ClosestPointIndex;
+ bool _viewDependant;
+
+ WXFaceLayer(WXFace *iFace, WXNature iNature, bool viewDependant)
+ {
+ _pWXFace = iFace;
+ _pSmoothEdge = NULL;
+ _nPosDotP = 0;
+ _nNullDotP = 0;
+ _Nature = iNature;
+ _viewDependant = viewDependant;
+ userdata = NULL;
+ }
+
+ WXFaceLayer(const WXFaceLayer& iBrother)
+ {
+ _pWXFace = iBrother._pWXFace;
+ _pSmoothEdge = NULL;
+ _DotP = iBrother._DotP;
+ _nPosDotP = iBrother._nPosDotP;
+ _nNullDotP = iBrother._nNullDotP;
+ _Nature = iBrother._Nature;
+ if (iBrother._pSmoothEdge) { // XXX ? It's set to null a few lines above!
+ _pSmoothEdge = new WXSmoothEdge(*(iBrother._pSmoothEdge));
+ }
+ _viewDependant = iBrother._viewDependant;
+ userdata = NULL;
+ }
+
+ virtual ~WXFaceLayer()
+ {
+ if (!_DotP.empty())
+ _DotP.clear();
+ if (_pSmoothEdge) {
+ delete _pSmoothEdge;
+ _pSmoothEdge = NULL;
+ }
+ }
+
+ inline const real dotP(int i) const
+ {
+ return _DotP[i];
+ }
+
+ inline unsigned nPosDotP() const
+ {
+ return _nPosDotP;
+ }
+
+ inline unsigned nNullDotP() const
+ {
+ return _nNullDotP;
+ }
+
+ inline int closestPointIndex() const
+ {
+ return _ClosestPointIndex;
+ }
+
+ inline Nature::EdgeNature nature() const
+ {
+ return _Nature;
+ }
+
+ inline bool hasSmoothEdge() const
+ {
+ if (_pSmoothEdge)
+ return true;
+ return false;
+ }
+
+ inline WXFace *getFace()
+ {
+ return _pWXFace;
+ }
+
+ inline WXSmoothEdge *getSmoothEdge()
+ {
+ return _pSmoothEdge;
+ }
+
+ inline bool isViewDependant() const
+ {
+ return _viewDependant;
+ }
+
+ inline void setClosestPointIndex(int iIndex)
+ {
+ _ClosestPointIndex = iIndex;
+ }
+
+ inline void removeSmoothEdge()
+ {
+ if (!_DotP.empty())
+ _DotP.clear();
+ if (_pSmoothEdge) {
+ delete _pSmoothEdge;
+ _pSmoothEdge = NULL;
+ }
+ }
+
+ /*! If one of the face layer vertex has a DotP equal to 0, this method returns the vertex where it happens */
+ unsigned int Get0VertexIndex() const;
+
+ /*! In case one of the edge of the triangle is a smooth edge, this method allows to retrieve the concerned edge */
+ unsigned int GetSmoothEdgeIndex() const;
+
+ /*! retrieves the edges of the triangle for which the signs are different (a null value is not considered) for
+ * the dotp values at each edge extrimity
+ */
+ void RetrieveCuspEdgesIndices(vector<int>& oCuspEdges);
+
+ WXSmoothEdge *BuildSmoothEdge();
+
+ inline void setDotP(const vector<real>& iDotP)
+ {
+ _DotP = iDotP;
+ }
+
+ inline void PushDotP(real iDotP)
+ {
+ _DotP.push_back(iDotP);
+ if (iDotP > 0)
+ ++_nPosDotP;
+ if (iDotP == 0)
+ ++_nNullDotP;
+ }
+
+ inline void ReplaceDotP(unsigned int index, real newDotP)
+ {
+ _DotP[index] = newDotP;
+ updateDotPInfos();
+ }
+
+ inline void updateDotPInfos()
+ {
+ _nPosDotP = 0;
+ _nNullDotP = 0;
+ for (vector<real>::iterator d = _DotP.begin(), dend = _DotP.end(); d != dend; ++d) {
+ if ((*d) > 0)
+ ++_nPosDotP;
+ if ((*d) == 0)
+ ++_nNullDotP;
+ }
+ }
};
-
class WXFace : public WFace
{
protected:
- Vec3r _center; // center of the face
- real _Z; // distance from viewpoint to the center of the face
- bool _front; // flag to tell whether the face is front facing or back facing
- real _dotp; // value obtained when computing the normal-viewpoint dot product
-
- vector<WXFaceLayer*> _SmoothLayers; // The data needed to store one or several smooth edges that traverse the face
+ Vec3r _center; // center of the face
+ real _Z; // distance from viewpoint to the center of the face
+ bool _front; // flag to tell whether the face is front facing or back facing
+ real _dotp; // value obtained when computing the normal-viewpoint dot product
+
+ vector<WXFaceLayer *> _SmoothLayers; // The data needed to store one or several smooth edges that traverse the face
+
public:
- inline WXFace() : WFace() {_Z=0.0;_front = false;}
- /*! Copy constructor */
- WXFace(WXFace& iBrother)
- : WFace(iBrother)
- {
- _center = iBrother.center();
- _Z = iBrother.Z();
- _front = iBrother.front();
- for(vector<WXFaceLayer*>::iterator wxf = iBrother._SmoothLayers.begin(), wxfend = iBrother._SmoothLayers.end();
- wxf != wxfend;
- ++wxf){
- _SmoothLayers.push_back(new WXFaceLayer(**wxf));
- }
- }
- virtual WFace * duplicate()
- {
- WXFace * clone = new WXFace(*this);
- return clone;
- }
-
- virtual ~WXFace() {
- if(!_SmoothLayers.empty()){
- for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
- wxf != wxfend;
- ++wxf){
- delete (*wxf);
- }
- _SmoothLayers.clear();
- }
- }
-
- /*! designed to build a specialized WEdge
- * for use in MakeEdge
- */
- virtual WEdge * instanciateEdge() const {return new WXEdge;}
-
- /*! accessors */
- inline Vec3r& center() {return _center;}
- inline real Z() {return _Z;}
- inline bool front() {return _front;}
- inline real dotp() {return _dotp;}
- inline bool hasSmoothEdges() const {
- for(vector<WXFaceLayer*>::const_iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
- wxf != wxfend;
- ++wxf){
- if( ((*wxf)->hasSmoothEdge())){
- return true;
- }
- }
- return false;
- }
- vector<WXFaceLayer*>& getSmoothLayers() {return _SmoothLayers;}
- /*! retrieve the smooth edges that match the Nature given as argument */
- void retrieveSmoothEdges(WXNature iNature, vector<WXSmoothEdge*>& oSmoothEdges){
- for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
- wxf != wxfend;
- ++wxf){
- if( ((*wxf)->hasSmoothEdge()) && ((*wxf)->_Nature & iNature) ){
- oSmoothEdges.push_back((*wxf)->_pSmoothEdge);
- }
- }
- }
- void retrieveSmoothEdgesLayers(WXNature iNature, vector<WXFaceLayer*>& oSmoothEdgesLayers){
- for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
- wxf != wxfend;
- ++wxf){
- if( ((*wxf)->hasSmoothEdge()) && ((*wxf)->_Nature & iNature) ){
- oSmoothEdgesLayers.push_back((*wxf));
- }
- }
- }
- void retrieveSmoothLayers(WXNature iNature, vector<WXFaceLayer*>& oSmoothLayers){
- for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
- wxf != wxfend;
- ++wxf){
- if((*wxf)->_Nature & iNature){
- oSmoothLayers.push_back(*wxf);
- }
- }
- }
- /*! modifiers */
- inline void setCenter(const Vec3r& iCenter) {_center = iCenter;}
- void ComputeCenter();
- inline void setZ(real z) {_Z = z;}
- inline void setFront(bool iFront) {_front = iFront;}
- inline void setDotP(real iDotP)
- {
- _dotp = iDotP;
- if(_dotp > 0)
- _front = true;
- else
- _front = false;
- }
- inline void AddSmoothLayer(WXFaceLayer * iLayer){
- _SmoothLayers.push_back(iLayer);
- }
- inline void Reset() {
- vector<WXFaceLayer*> layersToKeep;
- for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
- wxf != wxfend;
- ++wxf){
- if((*wxf)->isViewDependant())
- delete (*wxf);
- else
- layersToKeep.push_back(*wxf);
- }
- _SmoothLayers = layersToKeep;
- }
- /*! Clears everything */
- inline void Clear() {
- for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
- wxf != wxfend;
- ++wxf){
- delete (*wxf);
- }
- _SmoothLayers.clear();
- }
- virtual void ResetUserData() {
- WFace::ResetUserData();
- for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
- wxf != wxfend;
- ++wxf){
- (*wxf)->userdata = 0;
- }
- }
+ inline WXFace() : WFace()
+ {
+ _Z = 0.0;
+ _front = false;
+ }
+
+ /*! Copy constructor */
+ WXFace(WXFace& iBrother) : WFace(iBrother)
+ {
+ _center = iBrother.center();
+ _Z = iBrother.Z();
+ _front = iBrother.front();
+ for (vector<WXFaceLayer*>::iterator wxf = iBrother._SmoothLayers.begin(), wxfend = iBrother._SmoothLayers.end();
+ wxf != wxfend;
+ ++wxf)
+ {
+ _SmoothLayers.push_back(new WXFaceLayer(**wxf));
+ }
+ }
+
+ virtual WFace *duplicate()
+ {
+ WXFace *clone = new WXFace(*this);
+ return clone;
+ }
+
+ virtual ~WXFace()
+ {
+ if (!_SmoothLayers.empty()) {
+ for (vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
+ wxf != wxfend;
+ ++wxf)
+ {
+ delete (*wxf);
+ }
+ _SmoothLayers.clear();
+ }
+ }
+
+ /*! designed to build a specialized WEdge for use in MakeEdge */
+ virtual WEdge *instanciateEdge() const
+ {
+ return new WXEdge;
+ }
+
+ /*! accessors */
+ inline Vec3r& center()
+ {
+ return _center;
+ }
+
+ inline real Z()
+ {
+ return _Z;
+ }
+
+ inline bool front()
+ {
+ return _front;
+ }
+
+ inline real dotp()
+ {
+ return _dotp;
+ }
+
+ inline bool hasSmoothEdges() const
+ {
+ for (vector<WXFaceLayer*>::const_iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
+ wxf != wxfend;
+ ++wxf)
+ {
+ if ((*wxf)->hasSmoothEdge()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ vector<WXFaceLayer*>& getSmoothLayers()
+ {
+ return _SmoothLayers;
+ }
+
+ /*! retrieve the smooth edges that match the Nature given as argument */
+ void retrieveSmoothEdges(WXNature iNature, vector<WXSmoothEdge *>& oSmoothEdges)
+ {
+ for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
+ wxf != wxfend;
+ ++wxf)
+ {
+ if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) {
+ oSmoothEdges.push_back((*wxf)->_pSmoothEdge);
+ }
+ }
+ }
+
+ void retrieveSmoothEdgesLayers(WXNature iNature, vector<WXFaceLayer *>& oSmoothEdgesLayers)
+ {
+ for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
+ wxf != wxfend;
+ ++wxf)
+ {
+ if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) {
+ oSmoothEdgesLayers.push_back((*wxf));
+ }
+ }
+ }
+
+ void retrieveSmoothLayers(WXNature iNature, vector<WXFaceLayer *>& oSmoothLayers)
+ {
+ for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
+ wxf != wxfend;
+ ++wxf)
+ {
+ if ((*wxf)->_Nature & iNature) {
+ oSmoothLayers.push_back(*wxf);
+ }
+ }
+ }
+
+ /*! modifiers */
+ inline void setCenter(const Vec3r& iCenter)
+ {
+ _center = iCenter;
+ }
+
+ void ComputeCenter();
+
+ inline void setZ(real z)
+ {
+ _Z = z;
+ }
+
+ inline void setFront(bool iFront)
+ {
+ _front = iFront;
+ }
+
+ inline void setDotP(real iDotP)
+ {
+ _dotp = iDotP;
+ if (_dotp > 0)
+ _front = true;
+ else
+ _front = false;
+ }
+
+ inline void AddSmoothLayer(WXFaceLayer *iLayer)
+ {
+ _SmoothLayers.push_back(iLayer);
+ }
+
+ inline void Reset()
+ {
+ vector<WXFaceLayer *> layersToKeep;
+ for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
+ wxf != wxfend;
+ ++wxf)
+ {
+ if ((*wxf)->isViewDependant())
+ delete (*wxf);
+ else
+ layersToKeep.push_back(*wxf);
+ }
+ _SmoothLayers = layersToKeep;
+ }
+
+ /*! Clears everything */
+ inline void Clear()
+ {
+ for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
+ wxf != wxfend;
+ ++wxf)
+ {
+ delete (*wxf);
+ }
+ _SmoothLayers.clear();
+ }
+
+ virtual void ResetUserData()
+ {
+ WFace::ResetUserData();
+ for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
+ wxf != wxfend;
+ ++wxf)
+ {
+ (*wxf)->userdata = NULL;
+ }
+ }
};
- /**********************************/
- /* */
- /* */
- /* WXShape */
- /* */
- /* */
- /**********************************/
-
+/**********************************
+ * *
+ * *
+ * WXShape *
+ * *
+ * *
+ **********************************/
class WXShape : public WShape
{
public:
- typedef WXShape type_name;
+ typedef WXShape type_name;
+
protected:
- bool _computeViewIndependant; // flag to indicate whether the view independant stuff must be computed or not
+ bool _computeViewIndependant; // flag to indicate whether the view independant stuff must be computed or not
+
public:
- inline WXShape() : WShape() {_computeViewIndependant = true;}
- /*! copy constructor */
- inline WXShape(WXShape& iBrother)
- :WShape(iBrother)
- {
- _computeViewIndependant = iBrother._computeViewIndependant;
- }
- virtual WShape * duplicate()
- {
- WXShape *clone = new WXShape(*this);
- return clone;
- }
-
- virtual ~WXShape()
- {
- }
-
- inline bool getComputeViewIndependantFlag() const {return _computeViewIndependant;}
- inline void setComputeViewIndependantFlag(bool iFlag) {_computeViewIndependant = iFlag;}
-
- /*! designed to build a specialized WFace
- * for use in MakeFace
- */
- virtual WFace * instanciateFace() const {return new WXFace;}
-
- /*! adds a new face to the shape
- * returns the built face.
- * iVertexList
- * List of face's vertices. These vertices are
- * not added to the WShape vertex list; they are
- * supposed to be already stored when calling MakeFace.
- * The order in which the vertices are stored in the list
- * determines the face's edges orientation and (so) the
- * face orientation.
- */
- virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
-
- /*! adds a new face to the shape. The difference with
- * the previous method is that this one is designed
- * to build a WingedEdge structure for which there are
- * per vertex normals, opposed to per face normals.
- * returns the built face.
- * iVertexList
- * List of face's vertices. These vertices are
- * not added to the WShape vertex list; they are
- * supposed to be already stored when calling MakeFace.
- * The order in which the vertices are stored in the list
- * determines the face's edges orientation and (so) the
- * face orientation.
- * iNormalsList
- * The list of normals, iNormalsList[i] corresponding to the
- * normal of the vertex iVertexList[i] for that face.
- * iTexCoordsList
- * The list of tex coords, iTexCoordsList[i] corresponding to the
- * normal of the vertex iVertexList[i] for that face.
- */
- virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
-
- /*! Reset all edges and vertices flags (which might
- * have been set up on a previous pass)
- */
- virtual void Reset(){
- // Reset Edges
- vector<WEdge*>& wedges = getEdgeList();
- for(vector<WEdge*>::iterator we=wedges.begin(),weend=wedges.end();
- we!=weend;
- we++){
- ((WXEdge*)(*we))->Reset();
- }
-
- //Reset faces:
- vector<WFace*>& wfaces = GetFaceList();
- for(vector<WFace*>::iterator wf=wfaces.begin(),wfend=wfaces.end();
- wf!=wfend;
- wf++){
- ((WXFace*)(*wf))->Reset();
- }
- }
- /*! accessors */
+ inline WXShape() : WShape()
+ {
+ _computeViewIndependant = true;
+ }
+
+ /*! copy constructor */
+ inline WXShape(WXShape& iBrother) : WShape(iBrother)
+ {
+ _computeViewIndependant = iBrother._computeViewIndependant;
+ }
+
+ virtual WShape *duplicate()
+ {
+ WXShape *clone = new WXShape(*this);
+ return clone;
+ }
+
+ virtual ~WXShape() {}
+
+ inline bool getComputeViewIndependantFlag() const
+ {
+ return _computeViewIndependant;
+ }
+
+ inline void setComputeViewIndependantFlag(bool iFlag)
+ {
+ _computeViewIndependant = iFlag;
+ }
+
+ /*! designed to build a specialized WFace for use in MakeFace */
+ virtual WFace *instanciateFace() const
+ {
+ return new WXFace;
+ }
+
+ /*! adds a new face to the shape returns the built face.
+ * iVertexList
+ * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed
+ * to be already stored when calling MakeFace. The order in which the vertices are stored in the list
+ * determines the face's edges orientation and (so) the face orientation.
+ */
+ virtual WFace *MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
+
+ /*! adds a new face to the shape. The difference with the previous method is that this one is designed to build
+ * a WingedEdge structure for which there are per vertex normals, opposed to per face normals.
+ * returns the built face.
+ * iVertexList
+ * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be
+ * already stored when calling MakeFace.
+ * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the
+ * face orientation.
+ * iNormalsList
+ * The list of normals, iNormalsList[i] corresponding to the normal of the vertex iVertexList[i] for that face.
+ * iTexCoordsList
+ * The list of tex coords, iTexCoordsList[i] corresponding to the normal of the vertex iVertexList[i] for
+ * that face.
+ */
+ virtual WFace *MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
+ vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
+
+ /*! Reset all edges and vertices flags (which might have been set up on a previous pass) */
+ virtual void Reset()
+ {
+ // Reset Edges
+ vector<WEdge *>& wedges = getEdgeList();
+ for (vector<WEdge *>::iterator we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
+ ((WXEdge*)(*we))->Reset();
+ }
+
+ //Reset faces:
+ vector<WFace *>& wfaces = GetFaceList();
+ for (vector<WFace *>::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; ++wf) {
+ ((WXFace*)(*wf))->Reset();
+ }
+ }
+ /*! accessors */
};
/*
-
- #############################################
- #############################################
- #############################################
- ###### ######
- ###### I M P L E M E N T A T I O N ######
- ###### ######
- #############################################
- #############################################
- #############################################
-
+
+#############################################
+#############################################
+#############################################
+###### ######
+###### I M P L E M E N T A T I O N ######
+###### ######
+#############################################
+#############################################
+#############################################
+
*/
/* for inline functions */
-bool WXVertex::isFeature()
-{
- int counter = 0;
- vector<WEdge*>& vedges = GetEdges();
- for(vector<WEdge*>::iterator ve=vedges.begin(), vend=vedges.end();
- ve!=vend;
- ve++)
- {
- if(((WXEdge*)(*ve))->nature() != Nature::NO_FEATURE)
- counter++;
- }
-
- if((counter == 1) || (counter > 2))
- return true;
-
- return false;
+bool WXVertex::isFeature()
+{
+ int counter = 0;
+ vector<WEdge *>& vedges = GetEdges();
+ for (vector<WEdge *>::iterator ve = vedges.begin(), vend = vedges.end(); ve != vend; ++ve) {
+ if (((WXEdge *)(*ve))->nature() != Nature::NO_FEATURE)
+ counter++;
+ }
+
+ if ((counter == 1) || (counter > 2))
+ return true;
+ return false;
}
-
-#endif
+#endif // __FREESTYLE_WX_EDGE_H__ \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp
index b29f0c7e9ee..51e93f34fa3 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp
@@ -1,46 +1,58 @@
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/winged_edge/WSBuilder.cpp
+ * \ingroup freestyle
+ * \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info
+ * (silhouette etc...)) structure from a polygonal model
+ * \author Stephane Grabli
+ * \date 28/05/2003
+ */
-#include "WXEdgeBuilder.h"
#include "WXEdge.h"
+#include "WXEdgeBuilder.h"
void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
{
- if (_pRenderMonitor && _pRenderMonitor->testBreak())
- return;
- WXShape *shape = new WXShape;
- buildWShape(*shape, ifs);
- shape->setId(ifs.getId().getFirst());
- shape->setName(ifs.getName());
- //ifs.setId(shape->GetId());
+ if (_pRenderMonitor && _pRenderMonitor->testBreak())
+ return;
+ WXShape *shape = new WXShape;
+ buildWShape(*shape, ifs);
+ shape->setId(ifs.getId().getFirst());
+ shape->setName(ifs.getName());
+ //ifs.setId(shape->GetId());
}
-void WXEdgeBuilder::buildWVertices(WShape& shape,
- const real *vertices,
- unsigned vsize) {
- WXVertex *vertex;
- for (unsigned i = 0; i < vsize; i += 3) {
- vertex = new WXVertex(Vec3r(vertices[i],
- vertices[i + 1],
- vertices[i + 2]));
- vertex->setId(i / 3);
- shape.AddVertex(vertex);
- }
-}
+void WXEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize)
+{
+ WXVertex *vertex;
+ for (unsigned int i = 0; i < vsize; i += 3) {
+ vertex = new WXVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
+ vertex->setId(i / 3);
+ shape.AddVertex(vertex);
+ }
+} \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
index b646d66a285..91e9b389f7c 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
+++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
@@ -1,51 +1,54 @@
-#ifndef WXEDGEBUILDER_H
-# define WXEDGEBUILDER_H
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
-//
-// Filename : WSBuilder.h
-// Author(s) : Stephane Grabli
-// Purpose : Class inherited from WingedEdgeBuilder and
-// designed to build a WX (WingedEdge + extended info(silhouette etc...))
-// structure from a polygonal model
-// Date of creation : 28/05/03
-//
-///////////////////////////////////////////////////////////////////////////////
+#ifndef __FREESTYLE_WX_EDGE_BUILDER_H__
+#define __FREESTYLE_WX_EDGE_BUILDER_H__
+/** \file blender/freestyle/intern/winged_edge/WSBuilder.h
+ * \ingroup freestyle
+ * \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info
+ * (silhouette etc...)) structure from a polygonal model
+ * \author Stephane Grabli
+ * \date 28/05/2003
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+#include "WingedEdgeBuilder.h"
-# include "WingedEdgeBuilder.h"
-# include "../scene_graph/IndexedFaceSet.h"
+#include "../scene_graph/IndexedFaceSet.h"
class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder
{
public:
WXEdgeBuilder() : WingedEdgeBuilder() {}
- virtual ~WXEdgeBuilder() {}
- VISIT_DECL(IndexedFaceSet)
+ virtual ~WXEdgeBuilder() {}
+ VISIT_DECL(IndexedFaceSet)
protected:
- virtual void buildWVertices(WShape& shape,
- const real *vertices,
- unsigned vsize);
+ virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
};
-#endif // WXEDGEBUILDER_H
+#endif // __FREESTYLE_WX_EDGE_BUILDER_H__ \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
index e56ac0f9c42..4ef34bbe3ee 100644
--- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
@@ -1,386 +1,373 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
+ * \ingroup freestyle
+ * \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes
+ * of a scene graph
+ * \author Stephane Grabli
+ * \date 28/05/2003
+ */
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+#include <set>
+
+#include "WingedEdgeBuilder.h"
#include "../geometry/GeomUtils.h"
+
#include "../scene_graph/NodeShape.h"
-#include "WingedEdgeBuilder.h"
-#include <set>
+
using namespace std;
-void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) {
- if (_pRenderMonitor && _pRenderMonitor->testBreak())
- return;
- WShape *shape = new WShape;
- buildWShape(*shape, ifs);
- shape->setId(ifs.getId().getFirst());
- //ifs.setId(shape->GetId());
+void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
+{
+ if (_pRenderMonitor && _pRenderMonitor->testBreak())
+ return;
+ WShape *shape = new WShape;
+ buildWShape(*shape, ifs);
+ shape->setId(ifs.getId().getFirst());
+ //ifs.setId(shape->GetId());
}
-void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) {
- //Sets the current material to iShapeode->material:
- _current_frs_material = &(ns.frs_material());
+void WingedEdgeBuilder::visitNodeShape(NodeShape& ns)
+{
+ //Sets the current material to iShapeode->material:
+ _current_frs_material = &(ns.frs_material());
}
-void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) {
- if(!_current_matrix) {
- _current_matrix = new Matrix44r(tn.matrix());
- return;
- }
+void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn)
+{
+ if (!_current_matrix) {
+ _current_matrix = new Matrix44r(tn.matrix());
+ return;
+ }
- _matrices_stack.push_back(_current_matrix);
- Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix());
- _current_matrix = new_matrix;
+ _matrices_stack.push_back(_current_matrix);
+ Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix());
+ _current_matrix = new_matrix;
}
-void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) {
- if(_current_matrix)
- delete _current_matrix;
+void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&)
+{
+ if (_current_matrix)
+ delete _current_matrix;
- if(_matrices_stack.empty()) {
- _current_matrix = NULL;
- return;
- }
+ if (_matrices_stack.empty()) {
+ _current_matrix = NULL;
+ return;
+ }
- _current_matrix = _matrices_stack.back();
- _matrices_stack.pop_back();
+ _current_matrix = _matrices_stack.back();
+ _matrices_stack.pop_back();
}
-void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
- unsigned vsize = ifs.vsize();
- unsigned nsize = ifs.nsize();
- //soc unused - unsigned tsize = ifs.tsize();
+void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs)
+{
+ unsigned int vsize = ifs.vsize();
+ unsigned int nsize = ifs.nsize();
+ //soc unused - unsigned tsize = ifs.tsize();
- const real* vertices = ifs.vertices();
- const real* normals = ifs.normals();
- const real* texCoords = ifs.texCoords();
+ const real *vertices = ifs.vertices();
+ const real *normals = ifs.normals();
+ const real *texCoords = ifs.texCoords();
- real* new_vertices;
- real* new_normals;
+ real *new_vertices;
+ real *new_normals;
new_vertices = new real[vsize];
new_normals = new real[nsize];
- // transform coordinates from local to world system
- if(_current_matrix) {
- transformVertices(vertices, vsize, *_current_matrix, new_vertices);
- transformNormals(normals, nsize, *_current_matrix, new_normals);
- }
- else {
- memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices));
- memcpy(new_normals, normals, nsize * sizeof(*new_normals));
- }
+ // transform coordinates from local to world system
+ if (_current_matrix) {
+ transformVertices(vertices, vsize, *_current_matrix, new_vertices);
+ transformNormals(normals, nsize, *_current_matrix, new_normals);
+ }
+ else {
+ memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices));
+ memcpy(new_normals, normals, nsize * sizeof(*new_normals));
+ }
- const IndexedFaceSet::TRIANGLES_STYLE* faceStyle = ifs.trianglesStyle();
+ const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle();
vector<FrsMaterial> frs_materials;
- if(ifs.msize()){
- const FrsMaterial*const* mats = ifs.frs_materials();
- for(unsigned i=0; i<ifs.msize(); ++i)
+ if (ifs.msize()) {
+ const FrsMaterial *const *mats = ifs.frs_materials();
+ for (unsigned i = 0; i < ifs.msize(); ++i)
frs_materials.push_back(*(mats[i]));
shape.setFrsMaterials(frs_materials);
}
- // const FrsMaterial * mat = (ifs.frs_material());
- // if (mat)
- // shape.setFrsMaterial(*mat);
- // else if(_current_frs_material)
- // shape.setFrsMaterial(*_current_frs_material);
-
- const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();
-
- // sets the current WShape to shape
- _current_wshape = &shape;
-
- // create a WVertex for each vertex
- buildWVertices(shape, new_vertices, vsize);
-
- const unsigned* vindices = ifs.vindices();
- const unsigned* nindices = ifs.nindices();
- const unsigned* tindices = 0;
- if(ifs.tsize()){
- tindices = ifs.tindices();
- }
-
- const unsigned *mindices = 0;
- if(ifs.msize())
+#if 0
+ const FrsMaterial *mat = (ifs.frs_material());
+ if (mat)
+ shape.setFrsMaterial(*mat);
+ else if (_current_frs_material)
+ shape.setFrsMaterial(*_current_frs_material);
+#endif
+ const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();
+
+ // sets the current WShape to shape
+ _current_wshape = &shape;
+
+ // create a WVertex for each vertex
+ buildWVertices(shape, new_vertices, vsize);
+
+ const unsigned int *vindices = ifs.vindices();
+ const unsigned int *nindices = ifs.nindices();
+ const unsigned int *tindices = NULL;
+ if (ifs.tsize()) {
+ tindices = ifs.tindices();
+ }
+
+ const unsigned int *mindices = NULL;
+ if (ifs.msize())
mindices = ifs.mindices();
- const unsigned* numVertexPerFace = ifs.numVertexPerFaces();
- const unsigned numfaces = ifs.numFaces();
-
- for (unsigned index = 0; index < numfaces; index++) {
- switch(faceStyle[index]) {
- case IndexedFaceSet::TRIANGLE_STRIP:
- buildTriangleStrip(new_vertices,
- new_normals,
- frs_materials,
- texCoords,
- faceEdgeMarks,
- vindices,
- nindices,
- mindices,
- tindices,
- numVertexPerFace[index]);
- break;
- case IndexedFaceSet::TRIANGLE_FAN:
- buildTriangleFan(new_vertices,
- new_normals,
- frs_materials,
- texCoords,
- faceEdgeMarks,
- vindices,
- nindices,
- mindices,
- tindices,
- numVertexPerFace[index]);
- break;
- case IndexedFaceSet::TRIANGLES:
- buildTriangles(new_vertices,
- new_normals,
- frs_materials,
- texCoords,
- faceEdgeMarks,
- vindices,
- nindices,
- mindices,
- tindices,
- numVertexPerFace[index]);
- break;
- }
- vindices += numVertexPerFace[index];
- nindices += numVertexPerFace[index];
- if(mindices)
+ const unsigned int *numVertexPerFace = ifs.numVertexPerFaces();
+ const unsigned int numfaces = ifs.numFaces();
+
+ for (unsigned int index = 0; index < numfaces; index++) {
+ switch (faceStyle[index]) {
+ case IndexedFaceSet::TRIANGLE_STRIP:
+ buildTriangleStrip(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
+ nindices, mindices, tindices, numVertexPerFace[index]);
+ break;
+ case IndexedFaceSet::TRIANGLE_FAN:
+ buildTriangleFan(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
+ nindices, mindices, tindices, numVertexPerFace[index]);
+ break;
+ case IndexedFaceSet::TRIANGLES:
+ buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
+ nindices, mindices, tindices, numVertexPerFace[index]);
+ break;
+ }
+ vindices += numVertexPerFace[index];
+ nindices += numVertexPerFace[index];
+ if (mindices)
mindices += numVertexPerFace[index];
- if(tindices)
- tindices += numVertexPerFace[index];
- faceEdgeMarks++;
- }
-
- delete[] new_vertices;
- delete[] new_normals;
-
- // compute bbox
- shape.ComputeBBox();
- // compute mean edge size:
- shape.ComputeMeanEdgeSize();
-
- // Parse the built winged-edge shape to update post-flags
- set<Vec3r> normalsSet;
- vector<WVertex*>& wvertices = shape.getVertexList();
- for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end();
- wv!=wvend;
- ++wv){
- if((*wv)->isBoundary())
- continue;
- if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
- continue;
- normalsSet.clear();
- WVertex::face_iterator fit = (*wv)->faces_begin();
- WVertex::face_iterator fitend = (*wv)->faces_end();
- while(fit!=fitend){
- WFace *face = *fit;
- normalsSet.insert(face->GetVertexNormal(*wv));
- if(normalsSet.size()!=1){
- break;
- }
- ++fit;
- }
- if(normalsSet.size()!=1){
- (*wv)->setSmooth(false);
- }
- }
- // Adds the new WShape to the WingedEdge structure
- _winged_edge->addWShape(&shape);
+ if (tindices)
+ tindices += numVertexPerFace[index];
+ faceEdgeMarks++;
+ }
+
+ delete[] new_vertices;
+ delete[] new_normals;
+
+ // compute bbox
+ shape.ComputeBBox();
+ // compute mean edge size:
+ shape.ComputeMeanEdgeSize();
+
+ // Parse the built winged-edge shape to update post-flags
+ set<Vec3r> normalsSet;
+ vector<WVertex *>& wvertices = shape.getVertexList();
+ for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
+ if ((*wv)->isBoundary())
+ continue;
+ if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
+ continue;
+ normalsSet.clear();
+ WVertex::face_iterator fit = (*wv)->faces_begin();
+ WVertex::face_iterator fitend = (*wv)->faces_end();
+ for (; fit != fitend; ++fit) {
+ WFace *face = *fit;
+ normalsSet.insert(face->GetVertexNormal(*wv));
+ if (normalsSet.size() != 1) {
+ break;
+ }
+ }
+ if (normalsSet.size() !=1 ) {
+ (*wv)->setSmooth(false);
+ }
+ }
+ // Adds the new WShape to the WingedEdge structure
+ _winged_edge->addWShape(&shape);
}
-void WingedEdgeBuilder::buildWVertices(WShape& shape,
- const real *vertices,
- unsigned vsize) {
- WVertex *vertex;
- for (unsigned i = 0; i < vsize; i += 3) {
- vertex = new WVertex(Vec3r(vertices[i],
- vertices[i + 1],
- vertices[i + 2]));
- vertex->setId(i / 3);
- shape.AddVertex(vertex);
- }
+void WingedEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize)
+{
+ WVertex *vertex;
+ for (unsigned int i = 0; i < vsize; i += 3) {
+ vertex = new WVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
+ vertex->setId(i / 3);
+ shape.AddVertex(vertex);
+ }
}
-void WingedEdgeBuilder::buildTriangleStrip( const real *vertices,
- const real *normals,
- vector<FrsMaterial>& iMaterials,
- const real *texCoords,
- const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
- const unsigned *vindices,
- const unsigned *nindices,
- const unsigned *mindices,
- const unsigned *tindices,
- const unsigned nvertices) {
- unsigned nDoneVertices = 2; // number of vertices already treated
- unsigned nTriangle = 0; // number of the triangle currently being treated
- //int nVertex = 0; // vertex number
-
- WShape* currentShape = _current_wshape; // the current shape being built
- vector<WVertex *> triangleVertices;
- vector<Vec3r> triangleNormals;
- vector<Vec2r> triangleTexCoords;
- vector<bool> triangleFaceEdgeMarks;
-
- while(nDoneVertices < nvertices)
- {
- //clear the vertices list:
- triangleVertices.clear();
- //Then rebuild it:
- if(0 == nTriangle%2) // if nTriangle is even
- {
- triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]);
- triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+1]/3]);
- triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]);
-
- triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2]));
- triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]],normals[nindices[nTriangle+1]+1],normals[nindices[nTriangle+1]+2]));
- triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]], normals[nindices[nTriangle+2]+1], normals[nindices[nTriangle+2]+2]));
-
- if(texCoords){
- triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1]));
- triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]],texCoords[tindices[nTriangle+1]+1]));
- triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]], texCoords[tindices[nTriangle+2]+1]));
- }
- }
- else // if nTriangle is odd
- {
- triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]);
- triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]);
- triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+1]/3]);
-
- triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2]));
- triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]],normals[nindices[nTriangle+2]+1],normals[nindices[nTriangle+2]+2]));
- triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]], normals[nindices[nTriangle+1]+1], normals[nindices[nTriangle+1]+2]));
-
- if(texCoords){
- triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1]));
- triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]],texCoords[tindices[nTriangle+2]+1]));
- triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]], texCoords[tindices[nTriangle+1]+1]));
- }
- }
- triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::FACE_MARK) != 0);
- triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
- triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
- triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
- if(mindices)
- currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[nTriangle/3]);
- else
+void WingedEdgeBuilder::buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
+ const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
+ const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
+ const unsigned *tindices, const unsigned nvertices)
+{
+ unsigned nDoneVertices = 2; // number of vertices already treated
+ unsigned nTriangle = 0; // number of the triangle currently being treated
+ //int nVertex = 0; // vertex number
+
+ WShape *currentShape = _current_wshape; // the current shape being built
+ vector<WVertex *> triangleVertices;
+ vector<Vec3r> triangleNormals;
+ vector<Vec2r> triangleTexCoords;
+ vector<bool> triangleFaceEdgeMarks;
+
+ while (nDoneVertices < nvertices) {
+ //clear the vertices list:
+ triangleVertices.clear();
+ //Then rebuild it:
+ if (0 == nTriangle % 2) { // if nTriangle is even
+ triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
+ triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
+ triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
+
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
+ normals[nindices[nTriangle] + 2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
+ normals[nindices[nTriangle + 1] + 2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
+ normals[nindices[nTriangle + 2] + 2]));
+
+ if (texCoords) {
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
+ texCoords[tindices[nTriangle + 1] + 1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
+ texCoords[tindices[nTriangle + 2] + 1]));
+ }
+ }
+ else { // if nTriangle is odd
+ triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
+ triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
+ triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
+
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
+ normals[nindices[nTriangle] + 2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
+ normals[nindices[nTriangle + 2] + 2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
+ normals[nindices[nTriangle + 1] + 2]));
+
+ if (texCoords) {
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
+ texCoords[tindices[nTriangle + 2] + 1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
+ texCoords[tindices[nTriangle + 1] + 1]));
+ }
+ }
+ triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != 0);
+ triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
+ triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
+ triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
+ if (mindices) {
+ currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
+ mindices[nTriangle / 3]);
+ }
+ else {
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
- nDoneVertices++; // with a strip, each triangle is one vertex more
- nTriangle++;
- }
+ }
+ nDoneVertices++; // with a strip, each triangle is one vertex more
+ nTriangle++;
+ }
}
-void WingedEdgeBuilder::buildTriangleFan( const real *vertices,
- const real *normals,
- vector<FrsMaterial>& iMaterials,
- const real *texCoords,
- const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
- const unsigned *vindices,
- const unsigned *nindices,
- const unsigned *mindices,
- const unsigned *tindices,
- const unsigned nvertices) {
- // Nothing to be done
+void WingedEdgeBuilder::buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
+ const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
+ const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
+ const unsigned *tindices, const unsigned nvertices)
+{
+ // Nothing to be done
}
-void WingedEdgeBuilder::buildTriangles(const real *vertices,
- const real *normals,
- vector<FrsMaterial>& iMaterials,
- const real *texCoords,
- const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
- const unsigned *vindices,
- const unsigned *nindices,
- const unsigned *mindices,
- const unsigned *tindices,
- const unsigned nvertices) {
- WShape * currentShape = _current_wshape; // the current shape begin built
- vector<WVertex *> triangleVertices;
- vector<Vec3r> triangleNormals;
- vector<Vec2r> triangleTexCoords;
- vector<bool> triangleFaceEdgeMarks;
-
- // Each triplet of vertices is considered as an independent triangle
- for(unsigned i = 0; i < nvertices / 3; i++)
- {
- triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i]/3]);
- triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+1]/3]);
- triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+2]/3]);
-
- triangleNormals.push_back(Vec3r(normals[nindices[3*i]],normals[nindices[3*i]+1], normals[nindices[3*i]+2]));
- triangleNormals.push_back(Vec3r(normals[nindices[3*i+1]],normals[nindices[3*i+1]+1],normals[nindices[3*i+1]+2]));
- triangleNormals.push_back(Vec3r(normals[nindices[3*i+2]], normals[nindices[3*i+2]+1], normals[nindices[3*i+2]+2]));
-
- if(texCoords){
- triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i]],texCoords[tindices[3*i]+1]));
- triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+1]],texCoords[tindices[3*i+1]+1]));
- triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+2]], texCoords[tindices[3*i+2]+1]));
- }
-
- triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
- triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
- triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
- triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
- }
- if(mindices)
- currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]);
+void WingedEdgeBuilder::buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
+ const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
+ const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
+ const unsigned *tindices, const unsigned nvertices)
+{
+ WShape *currentShape = _current_wshape; // the current shape begin built
+ vector<WVertex *> triangleVertices;
+ vector<Vec3r> triangleNormals;
+ vector<Vec2r> triangleTexCoords;
+ vector<bool> triangleFaceEdgeMarks;
+
+ // Each triplet of vertices is considered as an independent triangle
+ for (unsigned int i = 0; i < nvertices / 3; i++) {
+ triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]);
+ triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]);
+ triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]);
+
+ triangleNormals.push_back(Vec3r(normals[nindices[3 * i]], normals[nindices[3 * i] + 1],
+ normals[nindices[3 * i] + 2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 1]], normals[nindices[3 * i + 1] + 1],
+ normals[nindices[3 * i + 1] + 2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 2]], normals[nindices[3 * i + 2] + 1],
+ normals[nindices[3 * i + 2] + 2]));
+
+ if (texCoords) {
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 2]], texCoords[tindices[3 * i + 2] + 1]));
+ }
+
+ triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
+ triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
+ triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
+ triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
+ }
+ if (mindices)
+ currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
+ mindices[0]);
else
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
-
}
-void WingedEdgeBuilder::transformVertices(const real *vertices,
- unsigned vsize,
- const Matrix44r& transform,
- real *res) {
- const real *v = vertices;
- real *pv = res;
-
- for (unsigned i = 0; i < vsize / 3; i++) {
- HVec3r hv_tmp(v[0], v[1], v[2]);
- HVec3r hv(transform * hv_tmp);
- for (unsigned j = 0; j < 3; j++)
- pv[j] = hv[j] / hv[3];
- v += 3;
- pv += 3;
- }
+void WingedEdgeBuilder::transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res)
+{
+ const real *v = vertices;
+ real *pv = res;
+
+ for (unsigned int i = 0; i < vsize / 3; i++) {
+ HVec3r hv_tmp(v[0], v[1], v[2]);
+ HVec3r hv(transform * hv_tmp);
+ for (unsigned int j = 0; j < 3; j++)
+ pv[j] = hv[j] / hv[3];
+ v += 3;
+ pv += 3;
+ }
}
-void WingedEdgeBuilder::transformNormals(const real *normals,
- unsigned nsize,
- const Matrix44r& transform,
- real* res) {
- const real *n = normals;
- real *pn = res;
-
- for (unsigned i = 0; i < nsize / 3; i++) {
- Vec3r hn(n[0], n[1], n[2]);
- hn = GeomUtils::rotateVector(transform, hn);
- for (unsigned j = 0; j < 3; j++)
- pn[j] = hn[j];
- n += 3;
- pn += 3;
- }
-}
+void WingedEdgeBuilder::transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res)
+{
+ const real *n = normals;
+ real *pn = res;
+
+ for (unsigned int i = 0; i < nsize / 3; i++) {
+ Vec3r hn(n[0], n[1], n[2]);
+ hn = GeomUtils::rotateVector(transform, hn);
+ for (unsigned int j = 0; j < 3; j++)
+ pn[j] = hn[j];
+ n += 3;
+ pn += 3;
+ }
+} \ No newline at end of file
diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
index 972d67355d2..cf32c1191b2 100644
--- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
+++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
@@ -1,171 +1,157 @@
-//
-// Filename : WingedEdgeBuilder.h
-// Author(s) : Stephane Grabli
-// Purpose : Class to render a WingedEdge data structure
-// from a polyhedral data structure organized in
-// nodes of a scene graph
-// Date of creation : 28/05/03
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef WINGED_EDGE_BUILDER_H
-# define WINGED_EDGE_BUILDER_H
-
-# include "../system/FreestyleConfig.h"
-# include "../system/RenderMonitor.h"
-# include "../scene_graph/SceneVisitor.h"
-# include "WEdge.h"
-# include "../scene_graph/IndexedFaceSet.h"
-# include "../scene_graph/NodeTransform.h"
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_WINGED_EDGE_BUILDER_H__
+#define __FREESTYLE_WINGED_EDGE_BUILDER_H__
+
+/** \file blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
+ * \ingroup freestyle
+ * \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes
+ * of a scene graph
+ * \author Stephane Grabli
+ * \date 28/05/2003
+ */
+
+#include "WEdge.h"
+
+#include "../scene_graph/IndexedFaceSet.h"
+#include "../scene_graph/NodeTransform.h"
+#include "../scene_graph/SceneVisitor.h"
+
+#include "../system/FreestyleConfig.h"
+#include "../system/RenderMonitor.h"
class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
{
- public:
-
- inline WingedEdgeBuilder() : SceneVisitor() {
- _current_wshape = NULL;
- _current_frs_material = NULL;
- _current_matrix = NULL;
- _winged_edge = new WingedEdge; // Not deleted by the destructor
- _pRenderMonitor = NULL;
- }
-
- virtual ~WingedEdgeBuilder() {
- for (vector<Matrix44r*>::iterator it = _matrices_stack.begin();
- it != _matrices_stack.end();
- it++)
- delete *it;
- _matrices_stack.clear();
- }
-
- VISIT_DECL(IndexedFaceSet)
- VISIT_DECL(NodeShape)
- VISIT_DECL(NodeTransform)
-
- virtual void visitNodeTransformAfter(NodeTransform&);
-
- //
- // Accessors
- //
- /////////////////////////////////////////////////////////////////////////////
-
- inline WingedEdge* getWingedEdge() {
- return _winged_edge;
- }
-
- inline WShape* getCurrentWShape() {
- return _current_wshape;
- }
-
- inline FrsMaterial* getCurrentFrsMaterial() {
- return _current_frs_material;
- }
-
- inline Matrix44r* getCurrentMatrix() {
- return _current_matrix;
- }
-
- //
- // Modifiers
- //
- /////////////////////////////////////////////////////////////////////////////
-
- inline void setCurrentWShape(WShape* wshape) {
- _current_wshape = wshape;
- }
-
- inline void setCurrentFrsMaterial(FrsMaterial* mat) {
- _current_frs_material = mat;
- }
-
- // inline void setCurrentMatrix(Matrix44r* matrix) {
- // _current_matrix = matrix;
- // }
-
- inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {
- _pRenderMonitor = iRenderMonitor;
- }
-
- protected:
-
- virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs);
- virtual void buildWVertices(WShape& shape,
- const real *vertices,
- unsigned vsize);
-
- RenderMonitor *_pRenderMonitor;
-
- private:
-
- void buildTriangleStrip(const real *vertices,
- const real *normals,
- vector<FrsMaterial>& iMaterials,
- const real *texCoords,
- const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
- const unsigned *vindices,
- const unsigned *nindices,
- const unsigned *mindices,
- const unsigned *tindices,
- const unsigned nvertices);
-
- void buildTriangleFan(const real *vertices,
- const real *normals,
- vector<FrsMaterial>& iMaterials,
- const real *texCoords,
- const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
- const unsigned *vindices,
- const unsigned *nindices,
- const unsigned *mindices,
- const unsigned *tindices,
- const unsigned nvertices);
-
- void buildTriangles(const real *vertices,
- const real *normals,
- vector<FrsMaterial>& iMaterials,
- const real *texCoords,
- const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
- const unsigned *vindices,
- const unsigned *nindices,
- const unsigned *mindices,
- const unsigned *tindices,
- const unsigned nvertices);
-
- void transformVertices(const real *vertices,
- unsigned vsize,
- const Matrix44r& transform,
- real *res);
-
- void transformNormals(const real *normals,
- unsigned nsize,
- const Matrix44r& transform,
- real *res);
-
- WShape* _current_wshape;
- FrsMaterial* _current_frs_material;
- WingedEdge* _winged_edge;
- Matrix44r* _current_matrix;
- vector<Matrix44r*> _matrices_stack;
+public:
+ inline WingedEdgeBuilder() : SceneVisitor()
+ {
+ _current_wshape = NULL;
+ _current_frs_material = NULL;
+ _current_matrix = NULL;
+ _winged_edge = new WingedEdge; // Not deleted by the destructor
+ _pRenderMonitor = NULL;
+ }
+
+ virtual ~WingedEdgeBuilder()
+ {
+ for (vector<Matrix44r*>::iterator it = _matrices_stack.begin(); it != _matrices_stack.end(); ++it)
+ delete *it;
+ _matrices_stack.clear();
+ }
+
+ VISIT_DECL(IndexedFaceSet)
+ VISIT_DECL(NodeShape)
+ VISIT_DECL(NodeTransform)
+
+ virtual void visitNodeTransformAfter(NodeTransform&);
+
+ //
+ // Accessors
+ //
+ /////////////////////////////////////////////////////////////////////////////
+
+ inline WingedEdge *getWingedEdge()
+ {
+ return _winged_edge;
+ }
+
+ inline WShape *getCurrentWShape()
+ {
+ return _current_wshape;
+ }
+
+ inline FrsMaterial *getCurrentFrsMaterial()
+ {
+ return _current_frs_material;
+ }
+
+ inline Matrix44r *getCurrentMatrix()
+ {
+ return _current_matrix;
+ }
+
+ //
+ // Modifiers
+ //
+ /////////////////////////////////////////////////////////////////////////////
+
+ inline void setCurrentWShape(WShape *wshape)
+ {
+ _current_wshape = wshape;
+ }
+
+ inline void setCurrentFrsMaterial(FrsMaterial *mat)
+ {
+ _current_frs_material = mat;
+ }
+
+#if 0
+ inline void setCurrentMatrix(Matrix44r *matrix)
+ {
+ _current_matrix = matrix;
+ }
+#endif
+
+ inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {
+ _pRenderMonitor = iRenderMonitor;
+ }
+
+protected:
+ virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs);
+ virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
+
+ RenderMonitor *_pRenderMonitor;
+
+private:
+ void buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
+ const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
+ const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
+ const unsigned *tindices, const unsigned nvertices);
+
+ void buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
+ const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
+ const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
+ const unsigned *tindices, const unsigned nvertices);
+
+ void buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
+ const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
+ const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
+ const unsigned *tindices, const unsigned nvertices);
+
+ void transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res);
+
+ void transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res);
+
+ WShape *_current_wshape;
+ FrsMaterial *_current_frs_material;
+ WingedEdge *_winged_edge;
+ Matrix44r *_current_matrix;
+ vector<Matrix44r *> _matrices_stack;
};
-#endif // WINGED_EDGE_BUILDER_H
+#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__ \ No newline at end of file