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! :)
This commit is contained in:
2013-01-02 01:55:30 +00:00
parent 520ab93465
commit 699da2fb0d
58 changed files with 19076 additions and 17097 deletions

View File

@@ -1,42 +1,48 @@
// /*
// Filename : ArbitraryGridDensityProvider.cpp * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-2-5 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \brief Class to define a cell grid surrounding the projected image of a scene
// with this source distribution. * \author Alexander Beels
// * \date 2011-2-5
// 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 "ArbitraryGridDensityProvider.h" #include "ArbitraryGridDensityProvider.h"
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells) ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4],
unsigned numCells)
: GridDensityProvider(source), numCells(numCells) : GridDensityProvider(source), numCells(numCells)
{ {
initialize (proscenium); initialize (proscenium);
} }
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numCells) ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, unsigned numCells)
: GridDensityProvider(source), numCells(numCells) : GridDensityProvider(source), numCells(numCells)
{ {
real proscenium[4]; real proscenium[4];
@@ -70,7 +76,7 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl; cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
// Make sure the grid exceeds the proscenium by a small amount // Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1; float safetyZone = 0.1f;
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) { if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize; _cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
} }
@@ -91,12 +97,15 @@ ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigne
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)); 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)); return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
} }
@@ -105,4 +114,3 @@ auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensit
{ {
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells)); return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
} }

View File

@@ -1,46 +1,52 @@
// /*
// Filename : ArbitraryGridDensityProvider.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-2-5 * 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__
// /** \file blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2011-2-5
// 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
#include "GridDensityProvider.h" #include "GridDensityProvider.h"
class ArbitraryGridDensityProvider : public GridDensityProvider { class ArbitraryGridDensityProvider : public GridDensityProvider
{
// Disallow copying and assignment // Disallow copying and assignment
ArbitraryGridDensityProvider(const ArbitraryGridDensityProvider& other); ArbitraryGridDensityProvider(const ArbitraryGridDensityProvider& other);
ArbitraryGridDensityProvider& operator=(const ArbitraryGridDensityProvider& other); ArbitraryGridDensityProvider& operator=(const ArbitraryGridDensityProvider& other);
public: public:
ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells); 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); ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells);
virtual ~ArbitraryGridDensityProvider(); virtual ~ArbitraryGridDensityProvider();
@@ -51,17 +57,19 @@ private:
void initialize (const real proscenium[4]); void initialize (const real proscenium[4]);
}; };
class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory { class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory
{
public: public:
ArbitraryGridDensityProviderFactory(unsigned numCells); ArbitraryGridDensityProviderFactory(unsigned numCells);
~ArbitraryGridDensityProviderFactory(); ~ArbitraryGridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]); 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); auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected: protected:
unsigned numCells; unsigned numCells;
}; };
#endif // ARBITRARYGRIDDENSITYPROVIDER_H #endif // __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__

View File

@@ -1,42 +1,48 @@
// /*
// Filename : AverageAreaGridDensityProvider.cpp * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-2-9 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \brief Class to define a cell grid surrounding the projected image of a scene
// with this source distribution. * \author Alexander Beels
// * \date 2011-2-9
// 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 "AverageAreaGridDensityProvider.h" #include "AverageAreaGridDensityProvider.h"
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor) AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4],
real sizeFactor)
: GridDensityProvider(source) : GridDensityProvider(source)
{ {
initialize (proscenium, sizeFactor); initialize (proscenium, sizeFactor);
} }
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, real sizeFactor) AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, real sizeFactor)
: GridDensityProvider(source) : GridDensityProvider(source)
{ {
real proscenium[4]; real proscenium[4];
@@ -82,7 +88,7 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl; cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
// Make sure the grid exceeds the proscenium by a small amount // Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1; float safetyZone = 0.1f;
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) { if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize; _cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
} }
@@ -103,12 +109,15 @@ AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(rea
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)); 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)); return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
} }
@@ -117,4 +126,3 @@ auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDens
{ {
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor)); return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
} }

View File

@@ -1,67 +1,72 @@
// /*
// Filename : AverageAreaGridDensityProvider.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-2-9 * 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__
// /** \file blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2011-2-9
// 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
#include "GridDensityProvider.h" #include "GridDensityProvider.h"
class AverageAreaGridDensityProvider : public GridDensityProvider { class AverageAreaGridDensityProvider : public GridDensityProvider
{
// Disallow copying and assignment // Disallow copying and assignment
AverageAreaGridDensityProvider(const AverageAreaGridDensityProvider& other); AverageAreaGridDensityProvider(const AverageAreaGridDensityProvider& other);
AverageAreaGridDensityProvider& operator=(const AverageAreaGridDensityProvider& other); AverageAreaGridDensityProvider& operator=(const AverageAreaGridDensityProvider& other);
public: public:
AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor); 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); AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor);
virtual ~AverageAreaGridDensityProvider(); virtual ~AverageAreaGridDensityProvider();
protected:
private: 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: public:
AverageAreaGridDensityProviderFactory(real sizeFactor); AverageAreaGridDensityProviderFactory(real sizeFactor);
~AverageAreaGridDensityProviderFactory(); ~AverageAreaGridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]); 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); auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected: protected:
real sizeFactor; real sizeFactor;
}; };
#endif // AVERAGEAREAGRIDDENSITYPROVIDER_H #endif // __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__

View File

@@ -1,37 +1,42 @@
// /*
// Filename : BoxGrid.cpp * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-1-29 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2011-1-29
// 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. #include <algorithm>
// #include <stdexcept>
// 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 "BoxGrid.h" #include "BoxGrid.h"
#include <stdexcept>
#include <algorithm>
using namespace std; using namespace std;
// Helper Classes // Helper Classes
@@ -46,7 +51,8 @@ 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; const real epsilon = 1.0e-06;
boundary[0] = x - epsilon; boundary[0] = x - epsilon;
boundary[1] = x + sizeX + 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; boundary[3] = y + sizeY + epsilon;
} }
bool BoxGrid::Cell::compareOccludersByShallowestPoint (const BoxGrid::OccluderData* a, const BoxGrid::OccluderData* b) { bool BoxGrid::Cell::compareOccludersByShallowestPoint(const BoxGrid::OccluderData *a, const BoxGrid::OccluderData *b)
{
return a->shallowest < b->shallowest; return a->shallowest < b->shallowest;
} }
void BoxGrid::Cell::indexPolygons() { void BoxGrid::Cell::indexPolygons()
{
// Sort occluders by their shallowest points. // Sort occluders by their shallowest points.
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint); sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
} }
@@ -67,12 +75,11 @@ void BoxGrid::Cell::indexPolygons() {
////////////////// //////////////////
BoxGrid::Iterator::Iterator (BoxGrid& grid, Vec3r& center, real epsilon) BoxGrid::Iterator::Iterator (BoxGrid& grid, Vec3r& center, real epsilon)
: _target(grid.transform(center)), : _target(grid.transform(center)), _foundOccludee(false)
_foundOccludee(false)
{ {
// Find target cell // Find target cell
_cell = grid.findCell(_target); _cell = grid.findCell(_target);
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
cout << "Searching for occluders of edge centered at " << _target << " in cell [" cout << "Searching for occluders of edge centered at " << _target << " in cell ["
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2] << _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl; << ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
@@ -87,26 +94,29 @@ BoxGrid::Iterator::~Iterator () {}
// BoxGrid // BoxGrid
///////////////// /////////////////
BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI) BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
: _viewpoint(viewpoint), bool enableQI)
_enableQI(enableQI) : _viewpoint(viewpoint), _enableQI(enableQI)
{ {
cout << "Generate Cell structure" << endl;
// Generate Cell structure // Generate Cell structure
cout << "Generate Cell structure" << endl;
assignCells(source, density, viewMap); assignCells(source, density, viewMap);
cout << "Distribute occluders" << endl;
// Fill Cells // Fill Cells
cout << "Distribute occluders" << endl;
distributePolygons(source); distributePolygons(source);
cout << "Reorganize cells" << endl;
// Reorganize Cells // Reorganize Cells
cout << "Reorganize cells" << endl;
reorganizeCells(); reorganizeCells();
cout << "Ready to use BoxGrid" << endl; 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(); _cellSize = density.cellSize();
_cellsX = density.cellsX(); _cellsX = density.cellsX();
_cellsY = density.cellsY(); _cellsY = density.cellsY();
@@ -124,11 +134,10 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) { for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
if ((*f)->isInImage()) { if ((*f)->isInImage()) {
Vec3r point = transform((*f)->center3d()); Vec3r point = transform((*f)->center3d());
unsigned i, j; unsigned int i, j;
getCellCoordinates(point, i, j); getCellCoordinates(point, i, j);
if (_cells[i * _cellsY + j] == NULL) { if (_cells[i * _cellsY + j] == NULL) {
// This is an uninitialized cell // This is an uninitialized cell
real x, y, width, height; real x, y, width, height;
x = _cellOrigin[0] + _cellSize * i; x = _cellOrigin[0] + _cellSize * i;
@@ -145,7 +154,8 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
} }
} }
void BoxGrid::distributePolygons (OccluderSource& source) { void BoxGrid::distributePolygons(OccluderSource& source)
{
unsigned long nFaces = 0; unsigned long nFaces = 0;
unsigned long nKeptFaces = 0; unsigned long nKeptFaces = 0;
@@ -157,7 +167,8 @@ void BoxGrid::distributePolygons (OccluderSource& source) {
_faces.push_back(occluder); _faces.push_back(occluder);
++nKeptFaces; ++nKeptFaces;
} }
} catch (...) { }
catch (...) {
// If an exception was thrown, _faces.push_back() cannot have succeeded. // If an exception was thrown, _faces.push_back() cannot have succeeded.
// occluder is not owned by anyone, and must be deleted. // occluder is not owned by anyone, and must be deleted.
// If the exception was thrown before or during new OccluderData(), then // If the exception was thrown before or during new OccluderData(), then
@@ -170,7 +181,8 @@ void BoxGrid::distributePolygons (OccluderSource& source) {
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl; cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
} }
void BoxGrid::reorganizeCells () { void BoxGrid::reorganizeCells()
{
// Sort the occluders by shallowest point // Sort the occluders by shallowest point
for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) { for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
if (*i != NULL) { if (*i != NULL) {
@@ -179,32 +191,37 @@ void BoxGrid::reorganizeCells () {
} }
} }
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)); 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)); y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
} }
BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point) { BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point)
unsigned x, y; {
unsigned int x, y;
getCellCoordinates(point, x, y); getCellCoordinates(point, x, y);
return _cells[x * _cellsY + y]; return _cells[x * _cellsY + y];
} }
bool BoxGrid::orthographicProjection () const { bool BoxGrid::orthographicProjection() const
{
return true; return true;
} }
const Vec3r& BoxGrid::viewpoint() const { const Vec3r& BoxGrid::viewpoint() const
{
return _viewpoint; return _viewpoint;
} }
bool BoxGrid::enableQI() const { bool BoxGrid::enableQI() const
{
return _enableQI; return _enableQI;
} }
BoxGrid::Transform::Transform() : GridHelpers::Transform() {} BoxGrid::Transform::Transform() : GridHelpers::Transform() {}
Vec3r BoxGrid::Transform::operator() (const Vec3r& point) const { Vec3r BoxGrid::Transform::operator()(const Vec3r& point) const
{
return Vec3r(point[0], point[1], -point[2]); return Vec3r(point[0], point[1], -point[2]);
} }

View File

@@ -1,70 +1,79 @@
// /*
// Filename : BoxGrid.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-1-29 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2011-1-29
// 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 BOX_GRID_LOGGING FALSE
#define BOXGRID_H
#define boxgridlogging 0
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector> // 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. // so it should be a safe fall-back.
//#include <vector> //#include <vector>
//#include <deque> //#include <deque>
#include "GridDensityProvider.h"
#include "OccluderSource.h"
#include "ViewMap.h" #include "ViewMap.h"
#include "../winged_edge/WEdge.h"
#include "../geometry/Polygon.h"
#include "../system/PointerSequence.h"
#include "../geometry/BBox.h" #include "../geometry/BBox.h"
#include "../geometry/GridHelpers.h" #include "../geometry/GridHelpers.h"
#include "OccluderSource.h" #include "../geometry/Polygon.h"
#include "GridDensityProvider.h"
#include "../system/PointerSequence.h"
#include "../winged_edge/WEdge.h"
class BoxGrid class BoxGrid
{ {
public: public:
// Helper classes // Helper classes
struct OccluderData { struct OccluderData
{
explicit OccluderData(OccluderSource& source, Polygon3r& p); explicit OccluderData(OccluderSource& source, Polygon3r& p);
Polygon3r poly; Polygon3r poly;
Polygon3r cameraSpacePolygon; Polygon3r cameraSpacePolygon;
real shallowest, deepest; real shallowest, deepest;
// N.B. We could, of course, store face in poly's userdata // N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
// member, like the old ViewMapBuilder code does. However, // However, code comments make it clear that userdata is deprecated, so we avoid the temptation
// code comments make it clear that userdata is deprecated, // to save 4 or 8 bytes.
// so we avoid the temptation to save 4 or 8 bytes.
WFace* face; WFace* face;
}; };
private: private:
struct Cell { struct Cell
{
// Can't store Cell in a vector without copy and assign // Can't store Cell in a vector without copy and assign
// Cell(const Cell& other); // Cell(const Cell& other);
// Cell& operator=(const Cell& other); // Cell& operator=(const Cell& other);
@@ -84,28 +93,21 @@ private:
}; };
public: public:
/***** /* Iterator needs to allow the user to avoid full 3D comparison in two cases:
*
Iterator needs to allow the user to avoid full 3D comparison in * (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
two cases: *
* (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
(1) Where (*current)->deepest < target[2], where the occluder is *
unambiguously in front 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
(2) Where (*current)->shallowest > target[2], where the occluder * could possibly be a better occludee.
is unambiguously in back of the target point. */
class Iterator
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: public:
// epsilon is not used in this class, but other grids with the same interface may need an epsilon // 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); explicit Iterator(BoxGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
~Iterator(); ~Iterator();
void initBeforeTarget(); void initBeforeTarget();
void initAfterTarget(); void initAfterTarget();
@@ -116,6 +118,7 @@ public:
WFace *getWFace() const; WFace *getWFace() const;
Polygon3r *getCameraSpacePolygon(); Polygon3r *getCameraSpacePolygon();
void reportDepth(Vec3r origin, Vec3r u, real t); void reportDepth(Vec3r origin, Vec3r u, real t);
private: private:
bool testOccluder(bool wantOccludee); bool testOccluder(bool wantOccludee);
void markCurrentOccludeeCandidate(real depth); void markCurrentOccludeeCandidate(real depth);
@@ -128,7 +131,8 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate; vector<OccluderData*>::iterator _current, _occludeeCandidate;
}; };
class Transform : public GridHelpers::Transform { class Transform : public GridHelpers::Transform
{
public: public:
explicit Transform(); explicit Transform();
explicit Transform(Transform& other); explicit Transform(Transform& other);
@@ -139,16 +143,17 @@ private:
// Prevent implicit copies and assignments. // Prevent implicit copies and assignments.
BoxGrid(const BoxGrid& other); BoxGrid(const BoxGrid& other);
BoxGrid& operator=(const BoxGrid& other); BoxGrid& operator=(const BoxGrid& other);
public: 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(); virtual ~BoxGrid();
// Generate Cell structure // Generate Cell structure
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap); void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
// Fill Cells // Fill Cells
void distributePolygons(OccluderSource& source); void distributePolygons(OccluderSource& source);
// Insert one polygon into each matching cell, // Insert one polygon into each matching cell, return true if any cell consumes the polygon
// return true if any cell consumes the polygon
bool insertOccluder(OccluderSource& source, OccluderData*& occluder); bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
// Sort occluders in each cell // Sort occluders in each cell
void reorganizeCells(); void reorganizeCells();
@@ -176,23 +181,25 @@ private:
bool _enableQI; bool _enableQI;
}; };
inline void BoxGrid::Iterator::initBeforeTarget () { inline void BoxGrid::Iterator::initBeforeTarget()
{
_current = _cell->faces.begin(); _current = _cell->faces.begin();
while (_current != _cell->faces.end() && !testOccluder(false)) { while (_current != _cell->faces.end() && !testOccluder(false)) {
++_current; ++_current;
} }
} }
inline void BoxGrid::Iterator::initAfterTarget () { inline void BoxGrid::Iterator::initAfterTarget()
{
if (_foundOccludee) { if (_foundOccludee) {
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl; std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
#endif #endif
_current = _occludeeCandidate; _current = _occludeeCandidate;
return; return;
} }
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
std::cout << "\tStarting occludee search from current position" << std::endl; std::cout << "\tStarting occludee search from current position" << std::endl;
#endif #endif
@@ -201,26 +208,25 @@ inline void BoxGrid::Iterator::initAfterTarget () {
} }
} }
inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) { inline bool BoxGrid::Iterator::testOccluder(bool wantOccludee)
{
// End-of-list is not even a valid iterator position // End-of-list is not even a valid iterator position
if (_current == _cell->faces.end()) { if (_current == _cell->faces.end()) {
// Returning true seems strange, but it will break us out of whatever loop // Returning true seems strange, but it will break us out of whatever loop is calling testOccluder,
// is calling testOccluder, and _current=_cell->face.end() will make // and _current = _cell->face.end() will make the calling routine give up.
// the calling routine give up.
return true; return true;
} }
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0]; 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 << ", " << (*_current)->poly.getVertices()[i];
} }
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl; std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
#endif #endif
// If we have an occluder candidate and we are unambiguously after it, abort // If we have an occluder candidate and we are unambiguously after it, abort
if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) { if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl; std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
#endif #endif
_current = _cell->faces.end(); _current = _cell->faces.end();
@@ -232,14 +238,15 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
// Specific continue or stop conditions when searching for each type // Specific continue or stop conditions when searching for each type
if (wantOccludee) { if (wantOccludee) {
if ((*_current)->deepest < _target[2]) { if ((*_current)->deepest < _target[2]) {
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl; std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
#endif #endif
return false; return false;
} }
} else { }
else {
if ((*_current)->shallowest > _target[2]) { if ((*_current)->shallowest > _target[2]) {
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl; std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
#endif #endif
return true; return true;
@@ -252,41 +259,43 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
Vec3r bbMin, bbMax; Vec3r bbMin, bbMax;
(*_current)->poly.getBBox(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 (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
std::cout << "\t\tSkipping: bounding box violation" << std::endl; std::cout << "\t\tSkipping: bounding box violation" << std::endl;
#endif #endif
return false; return false;
} }
// We've done all the corner cutting we can. // We've done all the corner cutting we can.
// Let the caller work out whether or not // Let the caller work out whether or not the geometry is correct.
// the geometry is correct.
return true; 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 // The reported depth is the length of a ray in camera space
// We need to convert it into a Z-value in grid space // We need to convert it into a Z-value in grid space
real depth = -(origin + (u * t))[2]; real depth = -(origin + (u * t))[2];
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
std::cout << "\t\tReporting depth of occluder/ee: " << depth; std::cout << "\t\tReporting depth of occluder/ee: " << depth;
#endif #endif
if (depth > _target[2]) { if (depth > _target[2]) {
#if boxgridlogging == 1 #if BOX_GRID_LOGGING
std::cout << " is deeper than target" << std::endl; std::cout << " is deeper than target" << std::endl;
#endif #endif
// If the current occluder is the best occludee so far, save it. // If the current occluder is the best occludee so far, save it.
if (! _foundOccludee || _occludeeDepth > depth) { if (! _foundOccludee || _occludeeDepth > depth) {
markCurrentOccludeeCandidate(depth); markCurrentOccludeeCandidate(depth);
} }
} else { }
#if boxgridlogging == 1 else {
#if BOX_GRID_LOGGING
std::cout << std::endl; std::cout << std::endl;
#endif #endif
} }
} }
inline void BoxGrid::Iterator::nextOccluder () { inline void BoxGrid::Iterator::nextOccluder()
{
if (_current != _cell->faces.end()) { if (_current != _cell->faces.end()) {
do { do {
++_current; ++_current;
@@ -294,7 +303,8 @@ inline void BoxGrid::Iterator::nextOccluder () {
} }
} }
inline void BoxGrid::Iterator::nextOccludee () { inline void BoxGrid::Iterator::nextOccludee()
{
if (_current != _cell->faces.end()) { if (_current != _cell->faces.end()) {
do { do {
++_current; ++_current;
@@ -302,16 +312,19 @@ inline void BoxGrid::Iterator::nextOccludee () {
} }
} }
inline bool BoxGrid::Iterator::validBeforeTarget () { inline bool BoxGrid::Iterator::validBeforeTarget()
{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2]; return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
} }
inline bool BoxGrid::Iterator::validAfterTarget () { inline bool BoxGrid::Iterator::validAfterTarget()
{
return _current != _cell->faces.end(); return _current != _cell->faces.end();
} }
inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) { inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth)
#if boxgridlogging == 1 {
#if BOX_GRID_LOGGING
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl; std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
#endif #endif
_occludeeCandidate = _current; _occludeeCandidate = _current;
@@ -319,11 +332,13 @@ inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
_foundOccludee = true; _foundOccludee = true;
} }
inline WFace* BoxGrid::Iterator::getWFace() const { inline WFace* BoxGrid::Iterator::getWFace() const
{
return (*_current)->face; return (*_current)->face;
} }
inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon() { inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon()
{
return &((*_current)->cameraSpacePolygon); return &((*_current)->cameraSpacePolygon);
} }
@@ -339,7 +354,8 @@ inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p
deepest = max[2]; deepest = max[2];
} }
inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) { inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
{
if (GridHelpers::insideProscenium (boundary, poly)) { if (GridHelpers::insideProscenium (boundary, poly)) {
if (occluder == NULL) { if (occluder == NULL) {
// Disposal of occluder will be handled in BoxGrid::distributePolygons(), // Disposal of occluder will be handled in BoxGrid::distributePolygons(),
@@ -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()); Polygon3r& poly(source.getGridSpacePolygon());
occluder = NULL; occluder = NULL;
@@ -361,8 +378,8 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
getCellCoordinates(bbMin, startX, startY); getCellCoordinates(bbMin, startX, startY);
getCellCoordinates(bbMax, endX, endY); getCellCoordinates(bbMax, endX, endY);
for ( unsigned i = startX; i <= endX; ++i ) { for (unsigned int i = startX; i <= endX; ++i) {
for ( unsigned j = startY; j <= endY; ++j ) { for (unsigned int j = startY; j <= endY; ++j) {
if (_cells[i * _cellsY + j] != NULL) { if (_cells[i * _cellsY + j] != NULL) {
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder); _cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
} }
@@ -372,5 +389,4 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
return occluder != NULL; return occluder != NULL;
} }
#endif // BOXGRID_H #endif // __FREESTYLE_BOX_GRID_H__

View File

@@ -1,46 +1,51 @@
// /*
// Filename : CulledOccluderSource.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2010-12-21 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \brief Class to define a cell grid surrounding the projected image of a scene
// with this source distribution. * \author Alexander Beels
// * \date 2010-12-21
// 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 "CulledOccluderSource.h" #include "CulledOccluderSource.h"
#include "../geometry/GridHelpers.h"
#include "FRS_freestyle.h" #include "FRS_freestyle.h"
CulledOccluderSource::CulledOccluderSource (const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap, bool extensiveFEdgeSearch) #include "../geometry/GridHelpers.h"
: OccluderSource(t, we),
rejected(0), CulledOccluderSource::CulledOccluderSource(const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap,
gridSpaceOccluderProsceniumInitialized(false) bool extensiveFEdgeSearch)
: OccluderSource(t, we), rejected(0), gridSpaceOccluderProsceniumInitialized(false)
{ {
cullViewEdges(viewMap, extensiveFEdgeSearch); cullViewEdges(viewMap, extensiveFEdgeSearch);
// If we have not found any visible FEdges during our cull, then there is nothing // If we have not found any visible FEdges during our cull, then there is nothing to iterate over.
// to iterate over. Short-circuit everything. // Short-circuit everything.
valid = gridSpaceOccluderProsceniumInitialized; valid = gridSpaceOccluderProsceniumInitialized;
if (valid && ! testCurrent()) { if (valid && ! testCurrent()) {
@@ -48,18 +53,20 @@ CulledOccluderSource::CulledOccluderSource (const GridHelpers::Transform& t, Win
} }
} }
CulledOccluderSource::~CulledOccluderSource() { CulledOccluderSource::~CulledOccluderSource() {}
}
bool CulledOccluderSource::testCurrent() { bool CulledOccluderSource::testCurrent()
{
if (valid) { if (valid) {
// The test for gridSpaceOccluderProsceniumInitialized should not be necessary // The test for gridSpaceOccluderProsceniumInitialized should not be necessary
return gridSpaceOccluderProsceniumInitialized && GridHelpers::insideProscenium (gridSpaceOccluderProscenium, cachedPolygon); return gridSpaceOccluderProsceniumInitialized &&
GridHelpers::insideProscenium(gridSpaceOccluderProscenium, cachedPolygon);
} }
return false; return false;
} }
bool CulledOccluderSource::next() { bool CulledOccluderSource::next()
{
while (OccluderSource::next()) { while (OccluderSource::next()) {
if (testCurrent()) { if (testCurrent()) {
++rejected; ++rejected;
@@ -70,17 +77,20 @@ bool CulledOccluderSource::next() {
return false; return false;
} }
void CulledOccluderSource::getOccluderProscenium(real proscenium[4]) { void CulledOccluderSource::getOccluderProscenium(real proscenium[4])
for ( unsigned i = 0; i < 4; ++i ) { {
for (unsigned int i = 0; i < 4; ++i) {
proscenium[i] = gridSpaceOccluderProscenium[i]; proscenium[i] = gridSpaceOccluderProscenium[i];
} }
} }
static inline real distance2D(const Vec3r & point, const real origin[2]) { static inline real distance2D(const Vec3r & point, const real origin[2])
{
return ::hypot((point[0] - origin[0]), (point[1] - origin[1])); return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
} }
static inline bool crossesProscenium(real proscenium[4], FEdge *fe) { static inline bool crossesProscenium(real proscenium[4], FEdge *fe)
{
Vec2r min(proscenium[0], proscenium[2]); Vec2r min(proscenium[0], proscenium[2]);
Vec2r max(proscenium[1], proscenium[3]); Vec2r max(proscenium[1], proscenium[3]);
Vec2r A(fe->vertexA()->getProjectedX(), fe->vertexA()->getProjectedY()); 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); return GeomUtils::intersect2dSeg2dArea (min, max, A, B);
} }
static inline bool insideProscenium(real proscenium[4], const Vec3r& point) { static inline bool insideProscenium(real proscenium[4], const Vec3r& point)
return ! ( point[0] < proscenium[0] || point[0] > proscenium[1] || point[1] < proscenium[2] || point[1] > proscenium[3] ); {
return !(point[0] < proscenium[0] || point[0] > proscenium[1] ||
point[1] < proscenium[2] || point[1] > proscenium[3]);
} }
void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch) { void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch)
{
// Cull view edges by marking them as non-displayable. // Cull view edges by marking them as non-displayable.
// This avoids the complications of trying to delete // This avoids the complications of trying to delete edges from the ViewMap.
// edges from the ViewMap.
// Non-displayable view edges will be skipped over during // Non-displayable view edges will be skipped over during visibility calculation.
// visibility calculation.
// View edges will be culled according to their position // View edges will be culled according to their position w.r.t. the viewport proscenium (viewport + 5% border,
// w.r.t. the viewport proscenium (viewport + 5% border,
// or some such). // or some such).
// Get proscenium boundary for culling // Get proscenium boundary for culling
@@ -112,23 +122,20 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0; prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0; prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
cout << "Proscenium culling:" << endl; 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; cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]"<< endl;
// A separate occluder proscenium will also be maintained, // A separate occluder proscenium will also be maintained, starting out the same as the viewport proscenium, and
// 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
// expanding as necessary so that it encompasses the center // retained view edge.
// point of at least one feature edge in each retained view // The occluder proscenium will be used later to cull occluding triangles before they are inserted into the Grid.
// edge. // 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); GridHelpers::getDefaultViewProscenium(occluderProscenium);
// N.B. Freestyle is inconsistent in its use of ViewMap::viewedges_container // XXX Freestyle is inconsistent in its use of ViewMap::viewedges_container and vector<ViewEdge*>::iterator.
// and vector<ViewEdge*>::iterator. Probably all occurences of vector<ViewEdge*>::iterator // Probably all occurences of vector<ViewEdge*>::iterator should be replaced ViewMap::viewedges_container
// should be replaced ViewMap::viewedges_container throughout the code. // throughout the code.
// For each view edge // For each view edge
ViewMap::viewedges_container::iterator ve, veend; ViewMap::viewedges_container::iterator ve, veend;
@@ -138,8 +145,7 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// If none: mark view edge as non-displayable // If none: mark view edge as non-displayable
// Otherwise: // Otherwise:
// Find a feature edge with center point inside occluder proscenium. // Find a feature edge with center point inside occluder proscenium.
// If none exists, find the feature edge with center point // If none exists, find the feature edge with center point closest to viewport origin.
// closest to viewport origin.
// Expand occluder proscenium to enclose center point. // Expand occluder proscenium to enclose center point.
// For each feature edge, while bestOccluderTarget not found and view edge not visibile // For each feature edge, while bestOccluderTarget not found and view edge not visibile
@@ -151,15 +157,13 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// All ViewEdges start culled // All ViewEdges start culled
(*ve)->setIsInImage(false); (*ve)->setIsInImage(false);
// For simple visibility calculation: mark a feature edge // For simple visibility calculation: mark a feature edge that is known to have a center point inside
// that is known to have a center point inside the occluder proscenium. // the occluder proscenium. Cull all other feature edges.
// Cull all other feature edges.
do { do {
// All FEdges start culled // All FEdges start culled
fe->setIsInImage(false); fe->setIsInImage(false);
// Look for the visible edge that can most easily be included // Look for the visible edge that can most easily be included in the occluder proscenium.
// in the occluder proscenium.
if (!bestOccluderTargetFound) { if (!bestOccluderTargetFound) {
// If center point is inside occluder proscenium, // If center point is inside occluder proscenium,
if (insideProscenium(occluderProscenium, fe->center2d())) { if (insideProscenium(occluderProscenium, fe->center2d())) {
@@ -169,7 +173,8 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// Mark bestOccluderTarget as found // Mark bestOccluderTarget as found
bestOccluderTargetFound = true; bestOccluderTargetFound = true;
bestOccluderTarget = fe; bestOccluderTarget = fe;
} else { }
else {
real d = distance2D(fe->center2d(), prosceniumOrigin); real d = distance2D(fe->center2d(), prosceniumOrigin);
// If center point is closer to viewport origin than current target // If center point is closer to viewport origin than current target
if (bestOccluderTarget == NULL || d < bestOccluderDistance) { if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
@@ -202,12 +207,14 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
Vec3r point = bestOccluderTarget->center2d(); Vec3r point = bestOccluderTarget->center2d();
if (point[0] < occluderProscenium[0]) { if (point[0] < occluderProscenium[0]) {
occluderProscenium[0] = point[0]; occluderProscenium[0] = point[0];
} else if ( point[0] > occluderProscenium[1] ) { }
else if (point[0] > occluderProscenium[1]) {
occluderProscenium[1] = point[0]; occluderProscenium[1] = point[0];
} }
if (point[1] < occluderProscenium[2]) { if (point[1] < occluderProscenium[2]) {
occluderProscenium[2] = point[1]; occluderProscenium[2] = point[1];
} else if ( point[1] > occluderProscenium[3] ) { }
else if (point[1] > occluderProscenium[3]) {
occluderProscenium[3] = point[1]; occluderProscenium[3] = point[1];
} }
// Use bestOccluderTarget for visibility determination // Use bestOccluderTarget for visibility determination
@@ -225,18 +232,14 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// For "Normal" or "Fast" style visibility computation only: // For "Normal" or "Fast" style visibility computation only:
// For more detailed visibility calculation, make a second pass through // For more detailed visibility calculation, make a second pass through the view map, marking all feature edges
// the view map, marking all feature edges with center points inside // with center points inside the final occluder proscenium. All of these feature edges can be considered during
// the final occluder proscenium. All of these feature edges can be // visibility calculation.
// considered during visibility calculation.
// So far we have only found one FEdge per ViewEdge. The "Normal" and // So far we have only found one FEdge per ViewEdge. The "Normal" and "Fast" styles of visibility computation
// "Fast" styles of visibility computation want to consider many // want to consider many FEdges for each ViewEdge.
// 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
// Here we re-scan the view map to find any usable FEdges that we // usable because the occluder proscenium has been expanded since the edge was visited on the first pass.
// 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) { if (extensiveFEdgeSearch) {
// For each view edge, // For each view edge,
for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) { for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
@@ -259,19 +262,20 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
} }
// Up until now, all calculations have been done in camera space. // Up until now, all calculations have been done in camera space.
// However, the occluder source's iteration and the grid that consumes the occluders // However, the occluder source's iteration and the grid that consumes the occluders both work in gridspace,
// both work in gridspace, so we need a version of the occluder proscenium in gridspace. // so we need a version of the occluder proscenium in gridspace.
// Set the gridspace occlude proscenium // Set the gridspace occlude proscenium
} }
void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge* fe) { void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge *fe)
{
if (gridSpaceOccluderProsceniumInitialized) { if (gridSpaceOccluderProsceniumInitialized) {
GridHelpers::expandProscenium(gridSpaceOccluderProscenium, transform(fe->center3d())); GridHelpers::expandProscenium(gridSpaceOccluderProscenium, transform(fe->center3d()));
} else { }
else {
const Vec3r& point = transform(fe->center3d()); const Vec3r& point = transform(fe->center3d());
gridSpaceOccluderProscenium[0] = gridSpaceOccluderProscenium[1] = point[0]; gridSpaceOccluderProscenium[0] = gridSpaceOccluderProscenium[1] = point[0];
gridSpaceOccluderProscenium[2] = gridSpaceOccluderProscenium[3] = point[1]; gridSpaceOccluderProscenium[2] = gridSpaceOccluderProscenium[3] = point[1];
gridSpaceOccluderProsceniumInitialized = true; gridSpaceOccluderProsceniumInitialized = true;
} }
} }

View File

@@ -1,46 +1,52 @@
// /*
// Filename : CulledOccluderSource.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2010-12-21 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2010-12-21
// 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
#include "OccluderSource.h" #include "OccluderSource.h"
#include "ViewMap.h" #include "ViewMap.h"
class CulledOccluderSource : public OccluderSource { class CulledOccluderSource : public OccluderSource
{
// Disallow copying and assignment // Disallow copying and assignment
CulledOccluderSource(const CulledOccluderSource& other); CulledOccluderSource(const CulledOccluderSource& other);
CulledOccluderSource& operator=(const CulledOccluderSource& other); CulledOccluderSource& operator=(const CulledOccluderSource& other);
public: 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(); virtual ~CulledOccluderSource();
void cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch); void cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch);
@@ -60,4 +66,4 @@ private:
bool gridSpaceOccluderProsceniumInitialized; bool gridSpaceOccluderProsceniumInitialized;
}; };
#endif // CULLEDOCCLUDERSOURCE_H #endif // __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__

View File

@@ -1,31 +1,47 @@
/*
* ***** 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Detects/flags/builds extended features edges on the WXEdge structure
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 26/10/2003
// 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. #include <float.h>
// #include <math.h>
// 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 "FEdgeXDetector.h" #include "FEdgeXDetector.h"
#include "float.h"
#include "../geometry/GeomUtils.h" #include "../geometry/GeomUtils.h"
#include <math.h>
#include "../geometry/normal_cycle.h" #include "../geometry/normal_cycle.h"
void FEdgeXDetector::processShapes(WingedEdge& we) { void FEdgeXDetector::processShapes(WingedEdge& we)
{
bool progressBarDisplay = false; bool progressBarDisplay = false;
Vec3r Min, Max; Vec3r Min, Max;
vector<WShape*> wshapes = we.getWShapes(); vector<WShape*> wshapes = we.getWShapes();
@@ -39,9 +55,7 @@ void FEdgeXDetector::processShapes(WingedEdge& we) {
progressBarDisplay = true; progressBarDisplay = true;
} }
for(vector<WShape*>::const_iterator it = wshapes.begin(); for (vector<WShape*>::const_iterator it = wshapes.begin(); it != wshapes.end(); it++) {
it != wshapes.end();
it++){
if (_pRenderMonitor && _pRenderMonitor->testBreak()) if (_pRenderMonitor && _pRenderMonitor->testBreak())
break; break;
wxs = dynamic_cast<WXShape*>(*it); wxs = dynamic_cast<WXShape*>(*it);
@@ -49,17 +63,17 @@ void FEdgeXDetector::processShapes(WingedEdge& we) {
_bbox_diagonal = (Max - Min).norm(); _bbox_diagonal = (Max - Min).norm();
if (_changes) { if (_changes) {
vector<WFace*>& wfaces = wxs->GetFaceList(); vector<WFace*>& wfaces = wxs->GetFaceList();
for(vector<WFace*>::iterator wf=wfaces.begin(), wfend=wfaces.end(); for (vector<WFace*>::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; ++wf) {
wf!=wfend;
++wf){
WXFace *wxf = dynamic_cast<WXFace*>(*wf); WXFace *wxf = dynamic_cast<WXFace*>(*wf);
wxf->Clear(); wxf->Clear();
} }
_computeViewIndependant = true; _computeViewIndependant = true;
} else if (!(wxs)->getComputeViewIndependantFlag()) { }
else if (!(wxs)->getComputeViewIndependantFlag()) {
wxs->Reset(); wxs->Reset();
_computeViewIndependant = false; _computeViewIndependant = false;
} else { }
else {
_computeViewIndependant = true; _computeViewIndependant = true;
} }
preProcessShape(wxs); preProcessShape(wxs);
@@ -98,7 +112,8 @@ void FEdgeXDetector::processShapes(WingedEdge& we) {
// GENERAL STUFF // GENERAL STUFF
//////////////// ////////////////
void FEdgeXDetector::preProcessShape(WXShape* iWShape) { void FEdgeXDetector::preProcessShape(WXShape *iWShape)
{
_meanK1 = 0; _meanK1 = 0;
_meanKr = 0; _meanKr = 0;
_minK1 = FLT_MAX; _minK1 = FLT_MAX;
@@ -111,17 +126,13 @@ void FEdgeXDetector::preProcessShape(WXShape* iWShape) {
vector<WFace*>& wfaces = iWShape->GetFaceList(); vector<WFace*>& wfaces = iWShape->GetFaceList();
vector<WFace*>::iterator f, fend; vector<WFace*>::iterator f, fend;
// view dependant stuff // view dependant stuff
for(f=wfaces.begin(), fend=wfaces.end(); for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
f!=fend;
++f){
preProcessFace((WXFace*)(*f)); preProcessFace((WXFace*)(*f));
} }
if (_computeRidgesAndValleys || _computeSuggestiveContours) { if (_computeRidgesAndValleys || _computeSuggestiveContours) {
vector<WVertex*>& wvertices = iWShape->getVertexList(); vector<WVertex*>& wvertices = iWShape->getVertexList();
for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end(); for (vector<WVertex*>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
wv!=wvend;
++wv){
// Compute curvatures // Compute curvatures
WXVertex *wxv = dynamic_cast<WXVertex*>(*wv); WXVertex *wxv = dynamic_cast<WXVertex*>(*wv);
computeCurvatures(wxv); computeCurvatures(wxv);
@@ -131,7 +142,8 @@ void FEdgeXDetector::preProcessShape(WXShape* iWShape) {
} }
} }
void FEdgeXDetector::preProcessFace(WXFace *iFace){ void FEdgeXDetector::preProcessFace(WXFace *iFace)
{
Vec3r firstPoint = iFace->GetVertex(0)->GetVertex(); Vec3r firstPoint = iFace->GetVertex(0)->GetVertex();
Vec3r N = iFace->GetNormal(); Vec3r N = iFace->GetNormal();
@@ -139,7 +151,8 @@ void FEdgeXDetector::preProcessFace(WXFace *iFace){
Vec3r V; Vec3r V;
if (_orthographicProjection) { if (_orthographicProjection) {
V = Vec3r(0.0, 0.0, _Viewpoint.z() - firstPoint.z()); V = Vec3r(0.0, 0.0, _Viewpoint.z() - firstPoint.z());
} else { }
else {
V = Vec3r(_Viewpoint - firstPoint); V = Vec3r(_Viewpoint - firstPoint);
} }
N.normalize(); N.normalize();
@@ -149,13 +162,15 @@ void FEdgeXDetector::preProcessFace(WXFace *iFace){
// compute the distance between the face center and the viewpoint: // compute the distance between the face center and the viewpoint:
if (_orthographicProjection) { if (_orthographicProjection) {
iFace->setZ(iFace->center().z() - _Viewpoint.z()); iFace->setZ(iFace->center().z() - _Viewpoint.z());
} else { }
else {
Vec3r dist_vec(iFace->center() - _Viewpoint); Vec3r dist_vec(iFace->center() - _Viewpoint);
iFace->setZ(dist_vec.norm()); iFace->setZ(dist_vec.norm());
} }
} }
void FEdgeXDetector::computeCurvatures(WXVertex *vertex){ void FEdgeXDetector::computeCurvatures(WXVertex *vertex)
{
// CURVATURE LAYER // CURVATURE LAYER
// store all the curvature datas for each vertex // store all the curvature datas for each vertex
@@ -174,7 +189,8 @@ void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
ncycle.begin(); ncycle.begin();
if (radius > 0) { if (radius > 0) {
OGF::compute_curvature_tensor(vertex, radius, ncycle); OGF::compute_curvature_tensor(vertex, radius, ncycle);
} else { }
else {
OGF::compute_curvature_tensor_one_ring(vertex, ncycle); OGF::compute_curvature_tensor_one_ring(vertex, ncycle);
} }
ncycle.end(); ncycle.end();
@@ -199,7 +215,8 @@ void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
n = C->e1 ^ C->e2; n = C->e1 ^ C->e2;
if (_orthographicProjection) { if (_orthographicProjection) {
v = Vec3r(0.0, 0.0, _Viewpoint.z() - vertex->GetVertex().z()); v = Vec3r(0.0, 0.0, _Viewpoint.z() - vertex->GetVertex().z());
} else { }
else {
v = Vec3r(_Viewpoint - vertex->GetVertex()); v = Vec3r(_Viewpoint - vertex->GetVertex());
} }
C->er = v - (v * n) * n; C->er = v - (v * n) * n;
@@ -222,39 +239,28 @@ void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
// SILHOUETTE // SILHOUETTE
///////////// /////////////
void FEdgeXDetector::processSilhouetteShape(WXShape* iWShape) { void FEdgeXDetector::processSilhouetteShape(WXShape *iWShape)
// Make a first pass on every polygons in order {
// to compute all their silhouette relative values: // Make a first pass on every polygons in order to compute all their silhouette relative values:
//------------------------------------------------
vector<WFace*>& wfaces = iWShape->GetFaceList(); vector<WFace*>& wfaces = iWShape->GetFaceList();
vector<WFace*>::iterator f, fend; vector<WFace*>::iterator f, fend;
for(f=wfaces.begin(), fend=wfaces.end(); for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
f!=fend;
++f)
{
ProcessSilhouetteFace((WXFace*)(*f)); ProcessSilhouetteFace((WXFace*)(*f));
} }
// Make a pass on the edges to detect // Make a pass on the edges to detect the silhouette edges that are not smooth
// the silhouette edges that are not smooth
// --------------------
vector<WEdge*>::iterator we, weend; vector<WEdge*>::iterator we, weend;
vector<WEdge*> &wedges = iWShape->getEdgeList(); vector<WEdge*> &wedges = iWShape->getEdgeList();
for(we=wedges.begin(), weend=wedges.end(); for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
we!=weend;
++we)
{
ProcessSilhouetteEdge((WXEdge*)(*we)); ProcessSilhouetteEdge((WXEdge*)(*we));
} }
} }
void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace) void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
{ {
// SILHOUETTE LAYER // SILHOUETTE LAYER
Vec3r normal; Vec3r normal;
// Compute the dot products between View direction and N at each vertex // Compute the dot products between View direction and N at each vertex of the face:
// of the face:
Vec3r point; Vec3r point;
int closestPointId = 0; int closestPointId = 0;
real dist, minDist = FLT_MAX; real dist, minDist = FLT_MAX;
@@ -267,7 +273,8 @@ void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
Vec3r V; Vec3r V;
if (_orthographicProjection) { if (_orthographicProjection) {
V = Vec3r(0.0, 0.0, _Viewpoint.z() - point.z()); V = Vec3r(0.0, 0.0, _Viewpoint.z() - point.z());
} else { }
else {
V = Vec3r(_Viewpoint - point); V = Vec3r(_Viewpoint - point);
} }
V.normalize(); V.normalize();
@@ -276,7 +283,8 @@ void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
// Find the point the closest to the viewpoint // Find the point the closest to the viewpoint
if (_orthographicProjection) { if (_orthographicProjection) {
dist = point.z() - _Viewpoint.z(); dist = point.z() - _Viewpoint.z();
} else { }
else {
Vec3r dist_vec(point - _Viewpoint); Vec3r dist_vec(point - _Viewpoint);
dist = dist_vec.norm(); dist = dist_vec.norm();
} }
@@ -301,8 +309,7 @@ void FEdgeXDetector::ProcessSilhouetteEdge(WXEdge *iEdge)
WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace(); 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) 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 // The only edges we want to set as silhouette edges in this way are the ones with 2 different normals for 1 vertex
// way are the ones with 2 different normals for 1 vertex
// for these two faces // for these two faces
//-------------------- //--------------------
// In reality we only test the normals for 1 of the 2 vertices. // In reality we only test the normals for 1 of the 2 vertices.
@@ -316,29 +323,23 @@ void FEdgeXDetector::ProcessSilhouetteEdge(WXEdge *iEdge)
} }
} }
// BORDER // BORDER
///////// /////////
void FEdgeXDetector::processBorderShape(WXShape* iWShape) { void FEdgeXDetector::processBorderShape(WXShape *iWShape)
{
if (!_computeViewIndependant) if (!_computeViewIndependant)
return; return;
// Make a pass on the edges to detect // Make a pass on the edges to detect the BORDER
// the BORDER
// --------------------
vector<WEdge*>::iterator we, weend; vector<WEdge*>::iterator we, weend;
vector<WEdge*> &wedges = iWShape->getEdgeList(); vector<WEdge*> &wedges = iWShape->getEdgeList();
for(we=wedges.begin(), weend=wedges.end(); for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
we!=weend;
++we){
ProcessBorderEdge((WXEdge *)(*we)); ProcessBorderEdge((WXEdge *)(*we));
} }
} }
void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge) void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge)
{ {
// first check whether it is a border edge: // first check whether it is a border edge: BORDER ?
// BORDER ?
//--------- //---------
if (iEdge->GetaFace() == 0) { if (iEdge->GetaFace() == 0) {
// it is a border edge // it is a border edge
@@ -349,18 +350,15 @@ void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge)
// CREASE // CREASE
///////// /////////
void FEdgeXDetector::processCreaseShape(WXShape* iWShape) { void FEdgeXDetector::processCreaseShape(WXShape *iWShape)
{
if (!_computeViewIndependant) if (!_computeViewIndependant)
return; return;
// Make a pass on the edges to detect // Make a pass on the edges to detect the CREASE
// the CREASE
// --------------------
vector<WEdge*>::iterator we, weend; vector<WEdge*>::iterator we, weend;
vector<WEdge*> &wedges = iWShape->getEdgeList(); vector<WEdge*> &wedges = iWShape->getEdgeList();
for(we=wedges.begin(), weend=wedges.end(); for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
we!=weend;
++we){
ProcessCreaseEdge((WXEdge *)(*we)); ProcessCreaseEdge((WXEdge *)(*we));
} }
} }
@@ -381,22 +379,18 @@ void FEdgeXDetector::ProcessCreaseEdge(WXEdge *iEdge)
// RIDGES AND VALLEYS // RIDGES AND VALLEYS
///////////////////// /////////////////////
void FEdgeXDetector::processRidgesAndValleysShape(WXShape *iWShape)
void FEdgeXDetector::processRidgesAndValleysShape(WXShape* iWShape) { {
// Don't forget to add the built layer to the face at the end // Don't forget to add the built layer to the face at the end of the ProcessFace:
// of the ProcessFace:
//iFace->AddSmoothLayer(faceLayer); //iFace->AddSmoothLayer(faceLayer);
if((!_computeViewIndependant)) if (!_computeViewIndependant)
return; return;
// Here the curvatures must already have been computed // Here the curvatures must already have been computed
vector<WFace*>& wfaces = iWShape->GetFaceList(); vector<WFace*>& wfaces = iWShape->GetFaceList();
vector<WFace*>::iterator f, fend; vector<WFace*>::iterator f, fend;
for(f=wfaces.begin(), fend=wfaces.end(); for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
f!=fend;
++f)
{
ProcessRidgeFace((WXFace*)(*f)); ProcessRidgeFace((WXFace*)(*f));
} }
} }
@@ -404,7 +398,6 @@ void FEdgeXDetector::processRidgesAndValleysShape(WXShape* iWShape) {
// RIDGES // RIDGES
///////// /////////
void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace) void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
{ {
WXFaceLayer *flayer = new WXFaceLayer(iFace, Nature::RIDGE|Nature::VALLEY, false); WXFaceLayer *flayer = new WXFaceLayer(iFace, Nature::RIDGE|Nature::VALLEY, false);
@@ -421,7 +414,9 @@ void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
//real threshold = _maxK1 - (_maxK1 - _meanK1) / 20.0; //real threshold = _maxK1 - (_maxK1 - _meanK1) / 20.0;
if (flayer->nPosDotP() != numVertices) { if (flayer->nPosDotP() != numVertices) {
if((fabs(flayer->dotP(0)) < threshold) && (fabs(flayer->dotP(1)) < threshold) && (fabs(flayer->dotP(2)) < threshold)){ if ((fabs(flayer->dotP(0)) < threshold) && (fabs(flayer->dotP(1)) < threshold) &&
(fabs(flayer->dotP(2)) < threshold))
{
flayer->ReplaceDotP(0, 0); flayer->ReplaceDotP(0, 0);
flayer->ReplaceDotP(1, 0); flayer->ReplaceDotP(1, 0);
flayer->ReplaceDotP(2, 0); flayer->ReplaceDotP(2, 0);
@@ -429,124 +424,119 @@ void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
} }
} }
// void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace) #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;
// // RIDGE LAYER // find the ridge layer of the face
// // compute the RidgeFunction, that is the derivative of the ppal curvature iFace->retrieveSmoothLayers(Nature::RIDGE, SmoothLayers);
// // along e1 at each vertex of the face if ( SmoothLayers.size()!=1 )
return;
faceLayer = SmoothLayers[0];
// retrieve the curvature info of this layer
layer_info = (Face_Curvature_Info *)faceLayer->userdata;
// WVertex *v; int numVertices = iFace->numberOfVertices();
// Vec3r v1v2; for (int i = 0; i < numVertices; i++) {
// real t; v = iFace->GetVertex(i);
// vector<WXFaceLayer*> SmoothLayers; // vec_curvature_info[i] contains the curvature info of this vertex
// WXFaceLayer *faceLayer; Vec3r e2 = layer_info->vec_curvature_info[i]->K2*layer_info->vec_curvature_info[i]->e2;
// Face_Curvature_Info *layer_info; Vec3r e1 = layer_info->vec_curvature_info[i]->K1*layer_info->vec_curvature_info[i]->e1;
// real K1_a(0), K1_b(0); e2.normalize();
// Vec3r Inter_a, Inter_b;
// // find the ridge layer of the face WVertex::face_iterator fit = v->faces_begin();
// iFace->retrieveSmoothLayers(Nature::RIDGE, SmoothLayers); WVertex::face_iterator fitend = v->faces_end();
// if(SmoothLayers.size()!=1) for (; fit != fitend; ++fit) {
// return; WXFace *wxf = dynamic_cast<WXFace*>(*fit);
// faceLayer = SmoothLayers[0]; WOEdge *oppositeEdge;
// // retrieve the curvature info of this layer if (!(wxf->getOppositeEdge(v, oppositeEdge)))
// layer_info = (Face_Curvature_Info *)faceLayer->userdata; 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;
// int numVertices = iFace->numberOfVertices(); unsigned index1 = wxf->GetIndex(oppositeEdge->GetaVertex());
// for(int i=0; i<numVertices; i++){ unsigned index2 = wxf->GetIndex(oppositeEdge->GetbVertex());
// v = iFace->GetVertex(i); real K1_1 = second_layer_info->vec_curvature_info[index1]->K1;
// // vec_curvature_info[i] contains the curvature info of this vertex real K1_2 = second_layer_info->vec_curvature_info[index2]->K1;
// Vec3r e2 = layer_info->vec_curvature_info[i]->K2*layer_info->vec_curvature_info[i]->e2; real K1 = (1.0 - t) * K1_1 + t * K1_2;
// Vec3r e1 = layer_info->vec_curvature_info[i]->K1*layer_info->vec_curvature_info[i]->e1; Vec3r inter((1.0 - t) * oppositeEdge->GetaVertex()->GetVertex() +
// e2.normalize(); 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);
}
// WVertex::face_iterator fit = v->faces_begin(); // Make the values relevant by checking whether all principal directions have the "same" direction:
// WVertex::face_iterator fitend = v->faces_end(); Vec3r e0((layer_info->vec_curvature_info[0]->K1 * layer_info->vec_curvature_info[0]->e1));
// for(; fit!=fitend; ++fit){ e0.normalize();
// WXFace * wxf = dynamic_cast<WXFace*>(*fit); Vec3r e1((layer_info->vec_curvature_info[1]->K1 * layer_info->vec_curvature_info[1]->e1));
// WOEdge * oppositeEdge; e1.normalize();
// if(!(wxf->getOppositeEdge(v, oppositeEdge))) Vec3r e2((layer_info->vec_curvature_info[2]->K1 * layer_info->vec_curvature_info[2]->e1));
// continue; e2.normalize();
// v1v2 = oppositeEdge->GetbVertex()->GetVertex() - oppositeEdge->GetaVertex()->GetVertex(); if (e0 * e1 < 0)
// GeomUtils::intersection_test res; // invert dotP[1]
// res = GeomUtils::intersectRayPlane(oppositeEdge->GetaVertex()->GetVertex(), v1v2, faceLayer->ReplaceDotP(1, -faceLayer->dotP(1));
// e2, -(v->GetVertex()*e2), if (e0 * e2 < 0)
// t,1.e-06); // invert dotP[2]
// if((res == GeomUtils::DO_INTERSECT) && (t>=0.0) && (t<=1.0)){ faceLayer->ReplaceDotP(2, -faceLayer->dotP(2));
// 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()); #if 0 // remove the weakest values;
// unsigned index2 = wxf->GetIndex(oppositeEdge->GetbVertex()); real minDiff = (_maxK1 - _minK1) / 10.0;
// real K1_1 = second_layer_info->vec_curvature_info[index1]->K1; real minDiff = _meanK1;
// real K1_2 = second_layer_info->vec_curvature_info[index2]->K1; if ((faceLayer->dotP(0) < minDiff) && (faceLayer->dotP(1) < minDiff) && (faceLayer->dotP(2) < minDiff)) {
// real K1 = (1.0-t)*K1_1 + t*K1_2; faceLayer->ReplaceDotP(0, 0);
// Vec3r inter((1.0-t)*oppositeEdge->GetaVertex()->GetVertex() + t*oppositeEdge->GetbVertex()->GetVertex()); faceLayer->ReplaceDotP(1, 0);
// Vec3r vtmp(inter - v->GetVertex()); faceLayer->ReplaceDotP(2, 0);
// // is it K1_a or K1_b ? }
// if(vtmp*e1 > 0){ #endif
// K1_b = K1; }
// Inter_b = inter; #endif
// }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);
// // }
// }
// SUGGESTIVE CONTOURS // SUGGESTIVE CONTOURS
////////////////////// //////////////////////
void FEdgeXDetector::processSuggestiveContourShape(WXShape* iWShape) { void FEdgeXDetector::processSuggestiveContourShape(WXShape *iWShape)
{
// Here the curvatures must already have been computed // Here the curvatures must already have been computed
vector<WFace*>& wfaces = iWShape->GetFaceList(); vector<WFace*>& wfaces = iWShape->GetFaceList();
vector<WFace*>::iterator f, fend; vector<WFace*>::iterator f, fend;
for(f=wfaces.begin(), fend=wfaces.end(); for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
f!=fend;
++f)
{
ProcessSuggestiveContourFace((WXFace*)(*f)); ProcessSuggestiveContourFace((WXFace*)(*f));
} }
} }
@@ -563,34 +553,32 @@ void FEdgeXDetector::ProcessSuggestiveContourFace(WXFace *iFace)
faceLayer->PushDotP(wxv->curvatures()->Kr); faceLayer->PushDotP(wxv->curvatures()->Kr);
} }
// FIXME: find a more clever way to compute the threshold #if 0 // FIXME: find a more clever way to compute the threshold
// real threshold = _meanKr; real threshold = _meanKr;
// if(faceLayer->nPosDotP()!=numVertices){ if (faceLayer->nPosDotP()!=numVertices) {
// if((fabs(faceLayer->dotP(0)) < threshold) && (fabs(faceLayer->dotP(1)) < threshold) && (fabs(faceLayer->dotP(2)) < threshold)){ if ((fabs(faceLayer->dotP(0)) < threshold) && (fabs(faceLayer->dotP(1)) < threshold) &&
// faceLayer->ReplaceDotP(0, 0); (fabs(faceLayer->dotP(2)) < threshold)) {
// faceLayer->ReplaceDotP(1, 0); faceLayer->ReplaceDotP(0, 0);
// faceLayer->ReplaceDotP(2, 0); faceLayer->ReplaceDotP(1, 0);
// } faceLayer->ReplaceDotP(2, 0);
// } }
}
#endif
} }
void FEdgeXDetector::postProcessSuggestiveContourShape(WXShape* iShape) { void FEdgeXDetector::postProcessSuggestiveContourShape(WXShape *iShape)
{
vector<WFace*>& wfaces = iShape->GetFaceList(); vector<WFace*>& wfaces = iShape->GetFaceList();
vector<WFace*>::iterator f, fend; vector<WFace*>::iterator f, fend;
for(f=wfaces.begin(), fend=wfaces.end(); for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
f!=fend;
++f)
{
postProcessSuggestiveContourFace((WXFace*)(*f)); postProcessSuggestiveContourFace((WXFace*)(*f));
} }
} }
void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) { void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace)
{
// Compute the derivative of the radial curvature in the radial direction, // Compute the derivative of the radial curvature in the radial direction, at the two extremities of the smooth edge.
// at the two extremities of the smooth edge. // If the derivative is smaller than a given threshold _kr_derivative_epsilon, discard the 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). // Find the suggestive contour layer of the face (zero or one edge).
vector<WXFaceLayer*> sc_layers; vector<WXFaceLayer*> sc_layers;
@@ -612,7 +600,7 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
GeomUtils::intersection_test res; GeomUtils::intersection_test res;
real kr(0), kr1(0), kr2(0), t; real kr(0), kr1(0), kr2(0), t;
for (unsigned i = 0; i < vertices_nb; ++i) { for (unsigned int i = 0; i < vertices_nb; ++i) {
v = (WXVertex*)(iFace->GetVertex(i)); v = (WXVertex*)(iFace->GetVertex(i));
// v is a singular vertex, skip it. // v is a singular vertex, skip it.
@@ -625,11 +613,9 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
er_vec = v->curvatures()->er; er_vec = v->curvatures()->er;
// For each vertex, iterate on its adjacent faces. // For each vertex, iterate on its adjacent faces.
for (WVertex::face_iterator fit = v->faces_begin(), fitend = v->faces_end(); for (WVertex::face_iterator fit = v->faces_begin(), fitend = v->faces_end(); fit != fitend; ++fit) {
fit != fitend;
++fit) {
wxf = dynamic_cast<WXFace*>(*fit); wxf = dynamic_cast<WXFace*>(*fit);
if(!(wxf->getOppositeEdge(v, opposite_edge))) if (!wxf->getOppositeEdge(v, opposite_edge))
continue; continue;
opposite_vertex_a = (WXVertex *)opposite_edge->GetaVertex(); opposite_vertex_a = (WXVertex *)opposite_edge->GetaVertex();
@@ -640,8 +626,7 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
// Test wether the radial plan intersects with the edge at the opposite of v. // Test wether the radial plan intersects with the edge at the opposite of v.
res = GeomUtils::intersectRayPlane(opposite_vertex_a->GetVertex(), opposite_edge->GetVec(), res = GeomUtils::intersectRayPlane(opposite_vertex_a->GetVertex(), opposite_edge->GetVec(),
radial_normal_vec, -(v_vec * radial_normal_vec), radial_normal_vec, -(v_vec * radial_normal_vec),
t, t, 1.0e-06);
1.e-06);
// If there is an intersection, compute the value of the derivative ath that point. // If there is an intersection, compute the value of the derivative ath that point.
if ((res == GeomUtils::DO_INTERSECT) && (t >= 0) && (t <= 1)) { if ((res == GeomUtils::DO_INTERSECT) && (t >= 0) && (t <= 1)) {
@@ -652,7 +637,8 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
if (tmp_vec * er_vec > 0) { if (tmp_vec * er_vec > 0) {
kr2 = kr; kr2 = kr;
inter2 = inter; inter2 = inter;
} else { }
else {
kr1 = kr; kr1 = kr;
inter1 = inter; inter1 = inter;
} }
@@ -668,13 +654,13 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
} }
// At that point, we have the derivatives for each vertex of iFace. // 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 // All we have to do now is to use linear interpolation to compute the values at the extremities of the smooth edge.
// the extremities of the smooth edge.
WXSmoothEdge *sc_edge = sc_layer->getSmoothEdge(); WXSmoothEdge *sc_edge = sc_layer->getSmoothEdge();
WOEdge *sc_oedge = sc_edge->woea(); WOEdge *sc_oedge = sc_edge->woea();
t = sc_edge->ta(); t = sc_edge->ta();
if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] + if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
(1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon) { (1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon)
{
sc_layer->removeSmoothEdge(); sc_layer->removeSmoothEdge();
return; return;
} }
@@ -682,21 +668,21 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
t = sc_edge->tb(); t = sc_edge->tb();
if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] + if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
(1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon) (1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon)
{
sc_layer->removeSmoothEdge(); sc_layer->removeSmoothEdge();
} }
}
// MATERIAL_BOUNDARY // MATERIAL_BOUNDARY
//////////////////// ////////////////////
void FEdgeXDetector::processMaterialBoundaryShape(WXShape* iWShape) { void FEdgeXDetector::processMaterialBoundaryShape(WXShape *iWShape)
{
if (!_computeViewIndependant) if (!_computeViewIndependant)
return; return;
// Make a pass on the edges to detect material boundaries // Make a pass on the edges to detect material boundaries
vector<WEdge*>::iterator we, weend; vector<WEdge*>::iterator we, weend;
vector<WEdge*> &wedges = iWShape->getEdgeList(); vector<WEdge*> &wedges = iWShape->getEdgeList();
for(we=wedges.begin(), weend=wedges.end(); for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
we!=weend;
++we){
ProcessMaterialBoundaryEdge((WXEdge*)(*we)); ProcessMaterialBoundaryEdge((WXEdge*)(*we));
} }
} }
@@ -713,19 +699,18 @@ void FEdgeXDetector::ProcessMaterialBoundaryEdge(WXEdge *iEdge)
// EDGE MARKS // EDGE MARKS
///////////// /////////////
void FEdgeXDetector::processEdgeMarksShape(WXShape *iShape)
void FEdgeXDetector::processEdgeMarksShape(WXShape* iShape) { {
// Make a pass on the edges to detect material boundaries // Make a pass on the edges to detect material boundaries
vector<WEdge*>::iterator we, weend; vector<WEdge*>::iterator we, weend;
vector<WEdge*> &wedges = iShape->getEdgeList(); vector<WEdge*> &wedges = iShape->getEdgeList();
for(we=wedges.begin(), weend=wedges.end(); for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
we!=weend;
++we){
ProcessEdgeMarks((WXEdge*)(*we)); ProcessEdgeMarks((WXEdge*)(*we));
} }
} }
void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge) { void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge)
{
if (iEdge->GetMark()) { if (iEdge->GetMark()) {
iEdge->AddNature(Nature::EDGE_MARK); iEdge->AddNature(Nature::EDGE_MARK);
} }
@@ -733,20 +718,19 @@ void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge) {
// Build Smooth edges // Build Smooth edges
///////////////////// /////////////////////
void FEdgeXDetector::buildSmoothEdges(WXShape* iShape){ void FEdgeXDetector::buildSmoothEdges(WXShape *iShape)
{
bool hasSmoothEdges = false; bool hasSmoothEdges = false;
// Make a last pass to build smooth edges from the previous stored values: // Make a last pass to build smooth edges from the previous stored values:
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
vector<WFace*>& wfaces = iShape->GetFaceList(); vector<WFace*>& wfaces = iShape->GetFaceList();
for(vector<WFace*>::iterator f=wfaces.begin(), fend=wfaces.end(); for (vector<WFace*>::iterator f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
f!=fend;
++f)
{
vector<WXFaceLayer*>& faceLayers = ((WXFace*)(*f))->getSmoothLayers(); vector<WXFaceLayer*>& faceLayers = ((WXFace*)(*f))->getSmoothLayers();
for (vector<WXFaceLayer*>::iterator wxfl = faceLayers.begin(), wxflend = faceLayers.end(); for (vector<WXFaceLayer*>::iterator wxfl = faceLayers.begin(), wxflend = faceLayers.end();
wxfl != wxflend; wxfl != wxflend;
++wxfl){ ++wxfl)
{
if ((*wxfl)->BuildSmoothEdge()) if ((*wxfl)->BuildSmoothEdge())
hasSmoothEdges = true; hasSmoothEdges = true;
} }
@@ -754,9 +738,7 @@ void FEdgeXDetector::buildSmoothEdges(WXShape* iShape){
if (hasSmoothEdges && !_computeRidgesAndValleys && !_computeSuggestiveContours) { if (hasSmoothEdges && !_computeRidgesAndValleys && !_computeSuggestiveContours) {
vector<WVertex*>& wvertices = iShape->getVertexList(); vector<WVertex*>& wvertices = iShape->getVertexList();
for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end(); for (vector<WVertex*>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
wv!=wvend;
++wv){
// Compute curvatures // Compute curvatures
WXVertex *wxv = dynamic_cast<WXVertex*>(*wv); WXVertex *wxv = dynamic_cast<WXVertex*>(*wv);
computeCurvatures(wxv); computeCurvatures(wxv);

View File

@@ -1,57 +1,61 @@
// /*
// Filename : FEdgeXDetector.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Detects/flags/builds extended features edges on the * This program is free software; you can redistribute it and/or
// WXEdge structure * modify it under the terms of the GNU General Public License
// Date of creation : 26/10/2003 * 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_FEDGE_X_DETECTOR_H__
#define __FREESTYLE_FEDGE_X_DETECTOR_H__
// /** \file blender/freestyle/intern/view_map/FEdgeXDetector.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Detects/flags/builds extended features edges on the WXEdge structure
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 26/10/2003
// 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 <vector>
# include "../system/FreestyleConfig.h"
#include "../geometry/Geom.h" #include "../geometry/Geom.h"
# include "../winged_edge/WXEdge.h"
# include "../winged_edge/Curvature.h" #include "../system/FreestyleConfig.h"
#include "../system/ProgressBar.h" #include "../system/ProgressBar.h"
#include "../system/RenderMonitor.h" #include "../system/RenderMonitor.h"
#include "../winged_edge/Curvature.h"
#include "../winged_edge/WXEdge.h"
using namespace Geometry; using namespace Geometry;
/*! This class takes as input a WXEdge structure and fills it /*! This class takes as input a WXEdge structure and fills it */
*/
class LIB_VIEW_MAP_EXPORT FEdgeXDetector class LIB_VIEW_MAP_EXPORT FEdgeXDetector
{ {
public: public:
FEdgeXDetector()
FEdgeXDetector() { {
_pProgressBar = 0; _pProgressBar = NULL;
_pRenderMonitor = 0; _pRenderMonitor = NULL;
_computeViewIndependant = true; _computeViewIndependant = true;
_bbox_diagonal = 1.0; _bbox_diagonal = 1.0;
_meanEdgeSize = 0; _meanEdgeSize = 0;
@@ -65,6 +69,7 @@ public:
_kr_derivative_epsilon = 0.0; _kr_derivative_epsilon = 0.0;
_creaseAngle = 0.7; // angle of 134.43 degrees _creaseAngle = 0.7; // angle of 134.43 degrees
} }
virtual ~FEdgeXDetector() {} virtual ~FEdgeXDetector() {}
/*! Process shapes from a WingedEdge containing a list of WShapes */ /*! Process shapes from a WingedEdge containing a list of WShapes */
@@ -83,13 +88,15 @@ public:
// CREASE // CREASE
virtual void processCreaseShape(WXShape *iShape); virtual void processCreaseShape(WXShape *iShape);
virtual void ProcessCreaseEdge(WXEdge *iEdge); virtual void ProcessCreaseEdge(WXEdge *iEdge);
/*! Sets the minimum angle for detecting crease edges /*! Sets the minimum angle for detecting crease edges
* \param angle * \param angle
* The angular threshold in degrees (between 0 and 180) for detecting crease * The angular threshold in degrees (between 0 and 180) for detecting crease edges. An edge is considered
* edges. An edge is considered a crease edge if the angle between two faces * a crease edge if the angle between two faces sharing the edge is smaller than the given threshold.
* sharing the edge is smaller than the given threshold.
*/ */
inline void setCreaseAngle(real angle) { // XXX angle should be in radian...
inline void setCreaseAngle(real angle)
{
if (angle < 0.0) if (angle < 0.0)
angle = 0.0; angle = 0.0;
else if (angle > 180.0) else if (angle > 180.0)
@@ -118,7 +125,8 @@ public:
* \param dkr * \param dkr
* The minimal derivative of the radial curvature * The minimal derivative of the radial curvature
*/ */
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr) { inline void setSuggestiveContourKrDerivativeEpsilon(real dkr)
{
if (dkr != _kr_derivative_epsilon) { if (dkr != _kr_derivative_epsilon) {
_kr_derivative_epsilon = dkr; _kr_derivative_epsilon = dkr;
_changes = true; _changes = true;
@@ -137,40 +145,70 @@ public:
virtual void buildSmoothEdges(WXShape *iShape); virtual void buildSmoothEdges(WXShape *iShape);
/*! Sets the current viewpoint */ /*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;} inline void setViewpoint(const Vec3r& ivp)
inline void enableOrthographicProjection(bool b) {_orthographicProjection = b;} {
inline void enableRidgesAndValleysFlag(bool b) {_computeRidgesAndValleys = b;} _Viewpoint = ivp;
inline void enableSuggestiveContours(bool b) {_computeSuggestiveContours = b;} }
inline void enableMaterialBoundaries(bool b) {_computeMaterialBoundaries = b;}
inline void enableFaceSmoothness(bool b) { 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) { if (b != _faceSmoothness) {
_faceSmoothness = b; _faceSmoothness = b;
_changes=true; _changes=true;
} }
} }
inline void enableFaceMarks(bool b) {
inline void enableFaceMarks(bool b)
{
if (b != _faceMarks) { if (b != _faceMarks) {
_faceMarks = b; _faceMarks = b;
_changes=true; _changes=true;
} }
} }
/*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation) /*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation)
* \param r * \param r
* The radius of the sphere expressed as a ratio of the mean edge size * The radius of the sphere expressed as a ratio of the mean edge size
*/ */
inline void setSphereRadius(real r) { inline void setSphereRadius(real r)
{
if (r != _sphereRadius) { if (r != _sphereRadius) {
_sphereRadius = r; _sphereRadius = r;
_changes=true; _changes=true;
} }
} }
inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;} inline void setProgressBar(ProgressBar *iProgressBar)
{
_pProgressBar = iProgressBar;
}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;} inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
{
_pRenderMonitor = iRenderMonitor;
}
protected: protected:
Vec3r _Viewpoint; Vec3r _Viewpoint;
real _bbox_diagonal; // diagonal of the current processed shape bbox real _bbox_diagonal; // diagonal of the current processed shape bbox
//oldtmp values //oldtmp values
@@ -200,4 +238,4 @@ protected:
RenderMonitor *_pRenderMonitor; RenderMonitor *_pRenderMonitor;
}; };
#endif // FEDGEDXETECTOR_H #endif // __FREESTYLE_FEDGE_X_DETECTOR_H__

View File

@@ -1,23 +1,37 @@
/*
* ***** 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/Functions0D.cpp
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Functions taking 0D input
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \author Emmanuel Turquin
// modify it under the terms of the GNU General Public License * \date 01/07/2003
// 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 "Functions0D.h" #include "Functions0D.h"
#include "ViewMap.h" #include "ViewMap.h"
@@ -27,13 +41,13 @@ using namespace std;
namespace Functions0D { namespace Functions0D {
// Internal function // Internal function
FEdge* getFEdge(Interface0D& it1, Interface0D& it2){ FEdge *getFEdge(Interface0D& it1, Interface0D& it2)
{
return it1.getFEdge(it2); return it1.getFEdge(it2);
} }
void getFEdges(Interface0DIterator& it, void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2)
FEdge*& fe1, {
FEdge*& fe2) {
// count number of vertices // count number of vertices
Interface0DIterator prev = it, next = it; Interface0DIterator prev = it, next = it;
++next; ++next;
@@ -41,26 +55,22 @@ namespace Functions0D {
if (!it.isBegin() && !next.isEnd()) { if (!it.isBegin() && !next.isEnd()) {
count = 3; count = 3;
} }
if(count < 3) if (count < 3) {
{
// if we only have 2 vertices // if we only have 2 vertices
FEdge *fe = 0; FEdge *fe = 0;
Interface0DIterator tmp = it; Interface0DIterator tmp = it;
if(it.isBegin()) if (it.isBegin()) {
{
++tmp; ++tmp;
fe = it->getFEdge(*tmp); fe = it->getFEdge(*tmp);
} }
else else {
{
--tmp; --tmp;
fe = it->getFEdge(*tmp); fe = it->getFEdge(*tmp);
} }
fe1 = fe; fe1 = fe;
fe2 = 0; fe2 = NULL;
} }
else else {
{
// we have more than 2 vertices // we have more than 2 vertices
bool begin = false, last = false; bool begin = false, last = false;
Interface0DIterator previous = it; Interface0DIterator previous = it;
@@ -72,39 +82,34 @@ namespace Functions0D {
++next; ++next;
if (next.isEnd()) if (next.isEnd())
last = true; last = true;
if(begin) if (begin) {
{
fe1 = it->getFEdge(*next); fe1 = it->getFEdge(*next);
fe2 = 0; fe2 = NULL;
} }
else if(last) else if (last) {
{
fe1 = previous->getFEdge(*it); fe1 = previous->getFEdge(*it);
fe2 = 0; fe2 = NULL;
} }
else else {
{
fe1 = previous->getFEdge(*it); fe1 = previous->getFEdge(*it);
fe2 = it->getFEdge(*next); fe2 = it->getFEdge(*next);
} }
} }
} }
void getViewEdges(Interface0DIterator &it, void getViewEdges(Interface0DIterator &it, ViewEdge *&ve1, ViewEdge *&ve2)
ViewEdge *&ve1,
ViewEdge *&ve2)
{ {
FEdge *fe1, *fe2; FEdge *fe1, *fe2;
getFEdges(it, fe1, fe2); getFEdges(it, fe1, fe2);
ve1 = fe1->viewedge(); ve1 = fe1->viewedge();
if(fe2 != 0) if (fe2 != NULL) {
{
ve2 = fe2->viewedge(); ve2 = fe2->viewedge();
if (ve2 == ve1) if (ve2 == ve1)
ve2 = 0; ve2 = NULL;
}
else {
ve2 = NULL;
} }
else
ve2 = 0;
} }
ViewShape *getShapeF0D(Interface0DIterator& it) ViewShape *getShapeF0D(Interface0DIterator& it)
@@ -114,7 +119,8 @@ namespace Functions0D {
return ve1->viewShape(); return ve1->viewShape();
} }
void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders){ void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders)
{
ViewEdge *ve1, *ve2; ViewEdge *ve1, *ve2;
getViewEdges(it, ve1, ve2); getViewEdges(it, ve1, ve2);
occluder_container::const_iterator oit = ve1->occluders_begin(); occluder_container::const_iterator oit = ve1->occluders_begin();
@@ -123,7 +129,7 @@ namespace Functions0D {
for (; oit != oitend; ++oit) for (; oit != oitend; ++oit)
oOccluders.insert((*oit)); oOccluders.insert((*oit));
if(ve2!=0){ if (ve2 != NULL) {
oit = ve2->occluders_begin(); oit = ve2->occluders_begin();
oitend = ve2->occluders_end(); oitend = ve2->occluders_end();
for (; oit != oitend; ++oit) for (; oit != oitend; ++oit)
@@ -131,7 +137,8 @@ namespace Functions0D {
} }
} }
ViewShape * getOccludeeF0D(Interface0DIterator& it){ ViewShape *getOccludeeF0D(Interface0DIterator& it)
{
ViewEdge *ve1, *ve2; ViewEdge *ve1, *ve2;
getViewEdges(it, ve1, ve2); getViewEdges(it, ve1, ve2);
ViewShape *aShape = ve1->aShape(); ViewShape *aShape = ve1->aShape();
@@ -139,13 +146,14 @@ namespace Functions0D {
} }
// //
int VertexOrientation2DF0D::operator()(Interface0DIterator& iter) { int VertexOrientation2DF0D::operator()(Interface0DIterator& iter)
{
Vec2f A, C; Vec2f A, C;
Vec2f B(iter->getProjectedX(), iter->getProjectedY()); Vec2f B(iter->getProjectedX(), iter->getProjectedY());
if(iter.isBegin()) if (iter.isBegin()) {
A = Vec2f(iter->getProjectedX(), iter->getProjectedY()); A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
else }
{ else {
Interface0DIterator previous = iter; Interface0DIterator previous = iter;
--previous ; --previous ;
A = Vec2f(previous->getProjectedX(), previous->getProjectedY()); A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
@@ -169,13 +177,14 @@ namespace Functions0D {
return 0; return 0;
} }
int VertexOrientation3DF0D::operator()(Interface0DIterator& iter) { int VertexOrientation3DF0D::operator()(Interface0DIterator& iter)
{
Vec3r A, C; Vec3r A, C;
Vec3r B(iter->getX(), iter->getY(), iter->getZ()); Vec3r B(iter->getX(), iter->getY(), iter->getZ());
if(iter.isBegin()) if (iter.isBegin()) {
A = Vec3r(iter->getX(), iter->getY(), iter->getZ()); A = Vec3r(iter->getX(), iter->getY(), iter->getZ());
else }
{ else {
Interface0DIterator previous = iter; Interface0DIterator previous = iter;
--previous ; --previous ;
A = Vec3r(previous->getX(), previous->getY(), previous->getZ()); A = Vec3r(previous->getX(), previous->getY(), previous->getZ());
@@ -199,17 +208,16 @@ namespace Functions0D {
return 0; return 0;
} }
int Curvature2DAngleF0D::operator()(Interface0DIterator& iter) { int Curvature2DAngleF0D::operator()(Interface0DIterator& iter)
{
Interface0DIterator tmp1 = iter, tmp2 = iter; Interface0DIterator tmp1 = iter, tmp2 = iter;
++tmp2; ++tmp2;
unsigned count = 1; unsigned count = 1;
while((!tmp1.isBegin()) && (count < 3)) while ((!tmp1.isBegin()) && (count < 3)) {
{
--tmp1; --tmp1;
++count; ++count;
} }
while((!tmp2.isEnd()) && (count < 3)) while ((!tmp2.isEnd()) && (count < 3)) {
{
++tmp2; ++tmp2;
++count; ++count;
} }
@@ -224,8 +232,7 @@ namespace Functions0D {
++v; ++v;
Interface0DIterator next = v; Interface0DIterator next = v;
++next; ++next;
if(next.isEnd()) if (next.isEnd()) {
{
next = v; next = v;
--v; --v;
} }
@@ -243,8 +250,7 @@ namespace Functions0D {
Vec2r N2(-BC[1], BC[0]); Vec2r N2(-BC[1], BC[0]);
if (N2.norm() != 0) if (N2.norm() != 0)
N2.normalize(); N2.normalize();
if((N1.norm() == 0) && (N2.norm() == 0)) if ((N1.norm() == 0) && (N2.norm() == 0)) {
{
Exception::raiseException(); Exception::raiseException();
result = 0; result = 0;
return -1; return -1;
@@ -258,25 +264,26 @@ namespace Functions0D {
return 0; return 0;
} }
int ZDiscontinuityF0D::operator()(Interface0DIterator& iter) { int ZDiscontinuityF0D::operator()(Interface0DIterator& iter)
{
FEdge *fe1, *fe2; FEdge *fe1, *fe2;
getFEdges(iter, fe1, fe2); getFEdges(iter, fe1, fe2);
result = fe1->z_discontinuity(); result = fe1->z_discontinuity();
if(fe2!=0){ if (fe2 != NULL) {
result += fe2->z_discontinuity(); result += fe2->z_discontinuity();
result /= 2.f; result /= 2.0f;
} }
return 0; return 0;
} }
int Normal2DF0D::operator()(Interface0DIterator& iter) { int Normal2DF0D::operator()(Interface0DIterator& iter)
{
FEdge *fe1, *fe2; FEdge *fe1, *fe2;
getFEdges(iter, fe1, fe2); getFEdges(iter, fe1, fe2);
Vec3f e1(fe1->orientation2d()); Vec3f e1(fe1->orientation2d());
Vec2f n1(e1[1], -e1[0]); Vec2f n1(e1[1], -e1[0]);
Vec2f n(n1); Vec2f n(n1);
if(fe2 != 0) if (fe2 != NULL) {
{
Vec3f e2(fe2->orientation2d()); Vec3f e2(fe2->orientation2d());
Vec2f n2(e2[1], -e2[0]); Vec2f n2(e2[1], -e2[0]);
n += n2; n += n2;
@@ -286,32 +293,37 @@ namespace Functions0D {
return 0; return 0;
} }
int MaterialF0D::operator()(Interface0DIterator& iter) { int MaterialF0D::operator()(Interface0DIterator& iter)
{
FEdge *fe1, *fe2; FEdge *fe1, *fe2;
getFEdges(iter, fe1, fe2); getFEdges(iter, fe1, fe2);
if(fe1 == 0) if (fe1 == NULL)
return -1; return -1;
if (fe1->isSmooth()) if (fe1->isSmooth())
result = ((FEdgeSmooth*)fe1)->frs_material(); result = ((FEdgeSmooth*)fe1)->frs_material();
else else
result = ((FEdgeSharp*)fe1)->bFrsMaterial(); result = ((FEdgeSharp*)fe1)->bFrsMaterial();
// const SShape * sshape = getShapeF0D(iter); #if 0
// return sshape->material(); const SShape *sshape = getShapeF0D(iter);
return sshape->material();
#endif
return 0; return 0;
} }
int ShapeIdF0D::operator()(Interface0DIterator& iter) { int ShapeIdF0D::operator()(Interface0DIterator& iter)
{
ViewShape *vshape = getShapeF0D(iter); ViewShape *vshape = getShapeF0D(iter);
result = vshape->getId(); result = vshape->getId();
return 0; return 0;
} }
int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter) { int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter)
{
ViewEdge *ve1, *ve2; ViewEdge *ve1, *ve2;
getViewEdges(iter, ve1, ve2); getViewEdges(iter, ve1, ve2);
unsigned int qi1, qi2; unsigned int qi1, qi2;
qi1 = ve1->qi(); qi1 = ve1->qi();
if(ve2 != 0){ if (ve2 != NULL) {
qi2 = ve2->qi(); qi2 = ve2->qi();
if (qi2 != qi1) if (qi2 != qi1)
cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl; cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
@@ -320,36 +332,38 @@ namespace Functions0D {
return 0; return 0;
} }
int CurveNatureF0D::operator()(Interface0DIterator& iter) { int CurveNatureF0D::operator()(Interface0DIterator& iter)
{
Nature::EdgeNature nat = 0; Nature::EdgeNature nat = 0;
ViewEdge *ve1, *ve2; ViewEdge *ve1, *ve2;
getViewEdges(iter, ve1, ve2); getViewEdges(iter, ve1, ve2);
nat |= ve1->getNature(); nat |= ve1->getNature();
if(ve2!=0) if (ve2 != NULL)
nat |= ve2->getNature(); nat |= ve2->getNature();
result = nat; result = nat;
return 0; return 0;
} }
int GetOccludersF0D::operator()(Interface0DIterator& iter) { int GetOccludersF0D::operator()(Interface0DIterator& iter)
{
set<ViewShape*> occluders; set<ViewShape*> occluders;
getOccludersF0D(iter, occluders); getOccludersF0D(iter, occluders);
result.clear(); result.clear();
//vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end()); //vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end());
for(set<ViewShape*>::iterator it=occluders.begin(), itend=occluders.end(); for (set<ViewShape*>::iterator it = occluders.begin(), itend = occluders.end(); it != itend; ++it) {
it!=itend;
++it){
result.push_back((*it)); result.push_back((*it));
} }
return 0; return 0;
} }
int GetShapeF0D::operator()(Interface0DIterator& iter) { int GetShapeF0D::operator()(Interface0DIterator& iter)
{
result = getShapeF0D(iter); result = getShapeF0D(iter);
return 0; return 0;
} }
int GetOccludeeF0D::operator()(Interface0DIterator& iter) { int GetOccludeeF0D::operator()(Interface0DIterator& iter)
{
result = getOccludeeF0D(iter); result = getOccludeeF0D(iter);
return 0; return 0;
} }

View File

@@ -1,64 +1,70 @@
// /*
// Filename : Functions0D.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli, Emmanuel Turquin *
// Purpose : Functions taking 0D input * This program is free software; you can redistribute it and/or
// Date of creation : 01/07/2003 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Functions taking 0D input
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \author Emmanuel Turquin
// modify it under the terms of the GNU General Public License * \date 01/07/2003
// 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 <set>
#include <vector> #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"
class FEdge; class FEdge;
class ViewEdge; class ViewEdge;
class SShape; class SShape;
using namespace Geometry; using namespace Geometry;
#include "../python/Director.h"
// //
// UnaryFunction0D (base class for functions in 0D) // UnaryFunction0D (base class for functions in 0D)
// //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
template <class T> /*! Base class for Unary Functions (functors) working on Interface0DIterator.
/*! Base class for Unary Functions (functors) working * A unary function will be used by calling its operator() on an Interface0DIterator.
* on Interface0DIterator. * \attention In the scripting language, there exists several prototypes depending on the returned value type.
* A unary function will be used by calling * For example, you would inherit from a UnaryFunction0DDouble if you wish to define a function that returns a double.
* 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: * The different existing prototypes are:
* - UnaryFunction0DVoid * - UnaryFunction0DVoid
* - UnaryFunction0DUnsigned * - UnaryFunction0DUnsigned
@@ -68,36 +74,40 @@ template <class T>
* - UnaryFunction0DVec2f * - UnaryFunction0DVec2f
* - UnaryFunction0DVec3f * - UnaryFunction0DVec3f
*/ */
template <class T>
class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction0D class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction0D
{ {
public: public:
T result; T result;
PyObject *py_uf0D; PyObject *py_uf0D;
/*! The type of the value /*! The type of the value returned by the functor. */
* returned by the functor.
*/
typedef T ReturnedValueType; typedef T ReturnedValueType;
/*! Default constructor. */ /*! Default constructor. */
UnaryFunction0D() { py_uf0D = 0;} UnaryFunction0D()
/*! Destructor; */ {
virtual ~UnaryFunction0D() {} py_uf0D = NULL;
/*! 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 );
} }
/*! 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 #ifdef SWIG
@@ -120,12 +130,12 @@ UnaryFunction0D() { py_uf0D = 0;}
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >; %template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
#endif // SWIG #endif // SWIG
// //
// Functions definitions // Functions definitions
// //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
class ViewShape; class ViewShape;
namespace Functions0D { namespace Functions0D {
// GetXF0D // GetXF0D
@@ -134,11 +144,14 @@ namespace Functions0D {
{ {
public: public:
/*! Returns the string "GetXF0D" */ /*! Returns the string "GetXF0D" */
string getName() const { string getName() const
{
return "GetXF0D"; return "GetXF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter) { int operator()(Interface0DIterator& iter)
{
result = iter->getX(); result = iter->getX();
return 0; return 0;
} }
@@ -150,11 +163,14 @@ namespace Functions0D {
{ {
public: public:
/*! Returns the string "GetYF0D" */ /*! Returns the string "GetYF0D" */
string getName() const { string getName() const
{
return "GetYF0D"; return "GetYF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter) { int operator()(Interface0DIterator& iter)
{
result = iter->getY(); result = iter->getY();
return 0; return 0;
} }
@@ -166,11 +182,14 @@ namespace Functions0D {
{ {
public: public:
/*! Returns the string "GetZF0D" */ /*! Returns the string "GetZF0D" */
string getName() const { string getName() const
{
return "GetZF0D"; return "GetZF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter) { int operator()(Interface0DIterator& iter)
{
result = iter->getZ(); result = iter->getZ();
return 0; return 0;
} }
@@ -182,11 +201,14 @@ namespace Functions0D {
{ {
public: public:
/*! Returns the string "GetProjectedXF0D" */ /*! Returns the string "GetProjectedXF0D" */
string getName() const { string getName() const
{
return "GetProjectedXF0D"; return "GetProjectedXF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter) { int operator()(Interface0DIterator& iter)
{
result = iter->getProjectedX(); result = iter->getProjectedX();
return 0; return 0;
} }
@@ -198,11 +220,14 @@ namespace Functions0D {
{ {
public: public:
/*! Returns the string "GetProjectedYF0D" */ /*! Returns the string "GetProjectedYF0D" */
string getName() const { string getName() const
{
return "GetProjectedYF0D"; return "GetProjectedYF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter) { int operator()(Interface0DIterator& iter)
{
result = iter->getProjectedY(); result = iter->getProjectedY();
return 0; return 0;
} }
@@ -214,11 +239,14 @@ namespace Functions0D {
{ {
public: public:
/*! Returns the string "GetProjectedZF0D" */ /*! Returns the string "GetProjectedZF0D" */
string getName() const { string getName() const
{
return "GetProjectedZF0D"; return "GetProjectedZF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter) { int operator()(Interface0DIterator& iter)
{
result = iter->getProjectedZ(); result = iter->getProjectedZ();
return 0; return 0;
} }
@@ -230,11 +258,14 @@ namespace Functions0D {
{ {
public: public:
/*! Returns the string "GetCurvilinearAbscissaF0D" */ /*! Returns the string "GetCurvilinearAbscissaF0D" */
string getName() const { string getName() const
{
return "GetCurvilinearAbscissaF0D"; return "GetCurvilinearAbscissaF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter) { int operator()(Interface0DIterator& iter)
{
result = iter.t(); result = iter.t();
return 0; return 0;
} }
@@ -246,94 +277,101 @@ namespace Functions0D {
{ {
public: public:
/*! Returns the string "GetCurvilinearAbscissaF0D" */ /*! Returns the string "GetCurvilinearAbscissaF0D" */
string getName() const { string getName() const
{
return "GetParameterF0D"; return "GetParameterF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter) { int operator()(Interface0DIterator& iter)
{
result = iter.u(); result = iter.u();
return 0; return 0;
} }
}; };
// VertexOrientation2DF0D // VertexOrientation2DF0D
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element /*! Returns a Vec2r giving the 2D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&. * evaluated at the Interface0D pointed by this Interface0DIterator&.
*/ */
class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f> class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
{ {
public: public:
/*! Returns the string "VertexOrientation2DF0D" */ /*! Returns the string "VertexOrientation2DF0D" */
string getName() const { string getName() const
{
return "VertexOrientation2DF0D"; return "VertexOrientation2DF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
// VertexOrientation3DF0D // VertexOrientation3DF0D
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element /*! Returns a Vec3r giving the 3D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&. * evaluated at the Interface0D pointed by this Interface0DIterator&.
*/ */
class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f> class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
{ {
public: public:
/*! Returns the string "VertexOrientation3DF0D" */ /*! Returns the string "VertexOrientation3DF0D" */
string getName() const { string getName() const
{
return "VertexOrientation3DF0D"; return "VertexOrientation3DF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
// Curvature2DAngleF0D // Curvature2DAngleF0D
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element /*! Returns a real giving the 2D curvature (as an angle) of the 1D element to which the Interface0DIterator&
* to which the Interface0DIterator& belongs to and * belongs to and evaluated at the Interface0D pointed by this Interface0DIterator&.
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/ */
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real> class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real>
{ {
public: public:
/*! Returns the string "Curvature2DAngleF0D" */ /*! Returns the string "Curvature2DAngleF0D" */
string getName() const { string getName() const
{
return "Curvature2DAngleF0D"; return "Curvature2DAngleF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
// ZDiscontinuity // ZDiscontinuity
/*! Returns a real giving the distance between /*! Returns a real giving the distance between and Interface0D and the shape that lies behind (occludee).
* 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
* This distance is evaluated in the camera space and normalized * by the shape to which the Interface0D belongs to, 1 is returned.
* 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> class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
{ {
public: public:
/*! Returns the string "ZDiscontinuityF0D" */ /*! Returns the string "ZDiscontinuityF0D" */
string getName() const { string getName() const
{
return "ZDiscontinuityF0D"; return "ZDiscontinuityF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
// Normal2DF0D // Normal2DF0D
/*! Returns a Vec2f giving the normalized 2D normal to the 1D element /*! Returns a Vec2f giving the normalized 2D normal to the 1D element to which the Interface0DIterator& belongs to and
* to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&. * evaluated at the Interface0D pointed by this Interface0DIterator&.
*/ */
class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f> class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f>
{ {
public: public:
/*! Returns the string "Normal2DF0D" */ /*! Returns the string "Normal2DF0D" */
string getName() const { string getName() const
{
return "Normal2DF0D"; return "Normal2DF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
@@ -341,22 +379,21 @@ namespace Functions0D {
// MaterialF0D // MaterialF0D
/*! Returns the material of the object evaluated at the Interface0D. /*! Returns the material of the object evaluated at the Interface0D.
* This evaluation can be ambiguous (in the case of a TVertex for example. * This evaluation can be ambiguous (in the case of a TVertex for example.
* This functor tries to remove this ambiguity using the context * This functor tries to remove this ambiguity using the context offered by the 1D element to which the
* offered by the 1D element to which the Interface0DIterator& belongs * Interface0DIterator& belongs to and by arbitrary chosing the material of the face that lies on its left when
* to and by arbitrary chosing the material of the face * following the 1D element if there are two different materials on each side of the point.
* that lies on its left when following the 1D element if there * However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* are two different materials on each side of the point. * should implement its own getMaterial functor.
* 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> class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
{ {
public: public:
/*! Returns the string "MaterialF0D" */ /*! Returns the string "MaterialF0D" */
string getName() const { string getName() const
{
return "MaterialF0D"; return "MaterialF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
@@ -364,20 +401,20 @@ namespace Functions0D {
// ShapeIdF0D // ShapeIdF0D
/*! Returns the Id of the Shape the Interface0D belongs to. /*! Returns the Id of the Shape the Interface0D belongs to.
* This evaluation can be ambiguous (in the case of a TVertex for example). * This evaluation can be ambiguous (in the case of a TVertex for example).
* This functor tries to remove this ambiguity using the context * This functor tries to remove this ambiguity using the context offered by the 1D element to which the
* offered by the 1D element to which the Interface0DIterator& belongs * Interface0DIterator& belongs to.
* to. * However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* However, there still can be problematic cases, and the user willing * should implement its own getShapeIdF0D functor.
* to deal with this cases in a specific way should implement
* its own getShapeIdF0D functor.
*/ */
class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id> class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
{ {
public: public:
/*! Returns the string "ShapeIdF0D" */ /*! Returns the string "ShapeIdF0D" */
string getName() const { string getName() const
{
return "ShapeIdF0D"; return "ShapeIdF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
@@ -385,86 +422,85 @@ namespace Functions0D {
// QiF0D // QiF0D
/*! Returns the quantitative invisibility of this Interface0D. /*! Returns the quantitative invisibility of this Interface0D.
* This evaluation can be ambiguous (in the case of a TVertex for example). * This evaluation can be ambiguous (in the case of a TVertex for example).
* This functor tries to remove this ambiguity using the context * This functor tries to remove this ambiguity using the context offered by the 1D element to which the
* offered by the 1D element to which the Interface0DIterator& belongs * Interface0DIterator& belongs to.
* to. * However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* However, there still can be problematic cases, and the user willing * should implement its own getQIF0D functor.
* 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> class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
{ {
public: public:
/*! Returns the string "QuantitativeInvisibilityF0D" */ /*! Returns the string "QuantitativeInvisibilityF0D" */
string getName() const { string getName() const
{
return "QuantitativeInvisibilityF0D"; return "QuantitativeInvisibilityF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
// CurveNatureF0D // CurveNatureF0D
/*! Returns the Nature::EdgeNature of the 1D element the /*! Returns the Nature::EdgeNature of the 1D element the Interface0DIterator& belongs to. */
* Interface0DIterator& belongs to.
*/
class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature> class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
{ {
public: public:
/*! Returns the string "QuantitativeInvisibilityF0D" */ /*! Returns the string "QuantitativeInvisibilityF0D" */
string getName() const { string getName() const
{
return "CurveNatureF0D"; return "CurveNatureF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
// GetShapeF0D // GetShapeF0D
/*! Returns the ViewShape* /*! Returns the ViewShape* containing the Interface0D */
* containing the Interface0D
*/
class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*> class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*>
{ {
public: public:
/*! Returns the string "GetShapeF0D" */ /*! Returns the string "GetShapeF0D" */
string getName() const { string getName() const
{
return "GetShapeF0D"; return "GetShapeF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
// GetOccludersF0D // GetOccludersF0D
/*! Returns a vector containing the ViewShape* /*! Returns a vector containing the ViewShape* occluding the Interface0D */
* occluding the Interface0D
*/
class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> > class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
{ {
public: public:
/*! Returns the string "GetOccludersF0D" */ /*! Returns the string "GetOccludersF0D" */
string getName() const { string getName() const
{
return "GetOccludersF0D"; return "GetOccludersF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
// GetOccludeeF0D // GetOccludeeF0D
/*! Returns the ViewShape* /*! Returns the ViewShape* "occluded" by the Interface0D */
* "occluded" by the Interface0D
*/
class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*> class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
{ {
public: public:
/*! Returns the string "GetOccludeeF0D" */ /*! Returns the string "GetOccludeeF0D" */
string getName() const { string getName() const
{
return "GetOccludeeF0D"; return "GetOccludeeF0D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface0DIterator& iter); int operator()(Interface0DIterator& iter);
}; };
/////////////////////////// Internal //////////////////////////// /////////////////////////// Internal ////////////////////////////
// getFEdge // getFEdge
@@ -473,15 +509,11 @@ namespace Functions0D {
// getFEdges // getFEdges
LIB_VIEW_MAP_EXPORT LIB_VIEW_MAP_EXPORT
void getFEdges(Interface0DIterator& it, void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
FEdge*& fe1,
FEdge*& fe2);
// getViewEdges // getViewEdges
LIB_VIEW_MAP_EXPORT LIB_VIEW_MAP_EXPORT
void getViewEdges(Interface0DIterator& it, void getViewEdges(Interface0DIterator& it, ViewEdge *&ve1, ViewEdge *&ve2);
ViewEdge *&ve1,
ViewEdge *&ve2);
// getShapeF0D // getShapeF0D
LIB_VIEW_MAP_EXPORT LIB_VIEW_MAP_EXPORT
@@ -497,4 +529,4 @@ namespace Functions0D {
} // end of namespace Functions0D } // end of namespace Functions0D
#endif // FUNCTIONS0D_H #endif // __FREESTYLE_FUNCTIONS_0D_H__

View File

@@ -1,81 +1,107 @@
/*
* ***** 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/Functions1D.cpp
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Functions taking 1D input
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \author Emmanuel Turquin
// modify it under the terms of the GNU General Public License * \date 01/07/2003
// 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 "Functions1D.h" # include "Functions1D.h"
using namespace std; using namespace std;
namespace Functions1D { namespace Functions1D {
int GetXF1D::operator()(Interface1D& inter) { int GetXF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int GetYF1D::operator()(Interface1D& inter) { int GetYF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int GetZF1D::operator()(Interface1D& inter) { int GetZF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int GetProjectedXF1D::operator()(Interface1D& inter) { int GetProjectedXF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int GetProjectedYF1D::operator()(Interface1D& inter) { int GetProjectedYF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int GetProjectedZF1D::operator()(Interface1D& inter) { int GetProjectedZF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int Orientation2DF1D::operator()(Interface1D& inter) { int Orientation2DF1D::operator()(Interface1D& inter)
{
FEdge *fe = dynamic_cast<FEdge*>(&inter); FEdge *fe = dynamic_cast<FEdge*>(&inter);
if (fe) { if (fe) {
Vec3r res = fe->orientation2d(); Vec3r res = fe->orientation2d();
result = Vec2f(res[0], res[1]); result = Vec2f(res[0], res[1]);
} else { }
else {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
} }
return 0; return 0;
} }
int Orientation3DF1D::operator()(Interface1D& inter) { int Orientation3DF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int ZDiscontinuityF1D::operator()(Interface1D& inter) { int ZDiscontinuityF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int QuantitativeInvisibilityF1D::operator()(Interface1D& inter) { int QuantitativeInvisibilityF1D::operator()(Interface1D& inter)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) { if (ve) {
result = ve->qi(); result = ve->qi();
@@ -90,13 +116,14 @@ namespace Functions1D {
return 0; return 0;
} }
int CurveNatureF1D::operator()(Interface1D& inter) { int CurveNatureF1D::operator()(Interface1D& inter)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) if (ve) {
result = ve->getNature(); result = ve->getNature();
}
else { else {
// we return a nature that contains every // we return a nature that contains every natures of the viewedges spanned by the chain.
// natures of the viewedges spanned by the chain.
Nature::EdgeNature nat = Nature::NO_FEATURE; Nature::EdgeNature nat = Nature::NO_FEATURE;
Interface0DIterator it = inter.verticesBegin(); Interface0DIterator it = inter.verticesBegin();
while (!it.isEnd()) { while (!it.isEnd()) {
@@ -108,13 +135,15 @@ namespace Functions1D {
return 0; return 0;
} }
int TimeStampF1D::operator()(Interface1D& inter) { int TimeStampF1D::operator()(Interface1D& inter)
{
TimeStamp *timestamp = TimeStamp::instance(); TimeStamp *timestamp = TimeStamp::instance();
inter.setTimeStamp(timestamp->getTimeStamp()); inter.setTimeStamp(timestamp->getTimeStamp());
return 0; return 0;
} }
int ChainingTimeStampF1D::operator()(Interface1D& inter) { int ChainingTimeStampF1D::operator()(Interface1D& inter)
{
TimeStamp *timestamp = TimeStamp::instance(); TimeStamp *timestamp = TimeStamp::instance();
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) if (ve)
@@ -122,20 +151,23 @@ namespace Functions1D {
return 0; return 0;
} }
int IncrementChainingTimeStampF1D::operator()(Interface1D& inter) { int IncrementChainingTimeStampF1D::operator()(Interface1D& inter)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) if (ve)
ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1); ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1);
return 0; return 0;
} }
int GetShapeF1D::operator()(Interface1D& inter) { int GetShapeF1D::operator()(Interface1D& inter)
{
vector<ViewShape*> shapesVector; vector<ViewShape*> shapesVector;
set<ViewShape*> shapesSet; set<ViewShape*> shapesSet;
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) { if (ve) {
shapesVector.push_back(ve->viewShape()); shapesVector.push_back(ve->viewShape());
}else{ }
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it) for (; it != itend; ++it)
shapesSet.insert(Functions0D::getShapeF0D(it)); shapesSet.insert(Functions0D::getShapeF0D(it));
@@ -145,13 +177,15 @@ namespace Functions1D {
return 0; return 0;
} }
int GetOccludersF1D::operator()(Interface1D& inter) { int GetOccludersF1D::operator()(Interface1D& inter)
{
vector<ViewShape*> shapesVector; vector<ViewShape*> shapesVector;
set<ViewShape*> shapesSet; set<ViewShape*> shapesSet;
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) { if (ve) {
result = ve->occluders(); result = ve->occluders();
}else{ }
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it) { for (; it != itend; ++it) {
Functions0D::getOccludersF0D(it, shapesSet); Functions0D::getOccludersF0D(it, shapesSet);
@@ -162,14 +196,16 @@ namespace Functions1D {
return 0; return 0;
} }
int GetOccludeeF1D::operator()(Interface1D& inter) { int GetOccludeeF1D::operator()(Interface1D& inter)
{
vector<ViewShape*> shapesVector; vector<ViewShape*> shapesVector;
set<ViewShape*> shapesSet; set<ViewShape*> shapesSet;
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) { if (ve) {
ViewShape *aShape = ve->aShape(); ViewShape *aShape = ve->aShape();
shapesVector.push_back(aShape); shapesVector.push_back(aShape);
}else{ }
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it) { for (; it != itend; ++it) {
shapesSet.insert(Functions0D::getOccludeeF0D(it)); shapesSet.insert(Functions0D::getOccludeeF0D(it));
@@ -179,10 +215,12 @@ namespace Functions1D {
result = shapesVector; result = shapesVector;
return 0; return 0;
} }
// Internal // Internal
//////////// ////////////
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes){ void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) { if (ve) {
ViewShape *aShape = ve->aShape(); ViewShape *aShape = ve->aShape();
@@ -199,7 +237,8 @@ namespace Functions1D {
} }
} }
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes){ void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) { if (ve) {
vector<ViewShape*>& occluders = ve->occluders(); vector<ViewShape*>& occluders = ve->occluders();
@@ -210,22 +249,23 @@ namespace Functions1D {
for (; it != itend; ++it) { for (; it != itend; ++it) {
set<ViewShape*> shapes; set<ViewShape*> shapes;
Functions0D::getOccludersF0D(it, shapes); Functions0D::getOccludersF0D(it, shapes);
for(set<ViewShape*>::iterator s=shapes.begin(), send=shapes.end(); for (set<ViewShape*>::iterator s = shapes.begin(), send = shapes.end(); s != send; ++s)
s!=send;
++s)
oShapes.insert(*s); oShapes.insert(*s);
} }
} }
} }
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes){ void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) { if (ve) {
oShapes.insert(ve->viewShape()); oShapes.insert(ve->viewShape());
}else{ }
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it) for (; it != itend; ++it)
oShapes.insert(Functions0D::getShapeF0D(it)); oShapes.insert(Functions0D::getShapeF0D(it));
} }
} }
} // end of namespace Functions1D } // end of namespace Functions1D

View File

@@ -1,41 +1,48 @@
// /*
// Filename : Functions1D.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli, Emmanuel Turquin *
// Purpose : Functions taking 1D input * This program is free software; you can redistribute it and/or
// Date of creation : 01/07/2003 * 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__
// /** \file blender/freestyle/intern/view_map/Functions1D.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Functions taking 1D input
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \author Emmanuel Turquin
// modify it under the terms of the GNU General Public License * \date 01/07/2003
// 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 FUNCTIONS1D_HPP
# define FUNCTIONS1D_HPP
# include "ViewMap.h"
#include "Functions0D.h" #include "Functions0D.h"
#include "Interface1D.h" #include "Interface1D.h"
#include "ViewMap.h"
#include "../system/FreestyleConfig.h"
#include "../system/Precision.h" #include "../system/Precision.h"
#include "../system/TimeStamp.h" #include "../system/TimeStamp.h"
# include "../system/FreestyleConfig.h"
#include "../python/Director.h" #include "../python/Director.h"
@@ -44,14 +51,10 @@
// //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
/*! Base class for Unary Functions (functors) working /*! Base class for Unary Functions (functors) working on Interface1D.
* on Interface1D. * A unary function will be used by calling its operator() on an Interface1D.
* A unary function will be used by calling * \attention In the scripting language, there exists several prototypes depending on the returned value type.
* its operator() on an Interface1D. * For example, you would inherit from a UnaryFunction1DDouble if you wish to define a function that returns a double.
* \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: * The different existing prototypes are:
* - UnaryFunction1DVoid * - UnaryFunction1DVoid
* - UnaryFunction1DUnsigned * - UnaryFunction1DUnsigned
@@ -65,54 +68,61 @@ template <class T>
class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction1D class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction1D
{ {
public: public:
T result; T result;
PyObject *py_uf1D; PyObject *py_uf1D;
/*! The type of the value /*! The type of the value returned by the functor. */
* returned by the functor.
*/
typedef T ReturnedValueType; typedef T ReturnedValueType;
/*! Default constructor */ /*! Default constructor */
UnaryFunction1D(){_integration = MEAN;} UnaryFunction1D()
{
_integration = MEAN;
}
/*! Builds a UnaryFunction1D from an integration type. /*! Builds a UnaryFunction1D from an integration type.
* \param iType * \param iType
* In case the result for the Interface1D would be * In case the result for the Interface1D would be obtained by evaluating a 0D function over the different
* obtained by evaluating a 0D function over the different * Interface0D of the Interface1D, \a iType tells which integration method to use.
* Interface0D of the Interface1D, \a iType tells which
* integration method to use.
* The default integration method is the MEAN. * The default integration method is the MEAN.
*/ */
UnaryFunction1D(IntegrationType iType){_integration = iType;} UnaryFunction1D(IntegrationType iType)
{
_integration = iType;
}
/*! destructor. */ /*! destructor. */
virtual ~UnaryFunction1D() {} virtual ~UnaryFunction1D() {}
/*! returns the string "UnaryFunction1D". */ /*! returns the string "UnaryFunction1D". */
virtual string getName() const { virtual string getName() const
{
return "UnaryFunction1D"; return "UnaryFunction1D";
} }
/*! The operator (). /*! The operator ().
* \param inter * \param inter
* The Interface1D on which we wish to evaluate * The Interface1D on which we wish to evaluate the function.
* the function.
* \return the result of the function of type T. * \return the result of the function of type T.
*/ */
virtual int operator()(Interface1D& inter) { virtual int operator()(Interface1D& inter)
{
return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter); return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
} }
/*! Sets the integration method */ /*! Sets the integration method */
void setIntegrationType(IntegrationType integration) { void setIntegrationType(IntegrationType integration)
{
_integration = integration; _integration = integration;
} }
/*! Returns the integration method. */ /*! Returns the integration method. */
IntegrationType getIntegrationType() const { IntegrationType getIntegrationType() const
{
return _integration; return _integration;
} }
protected: protected:
IntegrationType _integration; IntegrationType _integration;
}; };
@@ -120,23 +130,39 @@ protected:
class UnaryFunction1D_void class UnaryFunction1D_void
{ {
public: public:
PyObject *py_uf1D; PyObject *py_uf1D;
UnaryFunction1D_void(){_integration = MEAN;} UnaryFunction1D_void()
UnaryFunction1D_void(IntegrationType iType){_integration = iType;} {
_integration = MEAN;
}
UnaryFunction1D_void(IntegrationType iType)
{
_integration = iType;
}
virtual ~UnaryFunction1D_void() {} virtual ~UnaryFunction1D_void() {}
virtual string getName() const { virtual string getName() const
{
return "UnaryFunction1D_void"; return "UnaryFunction1D_void";
} }
int operator()(Interface1D& inter) { int operator()(Interface1D& inter)
{
return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter); return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
} }
void setIntegrationType(IntegrationType integration) { _integration = integration; } void setIntegrationType(IntegrationType integration)
IntegrationType getIntegrationType() const { return _integration; } {
_integration = integration;
}
IntegrationType getIntegrationType() const
{
return _integration;
}
protected: protected:
IntegrationType _integration; IntegrationType _integration;
@@ -156,17 +182,20 @@ namespace Functions1D {
{ {
private: private:
Functions0D::GetXF0D _func; Functions0D::GetXF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
GetXF1D(IntegrationType iType) : UnaryFunction1D<real>(iType) {} GetXF1D(IntegrationType iType) : UnaryFunction1D<real>(iType) {}
/*! Returns the string "GetXF1D" */ /*! Returns the string "GetXF1D" */
string getName() const { string getName() const
{
return "GetXF1D"; return "GetXF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -177,17 +206,20 @@ namespace Functions1D {
{ {
private: private:
Functions0D::GetYF0D _func; Functions0D::GetYF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {} GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
/*! Returns the string "GetYF1D" */ /*! Returns the string "GetYF1D" */
string getName() const { string getName() const
{
return "GetYF1D"; return "GetYF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -198,17 +230,20 @@ namespace Functions1D {
{ {
private: private:
Functions0D::GetZF0D _func; Functions0D::GetZF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {} GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
/*! Returns the string "GetZF1D" */ /*! Returns the string "GetZF1D" */
string getName() const { string getName() const
{
return "GetZF1D"; return "GetZF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -219,18 +254,20 @@ namespace Functions1D {
{ {
private: private:
Functions0D::GetProjectedXF0D _func; Functions0D::GetProjectedXF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {} GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
public:
/*! Returns the string "GetProjectedXF1D" */ /*! Returns the string "GetProjectedXF1D" */
string getName() const { string getName() const
{
return "GetProjectedXF1D"; return "GetProjectedXF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -241,18 +278,20 @@ namespace Functions1D {
{ {
private: private:
Functions0D::GetProjectedYF0D _func; Functions0D::GetProjectedYF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {} GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
public:
/*! Returns the string "GetProjectedYF1D" */ /*! Returns the string "GetProjectedYF1D" */
string getName() const { string getName() const
{
return "GetProjectedYF1D"; return "GetProjectedYF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -263,18 +302,20 @@ namespace Functions1D {
{ {
private: private:
Functions0D::GetProjectedZF0D _func; Functions0D::GetProjectedZF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {} GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
public:
/*! Returns the string "GetProjectedZF1D" */ /*! Returns the string "GetProjectedZF1D" */
string getName() const { string getName() const
{
return "GetProjectedZF1D"; return "GetProjectedZF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -285,17 +326,20 @@ namespace Functions1D {
{ {
private: private:
Functions0D::VertexOrientation2DF0D _func; Functions0D::VertexOrientation2DF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
Orientation2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {} Orientation2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {}
/*! Returns the string "Orientation2DF1D" */ /*! Returns the string "Orientation2DF1D" */
string getName() const { string getName() const
{
return "Orientation2DF1D"; return "Orientation2DF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -306,69 +350,75 @@ namespace Functions1D {
{ {
private: private:
Functions0D::VertexOrientation3DF0D _func; Functions0D::VertexOrientation3DF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
Orientation3DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec3f>(iType) {} Orientation3DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec3f>(iType) {}
/*! Returns the string "Orientation3DF1D" */ /*! Returns the string "Orientation3DF1D" */
string getName() const { string getName() const
{
return "Orientation3DF1D"; return "Orientation3DF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
// ZDiscontinuityF1D // ZDiscontinuityF1D
/*! Returns a real giving the distance between /*! Returns a real giving the distance between and Interface1D and the shape that lies behind (occludee).
* 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
* This distance is evaluated in the camera space and normalized * by the shape to which the Interface1D belongs to, 1 is returned.
* 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> class LIB_VIEW_MAP_EXPORT ZDiscontinuityF1D : public UnaryFunction1D<real>
{ {
private: private:
Functions0D::ZDiscontinuityF0D _func; Functions0D::ZDiscontinuityF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {} ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
/*! Returns the string "ZDiscontinuityF1D" */ /*! Returns the string "ZDiscontinuityF1D" */
string getName() const { string getName() const
{
return "ZDiscontinuityF1D"; return "ZDiscontinuityF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
// QuantitativeInvisibilityF1D // QuantitativeInvisibilityF1D
/*! Returns the Quantitative Invisibility of an Interface1D element. /*! Returns the Quantitative Invisibility of an Interface1D element.
* If the Interface1D is a ViewEdge, then there is no ambiguity * If the Interface1D is a ViewEdge, then there is no ambiguity concerning the result. But, if the Interface1D
* concerning the result. But, if the Interface1D results of a chaining * results of a chaining (chain, stroke), then it might be made of several 1D elements of different
* (chain, stroke), then it might be made of several 1D elements * Quantitative Invisibilities.
* of different Quantitative Invisibilities.
*/ */
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned> class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned>
{ {
private: private:
Functions0D::QuantitativeInvisibilityF0D _func; Functions0D::QuantitativeInvisibilityF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
QuantitativeInvisibilityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<unsigned int>(iType) {} QuantitativeInvisibilityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<unsigned int>(iType) {}
/*! Returns the string "QuantitativeInvisibilityF1D" */ /*! Returns the string "QuantitativeInvisibilityF1D" */
string getName() const { string getName() const
{
return "QuantitativeInvisibilityF1D"; return "QuantitativeInvisibilityF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -376,25 +426,27 @@ namespace Functions1D {
// CurveNatureF1D // CurveNatureF1D
/*! Returns the nature of the Interface1D (silhouette, ridge, crease...). /*! Returns the nature of the Interface1D (silhouette, ridge, crease...).
* Except if the Interface1D is a ViewEdge, this result might be ambiguous. * Except if the Interface1D is a ViewEdge, this result might be ambiguous.
* Indeed, the Interface1D might result from the gathering of several 1D elements, * Indeed, the Interface1D might result from the gathering of several 1D elements, each one being of a different
* each one being of a different nature. An integration method, such as * nature. An integration method, such as the MEAN, might give, in this case, irrelevant results.
* the MEAN, might give, in this case, irrelevant results.
*/ */
class LIB_VIEW_MAP_EXPORT CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature> class LIB_VIEW_MAP_EXPORT CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature>
{ {
private: private:
Functions0D::CurveNatureF0D _func; Functions0D::CurveNatureF0D _func;
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
CurveNatureF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Nature::EdgeNature>(iType) {} CurveNatureF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Nature::EdgeNature>(iType) {}
/*! Returns the string "CurveNatureF1D" */ /*! Returns the string "CurveNatureF1D" */
string getName() const { string getName() const
{
return "CurveNatureF1D"; return "CurveNatureF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -405,9 +457,11 @@ namespace Functions1D {
{ {
public: public:
/*! Returns the string "TimeStampF1D" */ /*! Returns the string "TimeStampF1D" */
string getName() const { string getName() const
{
return "TimeStampF1D"; return "TimeStampF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -418,9 +472,11 @@ namespace Functions1D {
{ {
public: public:
/*! Returns the string "IncrementChainingTimeStampF1D" */ /*! Returns the string "IncrementChainingTimeStampF1D" */
string getName() const { string getName() const
{
return "IncrementChainingTimeStampF1D"; return "IncrementChainingTimeStampF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -431,9 +487,11 @@ namespace Functions1D {
{ {
public: public:
/*! Returns the string "ChainingTimeStampF1D" */ /*! Returns the string "ChainingTimeStampF1D" */
string getName() const { string getName() const
{
return "ChainingTimeStampF1D"; return "ChainingTimeStampF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -446,19 +504,23 @@ namespace Functions1D {
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
Curvature2DAngleF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {} Curvature2DAngleF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
/*! Returns the string "Curvature2DAngleF1D" */ /*! Returns the string "Curvature2DAngleF1D" */
string getName() const { string getName() const
{
return "Curvature2DAngleF1D"; return "Curvature2DAngleF1D";
} }
/*! the () operator.*/ /*! the () operator.*/
int operator()(Interface1D& inter) { int operator()(Interface1D& inter)
{
result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
private: private:
Functions0D::Curvature2DAngleF0D _fun; Functions0D::Curvature2DAngleF0D _fun;
}; };
@@ -470,19 +532,23 @@ namespace Functions1D {
public: public:
/*! Builds the functor. /*! Builds the functor.
* \param iType * \param iType
* The integration method used to compute * The integration method used to compute a single value from a set of values.
* a single value from a set of values.
*/ */
Normal2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {} Normal2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {}
/*! Returns the string "Normal2DF1D" */ /*! Returns the string "Normal2DF1D" */
string getName() const { string getName() const
{
return "Normal2DF1D"; return "Normal2DF1D";
} }
/*! the () operator.*/ /*! the () operator.*/
int operator()(Interface1D& inter) { int operator()(Interface1D& inter)
{
result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration); result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
private: private:
Functions0D::Normal2DF0D _fun; Functions0D::Normal2DF0D _fun;
}; };
@@ -492,13 +558,15 @@ namespace Functions1D {
class LIB_VIEW_MAP_EXPORT GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape*> > class LIB_VIEW_MAP_EXPORT GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
{ {
public: public:
/*! Builds the functor. /*! Builds the functor. */
*/
GetShapeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {} GetShapeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
/*! Returns the string "GetShapeF1D" */ /*! Returns the string "GetShapeF1D" */
string getName() const { string getName() const
{
return "GetShapeF1D"; return "GetShapeF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -508,13 +576,15 @@ namespace Functions1D {
class LIB_VIEW_MAP_EXPORT GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape*> > class LIB_VIEW_MAP_EXPORT GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape*> >
{ {
public: public:
/*! Builds the functor. /*! Builds the functor. */
*/
GetOccludersF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {} GetOccludersF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
/*! Returns the string "GetOccludersF1D" */ /*! Returns the string "GetOccludersF1D" */
string getName() const { string getName() const
{
return "GetOccludersF1D"; return "GetOccludersF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -524,13 +594,15 @@ namespace Functions1D {
class LIB_VIEW_MAP_EXPORT GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape*> > class LIB_VIEW_MAP_EXPORT GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
{ {
public: public:
/*! Builds the functor. /*! Builds the functor. */
*/
GetOccludeeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {} GetOccludeeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
/*! Returns the string "GetOccludeeF1D" */ /*! Returns the string "GetOccludeeF1D" */
string getName() const { string getName() const
{
return "GetOccludeeF1D"; return "GetOccludeeF1D";
} }
/*! the () operator. */ /*! the () operator. */
int operator()(Interface1D& inter); int operator()(Interface1D& inter);
}; };
@@ -552,4 +624,4 @@ namespace Functions1D {
} // end of namespace Functions1D } // end of namespace Functions1D
#endif // FUNCTIONS1D_HPP #endif // __FREESTYLE_FUNCTIONS_1D_H__

View File

@@ -1,74 +1,85 @@
// /*
// Filename : GridDensityProvider.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-2-5 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2011-2-5
// 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
#include <stdexcept> #include <stdexcept>
#include <memory> #include <memory>
#include "OccluderSource.h" #include "OccluderSource.h"
#include "../geometry/BBox.h" #include "../geometry/BBox.h"
class GridDensityProvider { class GridDensityProvider
{
// Disallow copying and assignment // Disallow copying and assignment
GridDensityProvider(const GridDensityProvider& other); GridDensityProvider(const GridDensityProvider& other);
GridDensityProvider& operator=(const GridDensityProvider& other); GridDensityProvider& operator=(const GridDensityProvider& other);
public: public:
GridDensityProvider (OccluderSource& source) GridDensityProvider(OccluderSource& source) : source(source) {}
: source(source) {
}
virtual ~GridDensityProvider() {}; virtual ~GridDensityProvider() {};
float cellSize() { float cellSize()
{
return _cellSize; return _cellSize;
} }
unsigned cellsX() { unsigned cellsX()
{
return _cellsX; return _cellsX;
} }
unsigned cellsY() { unsigned cellsY()
{
return _cellsY; return _cellsY;
} }
float cellOrigin(int index) { float cellOrigin(int index)
{
if (index < 2) { if (index < 2) {
return _cellOrigin[index]; return _cellOrigin[index];
} else { }
else {
throw new out_of_range("GridDensityProvider::cellOrigin can take only indexes of 0 or 1."); 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(); source.begin();
if (source.isValid()) { if (source.isValid()) {
const Vec3r& initialPoint = source.getGridSpacePolygon().getVertices()[0]; const Vec3r& initialPoint = source.getGridSpacePolygon().getVertices()[0];
@@ -79,15 +90,19 @@ public:
source.next(); 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; real z;
// We want to use the z-coordinate closest to the camera to determine the proscenium face // 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]; z = bbox.getMin()[2];
} else { }
else {
z = bbox.getMax()[2]; z = bbox.getMax()[2];
} }
// Now calculate the proscenium according to the min and max values of the x and y coordinates // 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[1] = std::max(minPoint[0], maxPoint[0]);
proscenium[2] = std::min(minPoint[1], maxPoint[1]); proscenium[2] = std::min(minPoint[1], maxPoint[1]);
proscenium[3] = std::max(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: protected:
@@ -108,24 +124,23 @@ protected:
float _cellOrigin[2]; float _cellOrigin[2];
}; };
class GridDensityProviderFactory { class GridDensityProviderFactory
{
// Disallow copying and assignment // Disallow copying and assignment
GridDensityProviderFactory (const GridDensityProviderFactory& other); GridDensityProviderFactory (const GridDensityProviderFactory& other);
GridDensityProviderFactory& operator= (const GridDensityProviderFactory& other); GridDensityProviderFactory& operator= (const GridDensityProviderFactory& other);
public: 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 () {} virtual ~GridDensityProviderFactory () {}
}; };
#endif // GRIDDENSITYPROVIDER_H #endif // __FREESTYLE_GRID_DENSITY_PROVIDER_H__

View File

@@ -1,32 +1,36 @@
// /*
// Filename : HeuristicGridDensityProviderFactory.cpp * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-2-8 * 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/HeuristicGridDensityProviderFactory.cpp
// * \ingroup freestyle
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \brief Class to define a cell grid surrounding the projected image of a scene
// with this source distribution. * \author Alexander Beels
// * \date 2011-2-8
// 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 "HeuristicGridDensityProviderFactory.h" #include "HeuristicGridDensityProviderFactory.h"
@@ -37,24 +41,30 @@ HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real si
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<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces)); auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
if (avg->cellSize() > p23->cellSize()) { if (avg->cellSize() > p23->cellSize()) {
return (auto_ptr<GridDensityProvider>) p23; return (auto_ptr<GridDensityProvider>) p23;
} else { }
else {
return (auto_ptr<GridDensityProvider>) avg; 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)); 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; return (auto_ptr<GridDensityProvider>) p23;
} else { }
else {
return (auto_ptr<GridDensityProvider>) avg; return (auto_ptr<GridDensityProvider>) avg;
} }
} }
@@ -67,8 +77,8 @@ auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensit
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces)); auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
if (avg->cellSize() > p23->cellSize()) { if (avg->cellSize() > p23->cellSize()) {
return (auto_ptr<GridDensityProvider>) p23; return (auto_ptr<GridDensityProvider>) p23;
} else { }
else {
return (auto_ptr<GridDensityProvider>) avg; return (auto_ptr<GridDensityProvider>) avg;
} }
} }

View File

@@ -1,48 +1,55 @@
// /*
// Filename : HeuristicGridDensityProviderFactory.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-2-8 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2011-2-8
// 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 <memory> // provided by GridDensityProvider.h
#include "AverageAreaGridDensityProvider.h"
//#include "GridDensityProvider.h" // provided by *GridDensityProvider.h below //#include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
#include "Pow23GridDensityProvider.h" #include "Pow23GridDensityProvider.h"
#include "AverageAreaGridDensityProvider.h"
class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory { class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory
{
public: public:
HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces); HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
~HeuristicGridDensityProviderFactory(); ~HeuristicGridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]); 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); auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected: protected:
@@ -50,5 +57,4 @@ protected:
unsigned numFaces; unsigned numFaces;
}; };
#endif // HEURISTICGRIDDENSITYPROVIDERFACTORY_H #endif // __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__

View File

@@ -1,45 +1,53 @@
// /*
// Filename : Interface0D.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Emmanuel Turquin *
// Purpose : Interface to 0D elts * This program is free software; you can redistribute it and/or
// Date of creation : 01/07/2003 * 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__
// /** \file blender/freestyle/intern/view_map/Interface0D.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Interface to 0D elts
// * \author Emmanuel Turquin
// This program is free software; you can redistribute it and/or * \date 01/07/2003
// 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 <iostream>
#include <Python.h> #include <Python.h>
#include <string> #include <string>
# include <iostream>
# include "../system/Id.h"
# include "../system/Precision.h"
# include "../winged_edge/Nature.h"
# include "../geometry/Geom.h"
using namespace std;
#include "../geometry/Geom.h"
#include "../system/Id.h"
#include "../system/Iterator.h" //soc #include "../system/Iterator.h" //soc
#include "../system/Precision.h"
#include "../winged_edge/Nature.h"
using namespace std;
// //
// Interface0D // Interface0D
@@ -51,114 +59,128 @@ class SVertex;
class ViewVertex; class ViewVertex;
class NonTVertex; class NonTVertex;
class TVertex; class TVertex;
/*! Base class for any 0D element. */ /*! Base class for any 0D element. */
class Interface0D class Interface0D
{ {
public: public:
/*! Default constructor */ /*! Default constructor */
Interface0D() {} Interface0D() {}
virtual ~Interface0D() {}; //soc virtual ~Interface0D() {}; //soc
/*! Returns the string "Interface0D". */ /*! Returns the string "Interface0D". */
virtual string getExactTypeName() const { virtual string getExactTypeName() const
{
return "Interface0D"; return "Interface0D";
} }
// Data access methods // Data access methods
/*! Returns the 3D x coordinate of the point. */ /*! Returns the 3D x coordinate of the point. */
virtual real getX() const { virtual real getX() const
{
PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
return 0; return 0;
} }
/*! Returns the 3D y coordinate of the point. */ /*! Returns the 3D y coordinate of the point. */
virtual real getY() const { virtual real getY() const
{
PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
return 0; return 0;
} }
/*! Returns the 3D z coordinate of the point. */ /*! Returns the 3D z coordinate of the point. */
virtual real getZ() const { virtual real getZ() const
{
PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
return 0; return 0;
} }
/*! Returns the 3D point. */ /*! Returns the 3D point. */
virtual Geometry::Vec3f getPoint3D() const { virtual Geometry::Vec3f getPoint3D() const
{
PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
return 0; return 0;
} }
/*! Returns the 2D x coordinate of the point. */ /*! Returns the 2D x coordinate of the point. */
virtual real getProjectedX() const { virtual real getProjectedX() const
{
PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
return 0; return 0;
} }
/*! Returns the 2D y coordinate of the point. */ /*! Returns the 2D y coordinate of the point. */
virtual real getProjectedY() const { virtual real getProjectedY() const
{
PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
return 0; return 0;
} }
/*! Returns the 2D z coordinate of the point. */ /*! Returns the 2D z coordinate of the point. */
virtual real getProjectedZ() const { virtual real getProjectedZ() const
{
PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
return 0; return 0;
} }
/*! Returns the 2D point. */ /*! Returns the 2D point. */
virtual Geometry::Vec2f getPoint2D() const { virtual Geometry::Vec2f getPoint2D() const
{
PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
return 0; return 0;
} }
/*! Returns the FEdge that lies between this Interface0D and the /*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */
* Interface0D given as argument. */ virtual FEdge* getFEdge(Interface0D&)
virtual FEdge* getFEdge(Interface0D&) { {
PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
return 0; return 0;
} }
/*! Returns the Id of the point. */ /*! Returns the Id of the point. */
virtual Id getId() const { virtual Id getId() const
{
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
return 0; return 0;
} }
/*! Returns the nature of the point. */ /*! Returns the nature of the point. */
virtual Nature::VertexNature getNature() const { virtual Nature::VertexNature getNature() const
{
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
return Nature::POINT; return Nature::POINT;
} }
/*! Cast the Interface0D in SVertex if it can be. */ /*! Cast the Interface0D in SVertex if it can be. */
virtual SVertex * castToSVertex(){ virtual SVertex *castToSVertex()
{
PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
return 0; return 0;
} }
/*! Cast the Interface0D in ViewVertex if it can be. */ /*! Cast the Interface0D in ViewVertex if it can be. */
virtual ViewVertex * castToViewVertex(){ virtual ViewVertex * castToViewVertex()
{
PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
return 0; return 0;
} }
/*! Cast the Interface0D in NonTVertex if it can be. */ /*! Cast the Interface0D in NonTVertex if it can be. */
virtual NonTVertex * castToNonTVertex(){ virtual NonTVertex *castToNonTVertex()
{
PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
return 0; return 0;
} }
/*! Cast the Interface0D in TVertex if it can be. */ /*! Cast the Interface0D in TVertex if it can be. */
virtual TVertex * castToTVertex(){ virtual TVertex *castToTVertex()
{
PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
return 0; return 0;
} }
}; };
@@ -170,16 +192,17 @@ public:
class Interface0DIteratorNested : public Iterator class Interface0DIteratorNested : public Iterator
{ {
public: public:
virtual ~Interface0DIteratorNested() {} virtual ~Interface0DIteratorNested() {}
virtual string getExactTypeName() const { virtual string getExactTypeName() const
{
return "Interface0DIteratorNested"; return "Interface0DIteratorNested";
} }
virtual Interface0D& operator*() = 0; virtual Interface0D& operator*() = 0;
virtual Interface0D* operator->() { virtual Interface0D* operator->()
{
return &(operator*()); return &(operator*());
} }
@@ -193,12 +216,14 @@ public:
virtual bool operator==(const Interface0DIteratorNested& it) const = 0; virtual bool operator==(const Interface0DIteratorNested& it) const = 0;
virtual bool operator!=(const Interface0DIteratorNested& it) const { virtual bool operator!=(const Interface0DIteratorNested& it) const
{
return !(*this == it); return !(*this == it);
} }
/*! Returns the curvilinear abscissa */ /*! Returns the curvilinear abscissa */
virtual float t() const = 0; virtual float t() const = 0;
/*! Returns the point parameter 0<u<1 */ /*! Returns the point parameter 0<u<1 */
virtual float u() const = 0; virtual float u() const = 0;
@@ -212,39 +237,39 @@ public:
////////////////////////////////////////////////// //////////////////////////////////////////////////
/*! Class defining an iterator over Interface0D elements. /*! Class defining an iterator over Interface0D elements.
* An instance of this iterator is always obtained * An instance of this iterator is always obtained from a 1D element.
* from a 1D element. * \attention In the scripting language, you must call \code it2 = Interface0DIterator(it1) \endcode instead of
* \attention In the scripting language, you must call * \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
* \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. * Otherwise, incrementing \a it1 will also increment \a it2.
*/ */
class Interface0DIterator : public Iterator class Interface0DIterator : public Iterator
{ {
public: public:
Interface0DIterator(Interface0DIteratorNested* it = NULL)
Interface0DIterator(Interface0DIteratorNested* it = NULL) { {
_iterator = it; _iterator = it;
} }
/*! Copy constructor */ /*! Copy constructor */
Interface0DIterator(const Interface0DIterator& it) { Interface0DIterator(const Interface0DIterator& it)
{
_iterator = it._iterator->copy(); _iterator = it._iterator->copy();
} }
/*! Destructor */ /*! Destructor */
virtual ~Interface0DIterator() { virtual ~Interface0DIterator()
{
if (_iterator) if (_iterator)
delete _iterator; delete _iterator;
} }
/*! Operator = /*! Operator =
* \attention In the scripting language, you must call * \attention In the scripting language, you must call \code it2 = Interface0DIterator(it1) \endcode instead of
* \code it2 = Interface0DIterator(it1) \endcode instead of \code it2 = it1 \endcode * \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
* where \a it1 and \a it2 are 2 Interface0DIterator.
* Otherwise, incrementing \a it1 will also increment \a it2. * Otherwise, incrementing \a it1 will also increment \a it2.
*/ */
Interface0DIterator& operator=(const Interface0DIterator& it) { Interface0DIterator& operator=(const Interface0DIterator& it)
{
if(_iterator) if(_iterator)
delete _iterator; delete _iterator;
_iterator = it._iterator->copy(); _iterator = it._iterator->copy();
@@ -252,7 +277,8 @@ public:
} }
/*! Returns the string "Interface0DIterator". */ /*! Returns the string "Interface0DIterator". */
virtual string getExactTypeName() const { virtual string getExactTypeName() const
{
if (!_iterator) if (!_iterator)
return "Interface0DIterator"; return "Interface0DIterator";
return _iterator->getExactTypeName() + "Proxy"; return _iterator->getExactTypeName() + "Proxy";
@@ -261,100 +287,104 @@ public:
// FIXME test it != 0 (exceptions ?) // FIXME test it != 0 (exceptions ?)
/*! Returns a reference to the pointed Interface0D. /*! Returns a reference to the pointed Interface0D.
* In the scripting language, you must call * In the scripting language, you must call "getObject()" instead using this operator.
* "getObject()" instead using this operator.
*/ */
Interface0D& operator*() { Interface0D& operator*()
{
return _iterator->operator*(); return _iterator->operator*();
} }
/*! Returns a pointer to the pointed Interface0D. /*! Returns a pointer to the pointed Interface0D.
* Can't be called in the scripting language. * Can't be called in the scripting language.
*/ */
Interface0D* operator->() { Interface0D *operator->()
{
return &(operator*()); return &(operator*());
} }
/*! Increments. In the scripting language, call /*! Increments. In the scripting language, call "increment()". */
* "increment()". Interface0DIterator& operator++()
*/ {
Interface0DIterator& operator++() {
_iterator->increment(); _iterator->increment();
return *this; return *this;
} }
/*! Increments. In the scripting language, call /*! Increments. In the scripting language, call "increment()". */
* "increment()". Interface0DIterator operator++(int)
*/ {
Interface0DIterator operator++(int) {
Interface0DIterator ret(*this); Interface0DIterator ret(*this);
_iterator->increment(); _iterator->increment();
return ret; return ret;
} }
/*! Decrements. In the scripting language, call /*! Decrements. In the scripting language, call "decrement()". */
* "decrement()". Interface0DIterator& operator--()
*/ {
Interface0DIterator& operator--() {
_iterator->decrement(); _iterator->decrement();
return *this; return *this;
} }
/*! Decrements. In the scripting language, call /*! Decrements. In the scripting language, call "decrement()". */
* "decrement()". Interface0DIterator operator--(int)
*/ {
Interface0DIterator operator--(int) {
Interface0DIterator ret(*this); Interface0DIterator ret(*this);
_iterator->decrement(); _iterator->decrement();
return ret; return ret;
} }
/*! Increments. */ /*! Increments. */
virtual int increment() { virtual int increment()
{
return _iterator->increment(); return _iterator->increment();
} }
/*! Decrements. */ /*! Decrements. */
virtual int decrement() { virtual int decrement()
{
return _iterator->decrement(); return _iterator->decrement();
} }
/*! Returns true if the pointed Interface0D is the /*! Returns true if the pointed Interface0D is the first of the 1D element containing the points over which
* first of the 1D element containing the points over * we're iterating.
* which we're iterating.
*/ */
virtual bool isBegin() const { virtual bool isBegin() const
{
return _iterator->isBegin(); return _iterator->isBegin();
} }
/*! Returns true if the pointed Interface0D is after the /*! Returns true if the pointed Interface0D is after the after the last point of the 1D element we're
* after the last point of the 1D element we're iterating from. * iterating from. */
*/ virtual bool isEnd() const
virtual bool isEnd() const { {
return _iterator->isEnd(); return _iterator->isEnd();
} }
/*! operator == . */ /*! operator == . */
bool operator==(const Interface0DIterator& it) const { bool operator==(const Interface0DIterator& it) const
{
return _iterator->operator==(*(it._iterator)); return _iterator->operator==(*(it._iterator));
} }
/*! operator != . */ /*! operator != . */
bool operator!=(const Interface0DIterator& it) const { bool operator!=(const Interface0DIterator& it) const
{
return !(*this == it); return !(*this == it);
} }
/*! Returns the curvilinear abscissa. */ /*! Returns the curvilinear abscissa. */
inline float t() const { inline float t() const
{
return _iterator->t(); return _iterator->t();
} }
/*! Returns the point parameter in the curve 0<=u<=1. */ /*! Returns the point parameter in the curve 0<=u<=1. */
inline float u() const { inline float u() const
{
return _iterator->u(); return _iterator->u();
} }
protected:
protected:
Interface0DIteratorNested *_iterator; Interface0DIteratorNested *_iterator;
}; };
#endif // INTERFACE0D_H #endif // __FREESTYLE_INTERFACE_0D_H__

View File

@@ -1,52 +1,56 @@
// /*
// Filename : Interface1D.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Emmanuel Turquin *
// Purpose : Interface to 1D elts * This program is free software; you can redistribute it and/or
// Date of creation : 01/07/2003 * 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__
// /** \file blender/freestyle/intern/view_map/Interface1D.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Interface 1D and related tools definitions
// * \author Emmanuel Turquin
// This program is free software; you can redistribute it and/or * \date 01/07/2003
// 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 INTERFACE1D_H
# define INTERFACE1D_H
#include <float.h>
#include <iostream>
#include <Python.h> #include <Python.h>
#include <string> #include <string>
# include <iostream>
# include <float.h>
# include "../system/Id.h"
# include "../system/Precision.h"
# include "../winged_edge/Nature.h"
#include "Functions0D.h" #include "Functions0D.h"
#include "../system/Id.h"
#include "../system/Precision.h"
#include "../winged_edge/Nature.h"
using namespace std; using namespace std;
/*! \file Interface1D.h
* Interface1D and related tools definitions
*/
// Integration method // Integration method
/*! The different integration /*! The different integration methods that can be invoked to integrate into a single value the set of values obtained
* methods that can be invoked
* to integrate into a single value the set of values obtained
* from each 0D element of a 1D element. * from each 0D element of a 1D element.
*/ */
typedef enum { typedef enum {
@@ -57,34 +61,29 @@ typedef enum {
LAST /*!< The value computed for the 1D element is the last 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; } IntegrationType;
/*! Returns a single /*! Returns a single value from a set of values evaluated at each 0D element of this 1D element.
* value from a set of values evaluated at each 0D element
* of this 1D element.
* \param fun * \param fun
* The UnaryFunction0D used to compute a value at each Interface0D. * The UnaryFunction0D used to compute a value at each Interface0D.
* \param it * \param it
* The Interface0DIterator used to iterate over the 0D elements of * The Interface0DIterator used to iterate over the 0D elements of this 1D element. The integration will occur
* this 1D element. The integration will occur over the 0D elements * over the 0D elements starting from the one pointed by it.
* starting from the one pointed by it.
* \param it_end * \param it_end
* The Interface0DIterator pointing the end of the 0D elements of the * The Interface0DIterator pointing the end of the 0D elements of the 1D element.
* 1D element.
* \param integration_type * \param integration_type
* The integration method used to compute a single value from * The integration method used to compute a single value from a set of values.
* a set of values.
* \return the single value obtained for the 1D element. * \return the single value obtained for the 1D element.
*/ */
template <class T> template <class T>
T integrate(UnaryFunction0D<T>& fun, T integrate(UnaryFunction0D<T>& fun, Interface0DIterator it, Interface0DIterator it_end,
Interface0DIterator it, IntegrationType integration_type = MEAN)
Interface0DIterator it_end, {
IntegrationType integration_type = MEAN) {
T res; T res;
unsigned size; unsigned size;
switch (integration_type) { switch (integration_type) {
case MIN: case MIN:
fun(it); fun(it);
res = fun.result;++it; res = fun.result;
++it;
for (; !it.isEnd(); ++it) { for (; !it.isEnd(); ++it) {
fun(it); fun(it);
if (fun.result < res) if (fun.result < res)
@@ -93,7 +92,8 @@ T integrate(UnaryFunction0D<T>& fun,
break; break;
case MAX: case MAX:
fun(it); fun(it);
res = fun.result;++it; res = fun.result;
++it;
for (; !it.isEnd(); ++it) { for (; !it.isEnd(); ++it) {
fun(it); fun(it);
if (fun.result > res) if (fun.result > res)
@@ -111,7 +111,8 @@ T integrate(UnaryFunction0D<T>& fun,
case MEAN: case MEAN:
default: default:
fun(it); fun(it);
res = fun.result;++it; res = fun.result;
++it;
for (size = 1; !it.isEnd(); ++it, ++size) { for (size = 1; !it.isEnd(); ++it, ++size) {
fun(it); fun(it);
res += fun.result; res += fun.result;
@@ -131,58 +132,56 @@ T integrate(UnaryFunction0D<T>& fun,
class Interface1D class Interface1D
{ {
public: public:
/*! Default constructor */ /*! Default constructor */
Interface1D() {_timeStamp=0;} Interface1D()
{
_timeStamp = 0;
}
virtual ~Interface1D() {}; //soc virtual ~Interface1D() {}; //soc
/*! Returns the string "Interface1D". */ /*! Returns the string "Interface1D". */
virtual string getExactTypeName() const { virtual string getExactTypeName() const
{
return "Interface1D"; return "Interface1D";
} }
// Iterator access // Iterator access
/*! Returns an iterator over the Interface1D vertices, /*! Returns an iterator over the Interface1D vertices, pointing to the first vertex. */
* pointing to the first vertex. virtual Interface0DIterator verticesBegin()
*/ {
virtual Interface0DIterator verticesBegin() {
PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
return Interface0DIterator(); return Interface0DIterator();
} }
/*! Returns an iterator over the Interface1D vertices, /*! Returns an iterator over the Interface1D vertices, pointing after the last vertex. */
* pointing after the last vertex. virtual Interface0DIterator verticesEnd()
*/ {
virtual Interface0DIterator verticesEnd(){
PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
return Interface0DIterator(); return Interface0DIterator();
} }
/*! Returns an iterator over the Interface1D points, /*! Returns an iterator over the Interface1D points, pointing to the first point. The difference with
* 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.
* 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. * Indeed, for each iteration, a virtual point is created.
* \param t * \param t
* The sampling with which we want to iterate over points of * The sampling with which we want to iterate over points of this 1D element.
* this 1D element.
*/ */
virtual Interface0DIterator pointsBegin(float t=0.f) { virtual Interface0DIterator pointsBegin(float t = 0.0f)
{
PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
return Interface0DIterator(); return Interface0DIterator();
} }
/*! Returns an iterator over the Interface1D points, /*! Returns an iterator over the Interface1D points, pointing after the last point. The difference with
* 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.
* 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. * Indeed, for each iteration, a virtual point is created.
* \param t * \param t
* The sampling with which we want to iterate over points of * The sampling with which we want to iterate over points of this 1D element.
* this 1D element.
*/ */
virtual Interface0DIterator pointsEnd(float t=0.f) { virtual Interface0DIterator pointsEnd(float t = 0.0f)
{
PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
return Interface0DIterator(); return Interface0DIterator();
} }
@@ -190,13 +189,15 @@ public:
// Data access methods // Data access methods
/*! Returns the 2D length of the 1D element. */ /*! Returns the 2D length of the 1D element. */
virtual real getLength2D() const { virtual real getLength2D() const
{
PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
return 0; return 0;
} }
/*! Returns the Id of the 1D element. */ /*! Returns the Id of the 1D element. */
virtual Id getId() const { virtual Id getId() const
{
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
return Id(0, 0); return Id(0, 0);
} }
@@ -204,18 +205,21 @@ public:
// FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D) // 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. */ /*! Returns the nature of the 1D element. */
virtual Nature::EdgeNature getNature() const { virtual Nature::EdgeNature getNature() const
{
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden"); PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
return Nature::NO_FEATURE; return Nature::NO_FEATURE;
} }
/*! Returns the time stamp of the 1D element. Mainly used for selection. */ /*! Returns the time stamp of the 1D element. Mainly used for selection. */
virtual unsigned getTimeStamp() const { virtual unsigned getTimeStamp() const
{
return _timeStamp; return _timeStamp;
} }
/*! Sets the time stamp for the 1D element. */ /*! Sets the time stamp for the 1D element. */
inline void setTimeStamp(unsigned iTimeStamp){ inline void setTimeStamp(unsigned iTimeStamp)
{
_timeStamp = iTimeStamp; _timeStamp = iTimeStamp;
} }
@@ -223,4 +227,4 @@ protected:
unsigned _timeStamp; unsigned _timeStamp;
}; };
#endif // INTERFACE1D_H #endif // __FREESTYLE_INTERFACE_1D_H__

View File

@@ -1,44 +1,51 @@
// /*
// Filename : OccluderSource.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2010-12-21 * 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 "OccluderSource.h"
#include <algorithm> #include <algorithm>
OccluderSource::OccluderSource (const GridHelpers::Transform& t, WingedEdge& we) : wingedEdge(we), valid(false), transform(t) { #include "OccluderSource.h"
OccluderSource::OccluderSource(const GridHelpers::Transform& t, WingedEdge& we)
: wingedEdge(we), valid(false), transform(t)
{
begin(); begin();
} }
OccluderSource::~OccluderSource() { OccluderSource::~OccluderSource() {}
}
void OccluderSource::buildCachedPolygon() { void OccluderSource::buildCachedPolygon()
{
vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList())); vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()));
// This doesn't work, because our functor's polymorphism won't survive the copy: // This doesn't work, because our functor's polymorphism won't survive the copy:
// std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform); // std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform);
@@ -49,7 +56,8 @@ void OccluderSource::buildCachedPolygon() {
cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal())); cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
} }
void OccluderSource::begin() { void OccluderSource::begin()
{
vector<WShape*>& wshapes = wingedEdge.getWShapes(); vector<WShape*>& wshapes = wingedEdge.getWShapes();
currentShape = wshapes.begin(); currentShape = wshapes.begin();
shapesEnd = wshapes.end(); shapesEnd = wshapes.end();
@@ -74,7 +82,8 @@ bool OccluderSource::next() {
if (currentShape == shapesEnd) { if (currentShape == shapesEnd) {
valid = false; valid = false;
return false; return false;
} else { }
else {
vector<WFace*>& wFaces = (*currentShape)->GetFaceList(); vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
currentFace = wFaces.begin(); currentFace = wFaces.begin();
facesEnd = wFaces.end(); facesEnd = wFaces.end();
@@ -86,25 +95,30 @@ bool OccluderSource::next() {
return false; return false;
} }
bool OccluderSource::isValid() { bool OccluderSource::isValid()
{
// Or: // Or:
// return currentShapes != shapesEnd && currentFace != facesEnd; // return currentShapes != shapesEnd && currentFace != facesEnd;
return valid; return valid;
} }
WFace* OccluderSource::getWFace() { WFace *OccluderSource::getWFace()
{
return valid ? *currentFace : NULL; return valid ? *currentFace : NULL;
} }
Polygon3r OccluderSource::getCameraSpacePolygon() { Polygon3r OccluderSource::getCameraSpacePolygon()
{
return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()), (*currentFace)->GetNormal()); return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()), (*currentFace)->GetNormal());
} }
Polygon3r& OccluderSource::getGridSpacePolygon() { Polygon3r& OccluderSource::getGridSpacePolygon()
{
return cachedPolygon; return cachedPolygon;
} }
void OccluderSource::getOccluderProscenium(real proscenium[4]) { void OccluderSource::getOccluderProscenium(real proscenium[4])
{
begin(); begin();
const Vec3r& initialPoint = cachedPolygon.getVertices()[0]; const Vec3r& initialPoint = cachedPolygon.getVertices()[0];
proscenium[0] = proscenium[1] = initialPoint[0]; proscenium[0] = proscenium[1] = initialPoint[0];
@@ -113,10 +127,12 @@ void OccluderSource::getOccluderProscenium(real proscenium[4]) {
GridHelpers::expandProscenium (proscenium, cachedPolygon); GridHelpers::expandProscenium (proscenium, cachedPolygon);
next(); 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; real area = 0.0;
unsigned numFaces = 0; unsigned numFaces = 0;
for (begin(); isValid(); next()) { for (begin(); isValid(); next()) {
@@ -128,5 +144,3 @@ real OccluderSource::averageOccluderArea() {
area /= numFaces; area /= numFaces;
return area; return area;
} }

View File

@@ -1,40 +1,46 @@
// /*
// Filename : OccluderSource.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2010-12-21 * 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__
// /** \file blender/freestyle/intern/view_map/OccluderSource.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2010-12-21
// 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 OCCLUDERSOURCE_H
#define OCCLUDERSOURCE_H
#include "../winged_edge/WEdge.h"
#include "../geometry/GridHelpers.h" #include "../geometry/GridHelpers.h"
class OccluderSource { #include "../winged_edge/WEdge.h"
class OccluderSource
{
// Disallow copying and assignment // Disallow copying and assignment
OccluderSource(const OccluderSource& other); OccluderSource(const OccluderSource& other);
OccluderSource& operator=(const OccluderSource& other); OccluderSource& operator=(const OccluderSource& other);
@@ -67,4 +73,4 @@ protected:
void buildCachedPolygon(); void buildCachedPolygon();
}; };
#endif // OCCLUDERSOURCE_H #endif // __FREESTYLE_OCCLUDER_SOURCE_H__

View File

@@ -1,32 +1,36 @@
// /*
// Filename : Pow23GridDensityProvider.cpp * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-2-8 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \brief Class to define a cell grid surrounding the projected image of a scene
// with this source distribution. * \author Alexander Beels
// * \date 2011-2-8
// 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 "Pow23GridDensityProvider.h" #include "Pow23GridDensityProvider.h"
@@ -36,7 +40,8 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const
initialize (proscenium); initialize (proscenium);
} }
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numFaces) Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, unsigned numFaces)
: GridDensityProvider(source), numFaces(numFaces) : GridDensityProvider(source), numFaces(numFaces)
{ {
real proscenium[4]; real proscenium[4];
@@ -91,12 +96,15 @@ Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFac
Pow23GridDensityProviderFactory::~Pow23GridDensityProviderFactory () {} 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)); 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)); return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
} }
@@ -105,5 +113,3 @@ auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityPro
{ {
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces)); return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
} }

View File

@@ -1,46 +1,52 @@
// /*
// Filename : Pow23GridDensityProvider.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2011-2-8 * 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__
// /** \file blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2011-2-8
// 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
#include "GridDensityProvider.h" #include "GridDensityProvider.h"
class Pow23GridDensityProvider : public GridDensityProvider { class Pow23GridDensityProvider : public GridDensityProvider
{
// Disallow copying and assignment // Disallow copying and assignment
Pow23GridDensityProvider(const Pow23GridDensityProvider& other); Pow23GridDensityProvider(const Pow23GridDensityProvider& other);
Pow23GridDensityProvider& operator=(const Pow23GridDensityProvider& other); Pow23GridDensityProvider& operator=(const Pow23GridDensityProvider& other);
public: public:
Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces); 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); Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces);
virtual ~Pow23GridDensityProvider(); virtual ~Pow23GridDensityProvider();
@@ -51,17 +57,19 @@ private:
void initialize(const real proscenium[4]); void initialize(const real proscenium[4]);
}; };
class Pow23GridDensityProviderFactory : public GridDensityProviderFactory { class Pow23GridDensityProviderFactory : public GridDensityProviderFactory
{
public: public:
Pow23GridDensityProviderFactory(unsigned numFaces); Pow23GridDensityProviderFactory(unsigned numFaces);
~Pow23GridDensityProviderFactory(); ~Pow23GridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]); 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); auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected: protected:
unsigned numFaces; unsigned numFaces;
}; };
#endif // POW23GRIDDENSITYPROVIDER_H #endif // __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__

View File

@@ -1,23 +1,36 @@
/*
* ***** 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Classes to define a silhouette structure
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 25/03/2002
// 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 "Silhouette.h" #include "Silhouette.h"
#include "ViewMap.h" #include "ViewMap.h"
@@ -30,26 +43,31 @@
/* */ /* */
/**********************************/ /**********************************/
Nature::VertexNature SVertex::getNature() const { Nature::VertexNature SVertex::getNature() const
{
Nature::VertexNature nature = Nature::S_VERTEX; Nature::VertexNature nature = Nature::S_VERTEX;
if (_pViewVertex) if (_pViewVertex)
nature |= _pViewVertex->getNature(); nature |= _pViewVertex->getNature();
return nature; return nature;
} }
SVertex * SVertex::castToSVertex(){ SVertex *SVertex::castToSVertex()
{
return this; return this;
} }
ViewVertex * SVertex::castToViewVertex(){ ViewVertex *SVertex::castToViewVertex()
{
return _pViewVertex; return _pViewVertex;
} }
NonTVertex * SVertex::castToNonTVertex(){ NonTVertex *SVertex::castToNonTVertex()
{
return dynamic_cast<NonTVertex*>(_pViewVertex); return dynamic_cast<NonTVertex*>(_pViewVertex);
} }
TVertex * SVertex::castToTVertex(){ TVertex *SVertex::castToTVertex()
{
return dynamic_cast<TVertex*>(_pViewVertex); return dynamic_cast<TVertex*>(_pViewVertex);
} }
@@ -58,9 +76,22 @@ float SVertex::shape_importance() const
return shape()->importance(); return shape()->importance();
} }
//Material SVertex::material() const {return _Shape->material();} #if 0
Id SVertex::shape_id() const {return _Shape->getId();} Material SVertex::material() const
const SShape * SVertex::shape() const {return _Shape;} {
return _Shape->material();
}
#endif
Id SVertex::shape_id() const
{
return _Shape->getId();
}
const SShape *SVertex::shape() const
{
return _Shape;
}
const int SVertex::qi() const const int SVertex::qi() const
{ {
@@ -128,62 +159,49 @@ real SVertex::z_discontinuity() const
FEdge *SVertex::fedge() FEdge *SVertex::fedge()
{ {
if (getNature() & Nature::T_VERTEX) if (getNature() & Nature::T_VERTEX)
return 0; return NULL;
return _FEdges[0]; return _FEdges[0];
} }
FEdge *SVertex::getFEdge(Interface0D& inter) FEdge *SVertex::getFEdge(Interface0D& inter)
{ {
FEdge * result = 0; FEdge *result = NULL;
SVertex *iVertexB = dynamic_cast<SVertex*>(&inter); SVertex *iVertexB = dynamic_cast<SVertex*>(&inter);
if (!iVertexB) if (!iVertexB)
return result; return result;
vector<FEdge*>::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); vector<FEdge*>::const_iterator fe = _FEdges.begin(), feend = _FEdges.end();
for(; for (; fe != feend; ++fe) {
fe!=feend; if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB)) ||
++fe) (((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB)))
{
if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB))
|| (((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB)))
result = (*fe); result = (*fe);
} }
if((result == 0) && (getNature() & Nature::T_VERTEX)) if ((result == 0) && (getNature() & Nature::T_VERTEX)) {
{
SVertex *brother; SVertex *brother;
ViewVertex *vvertex = viewvertex(); ViewVertex *vvertex = viewvertex();
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex); TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
if(tvertex) if (tvertex) {
{
brother = tvertex->frontSVertex(); brother = tvertex->frontSVertex();
if (this == brother) if (this == brother)
brother = tvertex->backSVertex(); brother = tvertex->backSVertex();
const vector<FEdge*>& fedges = brother->fedges(); const vector<FEdge*>& fedges = brother->fedges();
for(fe=fedges.begin(),feend=fedges.end(); for (fe = fedges.begin(), feend = fedges.end(); fe != feend; ++fe) {
fe!=feend; if ((((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB)) ||
++fe) (((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB)))
{
if( (((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB))
|| (((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB)))
result = (*fe); result = (*fe);
} }
} }
} }
if((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) if ((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) {
{
SVertex *brother; SVertex *brother;
ViewVertex *vvertex = iVertexB->viewvertex(); ViewVertex *vvertex = iVertexB->viewvertex();
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex); TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
if(tvertex) if (tvertex) {
{
brother = tvertex->frontSVertex(); brother = tvertex->frontSVertex();
if (iVertexB == brother) if (iVertexB == brother)
brother = tvertex->backSVertex(); brother = tvertex->backSVertex();
for(fe=_FEdges.begin(),feend=_FEdges.end(); for (fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; ++fe) {
fe!=feend; if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother)) ||
++fe) (((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother)))
{
if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother))
|| (((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother)))
result = (*fe); result = (*fe);
} }
} }
@@ -202,8 +220,18 @@ FEdge* SVertex::getFEdge(Interface0D& inter)
/**********************************/ /**********************************/
int FEdge::viewedge_nature() const {return _ViewEdge->getNature();} int FEdge::viewedge_nature() const
//float FEdge::viewedge_length() const {return _ViewEdge->viewedge_length();} {
return _ViewEdge->getNature();
}
#if 0
float FEdge::viewedge_length() const
{
return _ViewEdge->viewedge_length();
}
#endif
const SShape *FEdge::occluded_shape() const const SShape *FEdge::occluded_shape() const
{ {
ViewShape *aShape = _ViewEdge->aShape(); ViewShape *aShape = _ViewEdge->aShape();
@@ -222,21 +250,36 @@ int FEdge::invisibility() const
return _ViewEdge->qi(); return _ViewEdge->qi();
} }
occluder_container::const_iterator FEdge::occluders_begin() const {return _ViewEdge->occluders_begin();} occluder_container::const_iterator FEdge::occluders_begin() const
occluder_container::const_iterator FEdge::occluders_end() const {return _ViewEdge->occluders_end();} {
bool FEdge::occluders_empty() const {return _ViewEdge->occluders_empty();} return _ViewEdge->occluders_begin();
int FEdge::occluders_size() const {return _ViewEdge->occluders_size();} }
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 const bool FEdge::occludee_empty() const
{ {
return _ViewEdge->occludee_empty(); return _ViewEdge->occludee_empty();
} }
Id FEdge::shape_id() const Id FEdge::shape_id() const
{ {
return _VertexA->shape()->getId(); return _VertexA->shape()->getId();
} }
const SShape *FEdge::shape() const const SShape *FEdge::shape() const
{ {
return _VertexA->shape(); return _VertexA->shape();
@@ -244,8 +287,7 @@ const SShape* FEdge::shape() const
real FEdge::z_discontinuity() const real FEdge::z_discontinuity() const
{ {
if(!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) if (!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) {
{
return 0; return 0;
} }
@@ -253,89 +295,85 @@ real FEdge::z_discontinuity() const
Vec3r bbox_size_vec(box.getMax() - box.getMin()); Vec3r bbox_size_vec(box.getMax() - box.getMin());
real bboxsize = bbox_size_vec.norm(); real bboxsize = bbox_size_vec.norm();
if(occludee_empty()) if (occludee_empty()) {
{
//return FLT_MAX; //return FLT_MAX;
return 1.0; return 1.0;
//return bboxsize; //return bboxsize;
} }
// real result;
// z_discontinuity_functor<SVertex> _functor;
// Evaluate<SVertex,z_discontinuity_functor<SVertex> >(&_functor, iCombination, result ) #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())); Vec3r middle((_VertexB->point3d() - _VertexA->point3d()));
middle /= 2; middle /= 2;
Vec3r disc_vec(middle - _occludeeIntersection); Vec3r disc_vec(middle - _occludeeIntersection);
real res = disc_vec.norm() / bboxsize; real res = disc_vec.norm() / bboxsize;
return res;
return res;
//return fabs((middle.z() - _occludeeIntersection.z())); //return fabs((middle.z() - _occludeeIntersection.z()));
} }
#if 0
float FEdge::local_average_depth(int iCombination ) const
{
float result;
local_average_depth_functor<SVertex> functor;
Evaluate(&functor, iCombination, result);
//float FEdge::local_average_depth(int iCombination ) const return result;
//{ }
//
// float result; float FEdge::local_depth_variance(int iCombination ) const
// local_average_depth_functor<SVertex> functor; {
// Evaluate(&functor, iCombination, result); float result;
//
// return result; local_depth_variance_functor<SVertex> functor;
//}
//float FEdge::local_depth_variance(int iCombination ) const Evaluate(&functor, iCombination, result);
//{
// float result; return result;
// }
// local_depth_variance_functor<SVertex> functor;
// real FEdge::local_average_density( float sigma, int iCombination) const
// Evaluate(&functor, iCombination, result); {
// float result;
// return result;
//} density_functor<SVertex> functor(sigma);
//
// Evaluate(&functor, iCombination, result);
//real FEdge::local_average_density( float sigma, int iCombination) const
//{ return result;
// float result; }
//
// density_functor<SVertex> functor(sigma); Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */)
// {
// Evaluate(&functor, iCombination, result); Vec3r Na = _VertexA->normal(oException);
// if (oException != Exception::NO_EXCEPTION)
// return result; return Na;
//} Vec3r Nb = _VertexB->normal(oException);
// if (oException != Exception::NO_EXCEPTION)
////Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */) return Nb;
////{ return (Na + Nb) / 2.0;
//// Vec3r Na = _VertexA->normal(oException); }
//// if(oException != Exception::NO_EXCEPTION)
//// return Na; Vec3r FEdge::curvature2d_as_vector(int iCombination) const
//// Vec3r Nb = _VertexB->normal(oException); {
//// if(oException != Exception::NO_EXCEPTION) Vec3r result;
//// return Nb; curvature2d_as_vector_functor<SVertex> _functor;
//// return (Na+Nb)/2.0; Evaluate<Vec3r, curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result);
////} return result;
// }
//Vec3r FEdge::curvature2d_as_vector(int iCombination) const
//{ real FEdge::curvature2d_as_angle(int iCombination) const
// Vec3r result; {
// curvature2d_as_vector_functor<SVertex> _functor; real result;
// Evaluate<Vec3r,curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result ); curvature2d_as_angle_functor<SVertex> _functor;
// return result; Evaluate<real, curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result);
//} return result;
// }
//real FEdge::curvature2d_as_angle(int iCombination) const #endif
//{
// real result;
// curvature2d_as_angle_functor<SVertex> _functor;
// Evaluate<real,curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result );
// return result;
//}
/**********************************/ /**********************************/
/* */ /* */
@@ -345,15 +383,20 @@ real FEdge::z_discontinuity() const
/* */ /* */
/**********************************/ /**********************************/
//Material FEdge::material() const #if 0
//{ Material FEdge::material() const
// return _VertexA->shape()->material(); {
//} return _VertexA->shape()->material();
const FrsMaterial& FEdgeSharp::aFrsMaterial() const { }
#endif
const FrsMaterial& FEdgeSharp::aFrsMaterial() const
{
return _VertexA->shape()->frs_material(_aFrsMaterialIndex); return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
} }
const FrsMaterial& FEdgeSharp::bFrsMaterial() const { const FrsMaterial& FEdgeSharp::bFrsMaterial() const
{
return _VertexA->shape()->frs_material(_bFrsMaterialIndex); return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
} }
@@ -365,6 +408,7 @@ const FrsMaterial& FEdgeSharp::bFrsMaterial() const {
/* */ /* */
/**********************************/ /**********************************/
const FrsMaterial& FEdgeSmooth::frs_material() const { const FrsMaterial& FEdgeSmooth::frs_material() const
{
return _VertexA->shape()->frs_material(_FrsMaterialIndex); return _VertexA->shape()->frs_material(_FrsMaterialIndex);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,62 +1,88 @@
/*
* ***** 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/SilhouetteGeomEngine.cpp
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \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...
// This program is free software; you can redistribute it and/or * \author Stephane Grabli
// modify it under the terms of the GNU General Public License * \date 03/09/2002
// 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 "Silhouette.h" #include "Silhouette.h"
#include "SilhouetteGeomEngine.h" #include "SilhouetteGeomEngine.h"
#include "../geometry/GeomUtils.h" #include "../geometry/GeomUtils.h"
using namespace std; using namespace std;
Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0, 0, 0); Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0, 0, 0);
real SilhouetteGeomEngine::_translation[3] = {0, 0, 0}; real SilhouetteGeomEngine::_translation[3] = {0, 0, 0};
real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {{1,0,0,0}, real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0}, {0, 1, 0, 0},
{0, 0, 1, 0}, {0, 0, 1, 0},
{0,0,0,1}}; {0, 0, 0, 1}
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {{1,0,0,0}, };
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0}, {0, 1, 0, 0},
{0, 0, 1, 0}, {0, 0, 1, 0},
{0,0,0,1}}; {0, 0, 0, 1}
real SilhouetteGeomEngine::_transform[4][4] = {{1,0,0,0}, };
real SilhouetteGeomEngine::_transform[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0}, {0, 1, 0, 0},
{0, 0, 1, 0}, {0, 0, 1, 0},
{0,0,0,1}}; {0, 0, 0, 1}
int SilhouetteGeomEngine::_viewport[4] = {1,1,1,1}; // the viewport };
int SilhouetteGeomEngine::_viewport[4] = {1, 1, 1, 1};
real SilhouetteGeomEngine::_Focal = 0.0; real SilhouetteGeomEngine::_Focal = 0.0;
real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {{1,0,0,0}, real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0}, {0, 1, 0, 0},
{0, 0, 1, 0}, {0, 0, 1, 0},
{0,0,0,1}}; {0, 0, 0, 1}
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {{1,0,0,0}, };
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0}, {0, 1, 0, 0},
{0, 0, 1, 0}, {0, 0, 1, 0},
{0,0,0,1}}; {0, 0, 0, 1}
};
real SilhouetteGeomEngine::_znear = 0.0; real SilhouetteGeomEngine::_znear = 0.0;
real SilhouetteGeomEngine::_zfar = 100.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; unsigned int i, j;
_translation[0] = iModelViewMatrix[3][0]; _translation[0] = iModelViewMatrix[3][0];
@@ -64,24 +90,21 @@ void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const
_translation[2] = iModelViewMatrix[3][2]; _translation[2] = iModelViewMatrix[3][2];
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
for(j=0; j<4; j++) for (j = 0; j < 4; j++) {
{
_modelViewMatrix[i][j] = iModelViewMatrix[j][i]; _modelViewMatrix[i][j] = iModelViewMatrix[j][i];
_glModelViewMatrix[i][j] = iModelViewMatrix[i][j]; _glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
} }
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
for(j=0; j<4; j++) for (j = 0; j < 4; j++) {
{
_projectionMatrix[i][j] = iProjectionMatrix[j][i]; _projectionMatrix[i][j] = iProjectionMatrix[j][i];
_glProjectionMatrix[i][j] = iProjectionMatrix[i][j]; _glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
} }
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
for(j=0; j<4; j++) for (j = 0; j < 4; j++) {
{
_transform[i][j] = 0; _transform[i][j] = 0;
for (unsigned int k = 0; k < 4; k++) for (unsigned int k = 0; k < 4; k++)
_transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j]; _transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
@@ -102,50 +125,56 @@ void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
_zfar = iZFar; _zfar = iZFar;
} }
void SilhouetteGeomEngine::retrieveViewport(int viewport[4]){ void SilhouetteGeomEngine::retrieveViewport(int viewport[4])
{
memcpy(viewport, _viewport, 4 * sizeof(int)); memcpy(viewport, _viewport, 4 * sizeof(int));
} }
//#define HUGE 1e9
//#define HUGE 1.0e9
void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices) void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices)
{ {
Vec3r newPoint; Vec3r newPoint;
// real min=HUGE; #if 0
// real max=-HUGE; real min = HUGE;
real max = -HUGE;
#endif
vector<SVertex*>::iterator sv, svend; vector<SVertex*>::iterator sv, svend;
const real depth = _zfar - _znear; const real depth = _zfar - _znear;
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth; const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
for(sv=ioVertices.begin(), svend=ioVertices.end(); for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
sv!=svend;
sv++)
{
GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport); GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1 newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
(*sv)->setPoint2D(newPoint); (*sv)->setPoint2D(newPoint);
//cerr << (*sv)->point2d().z() << " "; #if 0
// real d=(*sv)->point2d()[2]; cerr << (*sv)->point2d().z() << " ";
// if (d>max) max =d; real d = (*sv)->point2d()[2];
// if (d<min) min =d; if (d > max)
max =d;
if (d < min)
min =d;
#endif
} }
// for(sv=ioVertices.begin(), svend=ioVertices.end(); #if 0
// sv!=svend; for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
// sv++) Vec3r P((*sv)->point2d());
// { (*sv)->setPoint2D(Vec3r(P[0], P[1], 1.0 - (P[2] - min) / (max - min)));
// Vec3r P((*sv)->point2d()); //cerr << (*sv)->point2d()[2] << " ";
// (*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; Vec3r newPoint;
// real min=HUGE; #if 0
// real max=-HUGE; real min = HUGE;
real max = -HUGE;
vector<SVertex*>::iterator sv, svend; vector<SVertex*>::iterator sv, svend;
#endif
const real depth = _zfar - _znear; const real depth = _zfar - _znear;
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth; const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport); GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1 newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
ioVertex->setPoint2D(newPoint); ioVertex->setPoint2D(newPoint);
@@ -156,8 +185,7 @@ real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
if (_isOrthographicProjection) if (_isOrthographicProjection)
return t; return t;
// we need to compute for each parameter t the corresponding // we need to compute for each parameter t the corresponding parameter T which gives the intersection in 3D.
// parameter T which gives the intersection in 3D.
real T; real T;
// suffix w for world, c for camera, r for retina, i for image // 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 m22 = _projectionMatrix[1][1];
real m23 = _projectionMatrix[1][2]; real m23 = _projectionMatrix[1][2];
if (fabs(ABc[0]) > 1e-6) { if (fabs(ABc[0]) > 1.0e-6) {
alpha = ABc[2] / ABc[0]; alpha = ABc[2] / ABc[0];
beta = Ac[2] - alpha * Ac[0]; beta = Ac[2] - alpha * Ac[0];
denom = alpha * (Ir[0] + m13) + m11; denom = alpha * (Ir[0] + m13) + m11;
if (fabs(denom) < 1e-6) if (fabs(denom) < 1.0e-6)
goto iter; goto iter;
Ic[0] = -beta * (Ir[0] + m13) / denom; Ic[0] = -beta * (Ir[0] + m13) / denom;
// Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22; #if 0
// Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2]; Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
#endif
T = (Ic[0] - Ac[0]) / ABc[0]; 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]; alpha = ABc[2] / ABc[1];
beta = Ac[2] - alpha * Ac[1]; beta = Ac[2] - alpha * Ac[1];
denom = alpha * (Ir[1] + m23) + m22; denom = alpha * (Ir[1] + m23) + m22;
if (fabs(denom) < 1e-6) if (fabs(denom) < 1.0e-6)
goto iter; goto iter;
Ic[1] = -beta * (Ir[1] + m23) / denom; Ic[1] = -beta * (Ir[1] + m23) / denom;
// Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11; #if 0
// Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2]; Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
#endif
T = (Ic[1] - Ac[1]) / ABc[1]; T = (Ic[1] - Ac[1]) / ABc[1];
}
} else { else {
iter:
iter: bool x_coords, less_than; bool x_coords, less_than;
if (fabs(Bi[0] - Ai[0]) > 1e-6) { if (fabs(Bi[0] - Ai[0]) > 1.0e-6) {
x_coords = true; x_coords = true;
less_than = Ai[0] < Bi[0]; less_than = Ai[0] < Bi[0];
} else { }
else {
x_coords = false; x_coords = false;
less_than = Ai[1] < Bi[1]; less_than = Ai[1] < Bi[1];
} }
Vec3r Pc, Pr, Pi; Vec3r Pc, Pr, Pi;
real T_sta = 0.0; real T_sta = 0.0;
real T_end = 1.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; int i, max_iters = 100;
for (i = 0; i < max_iters; i++) { for (i = 0; i < max_iters; i++) {
T = T_sta + 0.5 * (T_end - T_sta); T = T_sta + 0.5 * (T_end - T_sta);
@@ -235,15 +267,30 @@ iter: bool x_coords, less_than;
break; break;
if (x_coords) { if (x_coords) {
if (less_than) { if (less_than) {
if (Pi[0] < Ii[0]) { T_sta = T; } else { T_end = T; } if (Pi[0] < Ii[0])
} else { T_sta = T;
if (Pi[0] > Ii[0]) { T_sta = T; } else { T_end = T; } else
T_end = T;
} }
} else { else {
if (Pi[0] > Ii[0])
T_sta = T;
else
T_end = T;
}
}
else {
if (less_than) { if (less_than) {
if (Pi[1] < Ii[1]) { T_sta = T; } else { T_end = T; } if (Pi[1] < Ii[1])
} else { T_sta = T;
if (Pi[1] > Ii[1]) { T_sta = T; } else { T_end = 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) Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r& M)
{ {
const real depth = _zfar - _znear; const real depth = _zfar - _znear;
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth; const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
Vec3r newPoint; Vec3r newPoint;
GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport); GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1 newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
return newPoint; return newPoint;
} }

View File

@@ -1,42 +1,47 @@
// /*
// Filename : SilhouetteGeomEngine.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Class to perform all geometric operations dedicated * This program is free software; you can redistribute it and/or
// to silhouette. That, for example, implies that * modify it under the terms of the GNU General Public License
// this geom engine has as member data the viewpoint, * as published by the Free Software Foundation; either version 2
// transformations, projections... * of the License, or (at your option) any later version.
// Date of creation : 03/09/2002 *
// * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \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...
// This program is free software; you can redistribute it and/or * \author Stephane Grabli
// modify it under the terms of the GNU General Public License * \date 03/09/2002
// 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 <vector>
# include "../system/FreestyleConfig.h"
#include "../geometry/Geom.h" #include "../geometry/Geom.h"
#include "../system/FreestyleConfig.h"
using namespace Geometry; using namespace Geometry;
class SVertex; class SVertex;
@@ -45,38 +50,47 @@ class FEdge;
class LIB_VIEW_MAP_EXPORT SilhouetteGeomEngine class LIB_VIEW_MAP_EXPORT SilhouetteGeomEngine
{ {
private: private:
static Vec3r _Viewpoint; // The viewpoint under which the silhouette has to be computed // The viewpoint under which the silhouette has to be computed
static Vec3r _Viewpoint;
static real _translation[3]; static real _translation[3];
static real _modelViewMatrix[4][4]; // the model view matrix (_modelViewMatrix[i][j] means element of line i and column j) // 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 _modelViewMatrix[4][4];
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) // the projection matrix (_projectionMatrix[i][j] means element of line i and column j)
static int _viewport[4]; // the viewport 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 _Focal;
static real _znear; static real _znear;
static real _zfar; static real _zfar;
static real _glProjectionMatrix[4][4]; // GL style (column major) projection matrix // GL style (column major) projection matrix
static real _glModelViewMatrix[4][4]; // GL style (column major) model view matrix static real _glProjectionMatrix[4][4];
// GL style (column major) model view matrix
static real _glModelViewMatrix[4][4];
static bool _isOrthographicProjection; static bool _isOrthographicProjection;
static SilhouetteGeomEngine *_pInstance; static SilhouetteGeomEngine *_pInstance;
public:
public:
/*! retrieves an instance on the singleton */ /*! retrieves an instance on the singleton */
static SilhouetteGeomEngine *getInstance() static SilhouetteGeomEngine *getInstance()
{ {
if(0 == _pInstance) if(0 == _pInstance) {
{
_pInstance = new SilhouetteGeomEngine; _pInstance = new SilhouetteGeomEngine;
} }
return _pInstance; return _pInstance;
} }
/*! Sets the current viewpoint */ /*! Sets the current viewpoint */
static inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;} static inline void setViewpoint(const Vec3r& ivp)
{
_Viewpoint = ivp;
}
/*! Sets the current transformation /*! Sets the current transformation
* iModelViewMatrix * iModelViewMatrix
@@ -88,10 +102,10 @@ public:
* iFocal * iFocal
* The focal length * The focal length
*/ */
static void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocal) ; 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 /*! Sets the current znear and zfar */
*/
static void setFrustum(real iZNear, real iZFar); static void setFrustum(real iZNear, real iZFar);
/* accessors */ /* accessors */
@@ -100,8 +114,7 @@ public:
/*! Projects the silhouette in camera coordinates /*! Projects the silhouette in camera coordinates
* This method modifies the ioEdges passed as argument. * This method modifies the ioEdges passed as argument.
* ioVertices * ioVertices
* The vertices to project. It is modified during the * The vertices to project. It is modified during the operation.
* operation.
*/ */
static void ProjectSilhouette(std::vector<SVertex*>& ioVertices); static void ProjectSilhouette(std::vector<SVertex*>& ioVertices);
static void ProjectSilhouette(SVertex *ioVertex); static void ProjectSilhouette(SVertex *ioVertex);
@@ -120,4 +133,4 @@ public:
static Vec3r WorldToImage(const Vec3r& M); static Vec3r WorldToImage(const Vec3r& M);
}; };
#endif // SILHOUETTEGEOMENGINE_H #endif // __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__

View File

@@ -1,37 +1,42 @@
// /*
// Filename : SphericalGrid.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2010-12-19 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2010-12-19
// 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. #include <algorithm>
// #include <stdexcept>
// 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 "SphericalGrid.h" #include "SphericalGrid.h"
#include <stdexcept>
#include <algorithm>
using namespace std; using namespace std;
// Helper Classes // Helper Classes
@@ -46,7 +51,8 @@ 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; const real epsilon = 1.0e-06;
boundary[0] = x - epsilon; boundary[0] = x - epsilon;
boundary[1] = x + sizeX + 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; 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; return a->shallowest < b->shallowest;
} }
void SphericalGrid::Cell::indexPolygons() { void SphericalGrid::Cell::indexPolygons()
{
// Sort occluders by their shallowest points. // Sort occluders by their shallowest points.
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint); sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
} }
@@ -67,12 +76,11 @@ void SphericalGrid::Cell::indexPolygons() {
////////////////// //////////////////
SphericalGrid::Iterator::Iterator(SphericalGrid& grid, Vec3r& center, real epsilon) SphericalGrid::Iterator::Iterator(SphericalGrid& grid, Vec3r& center, real epsilon)
: _target(SphericalGrid::Transform::sphericalProjection(center)), : _target(SphericalGrid::Transform::sphericalProjection(center)), _foundOccludee(false)
_foundOccludee(false)
{ {
// Find target cell // Find target cell
_cell = grid.findCell(_target); _cell = grid.findCell(_target);
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
cout << "Searching for occluders of edge centered at " << _target << " in cell [" cout << "Searching for occluders of edge centered at " << _target << " in cell ["
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2] << _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl; << ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
@@ -87,9 +95,9 @@ SphericalGrid::Iterator::~Iterator () {}
// SphericalGrid // SphericalGrid
///////////////// /////////////////
SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI) SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
: _viewpoint(viewpoint), Vec3r& viewpoint, bool enableQI)
_enableQI(enableQI) : _viewpoint(viewpoint), _enableQI(enableQI)
{ {
cout << "Generate Cell structure" << endl; cout << "Generate Cell structure" << endl;
// Generate Cell structure // Generate Cell structure
@@ -103,10 +111,10 @@ SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& densit
cout << "Ready to use SphericalGrid" << endl; 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(); _cellSize = density.cellSize();
_cellsX = density.cellsX(); _cellsX = density.cellsX();
_cellsY = density.cellsY(); _cellsY = density.cellsY();
@@ -128,7 +136,6 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
getCellCoordinates(point, i, j); getCellCoordinates(point, i, j);
if (_cells[i * _cellsY + j] == NULL) { if (_cells[i * _cellsY + j] == NULL) {
// This is an uninitialized cell // This is an uninitialized cell
real x, y, width, height; real x, y, width, height;
x = _cellOrigin[0] + _cellSize * i; x = _cellOrigin[0] + _cellSize * i;
@@ -145,7 +152,8 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
} }
} }
void SphericalGrid::distributePolygons (OccluderSource& source) { void SphericalGrid::distributePolygons(OccluderSource& source)
{
unsigned long nFaces = 0; unsigned long nFaces = 0;
unsigned long nKeptFaces = 0; unsigned long nKeptFaces = 0;
@@ -157,10 +165,10 @@ void SphericalGrid::distributePolygons (OccluderSource& source) {
_faces.push_back(occluder); _faces.push_back(occluder);
++nKeptFaces; ++nKeptFaces;
} }
} catch (...) { }
// If an exception was thrown, _faces.push_back() cannot have succeeded. catch (...) {
// occluder is not owned by anyone, and must be deleted. // If an exception was thrown, _faces.push_back() cannot have succeeded. Occluder is not owned by anyone,
// If the exception was thrown before or during new OccluderData(), then // and must be deleted. If the exception was thrown before or during new OccluderData(), then
// occluder is NULL, and this delete is harmless. // occluder is NULL, and this delete is harmless.
delete occluder; delete occluder;
throw; throw;
@@ -170,7 +178,8 @@ void SphericalGrid::distributePolygons (OccluderSource& source) {
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl; cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
} }
void SphericalGrid::reorganizeCells () { void SphericalGrid::reorganizeCells()
{
// Sort the occluders by shallowest point // Sort the occluders by shallowest point
for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) { for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
if (*i != NULL) { if (*i != NULL) {
@@ -179,37 +188,43 @@ void SphericalGrid::reorganizeCells () {
} }
} }
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)); 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)); 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; unsigned x, y;
getCellCoordinates(point, x, y); getCellCoordinates(point, x, y);
return _cells[x * _cellsY + y]; return _cells[x * _cellsY + y];
} }
bool SphericalGrid::orthographicProjection () const { bool SphericalGrid::orthographicProjection() const
{
return false; return false;
} }
const Vec3r& SphericalGrid::viewpoint() const { const Vec3r& SphericalGrid::viewpoint() const
{
return _viewpoint; return _viewpoint;
} }
bool SphericalGrid::enableQI() const { bool SphericalGrid::enableQI() const
{
return _enableQI; return _enableQI;
} }
SphericalGrid::Transform::Transform () : GridHelpers::Transform() { SphericalGrid::Transform::Transform () : GridHelpers::Transform() {}
}
Vec3r SphericalGrid::Transform::operator() (const Vec3r& point) const { Vec3r SphericalGrid::Transform::operator()(const Vec3r& point) const
{
return sphericalProjection(point); return sphericalProjection(point);
} }
Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) { Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M)
{
Vec3r newPoint; Vec3r newPoint;
newPoint[0] = ::atan(M[0] / M[2]); newPoint[0] = ::atan(M[0] / M[2]);
@@ -218,4 +233,3 @@ Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) {
return newPoint; return newPoint;
} }

View File

@@ -1,70 +1,78 @@
// /*
// Filename : SphericalGrid.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Alexander Beels *
// Purpose : Class to define a cell grid surrounding * This program is free software; you can redistribute it and/or
// the projected image of a scene * modify it under the terms of the GNU General Public License
// Date of creation : 2010-12-19 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to define a cell grid surrounding the projected image of a scene
// * \author Alexander Beels
// This program is free software; you can redistribute it and/or * \date 2010-12-19
// 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 SPHERICAL_GRID_LOGGING FALSE
#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.
// 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 <vector>
//#include <deque> //#include <deque>
#include "GridDensityProvider.h"
#include "OccluderSource.h"
#include "ViewMap.h" #include "ViewMap.h"
#include "../winged_edge/WEdge.h"
#include "../geometry/Polygon.h" #include "../geometry/Polygon.h"
#include "../system/PointerSequence.h"
#include "../geometry/BBox.h" #include "../geometry/BBox.h"
#include "../geometry/GridHelpers.h" #include "../geometry/GridHelpers.h"
#include "OccluderSource.h"
#include "GridDensityProvider.h" #include "../system/PointerSequence.h"
#include "../winged_edge/WEdge.h"
class SphericalGrid class SphericalGrid
{ {
public: public:
// Helper classes // Helper classes
struct OccluderData { struct OccluderData
{
explicit OccluderData (OccluderSource& source, Polygon3r& p); explicit OccluderData (OccluderSource& source, Polygon3r& p);
Polygon3r poly; Polygon3r poly;
Polygon3r cameraSpacePolygon; Polygon3r cameraSpacePolygon;
real shallowest, deepest; real shallowest, deepest;
// N.B. We could, of course, store face in poly's userdata // N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
// member, like the old ViewMapBuilder code does. However, // However, code comments make it clear that userdata is deprecated, so we avoid the temptation to save
// code comments make it clear that userdata is deprecated, // 4 or 8 bytes.
// so we avoid the temptation to save 4 or 8 bytes.
WFace *face; WFace *face;
}; };
private: private:
struct Cell { struct Cell
{
// Can't store Cell in a vector without copy and assign // Can't store Cell in a vector without copy and assign
//Cell(const Cell& other); //Cell(const Cell& other);
//Cell& operator=(const Cell& other); //Cell& operator=(const Cell& other);
@@ -84,28 +92,22 @@ private:
}; };
public: 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.
*/
Iterator needs to allow the user to avoid full 3D comparison in class Iterator
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: public:
// epsilon is not used in this class, but other grids with the same interface may need an epsilon // 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); explicit Iterator(SphericalGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
~Iterator(); ~Iterator();
void initBeforeTarget(); void initBeforeTarget();
void initAfterTarget(); void initAfterTarget();
@@ -128,7 +130,8 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate; vector<OccluderData*>::iterator _current, _occludeeCandidate;
}; };
class Transform : public GridHelpers::Transform { class Transform : public GridHelpers::Transform
{
public: public:
explicit Transform(); explicit Transform();
explicit Transform(Transform& other); explicit Transform(Transform& other);
@@ -140,16 +143,17 @@ private:
// Prevent implicit copies and assignments. // Prevent implicit copies and assignments.
SphericalGrid(const SphericalGrid& other); SphericalGrid(const SphericalGrid& other);
SphericalGrid& operator=(const SphericalGrid& other); SphericalGrid& operator=(const SphericalGrid& other);
public: 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(); virtual ~SphericalGrid();
// Generate Cell structure // Generate Cell structure
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap); void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
// Fill Cells // Fill Cells
void distributePolygons(OccluderSource& source); void distributePolygons(OccluderSource& source);
// Insert one polygon into each matching cell, // Insert one polygon into each matching cell, return true if any cell consumes the polygon
// return true if any cell consumes the polygon
bool insertOccluder(OccluderSource& source, OccluderData*& occluder); bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
// Sort occluders in each cell // Sort occluders in each cell
void reorganizeCells(); void reorganizeCells();
@@ -176,23 +180,25 @@ private:
bool _enableQI; bool _enableQI;
}; };
inline void SphericalGrid::Iterator::initBeforeTarget () { inline void SphericalGrid::Iterator::initBeforeTarget()
{
_current = _cell->faces.begin(); _current = _cell->faces.begin();
while (_current != _cell->faces.end() && !testOccluder(false)) { while (_current != _cell->faces.end() && !testOccluder(false)) {
++_current; ++_current;
} }
} }
inline void SphericalGrid::Iterator::initAfterTarget () { inline void SphericalGrid::Iterator::initAfterTarget()
{
if (_foundOccludee) { if (_foundOccludee) {
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl; std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
#endif #endif
_current = _occludeeCandidate; _current = _occludeeCandidate;
return; return;
} }
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
std::cout << "\tStarting occludee search from current position" << std::endl; std::cout << "\tStarting occludee search from current position" << std::endl;
#endif #endif
@@ -201,26 +207,25 @@ inline void SphericalGrid::Iterator::initAfterTarget () {
} }
} }
inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) { inline bool SphericalGrid::Iterator::testOccluder(bool wantOccludee)
{
// End-of-list is not even a valid iterator position // End-of-list is not even a valid iterator position
if (_current == _cell->faces.end()) { if (_current == _cell->faces.end()) {
// Returning true seems strange, but it will break us out of whatever loop // Returning true seems strange, but it will break us out of whatever loop is calling testOccluder, and
// is calling testOccluder, and _current=_cell->face.end() will make // _current=_cell->face.end() will make the calling routine give up.
// the calling routine give up.
return true; return true;
} }
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0]; 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 << ", " << (*_current)->poly.getVertices()[i];
} }
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl; std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
#endif #endif
// If we have an occluder candidate and we are unambiguously after it, abort // If we have an occluder candidate and we are unambiguously after it, abort
if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) { if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl; std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
#endif #endif
_current = _cell->faces.end(); _current = _cell->faces.end();
@@ -232,14 +237,15 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
// Specific continue or stop conditions when searching for each type // Specific continue or stop conditions when searching for each type
if (wantOccludee) { if (wantOccludee) {
if ((*_current)->deepest < _target[2]) { if ((*_current)->deepest < _target[2]) {
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl; std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
#endif #endif
return false; return false;
} }
} else { }
else {
if ((*_current)->shallowest > _target[2]) { if ((*_current)->shallowest > _target[2]) {
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl; std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
#endif #endif
return true; return true;
@@ -252,44 +258,43 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
Vec3r bbMin, bbMax; Vec3r bbMin, bbMax;
(*_current)->poly.getBBox(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 (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tSkipping: bounding box violation" << std::endl; std::cout << "\t\tSkipping: bounding box violation" << std::endl;
#endif #endif
return false; return false;
} }
// We've done all the corner cutting we can. // 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; return true;
} }
inline void SphericalGrid::Iterator::reportDepth (Vec3r origin, Vec3r u, real t) { 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 // 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 // If origin is the viewpoint, depth == t. A future optimization could allow the caller to tell us if origin is
// A future optimization could allow the caller to tell us if origin is viewponit or target, // viewponit or target, at the cost of changing the OptimizedGrid API.
// at the cost of changing the OptimizedGrid API.
real depth = (origin + u * t).norm(); real depth = (origin + u * t).norm();
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
std::cout << "\t\tReporting depth of occluder/ee: " << depth; std::cout << "\t\tReporting depth of occluder/ee: " << depth;
#endif #endif
if (depth > _target[2]) { if (depth > _target[2]) {
#if sphericalgridlogging == 1 #if SPHERICAL_GRID_LOGGING
std::cout << " is deeper than target" << std::endl; std::cout << " is deeper than target" << std::endl;
#endif #endif
// If the current occluder is the best occludee so far, save it. // If the current occluder is the best occludee so far, save it.
if (! _foundOccludee || _occludeeDepth > depth) { if (! _foundOccludee || _occludeeDepth > depth) {
markCurrentOccludeeCandidate(depth); markCurrentOccludeeCandidate(depth);
} }
} else { }
#if sphericalgridlogging == 1 else {
#if SPHERICAL_GRID_LOGGING
std::cout << std::endl; std::cout << std::endl;
#endif #endif
} }
} }
inline void SphericalGrid::Iterator::nextOccluder () { inline void SphericalGrid::Iterator::nextOccluder()
{
if (_current != _cell->faces.end()) { if (_current != _cell->faces.end()) {
do { do {
++_current; ++_current;
@@ -297,7 +302,8 @@ inline void SphericalGrid::Iterator::nextOccluder () {
} }
} }
inline void SphericalGrid::Iterator::nextOccludee () { inline void SphericalGrid::Iterator::nextOccludee()
{
if (_current != _cell->faces.end()) { if (_current != _cell->faces.end()) {
do { do {
++_current; ++_current;
@@ -305,16 +311,19 @@ inline void SphericalGrid::Iterator::nextOccludee () {
} }
} }
inline bool SphericalGrid::Iterator::validBeforeTarget () { inline bool SphericalGrid::Iterator::validBeforeTarget()
{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2]; return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
} }
inline bool SphericalGrid::Iterator::validAfterTarget () { inline bool SphericalGrid::Iterator::validAfterTarget()
{
return _current != _cell->faces.end(); return _current != _cell->faces.end();
} }
inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) { inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth)
#if sphericalgridlogging == 1 {
#if SPHERICAL_GRID_LOGGING
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl; std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
#endif #endif
_occludeeCandidate = _current; _occludeeCandidate = _current;
@@ -322,18 +331,18 @@ inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
_foundOccludee = true; _foundOccludee = true;
} }
inline WFace* SphericalGrid::Iterator::getWFace() const { inline WFace *SphericalGrid::Iterator::getWFace() const
{
return (*_current)->face; return (*_current)->face;
} }
inline Polygon3r* SphericalGrid::Iterator::getCameraSpacePolygon() { inline Polygon3r *SphericalGrid::Iterator::getCameraSpacePolygon()
{
return &((*_current)->cameraSpacePolygon); return &((*_current)->cameraSpacePolygon);
} }
inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p) inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
: poly(p), : poly(p), cameraSpacePolygon(source.getCameraSpacePolygon()), face(source.getWFace())
cameraSpacePolygon(source.getCameraSpacePolygon()),
face(source.getWFace())
{ {
const Vec3r viewpoint(0, 0, 0); const Vec3r viewpoint(0, 0, 0);
// Get the point on the camera-space polygon that is closest to the viewpoint // Get the point on the camera-space polygon that is closest to the viewpoint
@@ -343,7 +352,7 @@ inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygo
// Get the point on the camera-space polygon that is furthest from the viewpoint // 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 is the distance from the viewpoint to that point
deepest = cameraSpacePolygon.getVertices()[2].norm(); 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(); real t = cameraSpacePolygon.getVertices()[i].norm();
if (t > deepest) { if (t > deepest) {
deepest = t; deepest = t;
@@ -351,7 +360,8 @@ inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygo
} }
} }
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) { inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
{
if (GridHelpers::insideProscenium (boundary, poly)) { if (GridHelpers::insideProscenium (boundary, poly)) {
if (occluder == NULL) { if (occluder == NULL) {
// Disposal of occluder will be handled in SphericalGrid::distributePolygons(), // Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
@@ -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()); Polygon3r& poly(source.getGridSpacePolygon());
occluder = NULL; occluder = NULL;
@@ -373,8 +384,8 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
getCellCoordinates(bbMin, startX, startY); getCellCoordinates(bbMin, startX, startY);
getCellCoordinates(bbMax, endX, endY); getCellCoordinates(bbMax, endX, endY);
for ( unsigned i = startX; i <= endX; ++i ) { for (unsigned int i = startX; i <= endX; ++i) {
for ( unsigned j = startY; j <= endY; ++j ) { for (unsigned int j = startY; j <= endY; ++j) {
if (_cells[i * _cellsY + j] != NULL) { if (_cells[i * _cellsY + j] != NULL) {
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder); _cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
} }
@@ -384,5 +395,4 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
return occluder != NULL; return occluder != NULL;
} }
#endif // SPHERICALGRID_H #endif // __FREESTYLE_SPHERICAL_GRID_H__

View File

@@ -1,57 +1,78 @@
// /*
// Copyright (C) : Please refer to the COPYRIGHT file distributed * ***** BEGIN GPL LICENSE BLOCK *****
// with this source distribution. *
// * This program is free software; you can redistribute it and/or
// This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License
// modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2
// as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version.
// of the License, or (at your option) any later version. *
// * This program 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
// but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details.
// GNU General Public License for more details. *
// * You should have received a copy of the GNU General Public License
// You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation,
// along with this program; if not, write to the Free Software * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "Silhouette.h"
#include "SteerableViewMap.h" #include "SteerableViewMap.h"
#include "../geometry/Geom.h"
#include "../image/ImagePyramid.h" #include "../image/ImagePyramid.h"
#include "../image/Image.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>
extern "C" { extern "C" {
#include "IMB_imbuf.h" #include "IMB_imbuf.h"
#include "IMB_imbuf_types.h" #include "IMB_imbuf_types.h"
} }
SteerableViewMap::SteerableViewMap(unsigned int nbOrientations){ using namespace Geometry;
SteerableViewMap::SteerableViewMap(unsigned int nbOrientations)
{
_nbOrientations = nbOrientations; _nbOrientations = nbOrientations;
_bound = cos(M_PI/(float)_nbOrientations); _bound = cos(M_PI/(float)_nbOrientations);
for(unsigned i=0; i<_nbOrientations; ++i){ 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))); _directions.push_back(Vec2d(cos((float)i * M_PI / (float)_nbOrientations),
sin((float)i * M_PI / (float)_nbOrientations)));
} }
Build(); Build();
} }
void SteerableViewMap::Build(){ void SteerableViewMap::Build()
{
_imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM _imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
memset((_imagesPyramids), 0, (_nbOrientations + 1) * sizeof(ImagePyramid *)); memset((_imagesPyramids), 0, (_nbOrientations + 1) * sizeof(ImagePyramid *));
} }
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){ SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother)
{
_nbOrientations = iBrother._nbOrientations; _nbOrientations = iBrother._nbOrientations;
unsigned i; unsigned int i;
_bound = iBrother._bound; _bound = iBrother._bound;
_directions = iBrother._directions; _directions = iBrother._directions;
_mapping = iBrother._mapping; _mapping = iBrother._mapping;
@@ -60,12 +81,14 @@ SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){
_imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i]))); _imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
} }
SteerableViewMap::~SteerableViewMap(){ SteerableViewMap::~SteerableViewMap()
{
Clear(); Clear();
} }
void SteerableViewMap::Clear(){ void SteerableViewMap::Clear()
unsigned i; {
unsigned int i;
if (_imagesPyramids) { if (_imagesPyramids) {
for (i = 0; i <= _nbOrientations; ++i) { for (i = 0; i <= _nbOrientations; ++i) {
if (_imagesPyramids[i]) if (_imagesPyramids[i])
@@ -75,31 +98,32 @@ void SteerableViewMap::Clear(){
_imagesPyramids = 0; _imagesPyramids = 0;
} }
if (!_mapping.empty()) { if (!_mapping.empty()) {
for(map<unsigned int, double*>::iterator m=_mapping.begin(), mend=_mapping.end(); for (map<unsigned int, double*>::iterator m = _mapping.begin(), mend = _mapping.end(); m != mend; ++m) {
m!=mend;
++m){
delete[] (*m).second; delete[] (*m).second;
} }
_mapping.clear(); _mapping.clear();
} }
} }
void SteerableViewMap::Reset(){ void SteerableViewMap::Reset()
{
Clear(); Clear();
Build(); Build();
} }
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i){ double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i)
{
double dotp = fabs(dir * _directions[i]); double dotp = fabs(dir * _directions[i]);
if (dotp < _bound) if (dotp < _bound)
return 0; return 0.0;
if(dotp>1) if (dotp > 1.0)
dotp = 1; dotp = 1.0;
return cos((float)_nbOrientations / 2.0 * acos(dotp)); return cos((float)_nbOrientations / 2.0 * acos(dotp));
} }
double * SteerableViewMap::AddFEdge(FEdge *iFEdge){ double *SteerableViewMap::AddFEdge(FEdge *iFEdge)
{
unsigned i; unsigned i;
unsigned id = iFEdge->getId().getFirst(); unsigned id = iFEdge->getId().getFirst();
map<unsigned int, double* >::iterator o = _mapping.find(id); map<unsigned int, double* >::iterator o = _mapping.find(id);
@@ -108,12 +132,12 @@ double * SteerableViewMap::AddFEdge(FEdge *iFEdge){
} }
double *res = new double[_nbOrientations]; double *res = new double[_nbOrientations];
for (i = 0; i < _nbOrientations; ++i) { for (i = 0; i < _nbOrientations; ++i) {
res[i] = 0; res[i] = 0.0;
} }
Vec3r o2d3 = iFEdge->orientation2d(); Vec3r o2d3 = iFEdge->orientation2d();
Vec2r o2d2(o2d3.x(), o2d3.y()); Vec2r o2d2(o2d3.x(), o2d3.y());
real norm = o2d2.norm(); real norm = o2d2.norm();
if(norm < 1e-6){ if (norm < 1.0e-6) {
return res; return res;
} }
o2d2 /= norm; o2d2 /= norm;
@@ -125,17 +149,18 @@ double * SteerableViewMap::AddFEdge(FEdge *iFEdge){
return res; return res;
} }
unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){ unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient)
{
Vec2f dir(orient); Vec2f dir(orient);
//soc unsigned res = 0; //soc unsigned res = 0;
real norm = dir.norm(); real norm = dir.norm();
if(norm < 1e-6){ if (norm < 1.0e-6) {
return _nbOrientations + 1; return _nbOrientations + 1;
} }
dir /= norm; dir /= norm;
double maxw = 0.f; double maxw = 0.0f;
unsigned winner = _nbOrientations + 1; unsigned winner = _nbOrientations + 1;
for(unsigned i=0; i<_nbOrientations; ++i){ for (unsigned int i = 0; i < _nbOrientations; ++i) {
double w = ComputeWeight(dir, i); double w = ComputeWeight(dir, i);
if (w > maxw) { if (w > maxw) {
maxw = w; maxw = w;
@@ -145,12 +170,12 @@ unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){
return winner; return winner;
} }
unsigned SteerableViewMap::getSVMNumber(unsigned id)
unsigned SteerableViewMap::getSVMNumber(unsigned id){ {
map<unsigned int, double* >::iterator o = _mapping.find(id); map<unsigned int, double* >::iterator o = _mapping.find(id);
if (o != _mapping.end()) { if (o != _mapping.end()) {
double *wvalues = (*o).second; double *wvalues = (*o).second;
double maxw = 0.f; double maxw = 0.0;
unsigned winner = _nbOrientations + 1; unsigned winner = _nbOrientations + 1;
for (unsigned i = 0; i < _nbOrientations; ++i) { for (unsigned i = 0; i < _nbOrientations; ++i) {
double w = wvalues[i]; double w = wvalues[i];
@@ -164,8 +189,9 @@ unsigned SteerableViewMap::getSVMNumber(unsigned id){
return _nbOrientations + 1; return _nbOrientations + 1;
} }
void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma){ void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma)
for(unsigned i=0; i<=_nbOrientations; ++i){ {
for (unsigned int i = 0; i <= _nbOrientations; ++i) {
ImagePyramid *svm = (_imagesPyramids)[i]; ImagePyramid *svm = (_imagesPyramids)[i];
if (svm) if (svm)
delete svm; delete svm;
@@ -177,7 +203,8 @@ void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy
} }
} }
float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y){ float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y)
{
ImagePyramid *pyramid = _imagesPyramids[iOrientation]; ImagePyramid *pyramid = _imagesPyramids[iOrientation];
if (pyramid == 0) { if (pyramid == 0) {
cout << "Warning: this steerable ViewMap level doesn't exist" << endl; cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
@@ -185,29 +212,33 @@ float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLe
} }
if ((x < 0) || (x >= pyramid->width()) || (y < 0) || (y >= pyramid->height())) if ((x < 0) || (x >= pyramid->width()) || (y < 0) || (y >= pyramid->height()))
return 0; return 0;
//float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)*255.f; //float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) * 255.0f;
float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)/32.f; // we encode both the directionality and the lines counting on 8 bits // We encode both the directionality and the lines counting on 8 bits (because of frame buffer). Thus, we allow
// (because of frame buffer). Thus, we allow until 8 lines to pass through // until 8 lines to pass through the same pixel, so that we can discretize the Pi/_nbOrientations angle into
// 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
// 32 slices. Therefore, for example, in the vertical direction, a vertical line // each pixel it passes through.
// 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; return v;
} }
float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y){ float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y)
{
return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y); return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y);
} }
unsigned int SteerableViewMap::getNumberOfPyramidLevels() const{ unsigned int SteerableViewMap::getNumberOfPyramidLevels() const
{
if (_imagesPyramids[0]) if (_imagesPyramids[0])
return _imagesPyramids[0]->getNumberOfLevels(); return _imagesPyramids[0]->getNumberOfLevels();
return 0; return 0;
} }
void SteerableViewMap::saveSteerableViewMap() const { void SteerableViewMap::saveSteerableViewMap() const
for(unsigned i=0; i<=_nbOrientations; ++i){ {
for (unsigned int i = 0; i <= _nbOrientations; ++i) {
if (_imagesPyramids[i] == 0) { if (_imagesPyramids[i] == 0) {
cerr << "SteerableViewMap warning: orientation " << i <<" of steerable View Map whas not been computed yet" << endl; cerr << "SteerableViewMap warning: orientation " << i
<< " of steerable View Map whas not been computed yet" << endl;
continue; continue;
} }
int ow = _imagesPyramids[i]->width(0); int ow = _imagesPyramids[i]->width(0);
@@ -218,7 +249,7 @@ void SteerableViewMap::saveSteerableViewMap() const {
stringstream filename; stringstream filename;
for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc
float coeff = 1;//1/255.f; //100*255;//*pow(2,j); float coeff = 1.0f; // 1 / 255.0f; // 100 * 255; // * pow(2, j);
//soc QImage qtmp(ow, oh, QImage::Format_RGB32); //soc QImage qtmp(ow, oh, QImage::Format_RGB32);
ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect); ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
int rowbytes = ow * 4; int rowbytes = ow * 4;
@@ -242,26 +273,26 @@ void SteerableViewMap::saveSteerableViewMap() const {
filename << i << "-" << j << ".png"; filename << i << "-" << j << ".png";
ibuf->ftype = PNG; ibuf->ftype = PNG;
IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0); IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0);
} }
// QString base("SteerableViewMap"); #if 0
// for(unsigned j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ QString base("SteerableViewMap");
// GrayImage * img = _imagesPyramids[i]->getLevel(j); for (unsigned j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) {
// int ow = img->width(); GrayImage *img = _imagesPyramids[i]->getLevel(j);
// int oh = img->height(); int ow = img->width();
// float coeff = 1; //100*255;//*pow(2,j); int oh = img->height();
// QImage qtmp(ow, oh, 32); float coeff = 1.0f; // 100 * 255; // * pow(2, j);
// for(unsigned y=0;y<oh;++y){ QImage qtmp(ow, oh, 32);
// for(unsigned x=0;x<ow;++x){ for (unsigned int y = 0; y < oh; ++y) {
// int c = (int)(coeff*img->pixel(x,y)); for (unsigned int x = 0; x < ow; ++x) {
// if(c>255) int c = (int)(coeff * img->pixel(x, y));
// c=255; if (c > 255)
// //int c = (int)(_imagesPyramids[i]->pixel(x,y,j)); c = 255;
// qtmp.setPixel(x,y,qRgb(c,c,c)); //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"); }
// } qtmp.save(base + QString::number(i) + "-" + QString::number(j) + ".png", "PNG");
// }
#endif
} }
} }

View File

@@ -1,38 +1,46 @@
// /*
// Filename : SteerbaleViewMap.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Convenient access to the steerable ViewMap * This program is free software; you can redistribute it and/or
// to which any element of the ViewMap belongs to. * modify it under the terms of the GNU General Public License
// Date of creation : 01/07/2003 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Convenient access to the steerable ViewMap to which any element of the ViewMap belongs to.
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 01/07/2003
// 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
#include <map> #include <map>
#include "../system/FreestyleConfig.h"
#include "../geometry/Geom.h" #include "../geometry/Geom.h"
#include "../system/FreestyleConfig.h"
using namespace Geometry; using namespace Geometry;
using namespace std; using namespace std;
@@ -40,13 +48,16 @@ using namespace std;
class FEdge; class FEdge;
class ImagePyramid; class ImagePyramid;
class GrayImage; class GrayImage;
/*! This class checks for every FEdge in which steerable
* it belongs and stores the mapping allowing to retrieve /*! 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 information from the FEdge Id.
*/ */
class LIB_VIEW_MAP_EXPORT SteerableViewMap{ class LIB_VIEW_MAP_EXPORT SteerableViewMap
{
protected: protected:
map<unsigned int, double* > _mapping; // for each vector the list of nbOrientations weigths corresponding to its contributions to the nbOrientations directional maps // for each vector the list of nbOrientations weigths corresponding to its contributions
// to the nbOrientations directional maps
map<unsigned int, double*> _mapping;
unsigned _nbOrientations; unsigned _nbOrientations;
ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM
@@ -63,45 +74,40 @@ public:
virtual void Reset(); virtual void Reset();
/*! Adds a FEdge to steerable VM. /*! Adds a FEdge to steerable VM.
* Returns the nbOrientations weigths corresponding to * Returns the nbOrientations weigths corresponding to the FEdge contributions to the nbOrientations
* the FEdge contributions to the nbOrientations directional maps. * directional maps.
*/ */
double *AddFEdge(FEdge *iFEdge); double *AddFEdge(FEdge *iFEdge);
/*! Compute the weight of direction dir for orientation iNOrientation */ /*! Compute the weight of direction dir for orientation iNOrientation */
double ComputeWeight(const Vec2d& dir, unsigned iNOrientation); double ComputeWeight(const Vec2d& dir, unsigned iNOrientation);
/*! Returns the number of the SVM to which a direction belongs /*! Returns the number of the SVM to which a direction belongs to.
* to.
* \param dir * \param dir
* The direction * The direction
*/ */
unsigned getSVMNumber(const Vec2f& dir); unsigned getSVMNumber(const Vec2f& dir);
/*! Returns the number of the SVM to which a FEdge belongs /*! Returns the number of the SVM to which a FEdge belongs most.
* most.
* \param id * \param id
* The First element of the Id struct of the FEdge * The First element of the Id struct of the FEdge we're intersted in.
* we're intersted in.
*/ */
unsigned getSVMNumber(unsigned id); unsigned getSVMNumber(unsigned id);
/*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images /*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images of the steerable viewmap.
* of the steerable viewmap.
* \param steerableBases * \param steerableBases
* The _nbOrientations+1 images constituing the basis for the steerable * The _nbOrientations+1 images constituing the basis for the steerable pyramid.
* pyramid.
* \param copy * \param copy
* If false, the data is not duplicated, and Canvas deals * If false, the data is not duplicated, and Canvas deals with the memory management of these
* with the memory management of these _nbOrientations+1 images. If true, data * _nbOrientations+1 images. If true, data is copied, and it's up to the caller to delete the images.
* is copied, and it's up to the caller to delete the images.
* \params iNbLevels * \params iNbLevels
* The number of levels desired for each pyramid. * The number of levels desired for each pyramid.
* If iNbLevels == 0, the complete pyramid is built. * If iNbLevels == 0, the complete pyramid is built.
* \param iSigma * \param iSigma
* The sigma that will be used for the gaussian blur * The sigma that will be used for the gaussian blur
*/ */
void buildImagesPyramids(GrayImage **steerableBases, bool copy = false, unsigned iNbLevels=4, float iSigma = 1.f); 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. /*! Reads a pixel value in one of the VewMap density steerable pyramids.
* Returns a value between 0 and 1. * Returns a value between 0 and 1.
@@ -116,17 +122,13 @@ public:
* \param iLevel * \param iLevel
* The level of the pyramid we want to read * The level of the pyramid we want to read
* \param x * \param x
* The abscissa of the desired pixel specified in level0 coordinate * The abscissa of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
* system. The origin is the lower left corner.
* \param y * \param y
* The ordinate of the desired pixel specified in level0 coordinate * The ordinate of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
* system. The origin is the lower left corner.
*/ */
float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y); float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y);
/*! Reads a pixel in the one of the level of the /*! Reads a pixel in the one of the level of the pyramid containing the images of the complete ViewMap.
* pyramid containing the images of the complete
* ViewMap.
* Returns a value between 0 and 1. * Returns a value between 0 and 1.
* Equivalent to : readSteerableViewMapPixel(nbOrientations, x, y) * Equivalent to : readSteerableViewMapPixel(nbOrientations, x, y)
*/ */
@@ -136,7 +138,8 @@ public:
unsigned int getNumberOfPyramidLevels() const; unsigned int getNumberOfPyramidLevels() const;
/*! Returns the number of orientations */ /*! Returns the number of orientations */
unsigned int getNumberOfOrientations() const{ unsigned int getNumberOfOrientations() const
{
return _nbOrientations; return _nbOrientations;
} }
@@ -146,8 +149,6 @@ public:
protected: protected:
void Clear(); void Clear();
void Build(); void Build();
}; };
#endif // STEERABLEVIEWMAP_H #endif // __FREESTYLE_STEERABLE_VIEW_MAP_H__

View File

@@ -1,32 +1,49 @@
// /*
// Copyright (C) : Please refer to the COPYRIGHT file distributed * ***** BEGIN GPL LICENSE BLOCK *****
// with this source distribution. *
// * This program is free software; you can redistribute it and/or
// This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License
// modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2
// as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version.
// of the License, or (at your option) any later version. *
// * This program 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
// but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details.
// GNU General Public License for more details. *
// * You should have received a copy of the GNU General Public License
// You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation,
// along with this program; if not, write to the Free Software * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "ViewEdgeXBuilder.h"
#include "../winged_edge/WXEdge.h"
#include "SilhouetteGeomEngine.h"
#include <list> #include <list>
#include "SilhouetteGeomEngine.h"
#include "ViewEdgeXBuilder.h"
#include "ViewMap.h"
#include "../winged_edge/WXEdge.h"
using namespace std; using namespace std;
void ViewEdgeXBuilder::Init(ViewShape *oVShape){ void ViewEdgeXBuilder::Init(ViewShape *oVShape)
{
if (0 == oVShape) if (0 == oVShape)
return; return;
@@ -43,39 +60,33 @@ void ViewEdgeXBuilder::Init(ViewShape *oVShape){
_SVertexMap.clear(); _SVertexMap.clear();
} }
void ViewEdgeXBuilder::BuildViewEdges( WXShape *iWShape, ViewShape *oVShape, void ViewEdgeXBuilder::BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, vector<ViewEdge*>& ioVEdges,
vector<ViewEdge*>& ioVEdges, vector<ViewVertex*>& ioVVertices, vector<FEdge*>& ioFEdges,
vector<ViewVertex*>& ioVVertices, vector<SVertex*>& ioSVertices)
vector<FEdge*>& ioFEdges, {
vector<SVertex*>& ioSVertices){
// Reinit structures // Reinit structures
Init(oVShape); Init(oVShape);
ViewEdge *vedge; ViewEdge *vedge;
// Let us build the smooth stuff // Let us build the smooth stuff
//---------------------------------------- //----------------------------------------
// We parse all faces to find the ones // We parse all faces to find the ones that contain smooth edges
// that contain smooth edges
vector<WFace*>& wfaces = iWShape->GetFaceList(); vector<WFace*>& wfaces = iWShape->GetFaceList();
vector<WFace*>::iterator wf, wfend; vector<WFace*>::iterator wf, wfend;
WXFace *wxf; WXFace *wxf;
for(wf=wfaces.begin(), wfend=wfaces.end(); for (wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; wf++) {
wf!=wfend;
wf++){
wxf = dynamic_cast<WXFace*>(*wf); wxf = dynamic_cast<WXFace*>(*wf);
if (false == ((wxf))->hasSmoothEdges()) // does it contain at least one smooth edge ? if (false == ((wxf))->hasSmoothEdges()) // does it contain at least one smooth edge ?
continue; continue;
// parse all smooth layers: // parse all smooth layers:
vector<WXFaceLayer*>& smoothLayers = wxf->getSmoothLayers(); vector<WXFaceLayer*>& smoothLayers = wxf->getSmoothLayers();
for(vector<WXFaceLayer*>::iterator sl = smoothLayers.begin(), slend=smoothLayers.end(); for (vector<WXFaceLayer*>::iterator sl = smoothLayers.begin(), slend = smoothLayers.end(); sl != slend; ++sl) {
sl!=slend;
++sl){
if (!(*sl)->hasSmoothEdge()) if (!(*sl)->hasSmoothEdge())
continue; continue;
if (stopSmoothViewEdge((*sl))) // has it been parsed already ? if (stopSmoothViewEdge((*sl))) // has it been parsed already ?
continue; continue;
// here we know that we're dealing with a face layer that has not been // here we know that we're dealing with a face layer that has not been processed yet and that contains
// processed yet and that contains a smooth edge. // a smooth edge.
vedge = BuildSmoothViewEdge(OWXFaceLayer(*sl, true)); vedge = BuildSmoothViewEdge(OWXFaceLayer(*sl, true));
} }
} }
@@ -88,11 +99,8 @@ void ViewEdgeXBuilder::BuildViewEdges( WXShape *iWShape, ViewShape *oVShape,
WXEdge *wxe; WXEdge *wxe;
vector<WEdge*>& wedges = iWShape->getEdgeList(); vector<WEdge*>& wedges = iWShape->getEdgeList();
//
//------------------------------ //------------------------------
for(vector<WEdge*>::iterator we=wedges.begin(),weend=wedges.end(); for (vector<WEdge*>::iterator we = wedges.begin(), weend = wedges.end(); we != weend; we++) {
we!=weend;
we++){
wxe = dynamic_cast<WXEdge*>(*we); wxe = dynamic_cast<WXEdge*>(*we);
if (Nature::NO_FEATURE == wxe->nature()) if (Nature::NO_FEATURE == wxe->nature())
continue; continue;
@@ -121,10 +129,10 @@ void ViewEdgeXBuilder::BuildViewEdges( WXShape *iWShape, ViewShape *oVShape,
ioSVertices.insert(ioSVertices.end(), newVertices.begin(), newVertices.end()); ioSVertices.insert(ioSVertices.end(), newVertices.begin(), newVertices.end());
ioVVertices.insert(ioVVertices.end(), newVVertices.begin(), newVVertices.end()); ioVVertices.insert(ioVVertices.end(), newVVertices.begin(), newVVertices.end());
ioVEdges.insert(ioVEdges.end(), newVEdges.begin(), newVEdges.end()); ioVEdges.insert(ioVEdges.end(), newVEdges.begin(), newVEdges.end());
} }
ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer){ ViewEdge *ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
{
// Find first edge: // Find first edge:
OWXFaceLayer first = iFaceLayer; OWXFaceLayer first = iFaceLayer;
OWXFaceLayer currentFace = first; OWXFaceLayer currentFace = first;
@@ -165,14 +173,11 @@ ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
_pCurrentVShape->AddEdge(newVEdge); _pCurrentVShape->AddEdge(newVEdge);
// build FEdges // build FEdges
FEdge * feprevious = 0; FEdge *feprevious = NULL;
FEdge * fefirst = 0; FEdge *fefirst = NULL;
FEdge * fe = 0; FEdge *fe = NULL;
for(list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend=facesChain.end(); for (list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend = facesChain.end(); fl != flend; ++fl) {
fl!=flend;
++fl){
fe = BuildSmoothFEdge(feprevious, (*fl)); fe = BuildSmoothFEdge(feprevious, (*fl));
if (feprevious && fe == feprevious) if (feprevious && fe == feprevious)
continue; continue;
@@ -193,7 +198,8 @@ ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
fe->setNextEdge(fefirst); fe->setNextEdge(fefirst);
newVEdge->setA(0); newVEdge->setA(0);
newVEdge->setB(0); newVEdge->setB(0);
}else{ }
else {
ViewVertex *vva = MakeViewVertex(fefirst->vertexA()); ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
ViewVertex *vvb = MakeViewVertex(fe->vertexB()); ViewVertex *vvb = MakeViewVertex(fe->vertexB());
@@ -207,7 +213,8 @@ ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
return newVEdge; return newVEdge;
} }
ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) { ViewEdge *ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge)
{
// Start a new sharp chain edges // Start a new sharp chain edges
ViewEdge *newVEdge = new ViewEdge; ViewEdge *newVEdge = new ViewEdge;
newVEdge->setId(_currentViewId); newVEdge->setId(_currentViewId);
@@ -250,12 +257,10 @@ ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
firstWEdge = edgesChain.front(); firstWEdge = edgesChain.front();
// build FEdges // build FEdges
FEdge * feprevious = 0; FEdge *feprevious = NULL;
FEdge * fefirst = 0; FEdge *fefirst = NULL;
FEdge * fe = 0; FEdge *fe = NULL;
for(list<OWXEdge>::iterator we = edgesChain.begin(), weend=edgesChain.end(); for (list<OWXEdge>::iterator we = edgesChain.begin(), weend = edgesChain.end(); we != weend; ++we) {
we!=weend;
++we){
fe = BuildSharpFEdge(feprevious, (*we)); fe = BuildSharpFEdge(feprevious, (*we));
fe->setViewEdge(newVEdge); fe->setViewEdge(newVEdge);
if (!fefirst) if (!fefirst)
@@ -274,7 +279,8 @@ ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
fe->setNextEdge(fefirst); fe->setNextEdge(fefirst);
newVEdge->setA(0); newVEdge->setA(0);
newVEdge->setB(0); newVEdge->setB(0);
}else{ }
else {
ViewVertex *vva = MakeViewVertex(fefirst->vertexA()); ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
ViewVertex *vvb = MakeViewVertex(fe->vertexB()); ViewVertex *vvb = MakeViewVertex(fe->vertexB());
@@ -288,14 +294,16 @@ ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
return newVEdge; return newVEdge;
} }
OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer){ OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer)
WXFace *nextFace = 0; {
WXFace *nextFace = NULL;
WOEdge *woeend; WOEdge *woeend;
real tend; real tend;
if (iFaceLayer.order) { if (iFaceLayer.order) {
woeend = iFaceLayer.fl->getSmoothEdge()->woeb(); woeend = iFaceLayer.fl->getSmoothEdge()->woeb();
tend = iFaceLayer.fl->getSmoothEdge()->tb(); tend = iFaceLayer.fl->getSmoothEdge()->tb();
}else{ }
else {
woeend = iFaceLayer.fl->getSmoothEdge()->woea(); woeend = iFaceLayer.fl->getSmoothEdge()->woea();
tend = iFaceLayer.fl->getSmoothEdge()->ta(); tend = iFaceLayer.fl->getSmoothEdge()->ta();
} }
@@ -316,13 +324,12 @@ OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer)
if ((0 != nextFace) && (nextFace != iFaceLayer.fl->getFace())) { if ((0 != nextFace) && (nextFace != iFaceLayer.fl->getFace())) {
vector<WXFaceLayer*> sameNatureLayers; vector<WXFaceLayer*> sameNatureLayers;
nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers); nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
if(sameNatureLayers.size() == 1) {// don't know // don't know... Maybe should test whether this face has also a vertex_edge configuration.
// maybe should test whether this face has if (sameNatureLayers.size() == 1) {
// also a vertex_edge configuration
WXFaceLayer *winner = sameNatureLayers[0]; WXFaceLayer *winner = sameNatureLayers[0];
// check face mark continuity // check face mark continuity
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL, true);
if (woeend == winner->getSmoothEdge()->woea()->twin()) if (woeend == winner->getSmoothEdge()->woea()->twin())
return OWXFaceLayer(winner, true); return OWXFaceLayer(winner, true);
else else
@@ -331,40 +338,44 @@ OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer)
} }
++f; ++f;
} }
}else{ }
else {
nextFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woeend)); nextFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woeend));
if(0 == nextFace) if (!nextFace)
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL, true);
// if the next face layer has either no smooth edge or // if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
// no smooth edge of same nature, no next face
if (!nextFace->hasSmoothEdges()) if (!nextFace->hasSmoothEdges())
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL,true);
vector<WXFaceLayer*> sameNatureLayers; vector<WXFaceLayer*> sameNatureLayers;
nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), 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 // don't know how to deal with several edges of same nature on a single face
return OWXFaceLayer(0,true); if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
return OWXFaceLayer(NULL, true);
}
else { else {
WXFaceLayer *winner = sameNatureLayers[0]; WXFaceLayer *winner = sameNatureLayers[0];
// check face mark continuity // check face mark continuity
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL, true);
if (woeend == winner->getSmoothEdge()->woea()->twin()) if (woeend == winner->getSmoothEdge()->woea()->twin())
return OWXFaceLayer(winner, true); return OWXFaceLayer(winner, true);
else else
return OWXFaceLayer(winner, false); return OWXFaceLayer(winner, false);
} }
} }
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL, true);
} }
OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer) { OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer)
WXFace *previousFace = 0; {
WXFace *previousFace = NULL;
WOEdge *woebegin; WOEdge *woebegin;
real tend; real tend;
if (iFaceLayer.order) { if (iFaceLayer.order) {
woebegin = iFaceLayer.fl->getSmoothEdge()->woea(); woebegin = iFaceLayer.fl->getSmoothEdge()->woea();
tend = iFaceLayer.fl->getSmoothEdge()->ta(); tend = iFaceLayer.fl->getSmoothEdge()->ta();
}else{ }
else {
woebegin = iFaceLayer.fl->getSmoothEdge()->woeb(); woebegin = iFaceLayer.fl->getSmoothEdge()->woeb();
tend = iFaceLayer.fl->getSmoothEdge()->tb(); tend = iFaceLayer.fl->getSmoothEdge()->tb();
} }
@@ -377,58 +388,58 @@ OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLa
else else
previousVertex = woebegin->GetbVertex(); previousVertex = woebegin->GetbVertex();
if (previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore if (previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL, true);
bool found = false; bool found = false;
WVertex::face_iterator f = previousVertex->faces_begin(); WVertex::face_iterator f = previousVertex->faces_begin();
WVertex::face_iterator fend = previousVertex->faces_end(); WVertex::face_iterator fend = previousVertex->faces_end();
while((!found) && (f!=fend)){ for (; (!found) && (f != fend); ++f) {
previousFace = dynamic_cast<WXFace*>(*f); previousFace = dynamic_cast<WXFace*>(*f);
if ((0 != previousFace) && (previousFace!=iFaceLayer.fl->getFace())) { if ((0 != previousFace) && (previousFace!=iFaceLayer.fl->getFace())) {
vector<WXFaceLayer*> sameNatureLayers; vector<WXFaceLayer*> sameNatureLayers;
previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers); previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
if(sameNatureLayers.size() == 1) {// don't know // don't know... Maybe should test whether this face has also a vertex_edge configuration
// maybe should test whether this face has if (sameNatureLayers.size() == 1) {
// also a vertex_edge configuration
WXFaceLayer *winner = sameNatureLayers[0]; WXFaceLayer *winner = sameNatureLayers[0];
// check face mark continuity // check face mark continuity
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL, true);
if (woebegin == winner->getSmoothEdge()->woeb()->twin()) if (woebegin == winner->getSmoothEdge()->woeb()->twin())
return OWXFaceLayer(winner, true); return OWXFaceLayer(winner, true);
else else
return OWXFaceLayer(winner, false); return OWXFaceLayer(winner, false);
} }
} }
++f;
} }
}else{ }
else {
previousFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin)); previousFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin));
if (0 == previousFace) if (0 == previousFace)
return OWXFaceLayer(0,true); 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 the next face layer has either no smooth edge or
// no smooth edge of same nature, no next face
if (!previousFace->hasSmoothEdges()) if (!previousFace->hasSmoothEdges())
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL, true);
vector<WXFaceLayer*> sameNatureLayers; vector<WXFaceLayer*> sameNatureLayers;
previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), 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 // don't know how to deal with several edges of same nature on a single face
return OWXFaceLayer(0,true); if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
return OWXFaceLayer(NULL, true);
}
else { else {
WXFaceLayer *winner = sameNatureLayers[0]; WXFaceLayer *winner = sameNatureLayers[0];
// check face mark continuity // check face mark continuity
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL, true);
if (woebegin == winner->getSmoothEdge()->woeb()->twin()) if (woebegin == winner->getSmoothEdge()->woeb()->twin())
return OWXFaceLayer(winner, true); return OWXFaceLayer(winner, true);
else else
return OWXFaceLayer(winner, false); return OWXFaceLayer(winner, false);
} }
} }
return OWXFaceLayer(0,true); return OWXFaceLayer(NULL, true);
} }
FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl){ FEdge *ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl)
{
WOEdge *woea, *woeb; WOEdge *woea, *woeb;
real ta, tb; real ta, tb;
SVertex *va, *vb; SVertex *va, *vb;
@@ -441,7 +452,8 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
woeb = se->woeb(); woeb = se->woeb();
ta = se->ta(); ta = se->ta();
tb = se->tb(); tb = se->tb();
} else { }
else {
woea = se->woeb(); woea = se->woeb();
woeb = se->woea(); woeb = se->woea();
ta = se->tb(); ta = se->tb();
@@ -465,20 +477,20 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
normal = na; normal = na;
// Set CurvatureInfo // Set CurvatureInfo
CurvatureInfo* curvature_info_a = new CurvatureInfo( CurvatureInfo *curvature_info_a =
*(dynamic_cast<WXVertex*>(woea->GetaVertex())->curvatures()), new CurvatureInfo(*(dynamic_cast<WXVertex*>(woea->GetaVertex())->curvatures()),
*(dynamic_cast<WXVertex*>(woea->GetbVertex())->curvatures()), *(dynamic_cast<WXVertex*>(woea->GetbVertex())->curvatures()), ta);
ta);
va->setCurvatureInfo(curvature_info_a); va->setCurvatureInfo(curvature_info_a);
} }
else else {
va = feprevious->vertexB(); va = feprevious->vertexB();
}
Vec3r B1(woeb->GetaVertex()->GetVertex()); Vec3r B1(woeb->GetaVertex()->GetVertex());
Vec3r B2(woeb->GetbVertex()->GetVertex()); Vec3r B2(woeb->GetbVertex()->GetVertex());
Vec3r B(B1 + tb * (B2 - B1)); Vec3r B(B1 + tb * (B2 - B1));
if (feprevious && (B - va->point3D()).norm() < 1e-6) if (feprevious && (B - va->point3D()).norm() < 1.0e-6)
return feprevious; return feprevious;
vb = MakeSVertex(B, false); vb = MakeSVertex(B, false);
@@ -491,10 +503,9 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
vb->AddNormal(nb); vb->AddNormal(nb);
// Set CurvatureInfo // Set CurvatureInfo
CurvatureInfo* curvature_info_b = new CurvatureInfo( CurvatureInfo *curvature_info_b =
*(dynamic_cast<WXVertex*>(woeb->GetaVertex())->curvatures()), new CurvatureInfo(*(dynamic_cast<WXVertex*>(woeb->GetaVertex())->curvatures()),
*(dynamic_cast<WXVertex*>(woeb->GetbVertex())->curvatures()), *(dynamic_cast<WXVertex*>(woeb->GetbVertex())->curvatures()), tb);
tb);
vb->setCurvatureInfo(curvature_info_b); vb->setCurvatureInfo(curvature_info_b);
// Creates the corresponding feature edge // Creates the corresponding feature edge
@@ -519,7 +530,8 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
return fe; return fe;
} }
bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer){ bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer)
{
if (0 == iFaceLayer) if (0 == iFaceLayer)
return true; return true;
if (iFaceLayer->userdata == 0) if (iFaceLayer->userdata == 0)
@@ -539,9 +551,10 @@ int ViewEdgeXBuilder::retrieveFaceMarks(WXEdge *iEdge)
return result; return result;
} }
OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge){ OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge)
{
if (Nature::NO_FEATURE == iEdge.e->nature()) if (Nature::NO_FEATURE == iEdge.e->nature())
return OWXEdge(0, true); return OWXEdge(NULL, true);
WVertex *v; WVertex *v;
if (true == iEdge.order) if (true == iEdge.order)
@@ -550,14 +563,11 @@ OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge){
v = iEdge.e->GetaVertex(); v = iEdge.e->GetaVertex();
if (((WXVertex*)v)->isFeature()) if (((WXVertex*)v)->isFeature())
return 0; return 0; /* XXX eeek? NULL? OWXEdge(NULL, true/false)?*/
int faceMarks = retrieveFaceMarks(iEdge.e); int faceMarks = retrieveFaceMarks(iEdge.e);
vector<WEdge*>& vEdges = (v)->GetEdges(); vector<WEdge*>& vEdges = (v)->GetEdges();
for(vector<WEdge*>::iterator ve=vEdges.begin(),veend=vEdges.end(); for (vector<WEdge*>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
ve!=veend;
ve++){
WXEdge *wxe = dynamic_cast<WXEdge*>(*ve); WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
if (wxe == iEdge.e) if (wxe == iEdge.e)
continue; // same edge as the one processed continue; // same edge as the one processed
@@ -573,19 +583,21 @@ OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge){
// That means that the face necesarily lies on the edge left. // That means that the face necesarily lies on the edge left.
// So the vertex order is OK. // So the vertex order is OK.
return OWXEdge(wxe, true); return OWXEdge(wxe, true);
}else{ }
else {
// That means that the face necesarily lies on the edge left. // That means that the face necesarily lies on the edge left.
// So the vertex order is OK. // So the vertex order is OK.
return OWXEdge(wxe, false); return OWXEdge(wxe, false);
} }
} }
// we did not find: // we did not find:
return OWXEdge(0, true); return OWXEdge(NULL, true);
} }
OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge){ OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge)
{
if (Nature::NO_FEATURE == iEdge.e->nature()) if (Nature::NO_FEATURE == iEdge.e->nature())
return OWXEdge(0, true); return OWXEdge(NULL, true);
WVertex *v; WVertex *v;
if (true == iEdge.order) if (true == iEdge.order)
@@ -596,12 +608,9 @@ OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge){
if (((WXVertex*)v)->isFeature()) if (((WXVertex*)v)->isFeature())
return 0; return 0;
int faceMarks = retrieveFaceMarks(iEdge.e); int faceMarks = retrieveFaceMarks(iEdge.e);
vector<WEdge*>& vEdges = (v)->GetEdges(); vector<WEdge*>& vEdges = (v)->GetEdges();
for(vector<WEdge*>::iterator ve=vEdges.begin(),veend=vEdges.end(); for (vector<WEdge*>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
ve!=veend;
ve++){
WXEdge *wxe = dynamic_cast<WXEdge*>(*ve); WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
if (wxe == iEdge.e) if (wxe == iEdge.e)
continue; // same edge as the one processed continue; // same edge as the one processed
@@ -615,22 +624,25 @@ OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge){
if (wxe->GetbVertex() == v) { if (wxe->GetbVertex() == v) {
return OWXEdge(wxe, true); return OWXEdge(wxe, true);
}else{ }
else {
return OWXEdge(wxe, false); return OWXEdge(wxe, false);
} }
} }
// we did not find: // we did not find:
return OWXEdge(0, true); return OWXEdge(NULL, true);
} }
FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe){ FEdge *ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
{
SVertex *va, *vb; SVertex *va, *vb;
FEdgeSharp *fe; FEdgeSharp *fe;
WXVertex *wxVA, *wxVB; WXVertex *wxVA, *wxVB;
if (iwe.order) { if (iwe.order) {
wxVA = (WXVertex *)iwe.e->GetaVertex(); wxVA = (WXVertex *)iwe.e->GetaVertex();
wxVB = (WXVertex *)iwe.e->GetbVertex(); wxVB = (WXVertex *)iwe.e->GetbVertex();
}else{ }
else {
wxVA = (WXVertex *)iwe.e->GetbVertex(); wxVA = (WXVertex *)iwe.e->GetbVertex();
wxVB = (WXVertex *)iwe.e->GetaVertex(); wxVB = (WXVertex *)iwe.e->GetaVertex();
} }
@@ -651,7 +663,8 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
matA = (iwe.e->GetaFace()->frs_materialIndex()); matA = (iwe.e->GetaFace()->frs_materialIndex());
faceMarkA = (iwe.e->GetaFace()->GetMark()); faceMarkA = (iwe.e->GetaFace()->GetMark());
} }
}else{ }
else {
normalA = (iwe.e->GetbFace()->GetNormal()); normalA = (iwe.e->GetbFace()->GetNormal());
matA = (iwe.e->GetbFace()->frs_materialIndex()); matA = (iwe.e->GetbFace()->frs_materialIndex());
faceMarkA = (iwe.e->GetbFace()->GetMark()); faceMarkA = (iwe.e->GetbFace()->GetMark());
@@ -662,7 +675,6 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
} }
} }
// Creates the corresponding feature edge // Creates the corresponding feature edge
// Creates the corresponding feature edge
fe = new FEdgeSharp(va, vb); fe = new FEdgeSharp(va, vb);
fe->setNature(iwe.e->nature()); fe->setNature(iwe.e->nature());
fe->setId(_currentFId); fe->setId(_currentFId);
@@ -689,7 +701,8 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
return fe; return fe;
} }
bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge){ bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge)
{
if (0 == iEdge) if (0 == iEdge)
return true; return true;
if (iEdge->userdata == 0) if (iEdge->userdata == 0)
@@ -697,7 +710,8 @@ bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge){
return true; return true;
} }
SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint){ SVertex *ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint)
{
SVertex *va = new SVertex(iPoint, _currentSVertexId); SVertex *va = new SVertex(iPoint, _currentSVertexId);
SilhouetteGeomEngine::ProjectSilhouette(va); SilhouetteGeomEngine::ProjectSilhouette(va);
++_currentSVertexId; ++_currentSVertexId;
@@ -706,16 +720,19 @@ SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint){
return va; return va;
} }
SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint, bool shared){ SVertex *ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint, bool shared)
{
SVertex *va; SVertex *va;
if (!shared) { if (!shared) {
va = MakeSVertex(iPoint); va = MakeSVertex(iPoint);
} else { }
else {
// Check whether the iPoint is already in the table // Check whether the iPoint is already in the table
SVertexMap::const_iterator found = _SVertexMap.find(iPoint); SVertexMap::const_iterator found = _SVertexMap.find(iPoint);
if (shared && found != _SVertexMap.end()) { if (shared && found != _SVertexMap.end()) {
va = (*found).second; va = (*found).second;
}else{ }
else {
va = MakeSVertex(iPoint); va = MakeSVertex(iPoint);
// Add the svertex into the table using iPoint as the key // Add the svertex into the table using iPoint as the key
_SVertexMap[iPoint] = va; _SVertexMap[iPoint] = va;
@@ -724,13 +741,13 @@ SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint, bool shared){
return va; return va;
} }
ViewVertex * ViewEdgeXBuilder::MakeViewVertex(SVertex *iSVertex){ ViewVertex *ViewEdgeXBuilder::MakeViewVertex(SVertex *iSVertex)
{
ViewVertex *vva = iSVertex->viewvertex(); ViewVertex *vva = iSVertex->viewvertex();
if(vva != 0) if (vva)
return vva; return vva;
vva = new NonTVertex(iSVertex); vva = new NonTVertex(iSVertex);
// Add the view vertex to the ViewShape svertex list: // Add the view vertex to the ViewShape svertex list:
_pCurrentVShape->AddVertex(vva); _pCurrentVShape->AddVertex(vva);
return vva; return vva;
} }

View File

@@ -1,72 +1,86 @@
// /*
// Filename : ViewEdgeXBuilder.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Class to build view edges and the underlying chains * This program is free software; you can redistribute it and/or
// of feature edges... * modify it under the terms of the GNU General Public License
// Date of creation : 27/10/2003 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to build view edges and the underlying chains of feature edges...
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 27/10/2003
// 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 <map>
#include <utility> #include <utility>
#include <vector> #include <vector>
// soc #if 0 // soc
// # if defined(__GNUC__) && (__GNUC__ >= 3) #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 //hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
// # include <hash_map.h> # include <hash_map.h>
// # else #else
// # include <hash_map> # include <hash_map>
// # endif #endif
#endif
#include "Interface1D.h"
#include "../geometry/Geom.h"
#include "../system/FreestyleConfig.h" #include "../system/FreestyleConfig.h"
# include "../geometry/Geom.h"
# include "Interface1D.h"
using namespace Geometry; using namespace Geometry;
using namespace std; using namespace std;
class SVertex; class SVertex;
/*! Defines a hash table used for searching the SVertex */ /*! Defines a hash table used for searching the SVertex */
struct SVertexHasher { struct SVertexHasher
{
#define _MUL 950706376UL #define _MUL 950706376UL
#define _MOD 2147483647UL #define _MOD 2147483647UL
inline size_t operator() (const Vec3r& p) const { inline size_t operator()(const Vec3r& p) const
{
size_t res = ((unsigned long)(p[0] * _MUL)) % _MOD; size_t res = ((unsigned long)(p[0] * _MUL)) % _MOD;
res = ((res + (unsigned long)(p[1]) * _MUL)) % _MOD; res = ((res + (unsigned long)(p[1]) * _MUL)) % _MOD;
return ((res +(unsigned long)(p[2]) * _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. // Key_compare predicate for hash_map. In particular, return false if equal.
struct epsilonEquals{ struct epsilonEquals
bool operator()(const Vec3r& v1, const Vec3r& v2) const{ {
bool operator()(const Vec3r& v1, const Vec3r& v2) const
{
real norm = (v1 - v2).norm(); real norm = (v1 - v2).norm();
return (norm<1e-06); return (norm < 1.0e-06);
} }
}; };
@@ -75,45 +89,79 @@ struct epsilonEquals{
typedef map<Vec3r , SVertex*> SVertexMap; typedef map<Vec3r , SVertex*> SVertexMap;
class WXFaceLayer; class WXFaceLayer;
/*! class to describe an oriented smooth edge */ /*! class to describe an oriented smooth edge */
class OWXFaceLayer{ class OWXFaceLayer
{
public: public:
WXFaceLayer *fl; WXFaceLayer *fl;
bool order; bool order;
OWXFaceLayer() {fl=0;order=true;} OWXFaceLayer()
OWXFaceLayer(WXFaceLayer *ifl, bool iOrder=true){fl = ifl;order=iOrder;} {
OWXFaceLayer& operator=(const OWXFaceLayer& iBrother){ fl = NULL;
order = true;
}
OWXFaceLayer(WXFaceLayer *ifl, bool iOrder = true)
{
fl = ifl;
order = iOrder;
}
OWXFaceLayer& operator=(const OWXFaceLayer& iBrother)
{
fl = iBrother.fl; fl = iBrother.fl;
order = iBrother.order; order = iBrother.order;
return *this; return *this;
} }
bool operator==(const OWXFaceLayer& b){
bool operator==(const OWXFaceLayer& b)
{
return ((fl == b.fl) && (order == b.order)); return ((fl == b.fl) && (order == b.order));
} }
bool operator!=(const OWXFaceLayer& b){
bool operator!=(const OWXFaceLayer& b)
{
return !(*this == b); return !(*this == b);
} }
}; };
class WXEdge; class WXEdge;
/*! class to describe an oriented sharp edge */ /*! class to describe an oriented sharp edge */
class OWXEdge{ class OWXEdge
{
public: public:
WXEdge *e; WXEdge *e;
bool order; bool order;
OWXEdge() {e=0;order=true;} OWXEdge()
OWXEdge(WXEdge *ie, bool iOrder=true){e = ie;order=iOrder;} {
OWXEdge& operator=(const OWXEdge& iBrother){ e = NULL;
order = true;
}
OWXEdge(WXEdge *ie, bool iOrder = true)
{
e = ie;
order = iOrder;
}
OWXEdge& operator=(const OWXEdge& iBrother)
{
e = iBrother.e; e = iBrother.e;
order = iBrother.order; order = iBrother.order;
return *this; return *this;
} }
bool operator==(const OWXEdge& b){
bool operator==(const OWXEdge& b)
{
return ((e == b.e) && (order == b.order)); return ((e == b.e) && (order == b.order));
} }
bool operator!=(const OWXEdge& b){
bool operator!=(const OWXEdge& b)
{
return !(*this == b); return !(*this == b);
} }
}; };
@@ -126,24 +174,28 @@ class FEdge;
class ViewVertex; class ViewVertex;
class ViewEdge; class ViewEdge;
class ViewShape; class ViewShape;
class LIB_VIEW_MAP_EXPORT ViewEdgeXBuilder class LIB_VIEW_MAP_EXPORT ViewEdgeXBuilder
{ {
protected: protected:
int _currentViewId; // Id for view edges int _currentViewId; // Id for view edges
int _currentFId; // Id for FEdges int _currentFId; // Id for FEdges
int _currentSVertexId; // Id for SVertex int _currentSVertexId; // Id for SVertex
public:
public:
inline ViewEdgeXBuilder() inline ViewEdgeXBuilder()
{_currentViewId = 1;_currentFId=0;_currentSVertexId=0;} {
_currentViewId = 1;
_currentFId = 0;
_currentSVertexId = 0;
}
virtual ~ViewEdgeXBuilder() {} virtual ~ViewEdgeXBuilder() {}
/*! Builds a view shape from a WXShape in which the feature edges /*! Builds a view shape from a WXShape in which the feature edges are flagged
* are flagged
* Builds chains of feature edges (so ViewEdges) from a WXShape * Builds chains of feature edges (so ViewEdges) from a WXShape
* iWShape * iWShape
* The Winged Edge structure in which all silhouette edges * The Winged Edge structure in which all silhouette edges and vertices are flagged.
* and vertices are flagged.
* oViewShape * oViewShape
* The Silhouette Shape in which the chains must be added. * The Silhouette Shape in which the chains must be added.
* ioVEdges * ioVEdges
@@ -155,29 +207,48 @@ public:
* ioSVertices * ioSVertices
* A list of SVertex where all created SVertex are added. * A list of SVertex where all created SVertex are added.
*/ */
virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, std::vector<ViewEdge*>& ioVEdges,
std::vector<ViewEdge*>& ioVEdges, std::vector<ViewVertex*>& ioVVertices, std::vector<FEdge*>& ioFEdges,
std::vector<ViewVertex*>& ioVVertices,
std::vector<FEdge*>& ioFEdges,
std::vector<SVertex*>& ioSVertices); std::vector<SVertex*>& ioSVertices);
/*! Builds a smooth view edge, starting the face iFace. */ /*! Builds a smooth view edge, starting the face iFace. */
ViewEdge *BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer); ViewEdge *BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer);
/*! Makes a sharp viewedge /*! Makes a sharp viewedge */
*/
ViewEdge *BuildSharpViewEdge(const OWXEdge& iWEdge); ViewEdge *BuildSharpViewEdge(const OWXEdge& iWEdge);
public: public:
/*! accessors */ /*! accessors */
inline int currentViewId() const { return _currentViewId; } inline int currentViewId() const
inline int currentFId() const { return _currentFId; } {
inline int currentSVertexId() const { return _currentSVertexId; } return _currentViewId;
}
inline int currentFId() const
{
return _currentFId;
}
inline int currentSVertexId() const
{
return _currentSVertexId;
}
/*! modifiers */ /*! modifiers */
inline void setCurrentViewId(int id) { _currentViewId = id; } inline void setCurrentViewId(int id)
inline void setCurrentFId(int id) { _currentFId = id; } {
inline void setCurrentSVertexId(int id) { _currentSVertexId = id; } _currentViewId = id;
}
inline void setCurrentFId(int id)
{
_currentFId = id;
}
inline void setCurrentSVertexId(int id)
{
_currentSVertexId = id;
}
protected: protected:
/*! Init the view edges building */ /*! Init the view edges building */
@@ -214,5 +285,4 @@ protected:
ViewShape *_pCurrentVShape; ViewShape *_pCurrentVShape;
}; };
#endif #endif // __FREESTYLE_VIEW_EDGE_X_BUILDER_H__

View File

@@ -1,29 +1,44 @@
/*
* ***** 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Classes to define a View Map (ViewVertex, ViewEdge, etc.)
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 03/09/2002
// 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. #include <float.h>
//
// 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 "ViewMap.h" #include "ViewMap.h"
#include "../geometry/GeomUtils.h"
#include <float.h>
#include "ViewMapIterators.h"
#include "ViewMapAdvancedIterators.h" #include "ViewMapAdvancedIterators.h"
#include "ViewMapIterators.h"
#include "../geometry/GeomUtils.h"
/**********************************/ /**********************************/
/* */ /* */
@@ -33,24 +48,17 @@
/* */ /* */
/**********************************/ /**********************************/
ViewMap * ViewMap::_pInstance = 0; ViewMap *ViewMap::_pInstance = NULL;
ViewMap::~ViewMap() ViewMap::~ViewMap()
{ {
// The view vertices must be deleted here as some of them // The view vertices must be deleted here as some of them are shared between two shapes:
// are shared between two shapes: for (vector<ViewVertex*>::iterator vv = _VVertices.begin(), vvend = _VVertices.end(); vv != vvend; vv++) {
for(vector<ViewVertex*>::iterator vv=_VVertices.begin(), vvend=_VVertices.end();
vv!=vvend;
vv++)
{
delete (*vv); delete (*vv);
} }
_VVertices.clear(); _VVertices.clear();
for(vector<ViewShape*>::iterator vs=_VShapes.begin(),vsend=_VShapes.end(); for (vector<ViewShape*>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend; vs++) {
vs!=vsend;
vs++)
{
delete (*vs); delete (*vs);
} }
_VShapes.clear(); _VShapes.clear();
@@ -65,31 +73,27 @@ ViewShape * ViewMap::viewShape(unsigned id)
int index = _shapeIdToIndex[id]; int index = _shapeIdToIndex[id];
return _VShapes[ index ]; return _VShapes[ index ];
} }
void ViewMap::AddViewShape(ViewShape *iVShape) {
void ViewMap::AddViewShape(ViewShape *iVShape)
{
_shapeIdToIndex[iVShape->getId().getFirst()] = _VShapes.size(); _shapeIdToIndex[iVShape->getId().getFirst()] = _VShapes.size();
_VShapes.push_back(iVShape); _VShapes.push_back(iVShape);
} }
const FEdge *ViewMap::getClosestFEdge(real x, real y) const const FEdge *ViewMap::getClosestFEdge(real x, real y) const
{ {
// find the closest of this candidates: // find the closest of this candidates:
real minDist = DBL_MAX; real minDist = DBL_MAX;
FEdge * winner = 0; FEdge *winner = NULL;
for(fedges_container::const_iterator fe=_FEdges.begin(),feend=_FEdges.end(); for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; fe++) {
fe!=feend;
fe++)
{
Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]); Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]); Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B); real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
if(dist < minDist) if (dist < minDist) {
{
minDist = dist; minDist = dist;
winner = (*fe); winner = (*fe);
} }
} }
if(winner==0)
return 0;
return winner; return winner;
} }
@@ -98,31 +102,25 @@ const ViewEdge * ViewMap::getClosestViewEdge(real x, real y) const
{ {
// find the closest of this candidates: // find the closest of this candidates:
real minDist = DBL_MAX; real minDist = DBL_MAX;
FEdge * winner = 0; FEdge *winner = NULL;
for(fedges_container::const_iterator fe=_FEdges.begin(),feend=_FEdges.end(); for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; fe++) {
fe!=feend;
fe++)
{
Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]); Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]); Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B); real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
if(dist < minDist) if (dist < minDist) {
{
minDist = dist; minDist = dist;
winner = (*fe); winner = (*fe);
} }
} }
if(winner==0) if (!winner)
return 0; return NULL;
return winner->viewedge(); return winner->viewedge();
} }
TVertex *ViewMap::CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFEdgeA, TVertex *ViewMap::CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFEdgeA,
const Vec3r& iB3D, const Vec3r& iB2D, FEdge *iFEdgeB, const Vec3r& iB3D, const Vec3r& iB2D, FEdge *iFEdgeB, const Id& id)
const Id& id)
{ {
ViewShape *vshapeA = iFEdgeA->viewedge()->viewShape(); ViewShape *vshapeA = iFEdgeA->viewedge()->viewShape();
SShape *shapeA = iFEdgeA->shape(); SShape *shapeA = iFEdgeA->shape();
@@ -132,9 +130,8 @@ TVertex* ViewMap::CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFE
SVertex *Ia = shapeA->CreateSVertex(iA3D, iA2D, iFEdgeA->vertexA()->getId()); SVertex *Ia = shapeA->CreateSVertex(iA3D, iA2D, iFEdgeA->vertexA()->getId());
SVertex *Ib = shapeB->CreateSVertex(iB3D, iB2D, iFEdgeB->vertexA()->getId()); SVertex *Ib = shapeB->CreateSVertex(iB3D, iB2D, iFEdgeB->vertexA()->getId());
// depending on which of these 2 svertices is the nearest from the // depending on which of these 2 svertices is the nearest from the viewpoint, we're going to build the TVertex
// viewpoint, we're going to build the TVertex by giving them in // by giving them in an order or another (the first one must be the nearest)
// an order or another (the first one must be the nearest)
real dista = Ia->point2D()[2]; real dista = Ia->point2D()[2];
real distb = Ib->point2D()[2]; real distb = Ib->point2D()[2];
@@ -158,23 +155,20 @@ TVertex* ViewMap::CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFE
return tvertex; return tvertex;
} }
ViewVertex * ViewMap::InsertViewVertex(SVertex *iVertex, ViewVertex *ViewMap::InsertViewVertex(SVertex *iVertex, vector<ViewEdge*>& newViewEdges)
vector<ViewEdge*>& newViewEdges){ {
NonTVertex *vva = dynamic_cast<NonTVertex*>(iVertex->viewvertex()); NonTVertex *vva = dynamic_cast<NonTVertex*>(iVertex->viewvertex());
if(vva != 0) if (vva)
return vva; return vva;
// beacuse it is not already a ViewVertex, this SVertex must have only // because it is not already a ViewVertex, this SVertex must have only 2 FEdges. The incoming one still belongs
// 2 FEdges. The incoming one still belongs to ioEdge, the outgoing one // to ioEdge, the outgoing one now belongs to newVEdge
// now belongs to newVEdge
const vector<FEdge*>& fedges = iVertex->fedges(); const vector<FEdge*>& fedges = iVertex->fedges();
if (fedges.size() != 2) { if (fedges.size() != 2) {
cerr << "ViewMap warning: Can't split the ViewEdge" << endl; cerr << "ViewMap warning: Can't split the ViewEdge" << endl;
return 0; return NULL;
} }
FEdge *fend(0), *fbegin(0); FEdge *fend(0), *fbegin(0);
for(vector<FEdge*>::const_iterator fe=fedges.begin(), feend=fedges.end(); for (vector<FEdge*>::const_iterator fe = fedges.begin(), feend = fedges.end(); fe != feend; ++fe) {
fe!=feend;
++fe){
if ((*fe)->vertexB() == iVertex) { if ((*fe)->vertexB() == iVertex) {
fend = (*fe); fend = (*fe);
} }
@@ -187,8 +181,7 @@ ViewVertex * ViewMap::InsertViewVertex(SVertex *iVertex,
ViewEdge *ioEdge = fbegin->viewedge(); ViewEdge *ioEdge = fbegin->viewedge();
ViewShape * vshape = ioEdge->viewShape(); ViewShape * vshape = ioEdge->viewShape();
vva = new NonTVertex(iVertex); vva = new NonTVertex(iVertex);
// if the ViewEdge is a closed loop, we don't create // if the ViewEdge is a closed loop, we don't create a new VEdge
// a new VEdge
if (ioEdge->A() == 0) { if (ioEdge->A() == 0) {
// closed loop // closed loop
ioEdge->setA(vva); ioEdge->setA(vva);
@@ -201,8 +194,8 @@ ViewVertex * ViewMap::InsertViewVertex(SVertex *iVertex,
ioEdge->setFEdgeB(fend); ioEdge->setFEdgeB(fend);
// Update FEdges // Update FEdges
fend->setNextEdge(0); fend->setNextEdge(NULL);
fbegin->setPreviousEdge(0); fbegin->setPreviousEdge(NULL);
// update new View Vertex: // update new View Vertex:
vva->AddOutgoingViewEdge(ioEdge); vva->AddOutgoingViewEdge(ioEdge);
@@ -210,7 +203,8 @@ ViewVertex * ViewMap::InsertViewVertex(SVertex *iVertex,
vshape->sshape()->AddChain(ioEdge->fedgeA()); vshape->sshape()->AddChain(ioEdge->fedgeA());
vshape->sshape()->AddChain(ioEdge->fedgeB()); vshape->sshape()->AddChain(ioEdge->fedgeB());
}else{ }
else {
// Create new ViewEdge // Create new ViewEdge
ViewEdge *newVEdge = new ViewEdge(vva, ioEdge->B(), fbegin, ioEdge->fedgeB(), vshape); ViewEdge *newVEdge = new ViewEdge(vva, ioEdge->B(), fbegin, ioEdge->fedgeB(), vshape);
newVEdge->setId(Id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1)); newVEdge->setId(Id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1));
@@ -221,8 +215,8 @@ ViewVertex * ViewMap::InsertViewVertex(SVertex *iVertex,
ioEdge->setFEdgeB(fend); ioEdge->setFEdgeB(fend);
// Update FEdges // Update FEdges
fend->setNextEdge(0); fend->setNextEdge(NULL);
fbegin->setPreviousEdge(0); fbegin->setPreviousEdge(NULL);
// update new View Vertex: // update new View Vertex:
vva->AddOutgoingViewEdge(newVEdge); vva->AddOutgoingViewEdge(newVEdge);
@@ -245,13 +239,16 @@ ViewVertex * ViewMap::InsertViewVertex(SVertex *iVertex,
return vva; return vva;
} }
//FEdge * ViewMap::Connect(FEdge *ioEdge, SVertex *ioVertex, vector<ViewEdge*>& oNewVEdges){ #if 0
// SShape * sshape = ioEdge->shape(); FEdge *ViewMap::Connect(FEdge *ioEdge, SVertex *ioVertex, vector<ViewEdge*>& oNewVEdges)
// FEdge *newFEdge = sshape->SplitEdgeIn2(ioEdge, ioVertex); {
// AddFEdge(newFEdge); SShape *sshape = ioEdge->shape();
// InsertViewVertex(ioVertex, oNewVEdges); FEdge *newFEdge = sshape->SplitEdgeIn2(ioEdge, ioVertex);
// return newFEdge; AddFEdge(newFEdge);
//} InsertViewVertex(ioVertex, oNewVEdges);
return newFEdge;
}
#endif
/**********************************/ /**********************************/
/* */ /* */
@@ -262,7 +259,8 @@ ViewVertex * ViewMap::InsertViewVertex(SVertex *iVertex,
/**********************************/ /**********************************/
// is dve1 before dve2 ? (does it have a smaller angle ?) // is dve1 before dve2 ? (does it have a smaller angle ?)
static bool ViewEdgeComp(ViewVertex::directedViewEdge& dve1, ViewVertex::directedViewEdge& dve2){ static bool ViewEdgeComp(ViewVertex::directedViewEdge& dve1, ViewVertex::directedViewEdge& dve2)
{
FEdge *fe1; FEdge *fe1;
if (dve1.second) if (dve1.second)
fe1 = dve1.first->fedgeB(); fe1 = dve1.first->fedgeB();
@@ -275,15 +273,18 @@ static bool ViewEdgeComp(ViewVertex::directedViewEdge& dve1, ViewVertex::directe
fe2 = dve2.first->fedgeA(); fe2 = dve2.first->fedgeA();
Vec3r V1 = fe1->orientation2d(); Vec3r V1 = fe1->orientation2d();
Vec2r v1(V1.x(), V1.y());v1.normalize(); Vec2r v1(V1.x(), V1.y());
v1.normalize();
Vec3r V2 = fe2->orientation2d(); Vec3r V2 = fe2->orientation2d();
Vec2r v2(V2.x(), V2.y());v2.normalize(); Vec2r v2(V2.x(), V2.y());
v2.normalize();
if (v1.y() > 0) { if (v1.y() > 0) {
if (v2.y() < 0) if (v2.y() < 0)
return true; return true;
else else
return (v1.x() > v2.x()); return (v1.x() > v2.x());
}else{ }
else {
if (v2.y() > 0) if (v2.y() > 0)
return false; return false;
else else
@@ -291,7 +292,9 @@ static bool ViewEdgeComp(ViewVertex::directedViewEdge& dve1, ViewVertex::directe
} }
return false; return false;
} }
void TVertex::setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming) {
void TVertex::setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming)
{
if (!iFrontEdgeA) { if (!iFrontEdgeA) {
cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeA()" << endl; cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeA()" << endl;
return; return;
@@ -299,15 +302,16 @@ void TVertex::setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming) {
_FrontEdgeA = directedViewEdge(iFrontEdgeA, incoming); _FrontEdgeA = directedViewEdge(iFrontEdgeA, incoming);
if (!_sortedEdges.empty()) { if (!_sortedEdges.empty()) {
edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end(); edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
while((dve!=dveend) && ViewEdgeComp(**dve, _FrontEdgeA)){ for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeA); ++dve);
++dve;
}
_sortedEdges.insert( dve, &_FrontEdgeA); _sortedEdges.insert( dve, &_FrontEdgeA);
} }
else else {
_sortedEdges.push_back(&_FrontEdgeA); _sortedEdges.push_back(&_FrontEdgeA);
} }
void TVertex::setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming) { }
void TVertex::setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming)
{
if (!iFrontEdgeB) { if (!iFrontEdgeB) {
cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeB()" << endl; cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeB()" << endl;
return; return;
@@ -315,15 +319,16 @@ void TVertex::setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming) {
_FrontEdgeB = directedViewEdge(iFrontEdgeB, incoming); _FrontEdgeB = directedViewEdge(iFrontEdgeB, incoming);
if (!_sortedEdges.empty()) { if (!_sortedEdges.empty()) {
edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end(); edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
while((dve!=dveend) && ViewEdgeComp(**dve, _FrontEdgeB)){ for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeB); ++dve);
++dve;
}
_sortedEdges.insert(dve, &_FrontEdgeB); _sortedEdges.insert(dve, &_FrontEdgeB);
} }
else else {
_sortedEdges.push_back(&_FrontEdgeB); _sortedEdges.push_back(&_FrontEdgeB);
} }
void TVertex::setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming) { }
void TVertex::setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming)
{
if (!iBackEdgeA) { if (!iBackEdgeA) {
cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeA()" << endl; cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeA()" << endl;
return; return;
@@ -331,15 +336,16 @@ void TVertex::setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming) {
_BackEdgeA = directedViewEdge(iBackEdgeA, incoming); _BackEdgeA = directedViewEdge(iBackEdgeA, incoming);
if (!_sortedEdges.empty()) { if (!_sortedEdges.empty()) {
edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end(); edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
while((dve!=dveend) && ViewEdgeComp(**dve, _BackEdgeA)){ for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeA); ++dve);
++dve;
}
_sortedEdges.insert(dve, &_BackEdgeA); _sortedEdges.insert(dve, &_BackEdgeA);
} }
else else {
_sortedEdges.push_back(&_BackEdgeA); _sortedEdges.push_back(&_BackEdgeA);
} }
void TVertex::setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming) { }
void TVertex::setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming)
{
if (!iBackEdgeB) { if (!iBackEdgeB) {
cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeB()" << endl; cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeB()" << endl;
return; return;
@@ -347,35 +353,31 @@ void TVertex::setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming) {
_BackEdgeB = directedViewEdge(iBackEdgeB, incoming); _BackEdgeB = directedViewEdge(iBackEdgeB, incoming);
if (!_sortedEdges.empty()) { if (!_sortedEdges.empty()) {
edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end(); edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
while((dve!=dveend) && ViewEdgeComp(**dve, _BackEdgeB)){ for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeB); ++dve);
++dve;
}
_sortedEdges.insert(dve, &_BackEdgeB); _sortedEdges.insert(dve, &_BackEdgeB);
} }
else else {
_sortedEdges.push_back(&_BackEdgeB); _sortedEdges.push_back(&_BackEdgeB);
} }
}
void TVertex::Replace(ViewEdge *iOld, ViewEdge *iNew) void TVertex::Replace(ViewEdge *iOld, ViewEdge *iNew)
{ {
// theoritically, we only replace edges for which this // theoritically, we only replace edges for which this
// view vertex is the B vertex // view vertex is the B vertex
if((iOld == _FrontEdgeA.first) && (_FrontEdgeA.first->B() == this)) if ((iOld == _FrontEdgeA.first) && (_FrontEdgeA.first->B() == this)) {
{
_FrontEdgeA.first = iNew; _FrontEdgeA.first = iNew;
return; return;
} }
if((iOld == _FrontEdgeB.first) && (_FrontEdgeB.first->B() == this)) if ((iOld == _FrontEdgeB.first) && (_FrontEdgeB.first->B() == this)) {
{
_FrontEdgeB.first = iNew; _FrontEdgeB.first = iNew;
return; return;
} }
if((iOld == _BackEdgeA.first) && (_BackEdgeA.first->B() == this)) if ((iOld == _BackEdgeA.first) && (_BackEdgeA.first->B() == this)) {
{
_BackEdgeA.first = iNew; _BackEdgeA.first = iNew;
return; return;
} }
if((iOld == _BackEdgeB.first) && (_BackEdgeB.first->B() == this)) if ((iOld == _BackEdgeB.first) && (_BackEdgeB.first->B() == this)) {
{
_BackEdgeB.first = iNew; _BackEdgeB.first = iNew;
return; return;
} }
@@ -387,43 +389,47 @@ ViewVertex::edge_iterator TVertex::edges_begin()
//return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA); //return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
} }
ViewVertex::const_edge_iterator TVertex::edges_begin() const ViewVertex::const_edge_iterator TVertex::edges_begin() const
{ {
//return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA); //return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
} }
ViewVertex::edge_iterator TVertex::edges_end() ViewVertex::edge_iterator TVertex::edges_end()
{ {
//return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, directedViewEdge(0,true)); //return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, directedViewEdge(0,true));
return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end()); return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
} }
ViewVertex::const_edge_iterator TVertex::edges_end() const ViewVertex::const_edge_iterator TVertex::edges_end() const
{ {
//return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, directedViewEdge(0, true)); //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(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
} }
ViewVertex::edge_iterator TVertex::edges_iterator(ViewEdge *iEdge) ViewVertex::edge_iterator TVertex::edges_iterator(ViewEdge *iEdge)
{ {
for(edge_pointers_container::iterator it=_sortedEdges.begin(), itend=_sortedEdges.end(); for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end(); it != itend; it++) {
it!=itend;
it++)
{
if ((*it)->first == iEdge) if ((*it)->first == iEdge)
return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it); return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it);
} }
return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
// directedViewEdge dEdge; #if 0
// if(_FrontEdgeA.first == iEdge) directedViewEdge dEdge;
// dEdge = _FrontEdgeA; if (_FrontEdgeA.first == iEdge)
// else if(_FrontEdgeB.first == iEdge) dEdge = _FrontEdgeA;
// dEdge = _FrontEdgeB; else if (_FrontEdgeB.first == iEdge)
// else if(_BackEdgeA.first == iEdge) dEdge = _FrontEdgeB;
// dEdge = _BackEdgeA; else if (_BackEdgeA.first == iEdge)
// else if(_BackEdgeB.first == iEdge) dEdge = _BackEdgeA;
// dEdge = _BackEdgeB; else if (_BackEdgeB.first == iEdge)
// return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge); dEdge = _BackEdgeB;
return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
#endif
} }
ViewVertex::const_edge_iterator TVertex::edges_iterator(ViewEdge *iEdge) const ViewVertex::const_edge_iterator TVertex::edges_iterator(ViewEdge *iEdge) const
{ {
for (edge_pointers_container::const_iterator it = _sortedEdges.begin(), itend = _sortedEdges.end(); for (edge_pointers_container::const_iterator it = _sortedEdges.begin(), itend = _sortedEdges.end();
@@ -435,34 +441,39 @@ ViewVertex::const_edge_iterator TVertex::edges_iterator(ViewEdge *iEdge) const
} }
return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
// directedViewEdge dEdge; #if 0
// if(_FrontEdgeA.first == iEdge) directedViewEdge dEdge;
// dEdge = _FrontEdgeA; if (_FrontEdgeA.first == iEdge)
// else if(_FrontEdgeB.first == iEdge) dEdge = _FrontEdgeA;
// dEdge = _FrontEdgeB; else if (_FrontEdgeB.first == iEdge)
// else if(_BackEdgeA.first == iEdge) dEdge = _FrontEdgeB;
// dEdge = _BackEdgeA; else if (_BackEdgeA.first == iEdge)
// else if(_BackEdgeB.first == iEdge) dEdge = _BackEdgeA;
// dEdge = _BackEdgeB; else if (_BackEdgeB.first == iEdge)
// return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge); dEdge = _BackEdgeB;
return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
#endif
} }
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesBegin() { ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesBegin()
{
return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
} }
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesEnd() {
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesEnd()
{
return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end()); return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
} }
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesIterator(ViewEdge *iEdge) {
for(edge_pointers_container::iterator it=_sortedEdges.begin(), itend=_sortedEdges.end(); ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesIterator(ViewEdge *iEdge)
it!=itend;
it++)
{ {
for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end(); it != itend; it++) {
if ((*it)->first == iEdge) if ((*it)->first == iEdge)
return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), it); return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), it);
} }
return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
} }
/**********************************/ /**********************************/
/* */ /* */
/* */ /* */
@@ -472,91 +483,90 @@ ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesIterator(ViewEdge *iE
/**********************************/ /**********************************/
void NonTVertex::AddOutgoingViewEdge(ViewEdge *iVEdge){ void NonTVertex::AddOutgoingViewEdge(ViewEdge *iVEdge){
// let's keep the viewedges ordered in CCW order // let's keep the viewedges ordered in CCW order in the 2D image plan
// in the 2D image plan
directedViewEdge idve(iVEdge, false); directedViewEdge idve(iVEdge, false);
if (!_ViewEdges.empty()) { if (!_ViewEdges.empty()) {
edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end(); edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
while((dve!=dveend) && ViewEdgeComp(*dve, idve)){ for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve);
++dve;
}
_ViewEdges.insert(dve, idve); _ViewEdges.insert(dve, idve);
} }
else else {
_ViewEdges.push_back(idve); _ViewEdges.push_back(idve);
} }
}
void NonTVertex::AddIncomingViewEdge(ViewEdge * iVEdge){ void NonTVertex::AddIncomingViewEdge(ViewEdge *iVEdge)
// let's keep the viewedges ordered in CCW order {
// in the 2D image plan // let's keep the viewedges ordered in CCW order in the 2D image plan
directedViewEdge idve(iVEdge, true); directedViewEdge idve(iVEdge, true);
if (!_ViewEdges.empty()) { if (!_ViewEdges.empty()) {
edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end(); edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
while((dve!=dveend) && ViewEdgeComp(*dve, idve)){ for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve);
++dve;
}
_ViewEdges.insert(dve, idve); _ViewEdges.insert(dve, idve);
} }
else else {
_ViewEdges.push_back(idve); _ViewEdges.push_back(idve);
} }
}
/*! iterators access */ /*! iterators access */
ViewVertex::edge_iterator NonTVertex::edges_begin() 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 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() 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 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) ViewVertex::edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge)
{ {
for(edges_container::iterator it=_ViewEdges.begin(), itend=_ViewEdges.end(); for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend; it++) {
it!=itend;
it++)
{
if ((it)->first == iEdge) if ((it)->first == iEdge)
return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it); return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
} }
return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
} }
ViewVertex::const_edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge) const ViewVertex::const_edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge) const
{ {
for(edges_container::const_iterator it=_ViewEdges.begin(), itend=_ViewEdges.end(); for (edges_container::const_iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend; it++) {
it!=itend;
it++)
{
if ((it)->first == iEdge) if ((it)->first == iEdge)
return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it); return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
} }
return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
} }
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesBegin() { ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesBegin()
{
return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
} }
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesEnd() {
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesEnd()
{
return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end()); return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
} }
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesIterator(ViewEdge *iEdge) {
for(edges_container::iterator it=_ViewEdges.begin(), itend=_ViewEdges.end(); ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesIterator(ViewEdge *iEdge)
it!=itend;
it++)
{ {
for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend; it++) {
if ((it)->first == iEdge) if ((it)->first == iEdge)
return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), it); return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), it);
} }
return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
} }
/**********************************/ /**********************************/
/* */ /* */
/* */ /* */
@@ -567,7 +577,7 @@ ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesIterator(ViewEdge
real ViewEdge::getLength2D() const real ViewEdge::getLength2D() const
{ {
float length = 0.f; float length = 0.0f;
ViewEdge::const_fedge_iterator itlast = fedge_iterator_last(); ViewEdge::const_fedge_iterator itlast = fedge_iterator_last();
ViewEdge::const_fedge_iterator it = fedge_iterator_begin(), itend = fedge_iterator_end(); ViewEdge::const_fedge_iterator it = fedge_iterator_begin(), itend = fedge_iterator_end();
Vec2r seg; Vec2r seg;
@@ -579,46 +589,103 @@ real ViewEdge::getLength2D() const
return length; return length;
} }
//! view edge iterator //! view edge iterator
ViewEdge::edge_iterator ViewEdge::ViewEdge_iterator() {return edge_iterator(this);} ViewEdge::edge_iterator ViewEdge::ViewEdge_iterator()
ViewEdge::const_edge_iterator ViewEdge::ViewEdge_iterator() const {return const_edge_iterator((ViewEdge*)this);} {
return edge_iterator(this);
}
ViewEdge::const_edge_iterator ViewEdge::ViewEdge_iterator() const
{
return const_edge_iterator((ViewEdge*)this);
}
//! feature edge iterator //! feature edge iterator
ViewEdge::fedge_iterator ViewEdge::fedge_iterator_begin() {return fedge_iterator(this->_FEdgeA, this->_FEdgeB);} ViewEdge::fedge_iterator ViewEdge::fedge_iterator_begin()
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);} return fedge_iterator(this->_FEdgeA, 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::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 //! embedding vertex iterator
ViewEdge::const_vertex_iterator ViewEdge::vertices_begin() const {return const_vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);} ViewEdge::const_vertex_iterator ViewEdge::vertices_begin() const
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);} return const_vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
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::vertex_iterator ViewEdge::vertices_begin()
{
return vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
}
Interface0DIterator ViewEdge::verticesBegin() { ViewEdge::const_vertex_iterator ViewEdge::vertices_last() const
Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(this->_FEdgeA->vertexA(), this->_FEdgeA->vertexA(), 0, _FEdgeA, 0.f)); {
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);
}
Interface0DIterator ViewEdge::verticesBegin()
{
Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(this->_FEdgeA->vertexA(),
this->_FEdgeA->vertexA(), NULL, _FEdgeA, 0.0f));
return ret; return ret;
} }
Interface0DIterator ViewEdge::verticesEnd() { Interface0DIterator ViewEdge::verticesEnd()
Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(0, this->_FEdgeA->vertexA(), _FEdgeB, 0, getLength2D())); {
Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(NULL, this->_FEdgeA->vertexA(),
_FEdgeB, NULL, getLength2D()));
return ret; return ret;
} }
Interface0DIterator ViewEdge::pointsBegin(float t) { Interface0DIterator ViewEdge::pointsBegin(float t)
{
return verticesBegin(); return verticesBegin();
} }
Interface0DIterator ViewEdge::pointsEnd(float t) { Interface0DIterator ViewEdge::pointsEnd(float t)
{
return verticesEnd(); return verticesEnd();
} }
/**********************************/ /**********************************/
/* */ /* */
/* */ /* */
@@ -627,38 +694,28 @@ Interface0DIterator ViewEdge::pointsEnd(float t) {
/* */ /* */
/**********************************/ /**********************************/
ViewShape::~ViewShape() ViewShape::~ViewShape()
{ {
_Vertices.clear(); _Vertices.clear();
if(!(_Edges.empty())) if (!(_Edges.empty())) {
{ for (vector<ViewEdge*>::iterator e = _Edges.begin(), eend = _Edges.end(); e != eend; e++) {
for(vector<ViewEdge*>::iterator e=_Edges.begin(), eend=_Edges.end();
e!=eend;
e++)
{
delete (*e); delete (*e);
} }
_Edges.clear(); _Edges.clear();
} }
if(0 != _SShape) if (_SShape) {
{
delete _SShape; delete _SShape;
_SShape = 0; _SShape = NULL;
} }
} }
void ViewShape::RemoveEdge(ViewEdge *iViewEdge) void ViewShape::RemoveEdge(ViewEdge *iViewEdge)
{ {
FEdge *fedge = iViewEdge->fedgeA(); FEdge *fedge = iViewEdge->fedgeA();
for(vector<ViewEdge*>::iterator ve=_Edges.begin(),veend=_Edges.end(); for (vector<ViewEdge*>::iterator ve = _Edges.begin(), veend = _Edges.end(); ve != veend; ve++) {
ve!=veend; if (iViewEdge == (*ve)) {
ve++)
{
if(iViewEdge == (*ve))
{
_Edges.erase(ve); _Edges.erase(ve);
_SShape->RemoveEdge(fedge); _SShape->RemoveEdge(fedge);
break; break;
@@ -668,12 +725,8 @@ void ViewShape::RemoveEdge(ViewEdge * iViewEdge)
void ViewShape::RemoveVertex(ViewVertex *iViewVertex) void ViewShape::RemoveVertex(ViewVertex *iViewVertex)
{ {
for(vector<ViewVertex*>::iterator vv=_Vertices.begin(), vvend=_Vertices.end(); for (vector<ViewVertex*>::iterator vv = _Vertices.begin(), vvend = _Vertices.end(); vv != vvend; vv++) {
vv!=vvend; if (iViewVertex == (*vv)) {
vv++)
{
if(iViewVertex == (*vv))
{
_Vertices.erase(vv); _Vertices.erase(vv);
break; break;
} }
@@ -688,16 +741,13 @@ void ViewShape::RemoveVertex(ViewVertex * iViewVertex)
/* */ /* */
/**********************************/ /**********************************/
void ViewEdge::UpdateFEdges() void ViewEdge::UpdateFEdges()
{ {
FEdge *currentEdge = _FEdgeA; FEdge *currentEdge = _FEdgeA;
do do {
{
currentEdge->setViewEdge(this); currentEdge->setViewEdge(this);
currentEdge = currentEdge->nextEdge(); currentEdge = currentEdge->nextEdge();
} while ((currentEdge != NULL) && (currentEdge != _FEdgeB)); } while ((currentEdge != NULL) && (currentEdge != _FEdgeB));
// last one // last one
_FEdgeB->setViewEdge(this); _FEdgeB->setViewEdge(this);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,43 @@
// /*
// Filename : ViewMapAdvancedIterators.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Iterators used to iterate over the various elements of the ViewMap * This program is free software; you can redistribute it and/or
// These iterators can't be exported to python. * modify it under the terms of the GNU General Public License
// Date of creation : 01/07/2003 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Iterators used to iterate over the various elements of the ViewMap.
// * These iterators can't be exported to python.
// This program is free software; you can redistribute it and/or * \author Stephane Grabli
// modify it under the terms of the GNU General Public License * \date 01/07/2003
// 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
#include "ViewMap.h" #include "ViewMap.h"
#include "../system/Iterator.h" //soc #include "../system/Iterator.h" //soc
/**********************************/ /**********************************/
@@ -52,14 +58,17 @@
namespace ViewVertexInternal { namespace ViewVertexInternal {
class edge_const_traits : public Const_traits< ::ViewVertex::directedViewEdge> { class edge_const_traits : public Const_traits< ::ViewVertex::directedViewEdge>
{
public: public:
typedef vector< ::ViewVertex::directedViewEdge> edges_container; typedef vector< ::ViewVertex::directedViewEdge> edges_container;
typedef edges_container::const_iterator edges_container_iterator; typedef edges_container::const_iterator edges_container_iterator;
typedef vector< ::ViewVertex::directedViewEdge*> edge_pointers_container; typedef vector< ::ViewVertex::directedViewEdge*> edge_pointers_container;
typedef edge_pointers_container::const_iterator edge_pointers_container_iterator; typedef edge_pointers_container::const_iterator edge_pointers_container_iterator;
}; };
class edge_nonconst_traits : public Nonconst_traits< ::ViewVertex::directedViewEdge> {
class edge_nonconst_traits : public Nonconst_traits< ::ViewVertex::directedViewEdge>
{
public: public:
typedef vector< ::ViewVertex::directedViewEdge> edges_container; typedef vector< ::ViewVertex::directedViewEdge> edges_container;
typedef edges_container::iterator edges_container_iterator; typedef edges_container::iterator edges_container_iterator;
@@ -80,12 +89,14 @@ template<class Traits>
typedef typename Traits::edge_pointers_container_iterator edge_pointers_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_nonconst_traits> iterator;
typedef edge_iterator_base<edge_const_traits> const_iterator; typedef edge_iterator_base<edge_const_traits> const_iterator;
public: public:
friend class ViewVertex; friend class ViewVertex;
friend class TVertex; friend class TVertex;
friend class NonTVertex; friend class NonTVertex;
friend class ViewEdge; friend class ViewEdge;
friend class edge_iterator; friend class edge_iterator;
protected: protected:
Nature::VertexNature _Nature; // the nature of the underlying vertex Nature::VertexNature _Nature; // the nature of the underlying vertex
// T vertex attributes // T vertex attributes
@@ -93,11 +104,13 @@ template<class Traits>
edge_pointers_container_iterator _tend; edge_pointers_container_iterator _tend;
edge_pointers_container_iterator _tvertex_iter; edge_pointers_container_iterator _tvertex_iter;
// mutable value_type _tvertex_iter; #if 0
// value_type _feA; mutable value_type _tvertex_iter;
// value_type _feB; value_type _feA;
// value_type _beA; value_type _feB;
// value_type _beB; value_type _beA;
value_type _beB;
#endif
// Non TVertex attributes // Non TVertex attributes
edges_container_iterator _begin; edges_container_iterator _begin;
@@ -108,72 +121,74 @@ template<class Traits>
public: public:
inline edge_iterator_base() : parent_class() {} inline edge_iterator_base() : parent_class() {}
inline edge_iterator_base(Nature::VertexNature iNature)
: parent_class() inline edge_iterator_base(Nature::VertexNature iNature) : parent_class()
{_Nature = iNature;} {
edge_iterator_base(const edge_iterator_base<edge_nonconst_traits>& iBrother) _Nature = iNature;
: parent_class(iBrother) }
edge_iterator_base(const edge_iterator_base<edge_nonconst_traits>& iBrother) : parent_class(iBrother)
{ {
_Nature = iBrother._Nature; _Nature = iBrother._Nature;
if(_Nature & Nature::T_VERTEX) if (_Nature & Nature::T_VERTEX) {
{ #if 0
// _feA = iBrother._feA; _feA = iBrother._feA;
// _feB = iBrother._feB; _feB = iBrother._feB;
// _beA = iBrother._beA; _beA = iBrother._beA;
// _beB = iBrother._beB; _beB = iBrother._beB;
// _tvertex_iter = iBrother._tvertex_iter; _tvertex_iter = iBrother._tvertex_iter;
#endif
_tbegin = iBrother._tbegin; _tbegin = iBrother._tbegin;
_tend = iBrother._tend; _tend = iBrother._tend;
_tvertex_iter = iBrother._tvertex_iter; _tvertex_iter = iBrother._tvertex_iter;
} }
else else {
{
_begin = iBrother._begin; _begin = iBrother._begin;
_end = iBrother._end; _end = iBrother._end;
_nontvertex_iter = iBrother._nontvertex_iter; _nontvertex_iter = iBrother._nontvertex_iter;
} }
} }
edge_iterator_base(const edge_iterator_base<edge_const_traits>& iBrother)
: parent_class(iBrother) edge_iterator_base(const edge_iterator_base<edge_const_traits>& iBrother) : parent_class(iBrother)
{ {
_Nature = iBrother._Nature; _Nature = iBrother._Nature;
if(_Nature & Nature::T_VERTEX) if (_Nature & Nature::T_VERTEX) {
{ #if 0
// _feA = iBrother._feA; _feA = iBrother._feA;
// _feB = iBrother._feB; _feB = iBrother._feB;
// _beA = iBrother._beA; _beA = iBrother._beA;
// _beB = iBrother._beB; _beB = iBrother._beB;
// _tvertex_iter = iBrother._tvertex_iter; _tvertex_iter = iBrother._tvertex_iter;
#endif
_tbegin = iBrother._tbegin; _tbegin = iBrother._tbegin;
_tend = iBrother._tend; _tend = iBrother._tend;
_tvertex_iter = iBrother._tvertex_iter; _tvertex_iter = iBrother._tvertex_iter;
} }
else else {
{
_begin = iBrother._begin; _begin = iBrother._begin;
_end = iBrother._end; _end = iBrother._end;
_nontvertex_iter = iBrother._nontvertex_iter; _nontvertex_iter = iBrother._nontvertex_iter;
} }
} }
virtual ~edge_iterator_base() {} virtual ~edge_iterator_base() {}
//protected://FIXME //protected://FIXME
public: public:
// inline edge_iterator_base(value_type ifeA, #if 0
// value_type ifeB, inline edge_iterator_base(value_type ifeA, value_type ifeB, value_type ibeA, value_type ibeB, value_type iter)
// value_type ibeA, : parent_class()
// value_type ibeB, {
// value_type iter) _Nature = Nature::T_VERTEX;
// : parent_class() _feA = ifeA;
// { _feB = ifeB;
// _Nature = Nature::T_VERTEX; _beA = ibeA;
// _feA = ifeA; _beB = ibeB;
// _feB = ifeB; _tvertex_iter = iter;
// _beA = ibeA; }
// _beB = ibeB; #endif
// _tvertex_iter = iter;
// } inline edge_iterator_base(edge_pointers_container_iterator begin, edge_pointers_container_iterator end,
inline edge_iterator_base(edge_pointers_container_iterator begin,
edge_pointers_container_iterator end,
edge_pointers_container_iterator iter) edge_pointers_container_iterator iter)
: parent_class() : parent_class()
{ {
@@ -182,8 +197,8 @@ template<class Traits>
_tend = end; _tend = end;
_tvertex_iter = iter; _tvertex_iter = iter;
} }
inline edge_iterator_base(edges_container_iterator begin,
edges_container_iterator end, inline edge_iterator_base(edges_container_iterator begin, edges_container_iterator end,
edges_container_iterator iter) edges_container_iterator iter)
: parent_class() : parent_class()
{ {
@@ -194,8 +209,6 @@ template<class Traits>
} }
public: public:
virtual bool begin() const virtual bool begin() const
{ {
if (_Nature & Nature::T_VERTEX) if (_Nature & Nature::T_VERTEX)
@@ -204,6 +217,7 @@ template<class Traits>
else else
return (_nontvertex_iter == _begin); return (_nontvertex_iter == _begin);
} }
virtual bool end() const virtual bool end() const
{ {
if (_Nature & Nature::T_VERTEX) if (_Nature & Nature::T_VERTEX)
@@ -214,15 +228,19 @@ template<class Traits>
} }
// operators // operators
virtual Self& operator++() // operator corresponding to ++i // operator corresponding to ++i
virtual Self& operator++()
{ {
increment(); increment();
return *this; 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++ 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 Self tmp = *this;
increment(); // dans un temporaire. increment();
return tmp; return tmp;
} }
@@ -236,7 +254,9 @@ template<class Traits>
} }
virtual bool operator==(const Self& b) const virtual bool operator==(const Self& b) const
{return !(*this != b);} {
return !(*this != b);
}
// dereferencing // dereferencing
virtual reference operator*() const virtual reference operator*() const
@@ -247,87 +267,82 @@ template<class Traits>
else else
return (*_nontvertex_iter); return (*_nontvertex_iter);
} }
virtual pointer operator->() const { return &(operator*());}
virtual pointer operator->() const
{
return &(operator*());
}
protected: protected:
inline void increment() inline void increment()
{ {
if(_Nature & Nature::T_VERTEX) if (_Nature & Nature::T_VERTEX) {
{
value_type tmp = (**_tvertex_iter); value_type tmp = (**_tvertex_iter);
++_tvertex_iter; ++_tvertex_iter;
value_type tmp2 = (**_tvertex_iter); value_type tmp2 = (**_tvertex_iter);
if (tmp2.first == tmp.first) if (tmp2.first == tmp.first)
++_tvertex_iter; ++_tvertex_iter;
// // Hack to deal with cusp. the result of a cusp #if 0
// // is a TVertex having two identical viewedges. // 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 // In order to iterate properly, we chose to to skip these last ones.
// // to skip these last ones. if (_feB.first == _beA.first) {
// if(_feB.first == _beA.first) if (_feA.first == _beB.first) {
// { _tvertex_iter.first = 0;
// if(_feA.first == _beB.first) return;
// {
// _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;
// }
} }
if (_tvertex_iter.first == _feA.first)
_tvertex_iter.first = _beB.first;
else if (_tvertex_iter.first == _beB.first)
_tvertex_iter.first = 0;
else 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; ++_nontvertex_iter;
} }
}
}; };
} } // ViewVertexInternal namespace
/**********************************/ /**********************************/
/* */ /* */
/* */ /* */
@@ -350,6 +365,7 @@ namespace ViewEdgeInternal {
typedef typename Traits::pointer pointer; typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference; typedef typename Traits::reference reference;
typedef edge_iterator_base<Traits> Self; typedef edge_iterator_base<Traits> Self;
public: public:
mutable value_type _ViewEdge; mutable value_type _ViewEdge;
//friend class edge_iterator_base<Nonconst_traits<ViewEdge*> >; //friend class edge_iterator_base<Nonconst_traits<ViewEdge*> >;
@@ -360,20 +376,20 @@ namespace ViewEdgeInternal {
public: public:
friend class ViewEdge; friend class ViewEdge;
inline edge_iterator_base() inline edge_iterator_base() : parent_class()
: parent_class() {
{_orientation=true;_first=0;} _orientation = true;
_first = 0;
}
inline edge_iterator_base(const edge_iterator_base<Nonconst_traits< ::ViewEdge*> >& iBrother) inline edge_iterator_base(const edge_iterator_base<Nonconst_traits< ::ViewEdge*> >& iBrother) : parent_class()
: parent_class()
{ {
_ViewEdge = iBrother._ViewEdge; _ViewEdge = iBrother._ViewEdge;
_first = iBrother._first; _first = iBrother._first;
_orientation = iBrother._orientation; _orientation = iBrother._orientation;
} }
inline edge_iterator_base(const edge_iterator_base<Const_traits< ::ViewEdge*> >& iBrother) inline edge_iterator_base(const edge_iterator_base<Const_traits< ::ViewEdge*> >& iBrother) : parent_class()
: parent_class()
{ {
_ViewEdge = iBrother._ViewEdge; _ViewEdge = iBrother._ViewEdge;
_first = iBrother._first; _first = iBrother._first;
@@ -382,54 +398,76 @@ namespace ViewEdgeInternal {
//protected://FIXME //protected://FIXME
public: public:
inline edge_iterator_base(value_type iEdge, bool orientation = true) inline edge_iterator_base(value_type iEdge, bool orientation = true) : parent_class()
: parent_class()
{ {
_ViewEdge = iEdge; _ViewEdge = iEdge;
_first = iEdge; _first = iEdge;
_orientation = orientation; _orientation = orientation;
} }
public: public:
virtual Self *clone() const virtual Self *clone() const
{ {
return new edge_iterator_base(*this); return new edge_iterator_base(*this);
} }
virtual ~edge_iterator_base() {} virtual ~edge_iterator_base() {}
public: public:
virtual bool orientation()
{
return _orientation;
}
virtual bool orientation() {return _orientation;} virtual void set_edge(value_type iVE)
virtual void set_edge(value_type iVE) {_ViewEdge=iVE;} {
virtual void set_orientation(bool iOrientation) {_orientation = iOrientation;} _ViewEdge = iVE;
virtual void change_orientation() {_orientation = !_orientation;} }
virtual void set_orientation(bool iOrientation)
{
_orientation = iOrientation;
}
virtual void change_orientation()
{
_orientation = !_orientation;
}
// operators // operators
inline Self& operator++() // operator corresponding to ++i // operator corresponding to ++i
inline Self& operator++()
{ {
//++_ViewEdge->getTimeStamp(); //++_ViewEdge->getTimeStamp();
increment(); increment();
return *this; return *this;
} }
inline Self operator++(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente. // 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(); //++_ViewEdge->getTimeStamp();
Self tmp = *this; // C'est pour cela qu'on stocke la valeur Self tmp = *this;
increment(); // dans un temporaire. increment();
return tmp; return tmp;
} }
inline Self& operator--() // operator corresponding to ++i
// operator corresponding to --i
inline Self& operator--()
{ {
//++_ViewEdge->getTimeStamp(); //++_ViewEdge->getTimeStamp();
decrement(); decrement();
return *this; return *this;
} }
inline Self operator--(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente. // 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(); //++_ViewEdge->getTimeStamp();
Self tmp = *this; // C'est pour cela qu'on stocke la valeur Self tmp = *this;
decrement(); // dans un temporaire. decrement();
return tmp; return tmp;
} }
@@ -438,18 +476,33 @@ namespace ViewEdgeInternal {
{ {
return (_ViewEdge != b._ViewEdge); return (_ViewEdge != b._ViewEdge);
} }
virtual bool operator==(const Self& b) const virtual bool operator==(const Self& b) const
{ {
return !(*this != b); return !(*this != b);
} }
// dereferencing // dereferencing
virtual reference operator*() const {return (_ViewEdge);} virtual reference operator*() const
virtual pointer operator->() const { return &(operator*());} {
return (_ViewEdge);
}
virtual pointer operator->() const
{
return &(operator*());
}
public: public:
virtual bool begin() const {return _ViewEdge==_first ? true : false;} virtual bool begin() const
virtual bool end() const {return _ViewEdge==0 ? true : false;} {
return (_ViewEdge == _first) ? true : false;
}
virtual bool end() const
{
return (_ViewEdge == 0) ? true : false;
}
protected: protected:
virtual void increment() {} virtual void increment() {}
@@ -465,6 +518,7 @@ namespace ViewEdgeInternal {
typedef typename Traits::pointer pointer; typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference; typedef typename Traits::reference reference;
typedef fedge_iterator_base<Traits> Self; typedef fedge_iterator_base<Traits> Self;
public: public:
typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class; typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class;
mutable value_type _FEdge; mutable value_type _FEdge;
@@ -474,27 +528,26 @@ namespace ViewEdgeInternal {
public: public:
friend class ::ViewEdge; friend class ::ViewEdge;
friend class fedge_iterator; friend class fedge_iterator;
inline fedge_iterator_base()
: parent_class() inline fedge_iterator_base() : parent_class() {}
{}
inline fedge_iterator_base(const fedge_iterator_base<Nonconst_traits<FEdge*> >& iBrother) inline fedge_iterator_base(const fedge_iterator_base<Nonconst_traits<FEdge*> >& iBrother) : parent_class()
: parent_class()
{ {
_FEdge = iBrother._FEdge; _FEdge = iBrother._FEdge;
_first = iBrother._first; _first = iBrother._first;
_FEdgeB = iBrother._FEdgeB; _FEdgeB = iBrother._FEdgeB;
} }
inline fedge_iterator_base(const fedge_iterator_base<Const_traits<FEdge*> >& iBrother)
: parent_class() inline fedge_iterator_base(const fedge_iterator_base<Const_traits<FEdge*> >& iBrother) : parent_class()
{ {
_FEdge = iBrother._FEdge; _FEdge = iBrother._FEdge;
_first = iBrother._first; _first = iBrother._first;
_FEdgeB = iBrother._FEdgeB; _FEdgeB = iBrother._FEdgeB;
} }
//protected://FIXME //protected://FIXME
public: public:
inline fedge_iterator_base(value_type iEdge, value_type iFEdgeB) inline fedge_iterator_base(value_type iEdge, value_type iFEdgeB) : parent_class()
: parent_class()
{ {
_FEdge = iEdge; _FEdge = iEdge;
_first = iEdge; _first = iEdge;
@@ -503,27 +556,37 @@ namespace ViewEdgeInternal {
public: public:
virtual ~fedge_iterator_base() {} virtual ~fedge_iterator_base() {}
// operators // operators
inline Self& operator++() // operator corresponding to ++i // operator corresponding to ++i.
inline Self& operator++()
{ {
increment(); increment();
return *this; return *this;
} }
inline Self operator++(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente. // operator corresponding to i++, i.e. which returns the value *and then* increments it.
Self tmp = *this; // C'est pour cela qu'on stocke la valeur // That's why we store the value in a temp.
increment(); // dans un temporaire. inline Self operator++(int)
{
Self tmp = *this;
increment();
return tmp; return tmp;
} }
inline Self& operator--() // operator corresponding to ++i
// operator corresponding to --i
inline Self& operator--()
{ {
decrement(); decrement();
return *this; return *this;
} }
inline Self operator--(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente. // operator corresponding to i--, i.e. which returns the value *and then* increments it.
Self tmp = *this; // C'est pour cela qu'on stocke la valeur // That's why we store the value in a temp.
decrement(); // dans un temporaire. inline Self operator--(int)
{
Self tmp = *this;
decrement();
return tmp; return tmp;
} }
@@ -532,19 +595,34 @@ namespace ViewEdgeInternal {
{ {
return (_FEdge != b._FEdge); return (_FEdge != b._FEdge);
} }
virtual bool operator==(const Self& b) const virtual bool operator==(const Self& b) const
{ {
return !(*this != b); return !(*this != b);
} }
// dereferencing // dereferencing
virtual reference operator*() const {return (_FEdge);} virtual reference operator*() const
virtual pointer operator->() const { return &(operator*());} {
return (_FEdge);
}
virtual pointer operator->() const
{
return &(operator*());
}
public: public:
virtual bool begin() const {return _FEdge==_first ? true : false;} virtual bool begin() const
virtual bool end() const {return _FEdge==0 ? true : false;} {
return (_FEdge == _first) ? true : false;
}
virtual bool end() const
{
return (_FEdge == 0) ? true : false;
}
protected: protected:
virtual void increment() virtual void increment()
{ {
@@ -553,8 +631,7 @@ namespace ViewEdgeInternal {
virtual void decrement() virtual void decrement()
{ {
if(0 == _FEdge) if (0 == _FEdge) {
{
_FEdge = _FEdgeB; _FEdge = _FEdgeB;
return; return;
} }
@@ -571,27 +648,29 @@ namespace ViewEdgeInternal {
typedef typename Traits::pointer pointer; typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference; typedef typename Traits::reference reference;
typedef vertex_iterator_base<Traits> Self; typedef vertex_iterator_base<Traits> Self;
protected: protected:
typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class; typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class;
public: public:
mutable value_type _SVertex; mutable value_type _SVertex;
FEdge *_NextFEdge; FEdge *_NextFEdge;
FEdge *_PreviousFEdge; FEdge *_PreviousFEdge;
public: public:
friend class ViewEdge; friend class ViewEdge;
friend class vertex_iterator; friend class vertex_iterator;
inline vertex_iterator_base()
: parent_class() inline vertex_iterator_base() : parent_class() {}
{}
inline vertex_iterator_base(const vertex_iterator_base<Const_traits<SVertex*> >& iBrother) inline vertex_iterator_base(const vertex_iterator_base<Const_traits<SVertex*> >& iBrother) : parent_class()
: parent_class()
{ {
_SVertex = iBrother._SVertex; _SVertex = iBrother._SVertex;
_NextFEdge = iBrother._NextFEdge; _NextFEdge = iBrother._NextFEdge;
_PreviousFEdge = iBrother._PreviousFEdge; _PreviousFEdge = iBrother._PreviousFEdge;
} }
inline vertex_iterator_base(const vertex_iterator_base<Nonconst_traits<SVertex*> >& iBrother)
: parent_class() inline vertex_iterator_base(const vertex_iterator_base<Nonconst_traits<SVertex*> >& iBrother) : parent_class()
{ {
_SVertex = iBrother._SVertex; _SVertex = iBrother._SVertex;
_NextFEdge = iBrother._NextFEdge; _NextFEdge = iBrother._NextFEdge;
@@ -600,9 +679,7 @@ namespace ViewEdgeInternal {
//protected://FIXME //protected://FIXME
public: public:
inline vertex_iterator_base(value_type iVertex, FEdge *iPreviousFEdge, FEdge *iNextFEdge) : parent_class()
inline vertex_iterator_base(value_type iVertex, FEdge *iPreviousFEdge, FEdge *iNextFEdge)
: parent_class()
{ {
_SVertex = iVertex; _SVertex = iVertex;
_NextFEdge = iNextFEdge; _NextFEdge = iNextFEdge;
@@ -612,30 +689,46 @@ namespace ViewEdgeInternal {
public: public:
virtual ~vertex_iterator_base() {} virtual ~vertex_iterator_base() {}
virtual bool begin() const {return _PreviousFEdge==0? true : false;} virtual bool begin() const
virtual bool end() const {return _SVertex==0 ? true : false;} {
return (_PreviousFEdge == 0) ? true : false;
}
virtual bool end() const
{
return (_SVertex == 0) ? true : false;
}
// operators // operators
inline Self& operator++() // operator corresponding to ++i // operator corresponding to ++i
inline Self& operator++()
{ {
increment(); increment();
return *this; return *this;
} }
inline Self operator++(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente. // operator corresponding to i++, i.e. which returns the value *and then* increments it.
Self tmp = *this; // C'est pour cela qu'on stocke la valeur // That's why we store the value in a temp.
increment(); // dans un temporaire. inline Self operator++(int)
{
Self tmp = *this;
increment();
return tmp; return tmp;
} }
inline Self& operator--() // operator corresponding to ++i
// operator corresponding to --i
inline Self& operator--()
{ {
decrement(); decrement();
return *this; return *this;
} }
inline Self operator--(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente. // operator corresponding to --i, i.e. which returns the value *and then* increments it.
Self tmp = *this; // C'est pour cela qu'on stocke la valeur // That's why we store the value in a temp.
decrement(); // dans un temporaire. inline Self operator--(int)
{
Self tmp = *this;
decrement();
return tmp; return tmp;
} }
@@ -644,39 +737,45 @@ namespace ViewEdgeInternal {
{ {
return (_SVertex != b._SVertex); return (_SVertex != b._SVertex);
} }
virtual bool operator==(const Self& b) const virtual bool operator==(const Self& b) const
{ {
return !(*this != b); return !(*this != b);
} }
// dereferencing // dereferencing
virtual reference operator*() const {return (_SVertex);} virtual reference operator*() const
virtual pointer operator->() const { return &(operator*());} {
return (_SVertex);
}
virtual pointer operator->() const
{
return &(operator*());
}
protected: protected:
virtual void increment() virtual void increment()
{ {
if(0 == _NextFEdge) if (!_NextFEdge) {
{ _SVertex = NULL;
_SVertex = 0;
return; return;
} }
_SVertex = _NextFEdge->vertexB(); _SVertex = _NextFEdge->vertexB();
_PreviousFEdge = _NextFEdge; _PreviousFEdge = _NextFEdge;
_NextFEdge = _NextFEdge->nextEdge(); _NextFEdge = _NextFEdge->nextEdge();
} }
virtual void decrement() virtual void decrement()
{ {
// if(0 == _SVertex) #if 0
// { if (!_SVertex) {
// _SVertex = _PreviousFEdge->vertexB(); _SVertex = _PreviousFEdge->vertexB();
// return; return;
// } }
if(0 == _PreviousFEdge) #endif
{ if (!_PreviousFEdge) {
_SVertex = 0; _SVertex = NULL;
return; return;
} }
_SVertex = _PreviousFEdge->vertexA(); _SVertex = _PreviousFEdge->vertexA();
@@ -685,7 +784,6 @@ namespace ViewEdgeInternal {
} }
}; };
} // end of namespace ViewEdgeInternal } // end of namespace ViewEdgeInternal
#endif // VIEWMAPADVANCEDITERATORS_H #endif // __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +1,69 @@
// /*
// Filename : ViewMapBuilder.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Class to build silhouette edges from a * This program is free software; you can redistribute it and/or
// Winged-Edge structure * modify it under the terms of the GNU General Public License
// Date of creation : 25/03/2002 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to build silhouette edges from a Winged-Edge structure
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 25/03/2002
// 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 <vector>
# include "../system/FreestyleConfig.h"
#include "GridDensityProvider.h"
#include "Silhouette.h"
#include "SilhouetteGeomEngine.h"
#include "ViewEdgeXBuilder.h"
#include "ViewMap.h"
#include "../geometry/Geom.h" #include "../geometry/Geom.h"
# include "../scene_graph/NodeGroup.h"
# include "../winged_edge/WXEdge.h"
#include "../geometry/GeomUtils.h" #include "../geometry/GeomUtils.h"
#include "../geometry/Grid.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/ProgressBar.h"
#include "../system/RenderMonitor.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 "../system/TimeUtils.h"
# include "GridDensityProvider.h"
#include "../winged_edge/WEdge.h"
#include "../winged_edge/WXEdge.h"
using namespace Geometry; using namespace Geometry;
class LIB_VIEW_MAP_EXPORT ViewMapBuilder class LIB_VIEW_MAP_EXPORT ViewMapBuilder
{ {
private: private:
ViewMap *_ViewMap; // result ViewMap *_ViewMap; // result
//SilhouetteGeomEngine _GeomEngine; //SilhouetteGeomEngine _GeomEngine;
ProgressBar *_pProgressBar; ProgressBar *_pProgressBar;
@@ -67,17 +75,14 @@ private:
bool _EnableQI; bool _EnableQI;
double _epsilon; double _epsilon;
// tmp values: // tmp values:
int _currentId; int _currentId;
int _currentFId; int _currentFId;
int _currentSVertexId; int _currentSVertexId;
public: public:
typedef enum { typedef enum {
sweep_line sweep_line,
} intersection_algo; } intersection_algo;
typedef enum { typedef enum {
@@ -87,14 +92,14 @@ public:
ray_casting_culled_adaptive_traditional, ray_casting_culled_adaptive_traditional,
ray_casting_adaptive_traditional, ray_casting_adaptive_traditional,
ray_casting_culled_adaptive_cumulative, ray_casting_culled_adaptive_cumulative,
ray_casting_adaptive_cumulative ray_casting_adaptive_cumulative,
} visibility_algo; } visibility_algo;
inline ViewMapBuilder() inline ViewMapBuilder()
{ {
_pProgressBar = 0; _pProgressBar = NULL;
_pRenderMonitor = 0; _pRenderMonitor = NULL;
_Grid = 0; _Grid = NULL;
_currentId = 1; _currentId = 1;
_currentFId = 0; _currentFId = 0;
_currentSVertexId = 0; _currentSVertexId = 0;
@@ -106,7 +111,7 @@ public:
{ {
if (_pViewEdgeBuilder) { if (_pViewEdgeBuilder) {
delete _pViewEdgeBuilder; delete _pViewEdgeBuilder;
_pViewEdgeBuilder = 0; _pViewEdgeBuilder = NULL;
} }
} }
@@ -119,15 +124,18 @@ public:
/*! Compute Cusps */ /*! Compute Cusps */
void computeCusps(ViewMap *ioViewMap); void computeCusps(ViewMap *ioViewMap);
/*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of
* each cusp SVertex /*! 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. * We use a hysteresis approach to avoid noise.
*/ */
void DetectCusps(ViewEdge *ioEdge); void DetectCusps(ViewEdge *ioEdge);
/*! Sets the current viewpoint */ /*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp) {_viewpoint = ivp; SilhouetteGeomEngine::setViewpoint(ivp);} inline void setViewpoint(const Vec3r& ivp)
{
_viewpoint = ivp;
SilhouetteGeomEngine::setViewpoint(ivp);
}
/*! Sets the current transformation /*! Sets the current transformation
* iModelViewMatrix * iModelViewMatrix
@@ -137,86 +145,91 @@ public:
* iViewport * iViewport
* The viewport. 4 real array: origin.x, origin.y, width, length * The viewport. 4 real array: origin.x, origin.y, width, length
*/ */
inline void setTransform(const real iModelViewMatrix[4][4], inline void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
const real iProjectionMatrix[4][4], const int iViewport[4], real iFocalLength, real iAspect, real iFovy)
const int iViewport[4], {
real iFocalLength,
real iAspect,
real iFovy) {
_orthographicProjection = (iProjectionMatrix[3][3] != 0.0); _orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength); SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
} }
inline void setFrustum(real iZnear, real iZfar) { inline void setFrustum(real iZnear, real iZfar)
{
SilhouetteGeomEngine::setFrustum(iZnear, iZfar); SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
} }
/*! Builds the scene view map /*! Builds the scene view map returns the list the view map
* returns the list the view map
* it is up to the caller to delete this ViewMap * it is up to the caller to delete this ViewMap
* iWRoot * iWRoot
* The root group node containing the WEdge structured scene * 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);
ViewMap* BuildViewMap(WingedEdge& we, visibility_algo iAlgo, real epsilon, void CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4],
const BBox<Vec3r>& bbox, unsigned int sceneNumFaces); bool extensiveFEdgeSearch = true);
void CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4], bool extensiveFEdgeSearch = true);
/*! computes the intersection between all 2D /*! computes the intersection between all 2D feature edges of the scene.
* feature edges of the scene.
* ioViewMap * ioViewMap
* The view map. It is modified by the method. * The view map. It is modified by the method.
* The list of all features edges of the scene. * The list of all features edges of the scene.
* Each time an intersection is found, the 2 intersecting * Each time an intersection is found, the 2 intersecting edges are splitted (creating 2 new vertices)
* 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).
* At the end, this list is updated with the adding
* of all new created edges (resulting from splitting).
* iAlgo * iAlgo
* The algo to use for computing the intersections * The algo to use for computing the intersections
*/ */
void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon=1e-06); void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon = 1.0e-06);
/*! Computes the 2D scene silhouette edges visibility /*! Computes the 2D scene silhouette edges visibility
* iGrid * iGrid
* For the Ray Casting algorithm. * For the Ray Casting algorithm.
*/ */
void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces, void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces,
visibility_algo iAlgo= ray_casting, real epsilon=1e-6); visibility_algo iAlgo = ray_casting, real epsilon = 1.0e-6);
void setGrid(Grid *iGrid) {_Grid = iGrid;} void setGrid(Grid *iGrid)
{
_Grid = iGrid;
}
/*! accessors */ /*! accessors */
/*! Modifiers */ /*! Modifiers */
inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;} inline void setProgressBar(ProgressBar *iProgressBar)
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;} {
inline void setEnableQI(bool iBool) {_EnableQI = iBool;} _pProgressBar = iProgressBar;
}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
{
_pRenderMonitor = iRenderMonitor;
}
inline void setEnableQI(bool iBool)
{
_EnableQI = iBool;
}
protected: protected:
/*! Computes intersections on all edges of the scene using a sweep line algorithm */
void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1.0e-6);
/*! Computes intersections on all edges of the scene using a sweep line /*! Computes the 2D scene silhouette edges visibility using a ray casting. On each edge, a ray is cast
* algorithm*/ * to check its quantitative invisibility. The list of occluders are each time stored in the tested edge.
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 * ioViewMap
* The view map. * The view map.
* The 2D scene silhouette edges as FEdges. * The 2D scene silhouette edges as FEdges.
* These edges have already been splitted at their intersections points. * These edges have already been splitted at their intersections points.
* Thus, these edges do not intersect anymore. * Thus, these edges do not intersect anymore.
* The visibility corresponding to each edge of ioScene is set is this * The visibility corresponding to each edge of ioScene is set is this edge.
* edge.
*/ */
void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6); void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6); void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6); void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we, void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory); bool cull, GridDensityProviderFactory& factory);
void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we, void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory); bool cull, GridDensityProviderFactory& factory);
/*! Compute the visibility for the FEdge fe. /*! Compute the visibility for the FEdge fe.
* The occluders are added to fe occluders list. * The occluders are added to fe occluders list.
@@ -228,12 +241,9 @@ void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we,
* The epsilon used for computation * The epsilon used for computation
* oShapeId * oShapeId
* fe is the border (in 2D) between 2 2D spaces. * fe is the border (in 2D) between 2 2D spaces.
* if fe is a silhouette, * if fe is a silhouette, One of these 2D spaces is occupied by the shape to which fe belongs (on its left)
* One of these 2D spaces is occupied by the shape * and the other one is either occupied by another shape or empty or occupied by the same shape.
* to which fe belongs (on its left) and the other one is either occupied * We use this ray csating operation to determine which shape lies on fe's right.
* 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 * The result is the shape id stored in oShapeId
*/ */
int ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders, int ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
@@ -242,7 +252,6 @@ void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we,
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp); void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
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); Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
}; };
#endif // VIEWMAPBUILDER_H #endif // __FREESTYLE_VIEW_MAP_BUILDER_H__

View File

@@ -1,23 +1,36 @@
/*
* ***** 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Functions to manage I/O for the view map
// * \author Emmanuel Turquin
// This program is free software; you can redistribute it and/or * \date 09/01/2003
// 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 "ViewMapIO.h" #include "ViewMapIO.h"
@@ -29,8 +42,22 @@
# define READ(n) in.read((char *)(&(n)), sizeof((n))) # define READ(n) in.read((char *)(&(n)), sizeof((n)))
#endif #endif
#define WRITE_IF_NON_NULL(ptr) if ((ptr) == NULL) { WRITE(ZERO); } else { WRITE((ptr)->userdata); } #define WRITE_IF_NON_NULL(ptr) \
#define READ_IF_NON_NULL(ptr, array) READ(tmp); if (tmp == ZERO) { (ptr) = NULL; } else { (ptr) = (array)[tmp]; } 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 ViewMapIO {
@@ -40,9 +67,8 @@ namespace ViewMapIO {
//////////////////// 'load' Functions //////////////////// //////////////////// 'load' Functions ////////////////////
inline inline int load(istream& in, Vec3r& v)
int load(istream& in, Vec3r& v) { {
if (Options::getFlags() & Options::FLOAT_VECTORS) { if (Options::getFlags() & Options::FLOAT_VECTORS) {
float tmp; float tmp;
READ(tmp); READ(tmp);
@@ -51,7 +77,8 @@ namespace ViewMapIO {
v[1] = tmp; v[1] = tmp;
READ(tmp); READ(tmp);
v[2] = tmp; v[2] = tmp;
} else { }
else {
Vec3r::value_type tmp; Vec3r::value_type tmp;
READ(tmp); READ(tmp);
v[0] = tmp; v[0] = tmp;
@@ -63,10 +90,8 @@ namespace ViewMapIO {
return 0; return 0;
} }
inline int load(istream& in, Polygon3r& p)
inline {
int load(istream& in, Polygon3r& p) {
unsigned tmp; unsigned tmp;
// Id // Id
@@ -77,7 +102,7 @@ namespace ViewMapIO {
vector<Vec3r> tmp_vec; vector<Vec3r> tmp_vec;
Vec3r v; Vec3r v;
READ(tmp); READ(tmp);
for (unsigned i = 0; i < tmp; i++) { for (unsigned int i = 0; i < tmp; i++) {
load(in, v); load(in, v);
tmp_vec.push_back(v); tmp_vec.push_back(v);
} }
@@ -89,10 +114,8 @@ namespace ViewMapIO {
return 0; return 0;
} }
inline int load(istream& in, FrsMaterial& m)
inline {
int load(istream& in, FrsMaterial& m) {
float tmp_array[4]; float tmp_array[4];
int i; int i;
@@ -123,9 +146,8 @@ namespace ViewMapIO {
return 0; return 0;
} }
static int load(istream& in, ViewShape *vs)
static int load(istream& in, ViewShape* vs) { {
if (!vs || !vs->sshape()) if (!vs || !vs->sshape())
return 1; return 1;
@@ -157,8 +179,6 @@ namespace ViewMapIO {
} }
vs->sshape()->setFrsMaterials(frs_materials); vs->sshape()->setFrsMaterials(frs_materials);
// -> VerticesList (List) // -> VerticesList (List)
READ(size); READ(size);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
@@ -203,18 +223,19 @@ namespace ViewMapIO {
} }
static int load(istream& in, FEdge* fe) { static int load(istream& in, FEdge *fe)
{
if (!fe) if (!fe)
return 1; return 1;
bool b; bool b;
FEdgeSmooth *fesmooth = 0; FEdgeSmooth *fesmooth = NULL;
FEdgeSharp * fesharp = 0; FEdgeSharp *fesharp = NULL;
if (fe->isSmooth()) { if (fe->isSmooth()) {
fesmooth = dynamic_cast<FEdgeSmooth*>(fe); fesmooth = dynamic_cast<FEdgeSmooth*>(fe);
}else{ }
else {
fesharp = dynamic_cast<FEdgeSharp*>(fe); fesharp = dynamic_cast<FEdgeSharp*>(fe);
} }
@@ -229,21 +250,24 @@ namespace ViewMapIO {
READ(nature); READ(nature);
fe->setNature(nature); fe->setNature(nature);
// hasVisibilityPoint #if 0 // hasVisibilityPoint
// bool b; bool b;
// READ(b); READ(b);
// fe->setHasVisibilityPoint(b); fe->setHasVisibilityPoint(b);
#endif
Vec3r v; Vec3r v;
unsigned int matindex; unsigned int matindex;
#if 0
// VisibilityPointA // VisibilityPointA
// load(in, v); load(in, v);
// fe->setVisibilityPointA(v); fe->setVisibilityPointA(v);
// VisibilityPointB // VisibilityPointB
// load(in, v); load(in, v);
// fe->setVisibilityPointB(v); fe->setVisibilityPointB(v);
#endif
if (fe->isSmooth()) { if (fe->isSmooth()) {
// Normal // Normal
@@ -253,7 +277,8 @@ namespace ViewMapIO {
// Material // Material
READ(matindex); READ(matindex);
fesmooth->setFrsMaterialIndex(matindex); fesmooth->setFrsMaterialIndex(matindex);
}else{ }
else {
// aNormal // aNormal
load(in, v); load(in, v);
fesharp->setNormalA(v); fesharp->setNormalA(v);
@@ -316,9 +341,8 @@ namespace ViewMapIO {
return 0; return 0;
} }
static int load(istream& in, SVertex *sv)
static int load(istream& in, SVertex* sv) { {
if (!sv) if (!sv)
return 1; return 1;
@@ -371,8 +395,8 @@ namespace ViewMapIO {
} }
static int load(istream& in, ViewEdge* ve) { static int load(istream& in, ViewEdge *ve)
{
if (!ve) if (!ve)
return 1; return 1;
@@ -428,7 +452,7 @@ namespace ViewMapIO {
unsigned size; unsigned size;
READ(size); READ(size);
ViewShape *vso; ViewShape *vso;
for (unsigned i = 0; i < size; i++) { for (unsigned int i = 0; i < size; i++) {
READ_IF_NON_NULL(vso, g_vm->ViewShapes()); READ_IF_NON_NULL(vso, g_vm->ViewShapes());
ve->AddOccluder(vso); ve->AddOccluder(vso);
} }
@@ -438,8 +462,8 @@ namespace ViewMapIO {
} }
static int load(istream& in, ViewVertex* vv) { static int load(istream& in, ViewVertex *vv)
{
if (!vv) if (!vv)
return 1; return 1;
@@ -506,7 +530,7 @@ namespace ViewMapIO {
unsigned size; unsigned size;
READ(size); READ(size);
ViewEdge *ve; ViewEdge *ve;
for (unsigned i = 0; i < size; i++) { for (unsigned int i = 0; i < size; i++) {
READ_IF_NON_NULL(ve, g_vm->ViewEdges()); READ_IF_NON_NULL(ve, g_vm->ViewEdges());
READ(b); READ(b);
ntv->AddViewEdge(ve, b); ntv->AddViewEdge(ve, b);
@@ -518,9 +542,8 @@ namespace ViewMapIO {
//////////////////// 'save' Functions //////////////////// //////////////////// 'save' Functions ////////////////////
inline inline int save(ostream& out, const Vec3r& v)
int save(ostream& out, const Vec3r& v) { {
if (Options::getFlags() & Options::FLOAT_VECTORS) { if (Options::getFlags() & Options::FLOAT_VECTORS) {
float tmp; float tmp;
@@ -530,7 +553,8 @@ namespace ViewMapIO {
WRITE(tmp); WRITE(tmp);
tmp = v[2]; tmp = v[2];
WRITE(tmp); WRITE(tmp);
} else { }
else {
Vec3r::value_type tmp; Vec3r::value_type tmp;
tmp = v[0]; tmp = v[0];
@@ -544,9 +568,8 @@ namespace ViewMapIO {
} }
inline inline int save(ostream& out, const Polygon3r& p)
int save(ostream& out, const Polygon3r& p) { {
unsigned tmp; unsigned tmp;
// Id // Id
@@ -556,8 +579,7 @@ namespace ViewMapIO {
// vertices (List) // vertices (List)
tmp = p.getVertices().size(); tmp = p.getVertices().size();
WRITE(tmp); WRITE(tmp);
for (vector<Vec3r>::const_iterator i = p.getVertices().begin(); for (vector<Vec3r>::const_iterator i = p.getVertices().begin(); i != p.getVertices().end(); i++) {
i != p.getVertices().end(); i++) {
save(out, *i); save(out, *i);
} }
@@ -567,10 +589,8 @@ namespace ViewMapIO {
return 0; return 0;
} }
inline int save(ostream& out, const FrsMaterial& m)
inline {
int save(ostream& out, const FrsMaterial& m) {
unsigned i; unsigned i;
// Diffuse // Diffuse
@@ -596,9 +616,8 @@ namespace ViewMapIO {
return 0; return 0;
} }
static int save(ostream& out, ViewShape *vs)
static int save(ostream& out, ViewShape* vs) { {
if (!vs || !vs->sshape()) { if (!vs || !vs->sshape()) {
cerr << "Warning: null ViewShape" << endl; cerr << "Warning: null ViewShape" << endl;
return 1; return 1;
@@ -622,53 +641,59 @@ namespace ViewMapIO {
// Not necessary (only used during view map computatiom) // Not necessary (only used during view map computatiom)
// -> Material // -> Material
unsigned size = vs->sshape()->frs_materials().size(); unsigned int size = vs->sshape()->frs_materials().size();
WRITE(size); WRITE(size);
for(unsigned i=0; i<size; ++i) for (unsigned int i = 0; i < size; ++i)
save(out, vs->sshape()->frs_material(i)); save(out, vs->sshape()->frs_material(i));
// -> VerticesList (List) // -> VerticesList (List)
tmp = vs->sshape()->getVertexList().size(); tmp = vs->sshape()->getVertexList().size();
WRITE(tmp); WRITE(tmp);
for (vector<SVertex*>::const_iterator i1 = vs->sshape()->getVertexList().begin(); for (vector<SVertex*>::const_iterator i1 = vs->sshape()->getVertexList().begin();
i1 != vs->sshape()->getVertexList().end(); i1++) i1 != vs->sshape()->getVertexList().end();
i1++)
{
WRITE_IF_NON_NULL(*i1); WRITE_IF_NON_NULL(*i1);
}
// -> Chains (List) // -> Chains (List)
tmp = vs->sshape()->getChains().size(); tmp = vs->sshape()->getChains().size();
WRITE(tmp); WRITE(tmp);
for (vector<FEdge*>::const_iterator i2 = vs->sshape()->getChains().begin(); for (vector<FEdge*>::const_iterator i2 = vs->sshape()->getChains().begin();
i2 != vs->sshape()->getChains().end(); i2++) i2 != vs->sshape()->getChains().end();
i2++)
{
WRITE_IF_NON_NULL(*i2); WRITE_IF_NON_NULL(*i2);
}
// -> EdgesList (List) // -> EdgesList (List)
tmp = vs->sshape()->getEdgeList().size(); tmp = vs->sshape()->getEdgeList().size();
WRITE(tmp); WRITE(tmp);
for (vector<FEdge*>::const_iterator i3 = vs->sshape()->getEdgeList().begin(); for (vector<FEdge*>::const_iterator i3 = vs->sshape()->getEdgeList().begin();
i3 != vs->sshape()->getEdgeList().end(); i3++) i3 != vs->sshape()->getEdgeList().end();
i3++)
{
WRITE_IF_NON_NULL(*i3); WRITE_IF_NON_NULL(*i3);
}
// ViewEdges (List) // ViewEdges (List)
tmp = vs->edges().size(); tmp = vs->edges().size();
WRITE(tmp); WRITE(tmp);
for (vector<ViewEdge*>::const_iterator i4 = vs->edges().begin(); for (vector<ViewEdge*>::const_iterator i4 = vs->edges().begin(); i4 != vs->edges().end(); i4++)
i4 != vs->edges().end(); i4++)
WRITE_IF_NON_NULL(*i4); WRITE_IF_NON_NULL(*i4);
// ViewVertices (List) // ViewVertices (List)
tmp = vs->vertices().size(); tmp = vs->vertices().size();
WRITE(tmp); WRITE(tmp);
for (vector<ViewVertex*>::const_iterator i5 = vs->vertices().begin(); for (vector<ViewVertex*>::const_iterator i5 = vs->vertices().begin(); i5 != vs->vertices().end(); i5++)
i5 != vs->vertices().end(); i5++)
WRITE_IF_NON_NULL(*i5); WRITE_IF_NON_NULL(*i5);
return 0; return 0;
} }
static int save(ostream& out, FEdge* fe) { static int save(ostream& out, FEdge *fe)
{
if (!fe) { if (!fe) {
cerr << "Warning: null FEdge" << endl; cerr << "Warning: null FEdge" << endl;
return 1; return 1;
@@ -689,15 +714,17 @@ namespace ViewMapIO {
bool b; bool b;
#if 0
// hasVisibilityPoint // hasVisibilityPoint
// b = fe->hasVisibilityPoint(); b = fe->hasVisibilityPoint();
// WRITE(b); WRITE(b);
// VisibilityPointA // VisibilityPointA
// save(out, fe->visibilityPointA()); save(out, fe->visibilityPointA());
//
// // VisibilityPointB // VisibilityPointB
// save(out, fe->visibilityPointB()); save(out, fe->visibilityPointB());
#endif
unsigned index; unsigned index;
if (fe->isSmooth()) { if (fe->isSmooth()) {
@@ -706,7 +733,8 @@ namespace ViewMapIO {
// material // material
index = fesmooth->frs_materialIndex(); index = fesmooth->frs_materialIndex();
WRITE(index); WRITE(index);
}else{ }
else {
// aNormal // aNormal
save(out, fesharp->normalA()); save(out, fesharp->normalA());
// bNormal // bNormal
@@ -719,7 +747,6 @@ namespace ViewMapIO {
WRITE(index); WRITE(index);
} }
// VertexA // VertexA
WRITE_IF_NON_NULL(fe->vertexA()); WRITE_IF_NON_NULL(fe->vertexA());
@@ -751,9 +778,8 @@ namespace ViewMapIO {
return 0; return 0;
} }
static int save(ostream& out, SVertex *sv)
static int save(ostream& out, SVertex* sv) { {
if (!sv) { if (!sv) {
cerr << "Warning: null SVertex" << endl; cerr << "Warning: null SVertex" << endl;
return 1; return 1;
@@ -784,12 +810,10 @@ namespace ViewMapIO {
WRITE_IF_NON_NULL(sv->viewvertex()); WRITE_IF_NON_NULL(sv->viewvertex());
// Normals (List) // Normals (List)
// Note: the 'size()' method of a set doesn't seem to return the // Note: the 'size()' method of a set doesn't seem to return the actual size of the given set, so we have to
// actual size of the given set, so we have to hack it... // hack it...
set<Vec3r>::const_iterator i; set<Vec3r>::const_iterator i;
for (i = sv->normals().begin(), tmp = 0; for (i = sv->normals().begin(), tmp = 0; i != sv->normals().end(); i++, tmp++);
i != sv->normals().end();
i++, tmp++);
WRITE(tmp); WRITE(tmp);
for (i = sv->normals().begin(); i != sv->normals().end(); i++) for (i = sv->normals().begin(); i != sv->normals().end(); i++)
save(out, *i); save(out, *i);
@@ -797,16 +821,15 @@ namespace ViewMapIO {
// FEdges (List) // FEdges (List)
tmp = sv->fedges().size(); tmp = sv->fedges().size();
WRITE(tmp); WRITE(tmp);
for (vector<FEdge*>::const_iterator j = sv->fedges_begin(); for (vector<FEdge*>::const_iterator j = sv->fedges_begin(); j != sv->fedges_end(); j++)
j != sv->fedges_end(); j++)
WRITE_IF_NON_NULL(*j); WRITE_IF_NON_NULL(*j);
return 0; return 0;
} }
static int save(ostream& out, ViewEdge* ve) { static int save(ostream& out, ViewEdge *ve)
{
if (!ve) { if (!ve) {
cerr << "Warning: null ViewEdge" << endl; cerr << "Warning: null ViewEdge" << endl;
return 1; return 1;
@@ -850,8 +873,7 @@ namespace ViewMapIO {
if (!(Options::getFlags() & Options::NO_OCCLUDERS)) { if (!(Options::getFlags() & Options::NO_OCCLUDERS)) {
tmp = ve->occluders().size(); tmp = ve->occluders().size();
WRITE(tmp); WRITE(tmp);
for (vector<ViewShape*>::const_iterator i = ve->occluders().begin(); for (vector<ViewShape*>::const_iterator i = ve->occluders().begin(); i != ve->occluders().end(); i++)
i != ve->occluders().end(); i++)
WRITE_IF_NON_NULL((*i)); WRITE_IF_NON_NULL((*i));
} }
@@ -859,8 +881,8 @@ namespace ViewMapIO {
} }
static int save(ostream& out, ViewVertex* vv) { static int save(ostream& out, ViewVertex *vv)
{
if (!vv) { if (!vv) {
cerr << "Warning: null ViewVertex" << endl; cerr << "Warning: null ViewVertex" << endl;
return 1; return 1;
@@ -900,7 +922,6 @@ namespace ViewMapIO {
// BackEdgeB // BackEdgeB
WRITE_IF_NON_NULL(tv->backEdgeB().first); WRITE_IF_NON_NULL(tv->backEdgeB().first);
WRITE(tv->backEdgeB().second); WRITE(tv->backEdgeB().second);
} }
else if (vv->getNature() & Nature::NON_T_VERTEX) { else if (vv->getNature() & Nature::NON_T_VERTEX) {
NonTVertex *ntv = dynamic_cast<NonTVertex*>(vv); NonTVertex *ntv = dynamic_cast<NonTVertex*>(vv);
@@ -916,8 +937,8 @@ namespace ViewMapIO {
WRITE_IF_NON_NULL(i->first); WRITE_IF_NON_NULL(i->first);
WRITE(i->second); WRITE(i->second);
} }
}
} else { else {
cerr << "Warning: unexpected ViewVertex nature" << endl; cerr << "Warning: unexpected ViewVertex nature" << endl;
return 1; return 1;
} }
@@ -930,17 +951,18 @@ namespace ViewMapIO {
//////////////////// "Public" 'load' and 'save' functions //////////////////// //////////////////// "Public" 'load' and 'save' functions ////////////////////
#define SET_PROGRESS(n) if (pb) pb->setProgress((n)) #define SET_PROGRESS(n) \
if (pb) { \
int load(istream& in, ViewMap* vm, ProgressBar* pb) { pb->setProgress((n)); \
} (void)0
int load(istream& in, ViewMap *vm, ProgressBar *pb)
{
if (!vm) if (!vm)
return 1; return 1;
//soc unused - unsigned tmp; //soc unused - unsigned tmp;
int err = 0; int err = 0;
Internal::g_vm = vm; Internal::g_vm = vm;
// Management of the progress bar (if present) // Management of the progress bar (if present)
@@ -965,18 +987,16 @@ namespace ViewMapIO {
if (fe_s) { if (fe_s) {
bool b; bool b;
READ(b); READ(b);
for (READ(fe_rle1), fe_rle2 = 0; for (READ(fe_rle1), fe_rle2 = 0; fe_rle1 < fe_s + 1; fe_rle2 = fe_rle1, READ(fe_rle1)) {
fe_rle1 < fe_s+1;
fe_rle2 = fe_rle1, READ(fe_rle1)) {
if (b) { if (b) {
for (unsigned i = fe_rle2; i < fe_rle1; i++) { for (unsigned int i = fe_rle2; i < fe_rle1; i++) {
FEdgeSmooth *fes = new FEdgeSmooth; FEdgeSmooth *fes = new FEdgeSmooth;
vm->AddFEdge(fes); vm->AddFEdge(fes);
} }
b = !b; b = !b;
} }
else if (!b) { else if (!b) {
for (unsigned i = fe_rle2; i < fe_rle1; i++) { for (unsigned int i = fe_rle2; i < fe_rle1; i++) {
FEdgeSharp *fes = new FEdgeSharp; FEdgeSharp *fes = new FEdgeSharp;
vm->AddFEdge(fes); vm->AddFEdge(fes);
} }
@@ -992,18 +1012,16 @@ namespace ViewMapIO {
if (vv_s) { if (vv_s) {
Nature::VertexNature nature; Nature::VertexNature nature;
READ(nature); READ(nature);
for (READ(vv_rle1), vv_rle2 = 0; for (READ(vv_rle1), vv_rle2 = 0; vv_rle1 < vv_s + 1; vv_rle2 = vv_rle1, READ(vv_rle1)) {
vv_rle1 < vv_s+1;
vv_rle2 = vv_rle1, READ(vv_rle1)) {
if (nature & Nature::T_VERTEX) { if (nature & Nature::T_VERTEX) {
for (unsigned i = vv_rle2; i < vv_rle1; i++) { for (unsigned int i = vv_rle2; i < vv_rle1; i++) {
TVertex *tv = new TVertex(); TVertex *tv = new TVertex();
vm->AddViewVertex(tv); vm->AddViewVertex(tv);
} }
nature = Nature::NON_T_VERTEX; nature = Nature::NON_T_VERTEX;
} }
else if (nature & Nature::NON_T_VERTEX) { else if (nature & Nature::NON_T_VERTEX) {
for (unsigned i = vv_rle2; i < vv_rle1; i++) { for (unsigned int i = vv_rle2; i < vv_rle1; i++) {
NonTVertex *ntv = new NonTVertex(); NonTVertex *ntv = new NonTVertex();
vm->AddViewVertex(ntv); vm->AddViewVertex(ntv);
} }
@@ -1012,47 +1030,43 @@ namespace ViewMapIO {
} }
} }
for (unsigned i0 = 0; i0 < vs_s; i0++) { for (unsigned int i0 = 0; i0 < vs_s; i0++) {
SShape *ss = new SShape(); SShape *ss = new SShape();
ViewShape *vs = new ViewShape(); ViewShape *vs = new ViewShape();
vs->setSShape(ss); vs->setSShape(ss);
ss->setViewShape(vs); ss->setViewShape(vs);
vm->AddViewShape(vs); vm->AddViewShape(vs);
} }
// for (unsigned i1 = 0; i1 < fe_s; i1++) { #if 0
// FEdge* fe = new FEdge(); for (unsigned int i1 = 0; i1 < fe_s; i1++) {
// vm->AddFEdge(fe); FEdge *fe = new FEdge();
// } vm->AddFEdge(fe);
for (unsigned i2 = 0; i2 < sv_s; i2++) { }
#endif
for (unsigned int i2 = 0; i2 < sv_s; i2++) {
SVertex *sv = new SVertex(); SVertex *sv = new SVertex();
vm->AddSVertex(sv); vm->AddSVertex(sv);
} }
for (unsigned i3 = 0; i3 < ve_s; i3++) { for (unsigned int i3 = 0; i3 < ve_s; i3++) {
ViewEdge *ve = new ViewEdge(); ViewEdge *ve = new ViewEdge();
vm->AddViewEdge(ve); vm->AddViewEdge(ve);
} }
// Read the values for all the objects created above // Read the values for all the objects created above
SET_PROGRESS(1); SET_PROGRESS(1);
for (vector<ViewShape*>::const_iterator i4 = vm->ViewShapes().begin(); for (vector<ViewShape*>::const_iterator i4 = vm->ViewShapes().begin(); i4 != vm->ViewShapes().end(); i4++)
i4 != vm->ViewShapes().end(); i4++)
err += Internal::load(in, *i4); err += Internal::load(in, *i4);
SET_PROGRESS(2); SET_PROGRESS(2);
for (vector<FEdge*>::const_iterator i5 = vm->FEdges().begin(); for (vector<FEdge*>::const_iterator i5 = vm->FEdges().begin(); i5 != vm->FEdges().end(); i5++)
i5 != vm->FEdges().end(); i5++)
err += Internal::load(in, *i5); err += Internal::load(in, *i5);
SET_PROGRESS(3); SET_PROGRESS(3);
for (vector<SVertex*>::const_iterator i6 = vm->SVertices().begin(); for (vector<SVertex*>::const_iterator i6 = vm->SVertices().begin(); i6 != vm->SVertices().end(); i6++)
i6 != vm->SVertices().end(); i6++)
err += Internal::load(in, *i6); err += Internal::load(in, *i6);
SET_PROGRESS(4); SET_PROGRESS(4);
for (vector<ViewEdge*>::const_iterator i7 = vm->ViewEdges().begin(); for (vector<ViewEdge*>::const_iterator i7 = vm->ViewEdges().begin(); i7 != vm->ViewEdges().end(); i7++)
i7 != vm->ViewEdges().end(); i7++)
err += Internal::load(in, *i7); err += Internal::load(in, *i7);
SET_PROGRESS(5); SET_PROGRESS(5);
for (vector<ViewVertex*>::const_iterator i8 = vm->ViewVertices().begin(); for (vector<ViewVertex*>::const_iterator i8 = vm->ViewVertices().begin(); i8 != vm->ViewVertices().end(); i8++)
i8 != vm->ViewVertices().end(); i8++)
err += Internal::load(in, *i8); err += Internal::load(in, *i8);
SET_PROGRESS(6); SET_PROGRESS(6);
@@ -1060,7 +1074,7 @@ namespace ViewMapIO {
unsigned map_s; unsigned map_s;
READ(map_s); READ(map_s);
unsigned id,index; unsigned id,index;
for(unsigned i4=0;i4<map_s;++i4){ for (unsigned int i4 = 0; i4 < map_s; ++i4) {
READ(id); READ(id);
READ(index); READ(index);
vm->shapeIdToIndexMap()[id] = index; vm->shapeIdToIndexMap()[id] = index;
@@ -1070,8 +1084,8 @@ namespace ViewMapIO {
} }
int save(ostream& out, ViewMap* vm, ProgressBar* pb) { int save(ostream& out, ViewMap *vm, ProgressBar *pb)
{
if (!vm) if (!vm)
return 1; return 1;
@@ -1086,17 +1100,17 @@ namespace ViewMapIO {
} }
// For every object, initialize its userdata member to its index in the ViewMap list // For every object, initialize its userdata member to its index in the ViewMap list
for (unsigned i0 = 0; i0 < vm->ViewShapes().size(); i0++) { for (unsigned int i0 = 0; i0 < vm->ViewShapes().size(); i0++) {
vm->ViewShapes()[i0]->userdata = (void *)i0; vm->ViewShapes()[i0]->userdata = (void *)i0;
vm->ViewShapes()[i0]->sshape()->userdata = (void *)i0; vm->ViewShapes()[i0]->sshape()->userdata = (void *)i0;
} }
for (unsigned i1 = 0; i1 < vm->FEdges().size(); i1++) for (unsigned int i1 = 0; i1 < vm->FEdges().size(); i1++)
vm->FEdges()[i1]->userdata = (void *)i1; vm->FEdges()[i1]->userdata = (void *)i1;
for (unsigned i2 = 0; i2 < vm->SVertices().size(); i2++) for (unsigned int i2 = 0; i2 < vm->SVertices().size(); i2++)
vm->SVertices()[i2]->userdata = (void *)i2; vm->SVertices()[i2]->userdata = (void *)i2;
for (unsigned i3 = 0; i3 < vm->ViewEdges().size(); i3++) for (unsigned int i3 = 0; i3 < vm->ViewEdges().size(); i3++)
vm->ViewEdges()[i3]->userdata = (void *)i3; vm->ViewEdges()[i3]->userdata = (void *)i3;
for (unsigned i4 = 0; i4 < vm->ViewVertices().size(); i4++) for (unsigned int i4 = 0; i4 < vm->ViewVertices().size(); i4++)
vm->ViewVertices()[i4]->userdata = (void *)i4; vm->ViewVertices()[i4]->userdata = (void *)i4;
// Write the current options // Write the current options
@@ -1112,7 +1126,7 @@ namespace ViewMapIO {
if (size) { if (size) {
bool b = vm->FEdges()[0]->isSmooth(); bool b = vm->FEdges()[0]->isSmooth();
WRITE(b); WRITE(b);
for (unsigned i = 0; i < size; i++) { for (unsigned int i = 0; i < size; i++) {
while (i < size && (vm->FEdges()[i]->isSmooth() == b)) while (i < size && (vm->FEdges()[i]->isSmooth() == b))
i++; i++;
if (i < size) { if (i < size) {
@@ -1134,7 +1148,7 @@ namespace ViewMapIO {
Nature::VertexNature nature = vm->ViewVertices()[0]->getNature(); Nature::VertexNature nature = vm->ViewVertices()[0]->getNature();
WRITE(nature); WRITE(nature);
nature &= ~Nature::VIEW_VERTEX; nature &= ~Nature::VIEW_VERTEX;
for (unsigned i = 0; i < size; i++) { for (unsigned int i = 0; i < size; i++) {
while (i < size && (vm->ViewVertices()[i]->getNature() & nature)) while (i < size && (vm->ViewVertices()[i]->getNature() & nature))
i++; i++;
if (i < size) { if (i < size) {
@@ -1147,34 +1161,32 @@ namespace ViewMapIO {
WRITE(size); WRITE(size);
} }
// Write all the elts of the ViewShapes List // Write all the elts of the ViewShapes List
SET_PROGRESS(1); SET_PROGRESS(1);
for (vector<ViewShape*>::const_iterator i5 = vm->ViewShapes().begin(); for (vector<ViewShape*>::const_iterator i5 = vm->ViewShapes().begin(); i5 != vm->ViewShapes().end(); i5++)
i5 != vm->ViewShapes().end(); i5++)
err += Internal::save(out, *i5); err += Internal::save(out, *i5);
SET_PROGRESS(2); SET_PROGRESS(2);
for (vector<FEdge*>::const_iterator i6 = vm->FEdges().begin(); for (vector<FEdge*>::const_iterator i6 = vm->FEdges().begin(); i6 != vm->FEdges().end(); i6++)
i6 != vm->FEdges().end(); i6++)
err += Internal::save(out, *i6); err += Internal::save(out, *i6);
SET_PROGRESS(3); SET_PROGRESS(3);
for (vector<SVertex*>::const_iterator i7 = vm->SVertices().begin(); for (vector<SVertex*>::const_iterator i7 = vm->SVertices().begin(); i7 != vm->SVertices().end(); i7++)
i7 != vm->SVertices().end(); i7++)
err += Internal::save(out, *i7); err += Internal::save(out, *i7);
SET_PROGRESS(4); SET_PROGRESS(4);
for (vector<ViewEdge*>::const_iterator i8 = vm->ViewEdges().begin(); for (vector<ViewEdge*>::const_iterator i8 = vm->ViewEdges().begin(); i8 != vm->ViewEdges().end(); i8++)
i8 != vm->ViewEdges().end(); i8++)
err += Internal::save(out, *i8); err += Internal::save(out, *i8);
SET_PROGRESS(5); SET_PROGRESS(5);
for (vector<ViewVertex*>::const_iterator i9 = vm->ViewVertices().begin(); for (vector<ViewVertex*>::const_iterator i9 = vm->ViewVertices().begin(); i9 != vm->ViewVertices().end(); i9++)
i9 != vm->ViewVertices().end(); i9++)
err += Internal::save(out, *i9); err += Internal::save(out, *i9);
// Write the shape id to index mapping // Write the shape id to index mapping
size = vm->shapeIdToIndexMap().size(); size = vm->shapeIdToIndexMap().size();
WRITE(size); WRITE(size);
unsigned id,index; unsigned int id, index;
for(ViewMap::id_to_index_map::iterator mit=vm->shapeIdToIndexMap().begin(), mitend=vm->shapeIdToIndexMap().end(); mit!=mitend; ++mit){ for (ViewMap::id_to_index_map::iterator mit = vm->shapeIdToIndexMap().begin(),
mitend = vm->shapeIdToIndexMap().end();
mit != mitend;
++mit)
{
id = mit->first; id = mit->first;
index = mit->second; index = mit->second;
WRITE(id); WRITE(id);
@@ -1182,23 +1194,18 @@ namespace ViewMapIO {
} }
// Reset 'userdata' members // Reset 'userdata' members
for (vector<ViewShape*>::const_iterator j0 = vm->ViewShapes().begin(); for (vector<ViewShape*>::const_iterator j0 = vm->ViewShapes().begin(); j0 != vm->ViewShapes().end(); j0++) {
j0 != vm->ViewShapes().end(); j0++) { (*j0)->userdata = NULL;
(*j0)->userdata = 0; (*j0)->sshape()->userdata = NULL;
(*j0)->sshape()->userdata = 0;
} }
for (vector<FEdge*>::const_iterator j1 = vm->FEdges().begin(); for (vector<FEdge*>::const_iterator j1 = vm->FEdges().begin(); j1 != vm->FEdges().end(); j1++)
j1 != vm->FEdges().end(); j1++) (*j1)->userdata = NULL;
(*j1)->userdata = 0; for (vector<SVertex*>::const_iterator j2 = vm->SVertices().begin(); j2 != vm->SVertices().end(); j2++)
for (vector<SVertex*>::const_iterator j2 = vm->SVertices().begin(); (*j2)->userdata = NULL;
j2 != vm->SVertices().end(); j2++) for (vector<ViewEdge*>::const_iterator j3 = vm->ViewEdges().begin(); j3 != vm->ViewEdges().end(); j3++)
(*j2)->userdata = 0; (*j3)->userdata = NULL;
for (vector<ViewEdge*>::const_iterator j3 = vm->ViewEdges().begin(); for (vector<ViewVertex*>::const_iterator j4 = vm->ViewVertices().begin(); j4 != vm->ViewVertices().end(); j4++)
j3 != vm->ViewEdges().end(); j3++) (*j4)->userdata = NULL;
(*j3)->userdata = 0;
for (vector<ViewVertex*>::const_iterator j4 = vm->ViewVertices().begin();
j4 != vm->ViewVertices().end(); j4++)
(*j4)->userdata = 0;
SET_PROGRESS(6); SET_PROGRESS(6);
return err; return err;
@@ -1216,30 +1223,36 @@ namespace ViewMapIO {
} // End of namespace Internal } // End of namespace Internal
void setFlags(const unsigned char flags) { void setFlags(const unsigned char flags)
{
Internal::g_flags = flags; Internal::g_flags = flags;
} }
void addFlags(const unsigned char flags) { void addFlags(const unsigned char flags)
{
Internal::g_flags |= flags; Internal::g_flags |= flags;
} }
void rmFlags(const unsigned char flags) { void rmFlags(const unsigned char flags)
{
Internal::g_flags &= ~flags; Internal::g_flags &= ~flags;
} }
unsigned char getFlags() { unsigned char getFlags()
{
return Internal::g_flags; return Internal::g_flags;
} }
void setModelsPath(const string& path) { void setModelsPath(const string& path)
{
Internal::g_models_path = path; Internal::g_models_path = path;
} }
string getModelsPath() { string getModelsPath()
{
return Internal::g_models_path; return Internal::g_models_path;
} }
}; // End of namepace Options } // End of namepace Options
} // End of namespace ViewMapIO } // End of namespace ViewMapIO

View File

@@ -1,38 +1,45 @@
// /*
// Filename : ViewMapIO.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Emmanuel Turquin *
// Purpose : Functions to manage I/O for the view map * This program is free software; you can redistribute it and/or
// Date of creation : 09/01/2003 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Functions to manage I/O for the view map
// * \author Emmanuel Turquin
// This program is free software; you can redistribute it and/or * \date 09/01/2003
// 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 <fstream>
#include <string> #include <string>
#include "ViewMap.h"
#include "../system/FreestyleConfig.h" #include "../system/FreestyleConfig.h"
#include "../system/ProgressBar.h" #include "../system/ProgressBar.h"
@@ -76,34 +83,40 @@ namespace ViewMapIO {
namespace Internal { namespace Internal {
template <unsigned S> template <unsigned S>
ostream& write(ostream& out, const char* str) { ostream& write(ostream& out, const char *str)
{
out.put(str[S - 1]); out.put(str[S - 1]);
return write<S - 1>(out, str); return write<S - 1>(out, str);
} }
template<> template<>
ostream& write<1>(ostream& out, const char* str) { ostream& write<1>(ostream& out, const char *str)
{
return out.put(str[0]); return out.put(str[0]);
} }
template<> template<>
ostream& write<0>(ostream& out, const char*) { ostream& write<0>(ostream& out, const char*)
{
return out; return out;
} }
template <unsigned S> template <unsigned S>
istream& read(istream& in, char* str) { istream& read(istream& in, char *str)
{
in.get(str[S - 1]); in.get(str[S - 1]);
return read<S - 1>(in, str); return read<S - 1>(in, str);
} }
template<> template<>
istream& read<1>(istream& in, char* str) { istream& read<1>(istream& in, char *str)
{
return in.get(str[0]); return in.get(str[0]);
} }
template<> template<>
istream& read<0>(istream& in, char*) { istream& read<0>(istream& in, char*)
{
return in; return in;
} }
@@ -113,4 +126,4 @@ namespace ViewMapIO {
} // End of namespace ViewMapIO } // End of namespace ViewMapIO
#endif // VIEWMAPIO_H #endif // __FREESTYLE_VIEW_MAP_IO_H__

View File

@@ -1,37 +1,42 @@
// /*
// Filename : ViewMapIterators.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Iterators used to iterate over the various elements * This program is free software; you can redistribute it and/or
// of the ViewMap * modify it under the terms of the GNU General Public License
// Date of creation : 01/07/2003 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Iterators used to iterate over the various elements of the ViewMap
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 01/07/2003
// 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 VIEWMAPITERATORS_H
# define VIEWMAPITERATORS_H
#include "ViewMap.h" #include "ViewMap.h"
#include "../system/Iterator.h" //soc #include "../system/Iterator.h" //soc
@@ -53,11 +58,10 @@
namespace ViewVertexInternal { namespace ViewVertexInternal {
/*! Class representing an iterator over oriented ViewEdges /*! Class representing an iterator over oriented ViewEdges around a ViewVertex. This iterator allows a CCW iteration
* around a ViewVertex. This iterator allows a CCW iteration
* (in the image plane). * (in the image plane).
* An instance of an orientedViewEdgeIterator can only * An instance of an orientedViewEdgeIterator can only be obtained from a ViewVertex by calling edgesBegin()
* be obtained from a ViewVertex by calling edgesBegin() or edgesEnd(). * or edgesEnd().
*/ */
class orientedViewEdgeIterator : public Iterator class orientedViewEdgeIterator : public Iterator
{ {
@@ -70,8 +74,8 @@ namespace ViewVertexInternal{
// FIXME // FIXME
typedef ::TVertex::edge_pointers_container edge_pointers_container; typedef ::TVertex::edge_pointers_container edge_pointers_container;
typedef ::NonTVertex::edges_container edges_container; typedef ::NonTVertex::edges_container edges_container;
protected:
protected:
Nature::VertexNature _Nature; // the nature of the underlying vertex Nature::VertexNature _Nature; // the nature of the underlying vertex
// T vertex attributes // T vertex attributes
edge_pointers_container::iterator _tbegin; edge_pointers_container::iterator _tbegin;
@@ -86,30 +90,32 @@ namespace ViewVertexInternal{
public: public:
/*! Default constructor */ /*! Default constructor */
inline orientedViewEdgeIterator() {} inline orientedViewEdgeIterator() {}
inline orientedViewEdgeIterator(Nature::VertexNature iNature) inline orientedViewEdgeIterator(Nature::VertexNature iNature)
{_Nature = iNature;} {
_Nature = iNature;
}
/*! Copy constructor */ /*! Copy constructor */
orientedViewEdgeIterator(const orientedViewEdgeIterator& iBrother) orientedViewEdgeIterator(const orientedViewEdgeIterator& iBrother)
{ {
_Nature = iBrother._Nature; _Nature = iBrother._Nature;
if(_Nature & Nature::T_VERTEX) if (_Nature & Nature::T_VERTEX) {
{
_tbegin = iBrother._tbegin; _tbegin = iBrother._tbegin;
_tend = iBrother._tend; _tend = iBrother._tend;
_tvertex_iter = iBrother._tvertex_iter; _tvertex_iter = iBrother._tvertex_iter;
} }
else else {
{
_begin = iBrother._begin; _begin = iBrother._begin;
_end = iBrother._end; _end = iBrother._end;
_nontvertex_iter = iBrother._nontvertex_iter; _nontvertex_iter = iBrother._nontvertex_iter;
} }
} }
virtual ~orientedViewEdgeIterator() {} virtual ~orientedViewEdgeIterator() {}
public: public:
inline orientedViewEdgeIterator(edge_pointers_container::iterator begin, inline orientedViewEdgeIterator(edge_pointers_container::iterator begin, edge_pointers_container::iterator end,
edge_pointers_container::iterator end,
edge_pointers_container::iterator iter) edge_pointers_container::iterator iter)
{ {
_Nature = Nature::T_VERTEX; _Nature = Nature::T_VERTEX;
@@ -117,8 +123,8 @@ namespace ViewVertexInternal{
_tend = end; _tend = end;
_tvertex_iter = iter; _tvertex_iter = iter;
} }
inline orientedViewEdgeIterator(edges_container::iterator begin,
edges_container::iterator end, inline orientedViewEdgeIterator(edges_container::iterator begin, edges_container::iterator end,
edges_container::iterator iter) edges_container::iterator iter)
{ {
_Nature = Nature::NON_T_VERTEX; _Nature = Nature::NON_T_VERTEX;
@@ -128,12 +134,7 @@ namespace ViewVertexInternal{
} }
public: public:
/*! Tells whether the ViewEdge pointed by this iterator is the first one of the iteration list or not. */
/*! Tells whether the ViewEdge pointed
* by this iterator is the first one of the
* iteration list or not.
*/
virtual bool isBegin() const virtual bool isBegin() const
{ {
if (_Nature & Nature::T_VERTEX) if (_Nature & Nature::T_VERTEX)
@@ -141,10 +142,8 @@ namespace ViewVertexInternal{
else else
return (_nontvertex_iter == _begin); return (_nontvertex_iter == _begin);
} }
/*! Tells whether the ViewEdge pointed
* by this iterator is after the last one of the /*! Tells whether the ViewEdge pointed by this iterator is after the last one of the iteration list or not. */
* iteration list or not.
*/
virtual bool isEnd() const virtual bool isEnd() const
{ {
if (_Nature & Nature::T_VERTEX) if (_Nature & Nature::T_VERTEX)
@@ -154,21 +153,20 @@ namespace ViewVertexInternal{
} }
// operators // operators
/*! Increments.In the scripting language, call /*! Increments. In the scripting language, call "increment()". */
* "increment()". // operator corresponding to ++i
*/ virtual orientedViewEdgeIterator& operator++()
virtual orientedViewEdgeIterator& operator++() // operator corresponding to ++i
{ {
increment(); increment();
return *this; return *this;
} }
/*! Increments.In the scripting language, call
* "increment()". // 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) // opérateur correspondant à i++ virtual orientedViewEdgeIterator operator++(int)
{ // c.a.d qui renvoie la valeur *puis* incrémente. {
orientedViewEdgeIterator tmp = *this; // C'est pour cela qu'on stocke la valeur orientedViewEdgeIterator tmp = *this;
increment(); // dans un temporaire. increment();
return tmp; return tmp;
} }
@@ -184,12 +182,13 @@ namespace ViewVertexInternal{
/*! operator == */ /*! operator == */
virtual bool operator==(const orientedViewEdgeIterator& b) const virtual bool operator==(const orientedViewEdgeIterator& b) const
{return !(*this != b);} {
return !(*this != b);
}
// dereferencing // dereferencing
/*! Returns a reference to the pointed orientedViewEdge. /*! Returns a reference to the pointed orientedViewEdge.
* In the scripting language, you must call * In the scripting language, you must call "getObject()" instead.
* "getObject()"instead.
*/ */
virtual ::ViewVertex::directedViewEdge& operator*() const virtual ::ViewVertex::directedViewEdge& operator*() const
{ {
@@ -202,14 +201,16 @@ namespace ViewVertexInternal{
/*! Returns a pointer to the pointed orientedViewEdge. /*! Returns a pointer to the pointed orientedViewEdge.
* Can't be called in the scripting language. * Can't be called in the scripting language.
*/ */
virtual ::ViewVertex::directedViewEdge* operator->() const { return &(operator*());} virtual ::ViewVertex::directedViewEdge *operator->() const
{
return &(operator*());
}
public: public:
/*! increments.*/ /*! increments.*/
virtual inline int increment() virtual inline int increment()
{ {
if(_Nature & Nature::T_VERTEX) if (_Nature & Nature::T_VERTEX) {
{
::ViewVertex::directedViewEdge tmp = (**_tvertex_iter); ::ViewVertex::directedViewEdge tmp = (**_tvertex_iter);
++_tvertex_iter; ++_tvertex_iter;
if (_tvertex_iter != _tend) { if (_tvertex_iter != _tend) {
@@ -219,13 +220,15 @@ namespace ViewVertexInternal{
++_tvertex_iter; ++_tvertex_iter;
} }
} }
else else {
++_nontvertex_iter; ++_nontvertex_iter;
}
return 0; return 0;
} }
}; };
} } // ViewVertexInternal namespace
/**********************************/ /**********************************/
/* */ /* */
/* */ /* */
@@ -235,6 +238,7 @@ namespace ViewVertexInternal{
/**********************************/ /**********************************/
namespace ViewEdgeInternal { namespace ViewEdgeInternal {
// //
// SVertexIterator // SVertexIterator
// //
@@ -243,8 +247,8 @@ namespace ViewEdgeInternal {
class SVertexIterator : public Interface0DIteratorNested class SVertexIterator : public Interface0DIteratorNested
{ {
public: public:
SVertexIterator()
SVertexIterator() { {
_vertex = NULL; _vertex = NULL;
_begin = NULL; _begin = NULL;
_previous_edge = NULL; _previous_edge = NULL;
@@ -252,7 +256,8 @@ namespace ViewEdgeInternal {
_t = 0; _t = 0;
} }
SVertexIterator(const SVertexIterator& vi) { SVertexIterator(const SVertexIterator& vi)
{
_vertex = vi._vertex; _vertex = vi._vertex;
_begin = vi._begin; _begin = vi._begin;
_previous_edge = vi._previous_edge; _previous_edge = vi._previous_edge;
@@ -260,7 +265,8 @@ namespace ViewEdgeInternal {
_t = vi._t; _t = vi._t;
} }
SVertexIterator(SVertex* v, SVertex* begin, FEdge* prev, FEdge* next, float t) { SVertexIterator(SVertex *v, SVertex *begin, FEdge *prev, FEdge *next, float t)
{
_vertex = v; _vertex = v;
_begin = begin; _begin = begin;
_previous_edge = prev; _previous_edge = prev;
@@ -268,7 +274,8 @@ namespace ViewEdgeInternal {
_t = t; _t = t;
} }
SVertexIterator& operator=(const SVertexIterator& vi) { SVertexIterator& operator=(const SVertexIterator& vi)
{
_vertex = vi._vertex; _vertex = vi._vertex;
_begin = vi._begin; _begin = vi._begin;
_previous_edge = vi._previous_edge; _previous_edge = vi._previous_edge;
@@ -279,43 +286,51 @@ namespace ViewEdgeInternal {
virtual ~SVertexIterator() {} virtual ~SVertexIterator() {}
virtual string getExactTypeName() const { virtual string getExactTypeName() const
{
return "SVertexIterator"; return "SVertexIterator";
} }
virtual SVertex& operator*() { virtual SVertex& operator*()
{
return *_vertex; return *_vertex;
} }
virtual SVertex* operator->() { virtual SVertex *operator->()
{
return &(operator*()); return &(operator*());
} }
virtual SVertexIterator& operator++() { virtual SVertexIterator& operator++()
{
increment(); increment();
return *this; return *this;
} }
virtual SVertexIterator operator++(int) { virtual SVertexIterator operator++(int)
{
SVertexIterator ret(*this); SVertexIterator ret(*this);
increment(); increment();
return ret; return ret;
} }
virtual SVertexIterator& operator--() { virtual SVertexIterator& operator--()
{
decrement(); decrement();
return *this; return *this;
} }
virtual SVertexIterator operator--(int) { virtual SVertexIterator operator--(int)
{
SVertexIterator ret(*this); SVertexIterator ret(*this);
decrement(); decrement();
return ret; return ret;
} }
virtual int increment(){ virtual int increment()
{
if (!_next_edge) { if (!_next_edge) {
_vertex = 0; _vertex = NULL;
return 0; return 0;
} }
_t += (float)_next_edge->getLength2D(); _t += (float)_next_edge->getLength2D();
@@ -323,11 +338,12 @@ namespace ViewEdgeInternal {
_previous_edge = _next_edge; _previous_edge = _next_edge;
_next_edge = _next_edge->nextEdge(); _next_edge = _next_edge->nextEdge();
return 0; return 0;
} }
virtual int decrement(){
virtual int decrement()
{
if (!_previous_edge) { if (!_previous_edge) {
_vertex = 0; _vertex = NULL;
return 0; return 0;
} }
if ((!_next_edge) && (!_vertex)) { if ((!_next_edge) && (!_vertex)) {
@@ -341,34 +357,40 @@ namespace ViewEdgeInternal {
return 0; return 0;
} }
virtual bool isBegin() const { virtual bool isBegin() const
{
return _vertex == _begin; return _vertex == _begin;
} }
virtual bool isEnd() const { virtual bool isEnd() const
{
return (!_vertex) || (_vertex == _begin && _previous_edge); return (!_vertex) || (_vertex == _begin && _previous_edge);
} }
virtual float t() const { virtual float t() const
{
return _t; return _t;
} }
virtual float u() const {
virtual float u() const
{
return _t / (float)_next_edge->viewedge()->getLength2D(); return _t / (float)_next_edge->viewedge()->getLength2D();
} }
virtual bool operator==(const Interface0DIteratorNested& it) const { virtual bool operator==(const Interface0DIteratorNested& it) const
{
const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator*>(&it); const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator*>(&it);
if (!it_exact) if (!it_exact)
return false; return false;
return (_vertex == it_exact->_vertex); return (_vertex == it_exact->_vertex);
} }
virtual SVertexIterator* copy() const { virtual SVertexIterator *copy() const
{
return new SVertexIterator(*this); return new SVertexIterator(*this);
} }
private: private:
SVertex *_vertex; SVertex *_vertex;
SVertex *_begin; SVertex *_begin;
FEdge *_previous_edge; FEdge *_previous_edge;
@@ -377,40 +399,36 @@ namespace ViewEdgeInternal {
}; };
// //
// ViewEdgeIterator (base class) // ViewEdgeIterator (base class)
// //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
/*! Base class for iterators over ViewEdges of the ViewMap Graph. /*! Base class for iterators over ViewEdges of the ViewMap Graph.
* Basically the "increment()" operator of this class should * Basically the "increment()" operator of this class should be able to take the decision of "where" (on which
* be able to take the decision of "where" (on which ViewEdge) to go * ViewEdge) to go when pointing on a given ViewEdge.
* when pointing on a given ViewEdge. * ::Caution::: the dereferencing operator returns a *pointer* to the pointed ViewEdge.
* ::Caution::: the dereferencing operator returns a *pointer* to
* the pointed ViewEdge.
*/ */
class ViewEdgeIterator : public Iterator class ViewEdgeIterator : public Iterator
{ {
public: public:
/*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation. /*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation.
* \param begin * \param begin
* The ViewEdge from where to start the iteration. * The ViewEdge from where to start the iteration.
* \param orientation * \param orientation
* If true, we'll look for the next ViewEdge among the * If true, we'll look for the next ViewEdge among the ViewEdges that surround the ending ViewVertex of begin.
* ViewEdges that surround the ending ViewVertex of begin. * If false, we'll search over the ViewEdges surrounding 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) { ViewEdgeIterator(ViewEdge *begin = NULL, bool orientation = true)
{
_orientation = orientation; _orientation = orientation;
_edge = begin; _edge = begin;
_begin = begin; _begin = begin;
} }
/*! Copy constructor */ /*! Copy constructor */
ViewEdgeIterator(const ViewEdgeIterator& it) { ViewEdgeIterator(const ViewEdgeIterator& it)
{
_orientation = it._orientation; _orientation = it._orientation;
_edge = it._edge; _edge = it._edge;
_begin = it._begin; _begin = it._begin;
@@ -419,125 +437,133 @@ public:
virtual ~ViewEdgeIterator() {} virtual ~ViewEdgeIterator() {}
/*! Returns the string "ViewEdgeIterator" */ /*! Returns the string "ViewEdgeIterator" */
virtual string getExactTypeName() const { virtual string getExactTypeName() const
{
return "ViewEdgeIterator"; return "ViewEdgeIterator";
} }
/*! Returns the current pointed ViewEdge. */ /*! Returns the current pointed ViewEdge. */
ViewEdge* getCurrentEdge() { ViewEdge *getCurrentEdge()
{
return _edge; return _edge;
} }
/*! Sets the current pointed ViewEdge. */ /*! Sets the current pointed ViewEdge. */
void setCurrentEdge(ViewEdge* edge) { void setCurrentEdge(ViewEdge *edge)
{
_edge = edge; _edge = edge;
} }
/*! Returns the first ViewEdge used for the iteration. */ /*! Returns the first ViewEdge used for the iteration. */
ViewEdge* getBegin() { ViewEdge *getBegin()
{
return _begin; return _begin;
} }
/*! Sets the first ViewEdge used for the iteration. */ /*! Sets the first ViewEdge used for the iteration. */
void setBegin(ViewEdge* begin) { void setBegin(ViewEdge *begin)
{
_begin = begin; _begin = begin;
} }
/*! Gets the orientation of the pointed ViewEdge in the iteration. */ /*! Gets the orientation of the pointed ViewEdge in the iteration. */
bool getOrientation() const { bool getOrientation() const
{
return _orientation; return _orientation;
} }
/*! Sets the orientation of the pointed ViewEdge in the iteration. */ /*! Sets the orientation of the pointed ViewEdge in the iteration. */
void setOrientation(bool orientation) { void setOrientation(bool orientation)
{
_orientation = orientation; _orientation = orientation;
} }
/*! Changes the current orientation. */ /*! Changes the current orientation. */
void changeOrientation() { void changeOrientation()
{
_orientation = !_orientation; _orientation = !_orientation;
} }
/*! Returns a *pointer* to the pointed ViewEdge. */ /*! Returns a *pointer* to the pointed ViewEdge. */
virtual ViewEdge* operator*() { virtual ViewEdge *operator*()
{
return _edge; return _edge;
} }
virtual ViewEdge* operator->() { virtual ViewEdge *operator->()
{
return operator*(); return operator*();
} }
/*! Increments. In the scripting language, call /*! Increments. In the scripting language, call "increment()". */
* "increment()". virtual ViewEdgeIterator& operator++()
*/ {
virtual ViewEdgeIterator& operator++() {
increment(); increment();
return *this; return *this;
} }
/*! Increments. In the scripting language, call /*! Increments. In the scripting language, call "increment()". */
* "increment()". virtual ViewEdgeIterator operator++(int)
*/ {
virtual ViewEdgeIterator operator++(int) {
ViewEdgeIterator tmp(*this); ViewEdgeIterator tmp(*this);
increment(); increment();
return tmp; return tmp;
} }
/*! increments. */ /*! increments. */
virtual int increment() { virtual int increment()
{
cerr << "Warning: method increment() not implemented" << endl; cerr << "Warning: method increment() not implemented" << endl;
return 0; return 0;
} }
/*! Decrements. In the scripting language, call /*! Decrements. In the scripting language, call "decrement()". */
* "decrement()". virtual ViewEdgeIterator& operator--()
*/ {
virtual ViewEdgeIterator& operator--() {
decrement(); decrement();
return *this; return *this;
} }
/*! Decrements. In the scripting language, call /*! Decrements. In the scripting language, call "decrement()". */
* "decrement()". virtual ViewEdgeIterator operator--(int)
*/ {
virtual ViewEdgeIterator operator--(int) {
ViewEdgeIterator tmp(*this); ViewEdgeIterator tmp(*this);
decrement(); decrement();
return tmp; return tmp;
} }
/*! decrements. */ /*! decrements. */
virtual int decrement(){ virtual int decrement()
{
cerr << "Warning: method decrement() not implemented" << endl; cerr << "Warning: method decrement() not implemented" << endl;
return 0; return 0;
} }
/*! Returns true if the pointed ViewEdge is the /*! Returns true if the pointed ViewEdge is the first one used for the iteration. */
* first one used for the iteration. virtual bool isBegin() const
*/ {
virtual bool isBegin() const {
return _edge == _begin; return _edge == _begin;
} }
/*! Returns true if the pointed ViewEdge* equals 0. /*! Returns true if the pointed ViewEdge* equals 0. */
*/ virtual bool isEnd() const
virtual bool isEnd() const { {
return !_edge; return !_edge;
} }
/*! operator == */ /*! operator == */
virtual bool operator==(ViewEdgeIterator& it) const { virtual bool operator==(ViewEdgeIterator& it) const
{
return _edge == it._edge; return _edge == it._edge;
} }
/*! operator != */ /*! operator != */
virtual bool operator!=(ViewEdgeIterator& it) const { virtual bool operator!=(ViewEdgeIterator& it) const
{
return !(*this == it); return !(*this == it);
} }
protected: protected:
bool _orientation; bool _orientation;
ViewEdge *_edge; ViewEdge *_edge;
ViewEdge *_begin; ViewEdge *_begin;
@@ -545,5 +571,4 @@ protected:
} // end of namespace ViewEdgeInternal } // end of namespace ViewEdgeInternal
#endif // VIEWMAPITERATORS_H #endif // __FREESTYLE_VIEW_MAP_ITERATORS_H__

View File

@@ -1,23 +1,36 @@
/*
* ***** 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/ViewMapTesselator.cpp
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 26/03/2002
// 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 "ViewMapTesselator.h" #include "ViewMapTesselator.h"

View File

@@ -1,45 +1,51 @@
// /*
// Filename : ViewMapTesselator.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Class to build a Node Tree designed to be displayed * This program is free software; you can redistribute it and/or
// from a Silhouette View Map structure. * modify it under the terms of the GNU General Public License
// Date of creation : 26/03/2002 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 26/03/2002
// 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 "Silhouette.h"
#include "ViewMap.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/LineRep.h"
#include "../scene_graph/NodeShape.h"
#include "../scene_graph/NodeGroup.h"
#include "../scene_graph/OrientedLineRep.h" #include "../scene_graph/OrientedLineRep.h"
#include "../scene_graph/VertexRep.h" #include "../scene_graph/VertexRep.h"
#include "../winged_edge/WEdge.h"
class NodeShape; class NodeShape;
class NodeGroup; class NodeGroup;
class SShape; class SShape;
@@ -48,32 +54,47 @@ class WShape;
class LIB_VIEW_MAP_EXPORT ViewMapTesselator class LIB_VIEW_MAP_EXPORT ViewMapTesselator
{ {
public: public:
inline ViewMapTesselator()
{
_nature = Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE;
_FrsMaterial.setDiffuse(0, 0, 0, 1);
_overloadFrsMaterial = false;
}
inline ViewMapTesselator() {_nature = Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE;_FrsMaterial.setDiffuse(0,0,0,1);_overloadFrsMaterial=false;}
virtual ~ViewMapTesselator() {} virtual ~ViewMapTesselator() {}
/*! Builds a set of lines rep contained under a /*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a ViewMap */
* a NodeShape, itself contained under a NodeGroup from a ViewMap
*/
NodeGroup *Tesselate(ViewMap *iViewMap); NodeGroup *Tesselate(ViewMap *iViewMap);
/*! Builds a set of lines rep contained under a /*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a set of
* a NodeShape, itself contained under a NodeGroup from a * view edges
* set of view edges
*/ */
template<class ViewEdgesIterator> template<class ViewEdgesIterator>
NodeGroup *Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end); NodeGroup *Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end);
/*! Builds a set of lines rep contained among a /*! Builds a set of lines rep contained among a NodeShape, from a WShape */
* a NodeShape, from a WShape
*/
NodeGroup *Tesselate(WShape *iWShape); NodeGroup *Tesselate(WShape *iWShape);
inline void setNature(Nature::EdgeNature iNature)
{
_nature = iNature;
}
inline void setNature(Nature::EdgeNature iNature) {_nature = iNature;} inline void setFrsMaterial(const FrsMaterial& iMaterial)
inline void setFrsMaterial(const FrsMaterial& iMaterial) {_FrsMaterial=iMaterial;_overloadFrsMaterial=true;} {
inline Nature::EdgeNature nature() {return _nature;} _FrsMaterial = iMaterial;
inline const FrsMaterial& frs_material() const {return _FrsMaterial;} _overloadFrsMaterial = true;
}
inline Nature::EdgeNature nature()
{
return _nature;
}
inline const FrsMaterial& frs_material() const
{
return _FrsMaterial;
}
protected: protected:
virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0; virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
@@ -123,56 +144,51 @@ NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesItera
NodeGroup *group = new NodeGroup; NodeGroup *group = new NodeGroup;
NodeShape *tshape = new NodeShape; NodeShape *tshape = new NodeShape;
group->AddChild(tshape); group->AddChild(tshape);
//tshape->frs_material().setDiffuse(0.f, 0.f, 0.f, 1.f); //tshape->frs_material().setDiffuse(0.0f, 0.0f, 0.0f, 1.0f);
tshape->setFrsMaterial(_FrsMaterial); tshape->setFrsMaterial(_FrsMaterial);
LineRep *line; LineRep *line;
FEdge *firstEdge; FEdge *firstEdge;
FEdge *nextFEdge, *currentEdge; FEdge *nextFEdge, *currentEdge;
int id = 0; int id = 0;
// for(vector<ViewEdge*>::const_iterator c=viewedges.begin(),cend=viewedges.end(); //for (vector<ViewEdge*>::const_iterator c = viewedges.begin(), cend = viewedges.end(); c != cend; c++)
// c!=cend; for (ViewEdgesIterator c = begin, cend = end; c != cend; c++) {
// c++) #if 0
for(ViewEdgesIterator c=begin, cend=end; if ((*c)->qi() > 0) {
c!=cend; continue;
c++) }
{ if (!((*c)->nature() & (_nature))) {
// if((*c)->qi() > 0){ continue;
// continue; }
// } #endif
// if(!((*c)->nature() & (_nature)))
// continue;
//
firstEdge = (*c)->fedgeA(); firstEdge = (*c)->fedgeA();
// if(firstEdge->invisibility() > 0) #if 0
// continue; if (firstEdge->invisibility() > 0)
continue;
#endif
line = new OrientedLineRep(); line = new OrientedLineRep();
if (_overloadFrsMaterial) if (_overloadFrsMaterial)
line->setFrsMaterial(_FrsMaterial); line->setFrsMaterial(_FrsMaterial);
// there might be chains containing a single element // there might be chains containing a single element
if(0 == (firstEdge)->nextEdge()) if (0 == (firstEdge)->nextEdge()) {
{
line->setStyle(LineRep::LINES); line->setStyle(LineRep::LINES);
//line->AddVertex((*c)->vertexA()->point3D()); //line->AddVertex((*c)->vertexA()->point3D());
//line->AddVertex((*c)->vertexB()->point3D()); //line->AddVertex((*c)->vertexB()->point3D());
AddVertexToLine(line, firstEdge->vertexA()); AddVertexToLine(line, firstEdge->vertexA());
AddVertexToLine(line, firstEdge->vertexB()); AddVertexToLine(line, firstEdge->vertexB());
} }
else else {
{
line->setStyle(LineRep::LINE_STRIP); line->setStyle(LineRep::LINE_STRIP);
//firstEdge = (*c); //firstEdge = (*c);
nextFEdge = firstEdge; nextFEdge = firstEdge;
currentEdge = firstEdge; currentEdge = firstEdge;
do do {
{
//line->AddVertex(nextFEdge->vertexA()->point3D()); //line->AddVertex(nextFEdge->vertexA()->point3D());
AddVertexToLine(line, nextFEdge->vertexA()); AddVertexToLine(line, nextFEdge->vertexA());
currentEdge = nextFEdge; currentEdge = nextFEdge;
@@ -181,7 +197,6 @@ NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesItera
// Add the last vertex // Add the last vertex
//line->AddVertex(currentEdge->vertexB()->point3D()); //line->AddVertex(currentEdge->vertexB()->point3D());
AddVertexToLine(line, currentEdge->vertexB()); AddVertexToLine(line, currentEdge->vertexB());
} }
line->setId((*c)->getId().getFirst()); line->setId((*c)->getId().getFirst());
@@ -193,4 +208,4 @@ NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesItera
return group; return group;
} }
#endif // VIEWMAPTESSELATOR_H #endif // __FREESTYLE_VIEW_MAP_TESSELATOR_H__

View File

@@ -1,32 +1,64 @@
/* 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU General Public License
* License as published by the Free Software Foundation; either * as published by the Free Software Foundation; either version 2
* version 2 of the License, or (at your option) any later version. * 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 * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Library General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU Library General Public * You should have received a copy of the GNU General Public License
* License along with this library; if not, write to the * along with this program; if not, write to the Free Software Foundation,
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Boston, MA 02111-1307, 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 <cstdlib> // for malloc and free
#include "Curvature.h"
#include <math.h>
#include <assert.h> #include <assert.h>
#include "WEdge.h" #include <cstdlib> // for malloc and free
#include "../system/FreestyleConfig.h" #include <math.h>
#include "../geometry/normal_cycle.h"
#include <set> #include <set>
#include <stack> #include <stack>
#include "Curvature.h"
#include "WEdge.h"
#include "../geometry/normal_cycle.h"
#include "../system/FreestyleConfig.h"
static bool angle_obtuse(WVertex *v, WFace *f) static bool angle_obtuse(WVertex *v, WFace *f)
{ {
WOEdge *e; WOEdge *e;
@@ -43,8 +75,7 @@ static bool triangle_obtuse (WVertex*, WFace * f)
{ {
bool b = false; bool b = false;
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
b = b || b = b || ((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i + 1) % 3]->GetVec()) < 0);
((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i+1)%3]->GetVec()) < 0);
return b; return b;
} }
@@ -59,10 +90,9 @@ static real cotan (WVertex * vo, WVertex * v1, WVertex * v2)
udotv = u * v; udotv = u * v;
denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv); denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
/* denom can be zero if u==v. Returning 0 is acceptable, based on /* denom can be zero if u==v. Returning 0 is acceptable, based on the callers of this function below. */
* the callers of this function below. */ if (denom == 0.0)
if (denom == 0.0) return (0.0); return 0.0;
return (udotv / denom); return (udotv / denom);
} }
@@ -83,8 +113,7 @@ static real angle_from_cotan (WVertex * vo, WVertex * v1, WVertex * v2)
return (fabs(atan2(denom, udotv))); return (fabs(atan2(denom, udotv)));
} }
/** /*! gts_vertex_mean_curvature_normal:
* gts_vertex_mean_curvature_normal:
* @v: a #WVertex. * @v: a #WVertex.
* @s: a #GtsSurface. * @s: a #GtsSurface.
* @Kh: the Mean Curvature Normal at @v. * @Kh: the Mean Curvature Normal at @v.
@@ -92,10 +121,9 @@ static real angle_from_cotan (WVertex * vo, WVertex * v1, WVertex * v2)
* Computes the Discrete Mean Curvature Normal approximation at @v. * Computes the Discrete Mean Curvature Normal approximation at @v.
* The mean curvature at @v is half the magnitude of the vector @Kh. * 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 * Note: the normal computed is not unit length, and may point either into or out of the surface, depending on
* into or out of the surface, depending on the curvature at @v. It * the curvature at @v. It is the responsibility of the caller of the function to use the mean curvature normal
* is the responsibility of the caller of the function to use the mean * appropriately.
* curvature normal appropriately.
* *
* This approximation is from the paper: * This approximation is from the paper:
* Discrete Differential-Geometry Operators for Triangulated 2-Manifolds * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds
@@ -103,33 +131,33 @@ static real angle_from_cotan (WVertex * vo, WVertex * v1, WVertex * v2)
* VisMath '02, Berlin (Germany) * VisMath '02, Berlin (Germany)
* http://www-grail.usc.edu/pubs.html * http://www-grail.usc.edu/pubs.html
* *
* Returns: %TRUE if the operator could be evaluated, %FALSE if the * Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is
* evaluation failed for some reason (@v is boundary or is the * boundary or is the endpoint of a non-manifold edge.)
* 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; real area = 0.0;
if (!v) return false; if (!v)
return false;
/* this operator is not defined for boundary edges */ /* this operator is not defined for boundary edges */
if (v->isBoundary()) return false; if (v->isBoundary())
return false;
WVertex::incoming_edge_iterator itE; WVertex::incoming_edge_iterator itE;
for (itE=v->incoming_edges_begin(); for (itE=v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
itE!=v->incoming_edges_end(); itE++)
area += (*itE)->GetaFace()->getArea(); area += (*itE)->GetaFace()->getArea();
Kh = Vec3r(0.0, 0.0, 0.0); Kh = Vec3r(0.0, 0.0, 0.0);
for (itE=v->incoming_edges_begin(); for (itE=v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
itE!=v->incoming_edges_end(); itE++)
{
WOEdge *e = (*itE)->getPrevOnFace(); WOEdge *e = (*itE)->getPrevOnFace();
//if ((e->GetaVertex()==v) || (e->GetbVertex()==v)) cerr<< "BUG "; #if 0
if ((e->GetaVertex() == v) || (e->GetbVertex() == v))
cerr<< "BUG ";
#endif
WVertex *v1 = e->GetaVertex(); WVertex *v1 = e->GetaVertex();
WVertex *v2 = e->GetbVertex(); WVertex *v2 = e->GetbVertex();
real temp; real temp;
@@ -140,19 +168,19 @@ bool gts_vertex_mean_curvature_normal (WVertex * v, Vec3r &Kh)
temp = cotan(v2, v, v1); temp = cotan(v2, v, v1);
Kh = Vec3r(Kh + temp * (v1->GetVertex() - v->GetVertex())); Kh = Vec3r(Kh + temp * (v1->GetVertex() - v->GetVertex()));
} }
if (area > 0.0) if (area > 0.0) {
{
Kh[0] /= 2 * area; Kh[0] /= 2 * area;
Kh[1] /= 2 * area; Kh[1] /= 2 * area;
Kh[2] /= 2 * area; Kh[2] /= 2 * area;
} }
else return false; else {
return false;
}
return true; return true;
} }
/** /*! gts_vertex_gaussian_curvature:
* gts_vertex_gaussian_curvature:
* @v: a #WVertex. * @v: a #WVertex.
* @s: a #GtsSurface. * @s: a #GtsSurface.
* @Kg: the Discrete Gaussian Curvature approximation at @v. * @Kg: the Discrete Gaussian Curvature approximation at @v.
@@ -165,29 +193,30 @@ bool gts_vertex_mean_curvature_normal (WVertex * v, Vec3r &Kh)
* VisMath '02, Berlin (Germany) * VisMath '02, Berlin (Germany)
* http://www-grail.usc.edu/pubs.html * http://www-grail.usc.edu/pubs.html
* *
* Returns: %TRUE if the operator could be evaluated, %FALSE if the * Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is
* evaluation failed for some reason (@v is boundary or is the * boundary or is the endpoint of a non-manifold edge.)
* 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 area = 0.0;
real angle_sum = 0.0; real angle_sum = 0.0;
if (!v) return false; if (!v)
if (!Kg) return false; return false;
if (!Kg)
return false;
/* this operator is not defined for boundary edges */ /* this operator is not defined for boundary edges */
if (v->isBoundary()) {*Kg=0.0 ;return false;} if (v->isBoundary()) {
*Kg = 0.0;
return false;
}
WVertex::incoming_edge_iterator itE; WVertex::incoming_edge_iterator itE;
for (itE=v->incoming_edges_begin(); for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
itE!=v->incoming_edges_end(); itE++)
area += (*itE)->GetaFace()->getArea(); area += (*itE)->GetaFace()->getArea();
for (itE=v->incoming_edges_begin(); for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
itE!=v->incoming_edges_end(); itE++)
{
WOEdge *e = (*itE)->getPrevOnFace(); WOEdge *e = (*itE)->getPrevOnFace();
WVertex *v1 = e->GetaVertex(); WVertex *v1 = e->GetaVertex();
WVertex *v2 = e->GetbVertex(); WVertex *v2 = e->GetbVertex();
@@ -199,40 +228,35 @@ bool gts_vertex_gaussian_curvature (WVertex * v, real * Kg)
return true; return true;
} }
/** /*! gts_vertex_principal_curvatures:
* gts_vertex_principal_curvatures:
* @Kh: mean curvature. * @Kh: mean curvature.
* @Kg: Gaussian curvature. * @Kg: Gaussian curvature.
* @K1: first principal curvature. * @K1: first principal curvature.
* @K2: second principal curvature. * @K2: second principal curvature.
* *
* Computes the principal curvatures at a point given the mean and * Computes the principal curvatures at a point given the mean and Gaussian curvatures at that point.
* Gaussian curvatures at that point.
* *
* The mean curvature can be computed as one-half the magnitude of the * The mean curvature can be computed as one-half the magnitude of the vector computed by
* vector computed by gts_vertex_mean_curvature_normal(). * gts_vertex_mean_curvature_normal().
* *
* The Gaussian curvature can be computed with * The Gaussian curvature can be computed with gts_vertex_gaussian_curvature().
* gts_vertex_gaussian_curvature().
*/ */
void gts_vertex_principal_curvatures (real Kh, real Kg, void gts_vertex_principal_curvatures (real Kh, real Kg, real *K1, real *K2)
real * K1, real * K2)
{ {
real temp = Kh * Kh - Kg; real temp = Kh * Kh - Kg;
if (!K1) return; if (!K1 || !K2)
if (!K1) return; return;
if (temp < 0.0) temp = 0.0; if (temp < 0.0)
temp = 0.0;
temp = sqrt (temp); temp = sqrt (temp);
*K1 = Kh + temp; *K1 = Kh + temp;
*K2 = Kh - temp; *K2 = Kh - temp;
} }
/* from Maple */ /* from Maple */
static void linsolve (real m11, real m12, real b1, static void linsolve(real m11, real m12, real b1, real m21, real m22, real b2, real *x1, real *x2)
real m21, real m22, real b2,
real * x1, real * x2)
{ {
real temp; real temp;
@@ -242,20 +266,19 @@ static void linsolve (real m11, real m12, real b1,
} }
/* from Maple - largest eigenvector of [a b; b c] */ /* from Maple - largest eigenvector of [a b; b c] */
static void eigenvector (real a, real b, real c, static void eigenvector(real a, real b, real c, Vec3r e)
Vec3r e)
{ {
if (b == 0.0) { if (b == 0.0) {
e[0] = 0.0; e[0] = 0.0;
} else { }
else {
e[0] = -(c - a - sqrt(c * c - 2 * a * c + a * a + 4 * b * b)) / (2 * b); e[0] = -(c - a - sqrt(c * c - 2 * a * c + a * a + 4 * b * b)) / (2 * b);
} }
e[1] = 1.0; e[1] = 1.0;
e[2] = 0.0; e[2] = 0.0;
} }
/** /*! gts_vertex_principal_directions:
* gts_vertex_principal_directions:
* @v: a #WVertex. * @v: a #WVertex.
* @s: a #GtsSurface. * @s: a #GtsSurface.
* @Kh: mean curvature normal (a #Vec3r). * @Kh: mean curvature normal (a #Vec3r).
@@ -263,18 +286,14 @@ static void eigenvector (real a, real b, real c,
* @e1: first principal curvature direction (direction of largest curvature). * @e1: first principal curvature direction (direction of largest curvature).
* @e2: second principal curvature direction. * @e2: second principal curvature direction.
* *
* Computes the principal curvature directions at a point given @Kh * Computes the principal curvature directions at a point given @Kh and @Kg, the mean curvature normal and
* and @Kg, the mean curvature normal and Gaussian curvatures at that * Gaussian curvatures at that point, computed with gts_vertex_mean_curvature_normal() and
* point, computed with gts_vertex_mean_curvature_normal() and
* gts_vertex_gaussian_curvature(), respectively. * gts_vertex_gaussian_curvature(), respectively.
* *
* Note that this computation is very approximate and tends to be * Note that this computation is very approximate and tends to be unstable. Smoothing of the surface or the principal
* unstable. Smoothing of the surface or the principal directions may * directions may be necessary to achieve reasonable results.
* be necessary to achieve reasonable results.
*/ */
void gts_vertex_principal_directions (WVertex * v, void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2)
Vec3r Kh, real Kg,
Vec3r &e1, Vec3r &e2)
{ {
Vec3r N; Vec3r N;
real normKh; real normKh;
@@ -296,14 +315,14 @@ void gts_vertex_principal_directions (WVertex * v,
if (normKh > 0.0) { if (normKh > 0.0) {
Kh.normalize(); Kh.normalize();
} else { }
/* This vertex is a point of zero mean curvature (flat or saddle else {
* point). Compute a normal by averaging the adjacent triangles /* 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; N[0] = N[1] = N[2] = 0.0;
for (itE=v->incoming_edges_begin(); for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
itE!=v->incoming_edges_end(); itE++)
N = Vec3r(N + (*itE)->GetaFace()->GetNormal()); N = Vec3r(N + (*itE)->GetaFace()->GetNormal());
real normN = N.norm(); real normN = N.norm();
if (normN <= 0.0) if (normN <= 0.0)
@@ -311,7 +330,6 @@ void gts_vertex_principal_directions (WVertex * v,
N.normalize(); N.normalize();
} }
/* construct a basis from N: */ /* construct a basis from N: */
/* set basis1 to any component not the largest of N */ /* set basis1 to any component not the largest of N */
basis1[0] = basis1[1] = basis1[2] = 0.0; basis1[0] = basis1[1] = basis1[2] = 0.0;
@@ -338,18 +356,16 @@ void gts_vertex_principal_directions (WVertex * v,
d2s = (real *)malloc(sizeof (real) * nb_edges); d2s = (real *)malloc(sizeof (real) * nb_edges);
edge_count = 0; edge_count = 0;
for (itE=v->incoming_edges_begin(); for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
itE!=v->incoming_edges_end(); itE++)
{
WOEdge *e; WOEdge *e;
WFace *f1, *f2; WFace *f1, *f2;
real weight, kappa, d1, d2; real weight, kappa, d1, d2;
Vec3r vec_edge; Vec3r vec_edge;
if (! *itE) continue; if (!*itE)
continue;
e = *itE; e = *itE;
/* since this vertex passed the tests in /* since this vertex passed the tests in gts_vertex_mean_curvature_normal(), this should be true. */
* gts_vertex_mean_curvature_normal(), this should be true. */
//g_assert(gts_edge_face_number (e, s) == 2); //g_assert(gts_edge_face_number (e, s) == 2);
/* identify the two triangles bordering e in s */ /* identify the two triangles bordering e in s */
@@ -360,22 +376,17 @@ void gts_vertex_principal_directions (WVertex * v,
* B = [ a b ; b c ]. * B = [ a b ; b c ].
* The computations here are from section 5 of [Meyer et al 2002]. * The computations here are from section 5 of [Meyer et al 2002].
* *
* The first step is to calculate the linear equations governing * The first step is to calculate the linear equations governing the values of (a,b,c). These can be computed
* the values of (a,b,c). These can be computed by setting the * by setting the derivatives of the error E to zero (section 5.3).
* derivatives of the error E to zero (section 5.3).
* *
* Since a + c = norm(Kh), we only compute the linear equations * Since a + c = norm(Kh), we only compute the linear equations for dE/da and dE/db. (NB: [Meyer et al 2002]
* for dE/da and dE/db. (NB: [Meyer et al 2002] has the * has the equation a + b = norm(Kh), but I'm almost positive this is incorrect).
* 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 * Note that the w_ij (defined in section 5.2) are all scaled by (1/8*A_mixed). We drop this uniform scale
* (1/8*A_mixed). We drop this uniform scale factor because the * factor because the solution of the linear equations doesn't rely on it.
* solution of the linear equations doesn't rely on it.
* *
* The terms of the linear equations are xterm_dy with x in * 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
* {a,b,c} and y in {a,b}. There are also const_dy terms that are * terms that are the constant factors in the equations.
* the constant factors in the equations.
*/ */
/* find the vector from v along edge e */ /* find the vector from v along edge e */
@@ -384,38 +395,34 @@ void gts_vertex_principal_directions (WVertex * v,
ve2 = vec_edge.squareNorm(); ve2 = vec_edge.squareNorm();
vdotN = vec_edge * N; vdotN = vec_edge * N;
/* section 5.2 - There is a typo in the computation of kappa. The /* section 5.2 - There is a typo in the computation of kappa. The edges should be x_j-x_i. */
* edges should be x_j-x_i.
*/
kappa = 2.0 * vdotN / ve2; kappa = 2.0 * vdotN / ve2;
/* section 5.2 */ /* section 5.2 */
/* I don't like performing a minimization where some of the /* I don't like performing a minimization where some of the weights can be negative (as can be the case
* weights can be negative (as can be the case if f1 or f2 are * if f1 or f2 are obtuse). To ensure all-positive weights, we check for obtuseness. */
* obtuse). To ensure all-positive weights, we check for
* obtuseness. */
weight = 0.0; weight = 0.0;
if (!triangle_obtuse(v, f1)) { if (!triangle_obtuse(v, f1)) {
weight += ve2 * weight += ve2 * cotan(f1->GetNextOEdge(e->twin())->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
cotan (f1->GetNextOEdge(e->twin())->GetbVertex(), }
e->GetaVertex(), e->GetbVertex()) / 8.0; else {
} else {
if (angle_obtuse(v, f1)) { if (angle_obtuse(v, f1)) {
weight += ve2 * f1->getArea() / 4.0; weight += ve2 * f1->getArea() / 4.0;
} else { }
else {
weight += ve2 * f1->getArea() / 8.0; weight += ve2 * f1->getArea() / 8.0;
} }
} }
if (!triangle_obtuse(v, f2)) { if (!triangle_obtuse(v, f2)) {
weight += ve2 * weight += ve2 * cotan (f2->GetNextOEdge(e)->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
cotan (f2->GetNextOEdge(e)->GetbVertex(), }
e->GetaVertex(), e->GetbVertex()) / 8.0; else {
} else {
if (angle_obtuse(v, f2)) { if (angle_obtuse(v, f2)) {
weight += ve2 * f1->getArea() / 4.0; weight += ve2 * f1->getArea() / 4.0;
} else { }
else {
weight += ve2 * f1->getArea() / 8.0; weight += ve2 * f1->getArea() / 8.0;
} }
} }
@@ -447,7 +454,6 @@ void gts_vertex_principal_directions (WVertex * v,
bterm_db += weight * d1 * d2 * 2 * d1 * d2; bterm_db += weight * d1 * d2 * 2 * d1 * d2;
cterm_db += weight * d1 * d2 * d2 * d2; cterm_db += weight * d1 * d2 * d2 * d2;
const_db += weight * d1 * d2 * (-kappa); const_db += weight * d1 * d2 * (-kappa);
} }
/* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */ /* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */
@@ -458,31 +464,26 @@ void gts_vertex_principal_directions (WVertex * v,
const_db += cterm_db * normKh; const_db += cterm_db * normKh;
/* check for solvability of the linear system */ /* check for solvability of the linear system */
if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) && if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) && ((const_da != 0.0) || (const_db != 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);
linsolve (aterm_da, bterm_da, -const_da,
aterm_db, bterm_db, -const_db,
&a, &b);
c = normKh - a; c = normKh - a;
eigenvector(a, b, c, eig); eigenvector(a, b, c, eig);
} else { }
else {
/* region of v is planar */ /* region of v is planar */
eig[0] = 1.0; eig[0] = 1.0;
eig[1] = 0.0; eig[1] = 0.0;
} }
/* Although the eigenvectors of B are good estimates of the /* Although the eigenvectors of B are good estimates of the principal directions, it seems that which one is
* principal directions, it seems that which one is attached to * attached to which curvature direction is a bit arbitrary. This may be a bug in my implementation, or just
* which curvature direction is a bit arbitrary. This may be a bug * a side-effect of the inaccuracy of B due to the discrete nature of the sampling.
* 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 * To overcome this behavior, we'll evaluate which assignment best matches the given eigenvectors by comparing
* matches the given eigenvectors by comparing the curvature * the curvature estimates computed above and the curvatures calculated from the discrete differential operators.
* estimates computed above and the curvatures calculated from the */
* discrete differential operators. */
gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2); gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2);
@@ -535,7 +536,9 @@ void gts_vertex_principal_directions (WVertex * v,
} }
namespace OGF { namespace OGF {
inline static real angle(WOEdge * h) {
inline static real angle(WOEdge *h)
{
const Vec3r& n1 = h->GetbFace()->GetNormal(); const Vec3r& n1 = h->GetbFace()->GetNormal();
const Vec3r& n2 = h->GetaFace()->GetNormal(); const Vec3r& n2 = h->GetaFace()->GetNormal();
const Vec3r v = h->getVec3r(); const Vec3r v = h->getVec3r();
@@ -550,13 +553,9 @@ namespace OGF {
} }
// precondition1: P is inside the sphere // precondition1: P is inside the sphere
// precondition2: P,V points to the outside of // precondition2: P,V points to the outside of the sphere (i.e. OP.V > 0)
// the sphere (i.e. OP.V > 0) static bool sphere_clip_vector(const Vec3r& O, real r, const Vec3r& P, Vec3r& V)
static bool sphere_clip_vector( {
const Vec3r& O, real r,
const Vec3r& P, Vec3r& V
) {
Vec3r W = P - O; Vec3r W = P - O;
real a = V.squareNorm(); real a = V.squareNorm();
real b = 2.0 * V * W; real b = 2.0 * V * W;
@@ -585,9 +584,8 @@ namespace OGF {
// TODO: check optimizations: // TODO: check optimizations:
// use marking ? (measure *timings* ...) // use marking ? (measure *timings* ...)
void compute_curvature_tensor( void compute_curvature_tensor(WVertex *start, real radius, NormalCycle& nc)
WVertex* start, real radius, NormalCycle& nc {
) {
// in case we have a non-manifold vertex, skip it... // in case we have a non-manifold vertex, skip it...
if(start->isBoundary()) if(start->isBoundary())
return; return;
@@ -625,10 +623,8 @@ namespace OGF {
} }
} }
void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc)
void compute_curvature_tensor_one_ring( {
WVertex* start, NormalCycle& nc
) {
// in case we have a non-manifold vertex, skip it... // in case we have a non-manifold vertex, skip it...
if (start->isBoundary()) if (start->isBoundary())
return; return;
@@ -643,4 +639,4 @@ namespace OGF {
} }
} }
} } // OGF namespace

View File

@@ -1,29 +1,59 @@
/*
/* GTS - Library for the manipulation of triangulated surfaces * ***** BEGIN GPL LICENSE BLOCK *****
* Copyright (C) 1999 Stéphane Popinet
* *
* This library is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU General Public License
* License as published by the Free Software Foundation; either * as published by the Free Software Foundation; either version 2
* version 2 of the License, or (at your option) any later version. * 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 * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Library General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU Library General Public * You should have received a copy of the GNU General Public License
* License along with this library; if not, write to the * along with this program; if not, write to the Free Software Foundation,
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Boston, MA 02111-1307, 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 *****
*/ */
#ifndef __CURVATURE_H__ #ifndef __FREESTYLE_CURVATURE_H__
#define __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/FreestyleConfig.h"
#include "../system/Precision.h" #include "../system/Precision.h"
# include "../geometry/Geom.h"
using namespace Geometry; using namespace Geometry;
class WVertex; class WVertex;
@@ -31,7 +61,6 @@ class WVertex;
class LIB_WINGED_EDGE_EXPORT CurvatureInfo class LIB_WINGED_EDGE_EXPORT CurvatureInfo
{ {
public: public:
CurvatureInfo() CurvatureInfo()
{ {
K1 = 0.0; K1 = 0.0;
@@ -43,7 +72,8 @@ public:
er = Vec3r(0.0, 0.0, 0.0); er = Vec3r(0.0, 0.0, 0.0);
} }
CurvatureInfo(const CurvatureInfo& iBrother){ CurvatureInfo(const CurvatureInfo& iBrother)
{
K1 = iBrother.K1; K1 = iBrother.K1;
K2 = iBrother.K2; K2 = iBrother.K2;
e1 = iBrother.e1; e1 = iBrother.e1;
@@ -53,7 +83,8 @@ public:
er = iBrother.er; er = iBrother.er;
} }
CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t) { CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t)
{
K1 = ca.K1 + t * (cb.K1 - ca.K1); K1 = ca.K1 + t * (cb.K1 - ca.K1);
K2 = ca.K2 + t * (cb.K2 - ca.K2); K2 = ca.K2 + t * (cb.K2 - ca.K2);
e1 = ca.e1 + t * (cb.e1 - ca.e1); e1 = ca.e1 + t * (cb.e1 - ca.e1);
@@ -72,85 +103,41 @@ public:
Vec3r er; // radial curvature direction Vec3r er; // radial curvature direction
}; };
class Face_Curvature_Info{ class Face_Curvature_Info
{
public: public:
Face_Curvature_Info() {} Face_Curvature_Info() {}
~Face_Curvature_Info(){
~Face_Curvature_Info()
{
for (vector<CurvatureInfo*>::iterator ci = vec_curvature_info.begin(), ciend = vec_curvature_info.end(); for (vector<CurvatureInfo*>::iterator ci = vec_curvature_info.begin(), ciend = vec_curvature_info.end();
ci != ciend; ci != ciend;
++ci){ ++ci)
{
delete (*ci); delete (*ci);
} }
vec_curvature_info.clear(); vec_curvature_info.clear();
} }
vector<CurvatureInfo *> vec_curvature_info; vector<CurvatureInfo *> vec_curvature_info;
}; };
bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal (WVertex * v, bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &n);
Vec3r &n);
bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature (WVertex * v, bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature(WVertex *v, real *Kg);
real * Kg);
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures (real Kh, void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2);
real Kg,
real * K1,
real * K2);
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions (WVertex * v, void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2);
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 { namespace OGF {
class NormalCycle ; class NormalCycle ;
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( WVertex *start, double radius, NormalCycle& nc);
WVertex* start, double radius, NormalCycle& nc
) ;
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring( void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc);
WVertex* start, NormalCycle& nc
) ;
}
} // OGF namespace
#endif /* __CURVATURE_H__ */ #endif /* __FREESTYLE_CURVATURE_H__ */

View File

@@ -1,46 +1,46 @@
// /*
// Filename : Nature.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Emmanuel Turquin *
// Purpose : Different natures for both vertices and edges * This program is free software; you can redistribute it and/or
// Date of creation : 01/07/2003 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// with this source distribution. * GNU General Public License for more details.
// *
// This program is free software; you can redistribute it and/or * You should have received a copy of the GNU General Public License
// modify it under the terms of the GNU General Public License * along with this program; if not, write to the Free Software Foundation,
// as published by the Free Software Foundation; either version 2 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// of the License, or (at your option) any later version. *
// * The Original Code is Copyright (C) 2010 Blender Foundation.
// This program is distributed in the hope that it will be useful, * All rights reserved.
// but WITHOUT ANY WARRANTY; without even the implied warranty of *
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * The Original Code is: all of this file.
// GNU General Public License for more details. *
// * Contributor(s): none yet.
// You should have received a copy of the GNU General Public License *
// along with this program; if not, write to the Free Software * ***** END GPL LICENSE BLOCK *****
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NATURE_H
# define NATURE_H
/*! \file Nature.h
* Definitions of Natures of the ViewMap's elements
*/ */
/*! Namespace gathering the different possible #ifndef __FREESTYLE_NATURE_H__
* natures of 0D and 1D elements of the ViewMap #define __FREESTYLE_NATURE_H__
/** \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 Nature { namespace Nature {
typedef unsigned short VertexNature; /* XXX Why not using enums??? */
typedef unsigned short VertexNature;
/*! true for any 0D element */ /*! true for any 0D element */
static const VertexNature POINT = 0; // 0 static const VertexNature POINT = 0; // 0
/*! true for SVertex */ /*! true for SVertex */
@@ -76,4 +76,4 @@ namespace Nature {
} // end of namespace Nature } // end of namespace Nature
#endif // NATURE_H #endif // __FREESTYLE_NATURE_H__

View File

@@ -1,25 +1,39 @@
/*
* ***** 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Classes to define a Winged Edge data structure.
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 18/02/2002
// 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 <iostream> #include <iostream>
#include "WEdge.h" #include "WEdge.h"
/*! Temporary structures */ /*! Temporary structures */
@@ -48,13 +62,13 @@ public:
}; };
/**********************************/ /**********************************
/* */ * *
/* */ * *
/* WVertex */ * WVertex *
/* */ * *
/* */ * *
/**********************************/ **********************************/
WVertex::WVertex(WVertex& iBrother) WVertex::WVertex(WVertex& iBrother)
{ {
@@ -76,13 +90,13 @@ WVertex* WVertex::duplicate()
return clone; return clone;
} }
WOEdge *WVertex::incoming_edge_iterator::operator*() WOEdge *WVertex::incoming_edge_iterator::operator*()
{ {
return _current; return _current;
} }
void WVertex::incoming_edge_iterator::increment(){
void WVertex::incoming_edge_iterator::increment()
{
WOEdge *twin = _current->twin(); WOEdge *twin = _current->twin();
if (!twin) { if (!twin) {
// we reached a hole // we reached a hole
@@ -91,21 +105,25 @@ void WVertex::incoming_edge_iterator::increment(){
} }
WOEdge *next = twin->getPrevOnFace(); WOEdge *next = twin->getPrevOnFace();
if (next == _begin) { if (next == _begin) {
next = 0; next = NULL;
} }
_current = next; _current = next;
} }
WFace* WVertex::face_iterator::operator*(){ WFace *WVertex::face_iterator::operator*()
{
WOEdge *woedge = *_edge_it; WOEdge *woedge = *_edge_it;
if(woedge == 0) if (!woedge)
return 0; return NULL;
return (woedge)->GetbFace(); return (woedge)->GetbFace();
} }
//bool WVertex::isBoundary () const{ #if 0
// return _Border; bool WVertex::isBoundary () const
//} {
return _Border;
}
#endif
bool WVertex::isBoundary () bool WVertex::isBoundary ()
{ {
if (_Border == 1) if (_Border == 1)
@@ -120,16 +138,21 @@ bool WVertex::isBoundary ()
return true; return true;
} }
} }
//if (!(*it)->GetaOEdge()->GetaFace()) return true; #if 0
if (!(*it)->GetaOEdge()->GetaFace())
return true;
#endif
_Border = 0; _Border = 0;
return false; return false;
} }
void WVertex::AddEdge(WEdge *iEdge) { void WVertex::AddEdge(WEdge *iEdge)
{
_EdgeList.push_back(iEdge); _EdgeList.push_back(iEdge);
} }
WVertex::incoming_edge_iterator WVertex::incoming_edges_begin(){ WVertex::incoming_edge_iterator WVertex::incoming_edges_begin()
{
WOEdge *begin; WOEdge *begin;
WEdge *wedge = _EdgeList.front(); WEdge *wedge = _EdgeList.front();
WOEdge *aOEdge = wedge->GetaOEdge(); WOEdge *aOEdge = wedge->GetaOEdge();
@@ -139,7 +162,9 @@ WVertex::incoming_edge_iterator WVertex::incoming_edges_begin(){
begin = _EdgeList.front()->GetbOEdge(); begin = _EdgeList.front()->GetbOEdge();
return incoming_edge_iterator(this, begin, begin); return incoming_edge_iterator(this, begin, begin);
} }
WVertex::incoming_edge_iterator WVertex::incoming_edges_end(){
WVertex::incoming_edge_iterator WVertex::incoming_edges_end()
{
WOEdge *begin; WOEdge *begin;
WOEdge *aOEdge = _EdgeList.front()->GetaOEdge(); WOEdge *aOEdge = _EdgeList.front()->GetaOEdge();
if (aOEdge->GetbVertex() == this) if (aOEdge->GetbVertex() == this)
@@ -148,25 +173,27 @@ WVertex::incoming_edge_iterator WVertex::incoming_edges_end(){
begin = _EdgeList.front()->GetbOEdge(); begin = _EdgeList.front()->GetbOEdge();
return incoming_edge_iterator(this, begin, 0); return incoming_edge_iterator(this, begin, 0);
} }
//WOEdge** WVertex::incoming_edge_iterator::operator->() #if 0
//{ WOEdge **WVertex::incoming_edge_iterator::operator->()
// WOEdge ** ppaOEdge = (*_iter)->GetaOEdge(); {
// if(aOEdge->GetbVertex() == _vertex) WOEdge **ppaOEdge = (*_iter)->GetaOEdge();
// return ppaOEdge; if (aOEdge->GetbVertex() == _vertex) {
// else return ppaOEdge;
// { }
// WOEdge *bOEdge = (*_iter)->GetbOEdge(); else {
// return &bOEdge; WOEdge *bOEdge = (*_iter)->GetbOEdge();
// } return &bOEdge;
// }
//} }
/**********************************/ #endif
/* */
/* */ /**********************************
/* WOEdge */ * *
/* */ * *
/* */ * WOEdge *
/**********************************/ * *
* *
**********************************/
WOEdge::WOEdge(WOEdge& iBrother) WOEdge::WOEdge(WOEdge& iBrother)
{ {
@@ -189,8 +216,7 @@ WOEdge * WOEdge::duplicate()
return clone; return clone;
} }
Vec3r Vec3r WOEdge::getVec3r ()
WOEdge::getVec3r ()
{ {
return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex()); return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex());
} }
@@ -200,19 +226,18 @@ WOEdge * WOEdge::twin ()
return GetOwner()->GetOtherOEdge(this); return GetOwner()->GetOtherOEdge(this);
} }
WOEdge * WOEdge *WOEdge::getPrevOnFace()
WOEdge::getPrevOnFace()
{ {
return _pbFace->GetPrevOEdge(this); return _pbFace->GetPrevOEdge(this);
} }
/**********************************/ /**********************************
/* */ * *
/* */ * *
/* WEdge */ * WEdge *
/* */ * *
/* */ * *
/**********************************/ **********************************/
WEdge::WEdge(WEdge& iBrother) WEdge::WEdge(WEdge& iBrother)
{ {
@@ -222,10 +247,10 @@ WEdge::WEdge(WEdge& iBrother)
WOEdge *boedge = iBrother.GetbOEdge(); WOEdge *boedge = iBrother.GetbOEdge();
userdata = NULL; userdata = NULL;
if(NULL != aoedge) if (aoedge)
//_paOEdge = new WOEdge(*aoedge); //_paOEdge = new WOEdge(*aoedge);
_paOEdge = aoedge->duplicate(); _paOEdge = aoedge->duplicate();
if(NULL != boedge) if (boedge)
//_pbOEdge = new WOEdge(*boedge); //_pbOEdge = new WOEdge(*boedge);
_pbOEdge = boedge->duplicate(); _pbOEdge = boedge->duplicate();
@@ -241,14 +266,13 @@ WEdge * WEdge::duplicate()
return clone; return clone;
} }
/**********************************/ /**********************************
/* */ * *
/* */ * *
/* WFace */ * WFace *
/* */ * *
/* */ * *
/**********************************/ **********************************/
WFace::WFace(WFace& iBrother) WFace::WFace(WFace& iBrother)
{ {
@@ -270,27 +294,21 @@ WFace * WFace::duplicate()
return clone; return clone;
} }
const FrsMaterial& WFace::frs_material() { const FrsMaterial& WFace::frs_material()
{
return getShape()->frs_material(_FrsMaterialIndex); return getShape()->frs_material(_FrsMaterialIndex);
} }
WOEdge *WFace::MakeEdge(WVertex *v1, WVertex *v2) WOEdge *WFace::MakeEdge(WVertex *v1, WVertex *v2)
{ {
// First check whether the same oriented edge already exists // First check whether the same oriented edge already exists or not:
// or not:
vector<WEdge *>& v1Edges = v1->GetEdges(); vector<WEdge *>& v1Edges = v1->GetEdges();
for(vector<WEdge*>::iterator it1=v1Edges.begin(), end=v1Edges.end(); for (vector<WEdge*>::iterator it1 = v1Edges.begin(), end = v1Edges.end(); it1 != end; it1++) {
it1!=end;
it1++)
{
WEdge *we = (*it1); WEdge *we = (*it1);
WOEdge *woea = we->GetaOEdge(); WOEdge *woea = we->GetaOEdge();
if((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) //if ((*it1)->GetbVertex() == v2) {
//if((*it1)->GetbVertex() == v2) if ((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) {
{
// The oriented edge already exists // The oriented edge already exists
cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl; cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
// Adds the edge to the face // Adds the edge to the face
@@ -305,11 +323,8 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
} }
WOEdge *woeb = we->GetbOEdge(); WOEdge *woeb = we->GetbOEdge();
if((woeb != 0) && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2))
//if ((*it1)->GetbVertex() == v2) //if ((*it1)->GetbVertex() == v2)
if (woeb && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2)) {
{
// The oriented edge already exists // The oriented edge already exists
cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl; cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
// Adds the edge to the face // Adds the edge to the face
@@ -326,20 +341,17 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
// the oriented edge we're about to build // the oriented edge we're about to build
WOEdge *pOEdge = new WOEdge; WOEdge *pOEdge = new WOEdge;
// The edge containing the oriented edge.
WEdge * edge; // The edge containing the oriented edge. WEdge *edge;
// checks whether this edge already exists or not // checks whether this edge already exists or not
// If it exists, it points outward v2 // If it exists, it points outward v2
bool exist = false; bool exist = false;
WOEdge *pInvertEdge = NULL; // The inverted edge if it exists WOEdge *pInvertEdge = NULL; // The inverted edge if it exists
vector<WEdge *>& v2Edges = v2->GetEdges(); vector<WEdge *>& v2Edges = v2->GetEdges();
vector<WEdge *>::iterator it; vector<WEdge *>::iterator it;
for(it=v2Edges.begin(); it!=v2Edges.end(); it++) for (it = v2Edges.begin(); it != v2Edges.end(); it++) {
{ if ((*it)->GetbVertex() == v1) {
if((*it)->GetbVertex() == v1)
{
// The invert edge already exists // The invert edge already exists
exist = true; exist = true;
pInvertEdge = (*it)->GetaOEdge(); pInvertEdge = (*it)->GetaOEdge();
@@ -348,10 +360,7 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
} }
//DEBUG: //DEBUG:
if (true == exist) { // The invert edge already exists
if(true == exist) // The invert edge already exists
{
// Retrieves the corresponding edge // Retrieves the corresponding edge
edge = pInvertEdge->GetOwner(); edge = pInvertEdge->GetOwner();
@@ -361,8 +370,7 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
// Updates the invert edge: // Updates the invert edge:
pInvertEdge->setaFace(this); pInvertEdge->setaFace(this);
} }
else // The invert edge does not exist yet else { // The invert edge does not exist yet
{
// we must create a new edge // we must create a new edge
//edge = new WEdge; //edge = new WEdge;
edge = instanciateEdge(); edge = instanciateEdge();
@@ -370,7 +378,6 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
// updates the a,b vertex edges list: // updates the a,b vertex edges list:
v1->AddEdge(edge); v1->AddEdge(edge);
v2->AddEdge(edge); v2->AddEdge(edge);
} }
pOEdge->setOwner(edge); pOEdge->setOwner(edge);
@@ -395,25 +402,31 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
} }
bool bool WFace::getOppositeEdge (const WVertex *v, WOEdge *&e)
WFace::getOppositeEdge (const WVertex *v, WOEdge* &e)
{ {
if (_OEdgeList.size()!=3) return false; if (_OEdgeList.size() != 3)
return false;
vector<WOEdge *>::iterator it; vector<WOEdge *>::iterator it;
e = NULL; e = NULL;
for(it=_OEdgeList.begin(); it!=_OEdgeList.end(); it++) for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) {
if ((*it)->GetaVertex()==v) e=*it; if ((*it)->GetaVertex() == v)
if (!e) return false; e = *it;
}
if (!e)
return false;
e = NULL; e = NULL;
for(it=_OEdgeList.begin(); it!=_OEdgeList.end(); it++) for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) {
if (((*it)->GetaVertex()!=v) && ((*it)->GetbVertex()!=v)) e=*it; if (((*it)->GetaVertex() != v) && ((*it)->GetbVertex() != v))
if (!e) return false; e = *it;
else return true; }
if (!e)
return false;
else
return true;
} }
real real WFace::getArea ()
WFace::getArea ()
{ {
vector<WOEdge *>::iterator it; vector<WOEdge *>::iterator it;
Vec3r origin = (*(_OEdgeList.begin()))->GetaVertex()->GetVertex(); Vec3r origin = (*(_OEdgeList.begin()))->GetaVertex()->GetVertex();
@@ -428,25 +441,20 @@ WFace::getArea ()
} }
WOEdge* WOEdge *WFace::GetPrevOEdge(WOEdge* iOEdge)
WFace::GetPrevOEdge(WOEdge* iOEdge)
{ {
vector<WOEdge *>::iterator woe, woend, woefirst; vector<WOEdge *>::iterator woe, woend, woefirst;
woefirst = _OEdgeList.begin(); woefirst = _OEdgeList.begin();
woend = _OEdgeList.end(); woend = _OEdgeList.end();
WOEdge *prev = *woefirst; WOEdge *prev = *woefirst;
woe = woefirst; woe = woefirst;
woe++; ++woe;
for(; for (; woe != woend; woe++) {
woe!=woend;
woe++)
{
if ((*woe) == iOEdge) if ((*woe) == iOEdge)
return prev; return prev;
prev = *woe; prev = *woe;
} }
// We left the loop. That means that the first // We left the loop. That means that the first OEdge was the good one:
// OEdge was the good one:
if ((*woefirst) == iOEdge) if ((*woefirst) == iOEdge)
return prev; return prev;
@@ -458,14 +466,14 @@ WShape * WFace::getShape()
return GetVertex(0)->shape(); return GetVertex(0)->shape();
} }
/**********************************/
/* */
/* */
/* WShape */
/* */
/* */
/**********************************/
/**********************************
* *
* *
* WShape *
* *
* *
**********************************/
LIB_WINGED_EDGE_EXPORT LIB_WINGED_EDGE_EXPORT
unsigned WShape::_SceneCurrentId = 0; unsigned WShape::_SceneCurrentId = 0;
@@ -485,10 +493,7 @@ WShape::WShape(WShape& iBrother)
iBrother.bbox(_min, _max); iBrother.bbox(_min, _max);
vector<WVertex *>& vertexList = iBrother.getVertexList(); vector<WVertex *>& vertexList = iBrother.getVertexList();
vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end(); vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end();
for(; for (; v != vend; ++v) {
v!=vend;
v++)
{
//WVertex *newVertex = new WVertex(*(*v)); //WVertex *newVertex = new WVertex(*(*v));
WVertex *newVertex = (*v)->duplicate(); WVertex *newVertex = (*v)->duplicate();
@@ -498,10 +503,7 @@ WShape::WShape(WShape& iBrother)
vector<WEdge *>& edgeList = iBrother.getEdgeList(); vector<WEdge *>& edgeList = iBrother.getEdgeList();
vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end(); vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end();
for(; for (; e != eend; ++e) {
e!=eend;
e++)
{
//WEdge *newEdge = new WEdge(*(*e)); //WEdge *newEdge = new WEdge(*(*e));
WEdge *newEdge = (*e)->duplicate(); WEdge *newEdge = (*e)->duplicate();
AddEdge(newEdge); AddEdge(newEdge);
@@ -509,10 +511,7 @@ WShape::WShape(WShape& iBrother)
vector<WFace *>& faceList = iBrother.GetFaceList(); vector<WFace *>& faceList = iBrother.GetFaceList();
vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end(); vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end();
for(; for (; f != fend; ++f) {
f!=fend;
f++)
{
//WFace *newFace = new WFace(*(*f)); //WFace *newFace = new WFace(*(*f));
WFace *newFace = (*f)->duplicate(); WFace *newFace = (*f)->duplicate();
AddFace(newFace); AddFace(newFace);
@@ -520,15 +519,11 @@ WShape::WShape(WShape& iBrother)
// update all pointed addresses thanks to the newly created objects: // update all pointed addresses thanks to the newly created objects:
vend = _VertexList.end(); vend = _VertexList.end();
for(v=_VertexList.begin(); for (v = _VertexList.begin(); v != vend; ++v) {
v!=vend;
v++)
{
const vector<WEdge *>& vedgeList = (*v)->GetEdges(); const vector<WEdge *>& vedgeList = (*v)->GetEdges();
vector<WEdge *> newvedgelist; vector<WEdge *> newvedgelist;
unsigned int i; unsigned int i;
for(i=0; i<vedgeList.size(); i++) for (i = 0; i < vedgeList.size(); i++) {
{
WEdge *current = vedgeList[i]; WEdge *current = vedgeList[i];
edgedata *currentvedata = (edgedata *)current->userdata; edgedata *currentvedata = (edgedata *)current->userdata;
newvedgelist.push_back(currentvedata->_copy); newvedgelist.push_back(currentvedata->_copy);
@@ -537,26 +532,22 @@ WShape::WShape(WShape& iBrother)
} }
eend = _EdgeList.end(); eend = _EdgeList.end();
for(e=_EdgeList.begin(); for (e = _EdgeList.begin(); e != eend; ++e) {
e!=eend;
e++)
{
// update aOedge: // update aOedge:
WOEdge *aoEdge = (*e)->GetaOEdge(); WOEdge *aoEdge = (*e)->GetaOEdge();
aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy); aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy);
aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy); aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy);
if(NULL != aoEdge->GetaFace()) if (aoEdge->GetaFace())
aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy); aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy);
aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy); aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy);
aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy); aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy);
// update bOedge:
// update bOedge:
WOEdge *boEdge = (*e)->GetbOEdge(); WOEdge *boEdge = (*e)->GetbOEdge();
if(boEdge != 0) if (boEdge) {
{
boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy); boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy);
boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy); boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy);
if(NULL != boEdge->GetaFace()) if (boEdge->GetaFace())
boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy); boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy);
boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy); boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy);
boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy); boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy);
@@ -564,17 +555,13 @@ WShape::WShape(WShape& iBrother)
} }
fend = _FaceList.end(); fend = _FaceList.end();
for(f=_FaceList.begin(); for (f = _FaceList.begin(); f != fend; ++f) {
f!=fend; unsigned int i;
f++)
{
unsigned i;
const vector<WOEdge *>& oedgeList = (*f)->getEdgeList(); const vector<WOEdge *>& oedgeList = (*f)->getEdgeList();
vector<WOEdge *> newoedgelist; vector<WOEdge *> newoedgelist;
unsigned n = oedgeList.size(); unsigned int n = oedgeList.size();
for(i=0; i<n; i++) for (i = 0; i < n; i++) {
{
WOEdge *current = oedgeList[i]; WOEdge *current = oedgeList[i];
oedgedata *currentoedata = (oedgedata *)current->userdata; oedgedata *currentoedata = (oedgedata *)current->userdata;
newoedgelist.push_back(currentoedata->_copy); newoedgelist.push_back(currentoedata->_copy);
@@ -587,20 +574,14 @@ WShape::WShape(WShape& iBrother)
// Free all memory (arghh!) // Free all memory (arghh!)
// Vertex // Vertex
vend = iBrother.getVertexList().end(); vend = iBrother.getVertexList().end();
for(v=iBrother.getVertexList().begin(); for (v = iBrother.getVertexList().begin(); v != vend; ++v) {
v!=vend;
v++)
{
delete (vertexdata *)((*v)->userdata); delete (vertexdata *)((*v)->userdata);
(*v)->userdata = NULL; (*v)->userdata = NULL;
} }
// Edges and OEdges: // Edges and OEdges:
eend = iBrother.getEdgeList().end(); eend = iBrother.getEdgeList().end();
for(e=iBrother.getEdgeList().begin(); for (e = iBrother.getEdgeList().begin(); e != eend; ++e) {
e!=eend;
e++)
{
delete (edgedata *)((*e)->userdata); delete (edgedata *)((*e)->userdata);
(*e)->userdata = NULL; (*e)->userdata = NULL;
// OEdge a: // OEdge a:
@@ -608,18 +589,15 @@ WShape::WShape(WShape& iBrother)
(*e)->GetaOEdge()->userdata = NULL; (*e)->GetaOEdge()->userdata = NULL;
// OEdge b: // OEdge b:
WOEdge *oedgeb = (*e)->GetbOEdge(); WOEdge *oedgeb = (*e)->GetbOEdge();
if(NULL != oedgeb) if (oedgeb) {
{
delete (oedgedata *)(oedgeb->userdata); delete (oedgedata *)(oedgeb->userdata);
oedgeb->userdata = NULL; oedgeb->userdata = NULL;
} }
} }
// Faces // Faces
fend = iBrother.GetFaceList().end(); fend = iBrother.GetFaceList().end();
for(f=iBrother.GetFaceList().begin(); for (f = iBrother.GetFaceList().begin(); f != fend; ++f) {
f!=fend;
f++)
{
delete (facedata *)((*f)->userdata); delete (facedata *)((*f)->userdata);
(*f)->userdata = NULL; (*f)->userdata = NULL;
} }
@@ -631,21 +609,19 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
WFace *face = instanciateFace(); WFace *face = instanciateFace();
WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face); WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face);
if (0 == result) { if (!result)
delete face; delete face;
return 0;
}
return result; return result;
} }
WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial) WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
{ {
// allocate the new face // allocate the new face
WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial); WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial);
if(0 == face) if (!face)
return NULL;
return 0;
// set the list of per-vertex normals // set the list of per-vertex normals
face->setNormalList(iNormalsList); face->setNormalList(iNormalsList);
@@ -655,9 +631,9 @@ WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsL
return face; return face;
} }
WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial, WFace *face) WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial,
WFace *face)
{ {
int id = _FaceList.size(); int id = _FaceList.size();
face->setFrsMaterialIndex(iMaterial); face->setFrsMaterialIndex(iMaterial);
@@ -666,23 +642,13 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
// LET'S HACK IT FOR THE TRIANGLE CASE: // LET'S HACK IT FOR THE TRIANGLE CASE:
if(3 == iVertexList.size()) if (3 == iVertexList.size()) {
if ((iVertexList[0] == iVertexList[1]) ||
{ (iVertexList[0] == iVertexList[2]) ||
(iVertexList[2] == iVertexList[1])) {
if((iVertexList[0] == iVertexList[1])
|| (iVertexList[0] == iVertexList[2])
|| (iVertexList[2] == iVertexList[1]))
{
cerr << "Warning: degenerated triangle detected, correcting" << endl; cerr << "Warning: degenerated triangle detected, correcting" << endl;
return 0; return NULL;
} }
} }
vector<WVertex *>::iterator it; vector<WVertex *>::iterator it;
@@ -712,9 +678,8 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
va = iVertexList.begin(); va = iVertexList.begin();
vb = va; vb = va;
for(; va != iVertexList.end(); va = vb) for (; va != iVertexList.end(); va = vb) {
{ ++vb;
vb++;
// Adds va to the vertex list: // Adds va to the vertex list:
//face->AddVertex(*va); //face->AddVertex(*va);
@@ -724,16 +689,12 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
else else
oedge = face->MakeEdge(*va, *vb); oedge = face->MakeEdge(*va, *vb);
if (!oedge)
if(oedge == 0) return NULL;
return 0;
WEdge *edge = oedge->GetOwner(); WEdge *edge = oedge->GetOwner();
if(1 == edge->GetNumberOfOEdges()) if (1 == edge->GetNumberOfOEdges()) {
{ // means that we just created a new edge and that we must add it to the shape's edges list
// means that we just created a new edge and that we must add it to the
// shape's edges list
edge->setId(_EdgeList.size()); edge->setId(_EdgeList.size());
AddEdge(edge); AddEdge(edge);
// compute the mean edge value: // compute the mean edge value:
@@ -741,7 +702,7 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
} }
edge->setMark(*mit); edge->setMark(*mit);
mit++; ++mit;
} }
// Add the face to the shape's faces list: // Add the face to the shape's faces list:

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +1,43 @@
/*
* ***** 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/WFillGrid.cpp
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
// * \author Emmanuel Turquin
// This program is free software; you can redistribute it and/or * \author Stephane Grabli
// modify it under the terms of the GNU General Public License * \date 03/05/2003
// 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 "WEdge.h" #include "WEdge.h"
#include "WFillGrid.h" #include "WFillGrid.h"
void WFillGrid::fillGrid() { void WFillGrid::fillGrid()
{
if (!_winged_edge || !_grid) if (!_winged_edge || !_grid)
return; return;
@@ -31,24 +46,17 @@ void WFillGrid::fillGrid() {
vector<Vec3r> vectors; vector<Vec3r> vectors;
vector<WFace *> faces; vector<WFace *> faces;
for (vector<WShape*>::const_iterator it = wshapes.begin(); for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) {
it != wshapes.end();
it++) {
faces = (*it)->GetFaceList(); faces = (*it)->GetFaceList();
for (vector<WFace*>::const_iterator f = faces.begin(); for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) {
f != faces.end();
f++) {
(*f)->RetrieveVertexList(fvertices); (*f)->RetrieveVertexList(fvertices);
for (vector<WVertex*>::const_iterator wv = fvertices.begin(); for (vector<WVertex*>::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv)
wv != fvertices.end();
wv++)
vectors.push_back(Vec3r((*wv)->GetVertex())); vectors.push_back(Vec3r((*wv)->GetVertex()));
// occluder will be deleted by the grid // occluder will be deleted by the grid
Polygon3r *occluder = Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal());
new Polygon3r(vectors, (*f)->GetNormal());
occluder->setId(_polygon_id++); occluder->setId(_polygon_id++);
occluder->userdata = (void *)(*f); occluder->userdata = (void *)(*f);
_grid->insertOccluder(occluder); _grid->insertOccluder(occluder);

View File

@@ -1,46 +1,51 @@
// /*
// Filename : WFillGrid.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Emmanuel Turquin * This program is free software; you can redistribute it and/or
// Purpose : Class to fill in a grid from a SceneGraph * modify it under the terms of the GNU General Public License
// (uses only the WingedEdge structures) * as published by the Free Software Foundation; either version 2
// Date of creation : 03/05/2003 * 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__
// /** \file blender/freestyle/intern/winged_edge/WFillGrid.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
// * \author Emmanuel Turquin
// This program is free software; you can redistribute it and/or * \author Stephane Grabli
// modify it under the terms of the GNU General Public License * \date 03/05/2003
// 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 W_FILL_GRID_H #include "WEdge.h"
# define W_FILL_GRID_H
#include "../geometry/Grid.h" #include "../geometry/Grid.h"
#include "../geometry/Polygon.h" #include "../geometry/Polygon.h"
# include "WEdge.h"
class LIB_WINGED_EDGE_EXPORT WFillGrid class LIB_WINGED_EDGE_EXPORT WFillGrid
{ {
public: public:
inline WFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
inline WFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) { {
_winged_edge = winged_edge; _winged_edge = winged_edge;
_grid = grid; _grid = grid;
_polygon_id = 0; _polygon_id = 0;
@@ -51,30 +56,33 @@ public:
void fillGrid(); void fillGrid();
/*! Accessors */ /*! Accessors */
WingedEdge* getWingedEdge() { WingedEdge *getWingedEdge()
{
return _winged_edge; return _winged_edge;
} }
Grid* getGrid() { Grid *getGrid()
{
return _grid; return _grid;
} }
/*! Modifiers */ /*! Modifiers */
void setWingedEdge(WingedEdge* winged_edge) { void setWingedEdge(WingedEdge *winged_edge)
{
if (winged_edge) if (winged_edge)
_winged_edge = winged_edge; _winged_edge = winged_edge;
} }
void setGrid(Grid* grid) { void setGrid(Grid *grid)
{
if (grid) if (grid)
_grid = grid; _grid = grid;
} }
private: private:
Grid *_grid; Grid *_grid;
WingedEdge *_winged_edge; WingedEdge *_winged_edge;
unsigned _polygon_id; unsigned _polygon_id;
}; };
#endif // WS_FILL_GRID_H #endif // __FREESTYLE_W_FILL_GRID_H__

View File

@@ -1,28 +1,42 @@
/*
* ***** 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/WSFillGrid.cpp
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 03/05/2003
// 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 "WEdge.h" #include "WEdge.h"
#include "WSFillGrid.h" #include "WSFillGrid.h"
void WSFillGrid::fillGrid() { void WSFillGrid::fillGrid()
{
if (!_winged_edge || !_grid) if (!_winged_edge || !_grid)
return; return;
@@ -31,24 +45,17 @@ void WSFillGrid::fillGrid() {
vector<Vec3r> vectors; vector<Vec3r> vectors;
vector<WFace *> faces; vector<WFace *> faces;
for (vector<WShape*>::const_iterator it = wshapes.begin(); for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) {
it != wshapes.end();
it++) {
faces = (*it)->GetFaceList(); faces = (*it)->GetFaceList();
for (vector<WFace*>::const_iterator f = faces.begin(); for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) {
f != faces.end();
f++) {
(*f)->RetrieveVertexList(fvertices); (*f)->RetrieveVertexList(fvertices);
for (vector<WVertex*>::const_iterator wv = fvertices.begin(); for (vector<WVertex*>::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv)
wv != fvertices.end();
wv++)
vectors.push_back(Vec3r((*wv)->GetVertex())); vectors.push_back(Vec3r((*wv)->GetVertex()));
// occluder will be deleted by the grid // occluder will be deleted by the grid
Polygon3r *occluder = Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal());
new Polygon3r(vectors, (*f)->GetNormal());
occluder->setId(_polygon_id++); occluder->setId(_polygon_id++);
occluder->userdata = (void *)(*f); occluder->userdata = (void *)(*f);
_grid->insertOccluder(occluder); _grid->insertOccluder(occluder);

View File

@@ -1,45 +1,50 @@
// /*
// Filename : WSFillGrid.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Class to fill in a grid from a SceneGraph * This program is free software; you can redistribute it and/or
// (uses only the WingedEdge structures) * modify it under the terms of the GNU General Public License
// Date of creation : 03/05/2003 * 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__
// /** \file blender/freestyle/intern/winged_edge/WSFillGrid.h
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 03/05/2003
// 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 WS_FILL_GRID_H #include "WEdge.h"
# define WS_FILL_GRID_H
#include "../geometry/Grid.h" #include "../geometry/Grid.h"
#include "../geometry/Polygon.h" #include "../geometry/Polygon.h"
# include "WEdge.h"
class LIB_WINGED_EDGE_EXPORT WSFillGrid class LIB_WINGED_EDGE_EXPORT WSFillGrid
{ {
public: public:
inline WSFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
inline WSFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) { {
_winged_edge = winged_edge; _winged_edge = winged_edge;
_grid = grid; _grid = grid;
_polygon_id = 0; _polygon_id = 0;
@@ -50,30 +55,33 @@ public:
void fillGrid(); void fillGrid();
/*! Accessors */ /*! Accessors */
WingedEdge* getWingedEdge() { WingedEdge *getWingedEdge()
{
return _winged_edge; return _winged_edge;
} }
Grid* getGrid() { Grid *getGrid()
{
return _grid; return _grid;
} }
/*! Modifiers */ /*! Modifiers */
void setWingedEdge(WingedEdge* winged_edge) { void setWingedEdge(WingedEdge *winged_edge)
{
if (winged_edge) if (winged_edge)
_winged_edge = winged_edge; _winged_edge = winged_edge;
} }
void setGrid(Grid* grid) { void setGrid(Grid *grid)
{
if (grid) if (grid)
_grid = grid; _grid = grid;
} }
private: private:
Grid *_grid; Grid *_grid;
WingedEdge *_winged_edge; WingedEdge *_winged_edge;
unsigned _polygon_id; unsigned _polygon_id;
}; };
#endif // WS_FILL_GRID_H #endif // __FREESTYLE_WS_FILL_GRID_H__

View File

@@ -1,34 +1,49 @@
// /*
// Copyright (C) : Please refer to the COPYRIGHT file distributed * ***** BEGIN GPL LICENSE BLOCK *****
// with this source distribution. *
// * This program is free software; you can redistribute it and/or
// This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License
// modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2
// as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version.
// of the License, or (at your option) any later version. *
// * This program 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
// but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details.
// GNU General Public License for more details. *
// * You should have received a copy of the GNU General Public License
// You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation,
// along with this program; if not, write to the Free Software * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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" #include "WXEdge.h"
/**********************************/ /**********************************
/* */ * *
/* */ * *
/* WXFace */ * WXFace *
/* */ * *
/* */ * *
/**********************************/ **********************************/
unsigned int WXFaceLayer::Get0VertexIndex() const { unsigned int WXFaceLayer::Get0VertexIndex() const
{
int i = 0; int i = 0;
int nEdges = _pWXFace->numberOfEdges(); int nEdges = _pWXFace->numberOfEdges();
for (i = 0; i < nEdges; ++i) { for (i = 0; i < nEdges; ++i) {
@@ -38,7 +53,8 @@ unsigned int WXFaceLayer::Get0VertexIndex() const {
} }
return -1; return -1;
} }
unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{ unsigned int WXFaceLayer::GetSmoothEdgeIndex() const
{
int i = 0; int i = 0;
int nEdges = _pWXFace->numberOfEdges(); int nEdges = _pWXFace->numberOfEdges();
for (i = 0; i < nEdges; ++i) { for (i = 0; i < nEdges; ++i) {
@@ -49,7 +65,8 @@ unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{
return -1; return -1;
} }
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){ void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges)
{
int i = 0; int i = 0;
int nEdges = _pWXFace->numberOfEdges(); int nEdges = _pWXFace->numberOfEdges();
for (i = 0; i < nEdges; ++i) { for (i = 0; i < nEdges; ++i) {
@@ -60,10 +77,10 @@ void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){
} }
} }
WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){ WXSmoothEdge *WXFaceLayer::BuildSmoothEdge()
// if the smooth edge has already been {
// built: exit // if the smooth edge has already been built: exit
if(0 != _pSmoothEdge) if (_pSmoothEdge)
return _pSmoothEdge; return _pSmoothEdge;
real ta, tb; real ta, tb;
WOEdge *woea(0), *woeb(0); WOEdge *woea(0), *woeb(0);
@@ -72,24 +89,20 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
int indexStart, indexEnd; int indexStart, indexEnd;
unsigned nedges = _pWXFace->numberOfEdges(); unsigned nedges = _pWXFace->numberOfEdges();
if (_nNullDotP == nedges) { if (_nNullDotP == nedges) {
_pSmoothEdge = 0; _pSmoothEdge = NULL;
return _pSmoothEdge; return _pSmoothEdge;
} }
if ((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)) { if ((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)) {
// that means that we have a smooth edge that starts from // that means that we have a smooth edge that starts from an edge and ends at an edge
// an edge and ends at an edge
//----------------------------- //-----------------------------
// We retrieve the 2 edges for which we have // We retrieve the 2 edges for which we have opposite signs for each extremity
// opposite signs for each extremity
RetrieveCuspEdgesIndices(cuspEdgesIndices); RetrieveCuspEdgesIndices(cuspEdgesIndices);
if (cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges if (cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges
return 0; return 0;
// let us determine which cusp edge corresponds to the starting: // let us determine which cusp edge corresponds to the starting:
// We can do that because we defined that // We can do that because we defined that a silhouette edge had the back facing part on its right.
// 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.
// 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) { if (_DotP[cuspEdgesIndices[0]] > 0) {
@@ -97,7 +110,8 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]); woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
indexStart = cuspEdgesIndices[0]; indexStart = cuspEdgesIndices[0];
indexEnd = cuspEdgesIndices[1]; indexEnd = cuspEdgesIndices[1];
}else{ }
else {
woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]); woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
indexStart = cuspEdgesIndices[1]; indexStart = cuspEdgesIndices[1];
@@ -108,20 +122,19 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]); ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]); tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
ok = true; ok = true;
}else if(_nNullDotP == 1){ }
// that means that we have exactly one of the else if (_nNullDotP == 1) {
// 2 extremities of our silhouette edge is // that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex of the mesh
// a vertex of the mesh
if ((_nPosDotP == 2) || (_nPosDotP == 0)) { if ((_nPosDotP == 2) || (_nPosDotP == 0)) {
_pSmoothEdge = 0; _pSmoothEdge = NULL;
return _pSmoothEdge; return _pSmoothEdge;
} }
RetrieveCuspEdgesIndices(cuspEdgesIndices); RetrieveCuspEdgesIndices(cuspEdgesIndices);
// We should have only one EdgeCusp: // We should have only one EdgeCusp:
if (cuspEdgesIndices.size() != 1) { if (cuspEdgesIndices.size() != 1) {
cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl; cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl;
_pSmoothEdge = 0; _pSmoothEdge = NULL;
return 0; return NULL;
} }
unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
unsigned nedges = _pWXFace->numberOfEdges(); unsigned nedges = _pWXFace->numberOfEdges();
@@ -131,7 +144,8 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
indexStart = cuspEdgesIndices[0]; indexStart = cuspEdgesIndices[0];
ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]); ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
tb = 0.0; tb = 0.0;
}else{ }
else {
woea = _pWXFace->GetOEdge(index0); woea = _pWXFace->GetOEdge(index0);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
indexEnd = cuspEdgesIndices[0]; indexEnd = cuspEdgesIndices[0];
@@ -139,9 +153,9 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]); tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
} }
ok = true; ok = true;
}else if(_nNullDotP == 2){ }
// that means that the silhouette edge else if (_nNullDotP == 2) {
// is an edge of the mesh // that means that the silhouette edge is an edge of the mesh
int index = GetSmoothEdgeIndex(); int index = GetSmoothEdgeIndex();
if (!_pWXFace->front()) { // is it in the right order ? if (!_pWXFace->front()) { // is it in the right order ?
// the order of the WOEdge index is wrong // the order of the WOEdge index is wrong
@@ -150,14 +164,17 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
ta = 0; ta = 0;
tb = 1; tb = 1;
ok = true; ok = true;
}else{ }
else {
// here it's not good, our edge is a single point -> skip that face // here it's not good, our edge is a single point -> skip that face
ok = false; ok = false;
#if 0
// the order of the WOEdge index is good // the order of the WOEdge index is good
// woea = _pWXFace->GetOEdge((index-1)%nedges); woea = _pWXFace->GetOEdge((index - 1) % nedges);
// woeb = _pWXFace->GetOEdge((index+1)%nedges); woeb = _pWXFace->GetOEdge((index + 1) % nedges);
// ta = 1; ta = 1;
// tb = 0; tb = 0;
#endif
} }
} }
if (ok) { if (ok) {
@@ -176,60 +193,53 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
} }
} }
// check bording edges to see if they have different dotp values #if 0
// in bording faces. // check bording edges to see if they have different dotp values in bording faces.
// for(int i=0; i<numberOfEdges(); i++) for (int i = 0; i < numberOfEdges(); i++) {
// { WSFace *bface = (WSFace *)GetBordingFace(i);
// WSFace * bface = (WSFace*)GetBordingFace(i); if (bface) {
// 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
// if((front())^(bface->front())) // fA->front XOR fB->front (true if one is 0 and the other is 1) // CHECK FIRST WHETHER THE EXACTSILHOUETTEEDGE HAS NOT YET BEEN BUILT ON THE OTHER FACE (1 is enough).
// { if (((WSExactFace *)bface)->exactSilhouetteEdge()) {
// // that means that the edge i of the face is // that means that this silhouette edge has already been built
// // a silhouette edge return ((WSExactFace *)bface)->exactSilhouetteEdge();
// // TESTER D'ABORD SI LE EXACTSILHOUETTEEDGE N'A PAS }
// // ETE CONSTRUIT SUR L'AUTRE FACE.(1 suffit) // Else we must build it
// if(0 != ((WSExactFace*)bface)->exactSilhouetteEdge()) WOEdge *woea, *woeb;
// { real ta, tb;
// // that means that this silhouette edge has already been built if (!front()) { // is it in the right order ?
// return ((WSExactFace*)bface)->exactSilhouetteEdge(); // the order of the WOEdge index is wrong
// } woea = _OEdgeList[(i + 1) % numberOfEdges()];
// // Else we must build it if (0 == i)
// WOEdge *woea, *woeb; woeb = _OEdgeList[numberOfEdges() - 1];
// real ta, tb; else
// if(!front()) // is it in the right order ? woeb = _OEdgeList[(i - 1)];
// { ta = 0;
// // the order of the WOEdge index is wrong tb = 1;
// woea = _OEdgeList[(i+1)%numberOfEdges()]; }
// if(0 == i) else {
// woeb = _OEdgeList[numberOfEdges()-1]; // the order of the WOEdge index is good
// else if (0 == i)
// woeb = _OEdgeList[(i-1)]; woea = _OEdgeList[numberOfEdges() - 1];
// ta = 0; else
// tb = 1; woea = _OEdgeList[(i - 1)];
// } woeb = _OEdgeList[(i + 1) % numberOfEdges()];
// else ta = 1;
// { tb = 0;
// // the order of the WOEdge index is good }
// if(0 == i)
// woea = _OEdgeList[numberOfEdges()-1]; _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
// else _pSmoothEdge->setWOeA(woea);
// woea = _OEdgeList[(i-1)]; _pSmoothEdge->setWOeA(woeb);
// woeb = _OEdgeList[(i+1)%numberOfEdges()]; _pSmoothEdge->setTa(ta);
// ta = 1; _pSmoothEdge->setTb(tb);
// tb = 0;
// } return _pSmoothEdge;
// }
// _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX); }
// _pSmoothEdge->setWOeA(woea); }
// _pSmoothEdge->setWOeA(woeb); #endif
// _pSmoothEdge->setTa(ta);
// _pSmoothEdge->setTb(tb);
//
// return _pSmoothEdge;
// }
// }
//}
return _pSmoothEdge; return _pSmoothEdge;
} }
@@ -239,36 +249,29 @@ void WXFace::ComputeCenter()
vector<WVertex *> iVertexList; vector<WVertex *> iVertexList;
RetrieveVertexList(iVertexList); RetrieveVertexList(iVertexList);
Vec3r center; Vec3r center;
for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
wv!=wvend;
wv++)
{
center += (*wv)->GetVertex(); center += (*wv)->GetVertex();
} }
center /= (real)iVertexList.size(); center /= (real)iVertexList.size();
setCenter(center); 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); WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
if(0 == face) if (!face)
return 0; return NULL;
Vec3r center; Vec3r center;
for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
wv!=wvend;
wv++)
{
center += (*wv)->GetVertex(); center += (*wv)->GetVertex();
} }
center /= (real)iVertexList.size(); center /= (real)iVertexList.size();
@@ -277,20 +280,19 @@ WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeM
return face; 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); WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
// Vec3r center; #if 0
// for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); Vec3r center;
// wv!=wvend; for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
// wv++) center += (*wv)->GetVertex();
// { }
// center += (*wv)->GetVertex(); center /= (real)iVertexList.size();
// } ((WSFace *)face)->setCenter(center);
// center /= (real)iVertexList.size(); #endif
// ((WSFace*)face)->setCenter(center);
return face; return face;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +1,40 @@
// /*
// Copyright (C) : Please refer to the COPYRIGHT file distributed * ***** BEGIN GPL LICENSE BLOCK *****
// with this source distribution. *
// * This program is free software; you can redistribute it and/or
// This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License
// modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2
// as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version.
// of the License, or (at your option) any later version. *
// * This program 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
// but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details.
// GNU General Public License for more details. *
// * You should have received a copy of the GNU General Public License
// You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation,
// along with this program; if not, write to the Free Software * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "WXEdge.h"
#include "WXEdgeBuilder.h"
void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
{ {
@@ -32,14 +47,11 @@ void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
//ifs.setId(shape->GetId()); //ifs.setId(shape->GetId());
} }
void WXEdgeBuilder::buildWVertices(WShape& shape, void WXEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize)
const real *vertices, {
unsigned vsize) {
WXVertex *vertex; WXVertex *vertex;
for (unsigned i = 0; i < vsize; i += 3) { for (unsigned int i = 0; i < vsize; i += 3) {
vertex = new WXVertex(Vec3r(vertices[i], vertex = new WXVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
vertices[i + 1],
vertices[i + 2]));
vertex->setId(i / 3); vertex->setId(i / 3);
shape.AddVertex(vertex); shape.AddVertex(vertex);
} }

View File

@@ -1,38 +1,43 @@
#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 *****
*/
// #ifndef __FREESTYLE_WX_EDGE_BUILDER_H__
// Filename : WSBuilder.h #define __FREESTYLE_WX_EDGE_BUILDER_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
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/winged_edge/WSBuilder.h
// * \ingroup freestyle
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info
// with this source distribution. * (silhouette etc...)) structure from a polygonal model
// * \author Stephane Grabli
// This program is free software; you can redistribute it and/or * \date 28/05/2003
// 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 class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder
@@ -43,9 +48,7 @@ public:
VISIT_DECL(IndexedFaceSet) VISIT_DECL(IndexedFaceSet)
protected: protected:
virtual void buildWVertices(WShape& shape, virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
const real *vertices,
unsigned vsize);
}; };
#endif // WXEDGEBUILDER_H #endif // __FREESTYLE_WX_EDGE_BUILDER_H__

View File

@@ -1,31 +1,50 @@
/*
* ***** 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes
// * of a scene graph
// This program is free software; you can redistribute it and/or * \author Stephane Grabli
// modify it under the terms of the GNU General Public License * \date 28/05/2003
// as published by the Free Software Foundation; either version 2 */
// of the License, or (at your option) any later version.
// #include <set>
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of #include "WingedEdgeBuilder.h"
// 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 "../geometry/GeomUtils.h" #include "../geometry/GeomUtils.h"
#include "../scene_graph/NodeShape.h" #include "../scene_graph/NodeShape.h"
#include "WingedEdgeBuilder.h"
#include <set>
using namespace std; using namespace std;
void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) { void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
{
if (_pRenderMonitor && _pRenderMonitor->testBreak()) if (_pRenderMonitor && _pRenderMonitor->testBreak())
return; return;
WShape *shape = new WShape; WShape *shape = new WShape;
@@ -34,12 +53,14 @@ void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) {
//ifs.setId(shape->GetId()); //ifs.setId(shape->GetId());
} }
void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) { void WingedEdgeBuilder::visitNodeShape(NodeShape& ns)
{
//Sets the current material to iShapeode->material: //Sets the current material to iShapeode->material:
_current_frs_material = &(ns.frs_material()); _current_frs_material = &(ns.frs_material());
} }
void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) { void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn)
{
if (!_current_matrix) { if (!_current_matrix) {
_current_matrix = new Matrix44r(tn.matrix()); _current_matrix = new Matrix44r(tn.matrix());
return; return;
@@ -50,7 +71,8 @@ void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) {
_current_matrix = new_matrix; _current_matrix = new_matrix;
} }
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) { void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&)
{
if (_current_matrix) if (_current_matrix)
delete _current_matrix; delete _current_matrix;
@@ -63,9 +85,10 @@ void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) {
_matrices_stack.pop_back(); _matrices_stack.pop_back();
} }
void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs)
unsigned vsize = ifs.vsize(); {
unsigned nsize = ifs.nsize(); unsigned int vsize = ifs.vsize();
unsigned int nsize = ifs.nsize();
//soc unused - unsigned tsize = ifs.tsize(); //soc unused - unsigned tsize = ifs.tsize();
const real *vertices = ifs.vertices(); const real *vertices = ifs.vertices();
@@ -98,12 +121,13 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
shape.setFrsMaterials(frs_materials); shape.setFrsMaterials(frs_materials);
} }
// const FrsMaterial * mat = (ifs.frs_material()); #if 0
// if (mat) const FrsMaterial *mat = (ifs.frs_material());
// shape.setFrsMaterial(*mat); if (mat)
// else if(_current_frs_material) shape.setFrsMaterial(*mat);
// shape.setFrsMaterial(*_current_frs_material); else if (_current_frs_material)
shape.setFrsMaterial(*_current_frs_material);
#endif
const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks(); const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();
// sets the current WShape to shape // sets the current WShape to shape
@@ -112,56 +136,32 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
// create a WVertex for each vertex // create a WVertex for each vertex
buildWVertices(shape, new_vertices, vsize); buildWVertices(shape, new_vertices, vsize);
const unsigned* vindices = ifs.vindices(); const unsigned int *vindices = ifs.vindices();
const unsigned* nindices = ifs.nindices(); const unsigned int *nindices = ifs.nindices();
const unsigned* tindices = 0; const unsigned int *tindices = NULL;
if (ifs.tsize()) { if (ifs.tsize()) {
tindices = ifs.tindices(); tindices = ifs.tindices();
} }
const unsigned *mindices = 0; const unsigned int *mindices = NULL;
if (ifs.msize()) if (ifs.msize())
mindices = ifs.mindices(); mindices = ifs.mindices();
const unsigned* numVertexPerFace = ifs.numVertexPerFaces(); const unsigned int *numVertexPerFace = ifs.numVertexPerFaces();
const unsigned numfaces = ifs.numFaces(); const unsigned int numfaces = ifs.numFaces();
for (unsigned index = 0; index < numfaces; index++) { for (unsigned int index = 0; index < numfaces; index++) {
switch (faceStyle[index]) { switch (faceStyle[index]) {
case IndexedFaceSet::TRIANGLE_STRIP: case IndexedFaceSet::TRIANGLE_STRIP:
buildTriangleStrip(new_vertices, buildTriangleStrip(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
new_normals, nindices, mindices, tindices, numVertexPerFace[index]);
frs_materials,
texCoords,
faceEdgeMarks,
vindices,
nindices,
mindices,
tindices,
numVertexPerFace[index]);
break; break;
case IndexedFaceSet::TRIANGLE_FAN: case IndexedFaceSet::TRIANGLE_FAN:
buildTriangleFan(new_vertices, buildTriangleFan(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
new_normals, nindices, mindices, tindices, numVertexPerFace[index]);
frs_materials,
texCoords,
faceEdgeMarks,
vindices,
nindices,
mindices,
tindices,
numVertexPerFace[index]);
break; break;
case IndexedFaceSet::TRIANGLES: case IndexedFaceSet::TRIANGLES:
buildTriangles(new_vertices, buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
new_normals, nindices, mindices, tindices, numVertexPerFace[index]);
frs_materials,
texCoords,
faceEdgeMarks,
vindices,
nindices,
mindices,
tindices,
numVertexPerFace[index]);
break; break;
} }
vindices += numVertexPerFace[index]; vindices += numVertexPerFace[index];
@@ -184,9 +184,7 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
// Parse the built winged-edge shape to update post-flags // Parse the built winged-edge shape to update post-flags
set<Vec3r> normalsSet; set<Vec3r> normalsSet;
vector<WVertex *>& wvertices = shape.getVertexList(); vector<WVertex *>& wvertices = shape.getVertexList();
for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end(); for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
wv!=wvend;
++wv){
if ((*wv)->isBoundary()) if ((*wv)->isBoundary())
continue; continue;
if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.) if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
@@ -194,13 +192,12 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
normalsSet.clear(); normalsSet.clear();
WVertex::face_iterator fit = (*wv)->faces_begin(); WVertex::face_iterator fit = (*wv)->faces_begin();
WVertex::face_iterator fitend = (*wv)->faces_end(); WVertex::face_iterator fitend = (*wv)->faces_end();
while(fit!=fitend){ for (; fit != fitend; ++fit) {
WFace *face = *fit; WFace *face = *fit;
normalsSet.insert(face->GetVertexNormal(*wv)); normalsSet.insert(face->GetVertexNormal(*wv));
if (normalsSet.size() != 1) { if (normalsSet.size() != 1) {
break; break;
} }
++fit;
} }
if (normalsSet.size() !=1 ) { if (normalsSet.size() !=1 ) {
(*wv)->setSmooth(false); (*wv)->setSmooth(false);
@@ -210,29 +207,21 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
_winged_edge->addWShape(&shape); _winged_edge->addWShape(&shape);
} }
void WingedEdgeBuilder::buildWVertices(WShape& shape, void WingedEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize)
const real *vertices, {
unsigned vsize) {
WVertex *vertex; WVertex *vertex;
for (unsigned i = 0; i < vsize; i += 3) { for (unsigned int i = 0; i < vsize; i += 3) {
vertex = new WVertex(Vec3r(vertices[i], vertex = new WVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
vertices[i + 1],
vertices[i + 2]));
vertex->setId(i / 3); vertex->setId(i / 3);
shape.AddVertex(vertex); shape.AddVertex(vertex);
} }
} }
void WingedEdgeBuilder::buildTriangleStrip( const real *vertices, void WingedEdgeBuilder::buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *normals, const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
vector<FrsMaterial>& iMaterials, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const real *texCoords, const unsigned *tindices, const unsigned nvertices)
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 nDoneVertices = 2; // number of vertices already treated
unsigned nTriangle = 0; // number of the triangle currently being treated unsigned nTriangle = 0; // number of the triangle currently being treated
//int nVertex = 0; // vertex number //int nVertex = 0; // vertex number
@@ -243,79 +232,79 @@ void WingedEdgeBuilder::buildTriangleStrip( const real *vertices,
vector<Vec2r> triangleTexCoords; vector<Vec2r> triangleTexCoords;
vector<bool> triangleFaceEdgeMarks; vector<bool> triangleFaceEdgeMarks;
while(nDoneVertices < nvertices) while (nDoneVertices < nvertices) {
{
//clear the vertices list: //clear the vertices list:
triangleVertices.clear(); triangleVertices.clear();
//Then rebuild it: //Then rebuild it:
if(0 == nTriangle%2) // if nTriangle is even if (0 == nTriangle % 2) { // if nTriangle is even
{
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 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]], normals[nindices[nTriangle] + 1],
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]],normals[nindices[nTriangle+1]+1],normals[nindices[nTriangle+1]+2])); 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]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
normals[nindices[nTriangle + 2] + 2]));
if (texCoords) { if (texCoords) {
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); 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 + 1]],
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]], texCoords[tindices[nTriangle+2]+1])); texCoords[tindices[nTriangle + 1] + 1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
texCoords[tindices[nTriangle + 2] + 1]));
} }
} }
else // if nTriangle is odd else { // if nTriangle is odd
{
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 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]], normals[nindices[nTriangle] + 1],
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]],normals[nindices[nTriangle+2]+1],normals[nindices[nTriangle+2]+2])); 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]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
normals[nindices[nTriangle + 1] + 2]));
if (texCoords) { if (texCoords) {
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); 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 + 2]],
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]], texCoords[tindices[nTriangle+1]+1])); 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::FACE_MARK) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 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_V2V3) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
if(mindices) if (mindices) {
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[nTriangle/3]); currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
else mindices[nTriangle / 3]);
}
else {
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
}
nDoneVertices++; // with a strip, each triangle is one vertex more nDoneVertices++; // with a strip, each triangle is one vertex more
nTriangle++; nTriangle++;
} }
} }
void WingedEdgeBuilder::buildTriangleFan( const real *vertices, void WingedEdgeBuilder::buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *normals, const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
vector<FrsMaterial>& iMaterials, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const real *texCoords, const unsigned *tindices, const unsigned nvertices)
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, {
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices) {
// Nothing to be done // Nothing to be done
} }
void WingedEdgeBuilder::buildTriangles(const real *vertices, void WingedEdgeBuilder::buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *normals, const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
vector<FrsMaterial>& iMaterials, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const real *texCoords, const unsigned *tindices, const unsigned nvertices)
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 WShape *currentShape = _current_wshape; // the current shape begin built
vector<WVertex *> triangleVertices; vector<WVertex *> triangleVertices;
vector<Vec3r> triangleNormals; vector<Vec3r> triangleNormals;
@@ -323,15 +312,17 @@ void WingedEdgeBuilder::buildTriangles(const real *vertices,
vector<bool> triangleFaceEdgeMarks; vector<bool> triangleFaceEdgeMarks;
// Each triplet of vertices is considered as an independent triangle // Each triplet of vertices is considered as an independent triangle
for(unsigned i = 0; i < nvertices / 3; i++) 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] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 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]], normals[nindices[3 * i] + 1],
triangleNormals.push_back(Vec3r(normals[nindices[3*i+1]],normals[nindices[3*i+1]+1],normals[nindices[3*i+1]+2])); normals[nindices[3 * i] + 2]));
triangleNormals.push_back(Vec3r(normals[nindices[3*i+2]], normals[nindices[3*i+2]+1], normals[nindices[3*i+2]+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) { if (texCoords) {
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1]));
@@ -345,40 +336,36 @@ void WingedEdgeBuilder::buildTriangles(const real *vertices,
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
} }
if (mindices) if (mindices)
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]); currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
mindices[0]);
else else
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
} }
void WingedEdgeBuilder::transformVertices(const real *vertices, void WingedEdgeBuilder::transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res)
unsigned vsize, {
const Matrix44r& transform,
real *res) {
const real *v = vertices; const real *v = vertices;
real *pv = res; real *pv = res;
for (unsigned i = 0; i < vsize / 3; i++) { for (unsigned int i = 0; i < vsize / 3; i++) {
HVec3r hv_tmp(v[0], v[1], v[2]); HVec3r hv_tmp(v[0], v[1], v[2]);
HVec3r hv(transform * hv_tmp); HVec3r hv(transform * hv_tmp);
for (unsigned j = 0; j < 3; j++) for (unsigned int j = 0; j < 3; j++)
pv[j] = hv[j] / hv[3]; pv[j] = hv[j] / hv[3];
v += 3; v += 3;
pv += 3; pv += 3;
} }
} }
void WingedEdgeBuilder::transformNormals(const real *normals, void WingedEdgeBuilder::transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res)
unsigned nsize, {
const Matrix44r& transform,
real* res) {
const real *n = normals; const real *n = normals;
real *pn = res; real *pn = res;
for (unsigned i = 0; i < nsize / 3; i++) { for (unsigned int i = 0; i < nsize / 3; i++) {
Vec3r hn(n[0], n[1], n[2]); Vec3r hn(n[0], n[1], n[2]);
hn = GeomUtils::rotateVector(transform, hn); hn = GeomUtils::rotateVector(transform, hn);
for (unsigned j = 0; j < 3; j++) for (unsigned int j = 0; j < 3; j++)
pn[j] = hn[j]; pn[j] = hn[j];
n += 3; n += 3;
pn += 3; pn += 3;

View File

@@ -1,49 +1,55 @@
// /*
// Filename : WingedEdgeBuilder.h * ***** BEGIN GPL LICENSE BLOCK *****
// Author(s) : Stephane Grabli *
// Purpose : Class to render a WingedEdge data structure * This program is free software; you can redistribute it and/or
// from a polyhedral data structure organized in * modify it under the terms of the GNU General Public License
// nodes of a scene graph * as published by the Free Software Foundation; either version 2
// Date of creation : 28/05/03 * 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
// Copyright (C) : Please refer to the COPYRIGHT file distributed * \ingroup freestyle
// with this source distribution. * \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes
// * of a scene graph
// This program is free software; you can redistribute it and/or * \author Stephane Grabli
// modify it under the terms of the GNU General Public License * \date 28/05/2003
// 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 #include "WEdge.h"
# define WINGED_EDGE_BUILDER_H
#include "../scene_graph/IndexedFaceSet.h"
#include "../scene_graph/NodeTransform.h"
#include "../scene_graph/SceneVisitor.h"
#include "../system/FreestyleConfig.h" #include "../system/FreestyleConfig.h"
#include "../system/RenderMonitor.h" #include "../system/RenderMonitor.h"
# include "../scene_graph/SceneVisitor.h"
# include "WEdge.h"
# include "../scene_graph/IndexedFaceSet.h"
# include "../scene_graph/NodeTransform.h"
class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
{ {
public: public:
inline WingedEdgeBuilder() : SceneVisitor()
inline WingedEdgeBuilder() : SceneVisitor() { {
_current_wshape = NULL; _current_wshape = NULL;
_current_frs_material = NULL; _current_frs_material = NULL;
_current_matrix = NULL; _current_matrix = NULL;
@@ -51,10 +57,9 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
_pRenderMonitor = NULL; _pRenderMonitor = NULL;
} }
virtual ~WingedEdgeBuilder() { virtual ~WingedEdgeBuilder()
for (vector<Matrix44r*>::iterator it = _matrices_stack.begin(); {
it != _matrices_stack.end(); for (vector<Matrix44r*>::iterator it = _matrices_stack.begin(); it != _matrices_stack.end(); ++it)
it++)
delete *it; delete *it;
_matrices_stack.clear(); _matrices_stack.clear();
} }
@@ -70,19 +75,23 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
// //
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
inline WingedEdge* getWingedEdge() { inline WingedEdge *getWingedEdge()
{
return _winged_edge; return _winged_edge;
} }
inline WShape* getCurrentWShape() { inline WShape *getCurrentWShape()
{
return _current_wshape; return _current_wshape;
} }
inline FrsMaterial* getCurrentFrsMaterial() { inline FrsMaterial *getCurrentFrsMaterial()
{
return _current_frs_material; return _current_frs_material;
} }
inline Matrix44r* getCurrentMatrix() { inline Matrix44r *getCurrentMatrix()
{
return _current_matrix; return _current_matrix;
} }
@@ -91,75 +100,52 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
// //
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
inline void setCurrentWShape(WShape* wshape) { inline void setCurrentWShape(WShape *wshape)
{
_current_wshape = wshape; _current_wshape = wshape;
} }
inline void setCurrentFrsMaterial(FrsMaterial* mat) { inline void setCurrentFrsMaterial(FrsMaterial *mat)
{
_current_frs_material = mat; _current_frs_material = mat;
} }
// inline void setCurrentMatrix(Matrix44r* matrix) { #if 0
// _current_matrix = matrix; inline void setCurrentMatrix(Matrix44r *matrix)
// } {
_current_matrix = matrix;
}
#endif
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) { inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {
_pRenderMonitor = iRenderMonitor; _pRenderMonitor = iRenderMonitor;
} }
protected: protected:
virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs); virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs);
virtual void buildWVertices(WShape& shape, virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
const real *vertices,
unsigned vsize);
RenderMonitor *_pRenderMonitor; RenderMonitor *_pRenderMonitor;
private: 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 buildTriangleStrip(const real *vertices, void buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *normals, const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
vector<FrsMaterial>& iMaterials, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const real *texCoords, const unsigned *tindices, const unsigned nvertices);
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices);
void buildTriangleFan(const real *vertices, void buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *normals, const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
vector<FrsMaterial>& iMaterials, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const real *texCoords, const unsigned *tindices, const unsigned nvertices);
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices);
void buildTriangles(const real *vertices, void transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res);
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, void transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res);
unsigned vsize,
const Matrix44r& transform,
real *res);
void transformNormals(const real *normals,
unsigned nsize,
const Matrix44r& transform,
real *res);
WShape *_current_wshape; WShape *_current_wshape;
FrsMaterial *_current_frs_material; FrsMaterial *_current_frs_material;
@@ -168,4 +154,4 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
vector<Matrix44r *> _matrices_stack; vector<Matrix44r *> _matrices_stack;
}; };
#endif // WINGED_EDGE_BUILDER_H #endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__