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,52 +1,58 @@
// /*
// 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],
: GridDensityProvider(source), numCells(numCells) unsigned 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,
: GridDensityProvider(source), numCells(numCells) const GridHelpers::Transform& transform, unsigned numCells)
: GridDensityProvider(source), numCells(numCells)
{ {
real proscenium[4]; real proscenium[4];
calculateQuickProscenium(transform, bbox, proscenium); calculateQuickProscenium(transform, bbox, proscenium);
initialize (proscenium); initialize (proscenium);
} }
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells) ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells)
: GridDensityProvider(source), numCells(numCells) : GridDensityProvider(source), numCells(numCells)
{ {
real proscenium[4]; real proscenium[4];
calculateOptimalProscenium(source, proscenium); calculateOptimalProscenium(source, proscenium);
@@ -54,9 +60,9 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& sourc
initialize (proscenium); initialize (proscenium);
} }
ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider () {} ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider() {}
void ArbitraryGridDensityProvider::initialize (const real proscenium[4]) void ArbitraryGridDensityProvider::initialize(const real proscenium[4])
{ {
float prosceniumWidth = (proscenium[1] - proscenium[0]); float prosceniumWidth = (proscenium[1] - proscenium[0]);
float prosceniumHeight = (proscenium[3] - proscenium[2]); float prosceniumHeight = (proscenium[3] - proscenium[2]);
@@ -70,11 +76,11 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl; 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;
} }
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) { if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize; _cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
} }
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl; cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
@@ -85,24 +91,26 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
} }
ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigned numCells) ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigned numCells)
: numCells(numCells) : numCells(numCells)
{ {
} }
ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory () {} ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory() {}
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4]) auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source,
const real proscenium[4])
{ {
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, proscenium, numCells)); 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));
} }
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source) auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{ {
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells)); return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
} }

View File

@@ -1,48 +1,54 @@
// /*
// 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();
protected: protected:
unsigned numCells; unsigned numCells;
@@ -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,69 +1,75 @@
// /*
// 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],
: GridDensityProvider(source) real sizeFactor)
: 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,
: GridDensityProvider(source) const GridHelpers::Transform& transform, real sizeFactor)
: GridDensityProvider(source)
{ {
real proscenium[4]; real proscenium[4];
calculateQuickProscenium(transform, bbox, proscenium); calculateQuickProscenium(transform, bbox, proscenium);
initialize (proscenium, sizeFactor); initialize(proscenium, sizeFactor);
} }
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor) AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor)
: GridDensityProvider(source) : GridDensityProvider(source)
{ {
real proscenium[4]; real proscenium[4];
calculateOptimalProscenium(source, proscenium); calculateOptimalProscenium(source, proscenium);
initialize (proscenium, sizeFactor); initialize(proscenium, sizeFactor);
} }
AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider () {} AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider() {}
void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real sizeFactor) void AverageAreaGridDensityProvider::initialize(const real proscenium[4], real sizeFactor)
{ {
float prosceniumWidth = (proscenium[1] - proscenium[0]); float prosceniumWidth = (proscenium[1] - proscenium[0]);
float prosceniumHeight = (proscenium[3] - proscenium[2]); float prosceniumHeight = (proscenium[3] - proscenium[2]);
real cellArea = 0.0; real cellArea = 0.0;
unsigned numFaces = 0; unsigned numFaces = 0;
for ( source.begin(); source.isValid(); source.next() ) { for (source.begin(); source.isValid(); source.next()) {
Polygon3r& poly(source.getGridSpacePolygon()); Polygon3r& poly(source.getGridSpacePolygon());
Vec3r min, max; Vec3r min, max;
poly.getBBox(min, max); poly.getBBox(min, max);
@@ -82,11 +88,11 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl; 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;
} }
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) { if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize; _cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
} }
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl; cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
@@ -97,24 +103,26 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
} }
AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(real sizeFactor) AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(real sizeFactor)
: sizeFactor(sizeFactor) : sizeFactor(sizeFactor)
{ {
} }
AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory () {} AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory() {}
auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4]) auto_ptr<GridDensityProvider>
AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{ {
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor)); 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));
} }
auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source) auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{ {
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
@@ -42,11 +47,12 @@ using namespace std;
// Cell // Cell
///////// /////////
BoxGrid::Cell::Cell () {} BoxGrid::Cell::Cell() {}
BoxGrid::Cell::~Cell () {} BoxGrid::Cell::~Cell() {}
void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) { void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
{
const real epsilon = 1.0e-06; 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);
} }
@@ -66,47 +74,49 @@ void BoxGrid::Cell::indexPolygons() {
// Iterator // Iterator
////////////////// //////////////////
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;
#endif #endif
// Set iterator // Set iterator
_current = _cell->faces.begin(); _current = _cell->faces.begin();
} }
BoxGrid::Iterator::~Iterator () {} 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();
@@ -115,20 +125,19 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
// Now allocate the cell table and fill it with default (empty) cells // Now allocate the cell table and fill it with default (empty) cells
_cells.resize(_cellsX * _cellsY); _cells.resize(_cellsX * _cellsY);
for ( cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) { for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
(*i) = NULL; (*i) = NULL;
} }
// Identify cells that will be used, and set the dimensions for each // Identify cells that will be used, and set the dimensions for each
ViewMap::fedges_container& fedges = viewMap->FEdges(); ViewMap::fedges_container& fedges = viewMap->FEdges();
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,19 +154,21 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
} }
} }
void BoxGrid::distributePolygons (OccluderSource& source) { void BoxGrid::distributePolygons(OccluderSource& source)
{
unsigned long nFaces = 0; unsigned long nFaces = 0;
unsigned long nKeptFaces = 0; unsigned long nKeptFaces = 0;
for ( source.begin(); source.isValid(); source.next() ) { for (source.begin(); source.isValid(); source.next()) {
OccluderData* occluder = NULL; OccluderData *occluder = NULL;
try { try {
if ( insertOccluder(source, occluder) ) { if (insertOccluder(source, occluder)) {
_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,41 +181,47 @@ 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) {
(*i)->indexPolygons(); (*i)->indexPolygons();
} }
} }
} }
void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) { void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
{
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize)); 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,78 +1,87 @@
// /*
// 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);
explicit Cell (); explicit Cell();
~Cell (); ~Cell();
static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b); static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
void setDimensions(real x, real y, real sizeX, real sizeY); void setDimensions(real x, real y, real sizeX, real sizeY);
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder); void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
@@ -84,43 +93,37 @@ 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();
void nextOccluder (); void nextOccluder();
void nextOccludee (); void nextOccludee();
bool validBeforeTarget(); bool validBeforeTarget();
bool validAfterTarget(); bool validAfterTarget();
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);
Cell* _cell; Cell *_cell;
Vec3r _target; Vec3r _target;
bool _foundOccludee; bool _foundOccludee;
real _occludeeDepth; real _occludeeDepth;
@@ -128,37 +131,39 @@ 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);
Vec3r operator() (const Vec3r& point) const; Vec3r operator()(const Vec3r& point) const;
}; };
private: 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();
Cell* findCell(const Vec3r& point); Cell *findCell(const Vec3r& point);
// Accessors: // Accessors:
bool orthographicProjection() const; bool orthographicProjection() const;
const Vec3r& viewpoint() const; const Vec3r& viewpoint() const;
bool enableQI() const; bool enableQI() const;
Transform transform; Transform transform;
private: private:
@@ -176,51 +181,52 @@ 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 boxgridlogging == 1 if (_foundOccludee) {
#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
while ( _current != _cell->faces.end() && ! testOccluder(true) ) { while (_current != _cell->faces.end() && !testOccluder(true)) {
++_current; ++_current;
} }
} }
inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) { inline bool BoxGrid::Iterator::testOccluder(bool wantOccludee)
{
// End-of-list is not even a valid iterator position // 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();
@@ -230,16 +236,17 @@ 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 { }
if ( (*_current)->shallowest > _target[2] ) { else {
#if boxgridlogging == 1 if ((*_current)->shallowest > _target[2]) {
#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;
@@ -251,67 +258,73 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
// Check to see if target is in the 2D bounding box // Check to see if target is in the 2D bounding box
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;
} while ( _current != _cell->faces.end() && ! testOccluder(false) ); } while (_current != _cell->faces.end() && ! testOccluder(false));
} }
} }
inline void BoxGrid::Iterator::nextOccludee () { inline void BoxGrid::Iterator::nextOccludee()
if ( _current != _cell->faces.end() ) { {
if (_current != _cell->faces.end()) {
do { do {
++_current; ++_current;
} while ( _current != _cell->faces.end() && ! testOccluder(true) ); } while (_current != _cell->faces.end() && ! testOccluder(true));
} }
} }
inline bool BoxGrid::Iterator::validBeforeTarget () { inline bool BoxGrid::Iterator::validBeforeTarget()
{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2]; 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,18 +332,20 @@ 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);
} }
inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p) inline BoxGrid::OccluderData::OccluderData(OccluderSource& source, Polygon3r& p)
: poly(p), : poly(p),
cameraSpacePolygon(source.getCameraSpacePolygon()), cameraSpacePolygon(source.getCameraSpacePolygon()),
face(source.getWFace()) face(source.getWFace())
{ {
// Set shallowest and deepest based on bbox // Set shallowest and deepest based on bbox
Vec3r min, max; Vec3r min, max;
@@ -339,9 +354,10 @@ 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 ( occluder == NULL) { if (GridHelpers::insideProscenium (boundary, poly)) {
if (occluder == NULL) {
// Disposal of occluder will be handled in BoxGrid::distributePolygons(), // Disposal of occluder will be handled in BoxGrid::distributePolygons(),
// or automatically by BoxGrid::_faces; // or automatically by BoxGrid::_faces;
occluder = new OccluderData(source, poly); occluder = new OccluderData(source, poly);
@@ -350,7 +366,8 @@ inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& pol
} }
} }
inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) { inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
{
Polygon3r& poly(source.getGridSpacePolygon()); Polygon3r& poly(source.getGridSpacePolygon());
occluder = NULL; occluder = NULL;
@@ -361,9 +378,9 @@ 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,67 +1,74 @@
// /*
// 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()) {
next(); next();
} }
} }
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() ) { {
if ( testCurrent() ) { while (OccluderSource::next()) {
if (testCurrent()) {
++rejected; ++rejected;
return true; return true;
} }
@@ -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,34 +122,30 @@ 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;
for(ve=viewMap.ViewEdges().begin(), veend=viewMap.ViewEdges().end(); ve!=veend; ve++) { for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
// Overview: // Overview:
// Search for a visible feature edge // Search for a visible feature edge
// 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,28 +157,27 @@ 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()) ) {
// Use this feature edge for visibility deterimination // Use this feature edge for visibility deterimination
fe->setIsInImage(true); fe->setIsInImage(true);
expandGridSpaceOccluderProscenium(fe); expandGridSpaceOccluderProscenium(fe);
// 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) {
// Then store as bestOccluderTarget // Then store as bestOccluderTarget
bestOccluderDistance = d; bestOccluderDistance = d;
bestOccluderTarget = fe; bestOccluderTarget = fe;
@@ -181,33 +186,35 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
} }
// If feature edge crosses the view proscenium // If feature edge crosses the view proscenium
if ( ! (*ve)->isInImage() && crossesProscenium(viewProscenium, fe) ) { if (!(*ve)->isInImage() && crossesProscenium(viewProscenium, fe)) {
// Then the view edge will be included in the image // Then the view edge will be included in the image
(*ve)->setIsInImage(true); (*ve)->setIsInImage(true);
} }
fe = fe->nextEdge(); fe = fe->nextEdge();
} while ( fe != NULL && fe != festart && ! ( bestOccluderTargetFound && (*ve)->isInImage() ) ); } while (fe != NULL && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));
// Either we have run out of FEdges, or we already have the one edge we need to determine visibility // Either we have run out of FEdges, or we already have the one edge we need to determine visibility
// Cull all remaining edges. // Cull all remaining edges.
while ( fe != NULL && fe != festart ) { while (fe != NULL && fe != festart) {
fe->setIsInImage(false); fe->setIsInImage(false);
fe = fe->nextEdge(); fe = fe->nextEdge();
} }
// If bestOccluderTarget was not found inside the occluder proscenium, // If bestOccluderTarget was not found inside the occluder proscenium,
// we need to expand the occluder proscenium to include it. // we need to expand the occluder proscenium to include it.
if ( (*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound ) { if ((*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound) {
// Expand occluder proscenium to enclose bestOccluderTarget // Expand occluder proscenium to enclose bestOccluderTarget
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,22 +232,18 @@ 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 if (extensiveFEdgeSearch) {
// occluder proscenium has been expanded since the edge was visited
// on the first pass.
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++) {
if ( ! (*ve)->isInImage() ) { if (!(*ve)->isInImage()) {
continue; continue;
} }
// For each feature edge, // For each feature edge,
@@ -248,30 +251,31 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
FEdge *fe = festart; FEdge *fe = festart;
do { do {
// If not (already) visible and center point inside occluder proscenium, // If not (already) visible and center point inside occluder proscenium,
if ( ! fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d()) ) { if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
// Use the feature edge for visibility determination // Use the feature edge for visibility determination
fe->setIsInImage(true); fe->setIsInImage(true);
expandGridSpaceOccluderProscenium(fe); expandGridSpaceOccluderProscenium(fe);
} }
fe = fe->nextEdge(); fe = fe->nextEdge();
} while ( fe != NULL && fe != festart ); } while (fe != NULL && fe != festart);
} }
} }
// 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 ) { {
GridHelpers::expandProscenium (gridSpaceOccluderProscenium, transform(fe->center3d())); if (gridSpaceOccluderProsceniumInitialized) {
} else { GridHelpers::expandProscenium(gridSpaceOccluderProscenium, transform(fe->center3d()));
}
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);
@@ -51,7 +57,7 @@ public:
private: private:
bool testCurrent(); bool testCurrent();
void expandGridSpaceOccluderProscenium(FEdge* fe); void expandGridSpaceOccluderProscenium(FEdge *fe);
real occluderProscenium[4]; real occluderProscenium[4];
real gridSpaceOccluderProscenium[4]; real gridSpaceOccluderProscenium[4];
@@ -60,4 +66,4 @@ private:
bool gridSpaceOccluderProsceniumInitialized; bool gridSpaceOccluderProsceniumInitialized;
}; };
#endif // CULLEDOCCLUDERSOURCE_H #endif // __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,203 +1,241 @@
// /*
// 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.
//
///////////////////////////////////////////////////////////////////////////////
#include <vector>
#ifndef FEDGEXDETECTOR_H #include "../geometry/Geom.h"
# define FEDGEXDETECTOR_H
# include <vector> #include "../system/FreestyleConfig.h"
# include "../system/FreestyleConfig.h" #include "../system/ProgressBar.h"
# include "../geometry/Geom.h" #include "../system/RenderMonitor.h"
# include "../winged_edge/WXEdge.h"
# include "../winged_edge/Curvature.h" #include "../winged_edge/Curvature.h"
# include "../system/ProgressBar.h" #include "../winged_edge/WXEdge.h"
# include "../system/RenderMonitor.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()
{
_pProgressBar = NULL;
_pRenderMonitor = NULL;
_computeViewIndependant = true;
_bbox_diagonal = 1.0;
_meanEdgeSize = 0;
_computeRidgesAndValleys = true;
_computeSuggestiveContours = true;
_computeMaterialBoundaries = true;
_sphereRadius = 1.0;
_orthographicProjection = false;
_faceSmoothness = false;
_changes = false;
_kr_derivative_epsilon = 0.0;
_creaseAngle = 0.7; // angle of 134.43 degrees
}
FEdgeXDetector() { virtual ~FEdgeXDetector() {}
_pProgressBar = 0;
_pRenderMonitor = 0;
_computeViewIndependant = true;
_bbox_diagonal = 1.0;
_meanEdgeSize = 0;
_computeRidgesAndValleys = true;
_computeSuggestiveContours = true;
_computeMaterialBoundaries = true;
_sphereRadius = 1.0;
_orthographicProjection = false;
_faceSmoothness = false;
_changes = false;
_kr_derivative_epsilon = 0.0;
_creaseAngle = 0.7; // angle of 134.43 degrees
}
virtual ~FEdgeXDetector() {}
/*! Process shapes from a WingedEdge containing a list of WShapes */ /*! Process shapes from a WingedEdge containing a list of WShapes */
virtual void processShapes(WingedEdge&); virtual void processShapes(WingedEdge&);
// GENERAL STUFF // GENERAL STUFF
virtual void preProcessShape(WXShape* iShape); virtual void preProcessShape(WXShape *iShape);
virtual void preProcessFace(WXFace* iFace); virtual void preProcessFace(WXFace *iFace);
virtual void computeCurvatures(WXVertex *iVertex); virtual void computeCurvatures(WXVertex *iVertex);
// SILHOUETTE // SILHOUETTE
virtual void processSilhouetteShape(WXShape* iShape); virtual void processSilhouetteShape(WXShape *iShape);
virtual void ProcessSilhouetteFace(WXFace *iFace); virtual void ProcessSilhouetteFace(WXFace *iFace);
virtual void ProcessSilhouetteEdge(WXEdge *iEdge); virtual void ProcessSilhouetteEdge(WXEdge *iEdge);
// 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
* \param angle
* The angular threshold in degrees (between 0 and 180) for detecting crease
* edges. An edge is considered a crease edge if the angle between two faces
* sharing the edge is smaller than the given threshold.
*/
inline void setCreaseAngle(real angle) {
if (angle < 0.0)
angle = 0.0;
else if (angle > 180.0)
angle = 180.0;
angle = cos(M_PI * (180.0 - angle) / 180.0);
if (angle != _creaseAngle){
_creaseAngle = angle;
_changes = true;
}
}
// BORDER /*! Sets the minimum angle for detecting crease edges
virtual void processBorderShape(WXShape* iShape); * \param angle
virtual void ProcessBorderEdge(WXEdge *iEdge); * The angular threshold in degrees (between 0 and 180) for detecting crease edges. An edge is considered
* a crease edge if the angle between two faces sharing the edge is smaller than the given threshold.
*/
// XXX angle should be in radian...
inline void setCreaseAngle(real angle)
{
if (angle < 0.0)
angle = 0.0;
else if (angle > 180.0)
angle = 180.0;
angle = cos(M_PI * (180.0 - angle) / 180.0);
if (angle != _creaseAngle) {
_creaseAngle = angle;
_changes = true;
}
}
// RIDGES AND VALLEYS // BORDER
virtual void processRidgesAndValleysShape(WXShape* iShape); virtual void processBorderShape(WXShape *iShape);
virtual void ProcessRidgeFace(WXFace *iFace); virtual void ProcessBorderEdge(WXEdge *iEdge);
// SUGGESTIVE CONTOURS // RIDGES AND VALLEYS
virtual void processSuggestiveContourShape(WXShape* iShape); virtual void processRidgesAndValleysShape(WXShape *iShape);
virtual void ProcessSuggestiveContourFace(WXFace *iFace); virtual void ProcessRidgeFace(WXFace *iFace);
virtual void postProcessSuggestiveContourShape(WXShape* iShape);
virtual void postProcessSuggestiveContourFace(WXFace *iFace);
/*! Sets the minimal derivative of the radial curvature for suggestive contours
* \param dkr
* The minimal derivative of the radial curvature
*/
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr) {
if (dkr != _kr_derivative_epsilon){
_kr_derivative_epsilon = dkr;
_changes = true;
}
}
// MATERIAL BOUNDARY // SUGGESTIVE CONTOURS
virtual void processMaterialBoundaryShape(WXShape* iWShape); virtual void processSuggestiveContourShape(WXShape *iShape);
virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge); virtual void ProcessSuggestiveContourFace(WXFace *iFace);
virtual void postProcessSuggestiveContourShape(WXShape *iShape);
virtual void postProcessSuggestiveContourFace(WXFace *iFace);
/*! Sets the minimal derivative of the radial curvature for suggestive contours
* \param dkr
* The minimal derivative of the radial curvature
*/
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr)
{
if (dkr != _kr_derivative_epsilon) {
_kr_derivative_epsilon = dkr;
_changes = true;
}
}
// EDGE MARKS // MATERIAL BOUNDARY
virtual void processEdgeMarksShape(WXShape* iShape); virtual void processMaterialBoundaryShape(WXShape *iWShape);
virtual void ProcessEdgeMarks(WXEdge *iEdge); virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge);
// EVERYBODY // EDGE MARKS
virtual void buildSmoothEdges(WXShape* iShape); virtual void processEdgeMarksShape(WXShape *iShape);
virtual void ProcessEdgeMarks(WXEdge *iEdge);
/*! Sets the current viewpoint */ // EVERYBODY
inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;} virtual void buildSmoothEdges(WXShape *iShape);
inline void enableOrthographicProjection(bool b) {_orthographicProjection = b;}
inline void enableRidgesAndValleysFlag(bool b) {_computeRidgesAndValleys = b;}
inline void enableSuggestiveContours(bool b) {_computeSuggestiveContours = b;}
inline void enableMaterialBoundaries(bool b) {_computeMaterialBoundaries = b;}
inline void enableFaceSmoothness(bool b) {
if (b != _faceSmoothness) {
_faceSmoothness = b;
_changes=true;
}
}
inline void enableFaceMarks(bool b) {
if (b != _faceMarks) {
_faceMarks = b;
_changes=true;
}
}
/*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation)
* \param r
* The radius of the sphere expressed as a ratio of the mean edge size
*/
inline void setSphereRadius(real r) {
if(r!=_sphereRadius){
_sphereRadius = r;
_changes=true;
}
}
inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;} /*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp)
{
_Viewpoint = ivp;
}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;} inline void enableOrthographicProjection(bool b)
{
_orthographicProjection = b;
}
inline void enableRidgesAndValleysFlag(bool b)
{
_computeRidgesAndValleys = b;
}
inline void enableSuggestiveContours(bool b)
{
_computeSuggestiveContours = b;
}
inline void enableMaterialBoundaries(bool b)
{
_computeMaterialBoundaries = b;
}
inline void enableFaceSmoothness(bool b)
{
if (b != _faceSmoothness) {
_faceSmoothness = b;
_changes=true;
}
}
inline void enableFaceMarks(bool b)
{
if (b != _faceMarks) {
_faceMarks = b;
_changes=true;
}
}
/*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation)
* \param r
* The radius of the sphere expressed as a ratio of the mean edge size
*/
inline void setSphereRadius(real r)
{
if (r != _sphereRadius) {
_sphereRadius = r;
_changes=true;
}
}
inline void setProgressBar(ProgressBar *iProgressBar)
{
_pProgressBar = iProgressBar;
}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
{
_pRenderMonitor = iRenderMonitor;
}
protected: protected:
Vec3r _Viewpoint;
real _bbox_diagonal; // diagonal of the current processed shape bbox
//oldtmp values
bool _computeViewIndependant;
real _meanK1;
real _meanKr;
real _minK1;
real _minKr;
real _maxK1;
real _maxKr;
unsigned _nPoints;
real _meanEdgeSize;
bool _orthographicProjection;
Vec3r _Viewpoint; bool _computeRidgesAndValleys;
real _bbox_diagonal; // diagonal of the current processed shape bbox bool _computeSuggestiveContours;
//oldtmp values bool _computeMaterialBoundaries;
bool _computeViewIndependant; bool _faceSmoothness;
real _meanK1; bool _faceMarks;
real _meanKr; real _sphereRadius; // expressed as a ratio of the mean edge size
real _minK1; real _creaseAngle; // [-1, 1] compared with the inner product of face normals
real _minKr; bool _changes;
real _maxK1;
real _maxKr;
unsigned _nPoints;
real _meanEdgeSize;
bool _orthographicProjection;
bool _computeRidgesAndValleys; real _kr_derivative_epsilon;
bool _computeSuggestiveContours;
bool _computeMaterialBoundaries;
bool _faceSmoothness;
bool _faceMarks;
real _sphereRadius; // expressed as a ratio of the mean edge size
real _creaseAngle; // [-1, 1] compared with the inner product of face normals
bool _changes;
real _kr_derivative_epsilon; ProgressBar *_pProgressBar;
RenderMonitor *_pRenderMonitor;
ProgressBar *_pProgressBar;
RenderMonitor *_pRenderMonitor;
}; };
#endif // FEDGEDXETECTOR_H #endif // __FREESTYLE_FEDGE_X_DETECTOR_H__

View File

@@ -1,357 +1,371 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
// /** \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"
using namespace std; 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; int count = 1;
int count = 1; 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
{ FEdge *fe = 0;
// if we only have 2 vertices Interface0DIterator tmp = it;
FEdge * fe = 0; if (it.isBegin()) {
Interface0DIterator tmp = it; ++tmp;
if(it.isBegin()) fe = it->getFEdge(*tmp);
{ }
++tmp; else {
fe = it->getFEdge(*tmp); --tmp;
} fe = it->getFEdge(*tmp);
else }
{ fe1 = fe;
--tmp; fe2 = NULL;
fe = it->getFEdge(*tmp); }
} else {
fe1 = fe; // we have more than 2 vertices
fe2 = 0; bool begin = false, last = false;
} Interface0DIterator previous = it;
else if (!previous.isBegin())
{ --previous;
// we have more than 2 vertices else
bool begin=false,last=false; begin = true;
Interface0DIterator previous = it; Interface0DIterator next = it;
if(!previous.isBegin()) ++next;
--previous; if (next.isEnd())
else last = true;
begin=true; if (begin) {
Interface0DIterator next = it; fe1 = it->getFEdge(*next);
++next; fe2 = NULL;
if(next.isEnd()) }
last = true; else if (last) {
if(begin) fe1 = previous->getFEdge(*it);
{ fe2 = NULL;
fe1 = it->getFEdge(*next); }
fe2 = 0; else {
} fe1 = previous->getFEdge(*it);
else if(last) fe2 = it->getFEdge(*next);
{ }
fe1 = previous->getFEdge(*it); }
fe2 = 0; }
}
else
{
fe1 = previous->getFEdge(*it);
fe2 = it->getFEdge(*next);
}
}
}
void getViewEdges(Interface0DIterator &it, void getViewEdges(Interface0DIterator &it, ViewEdge *&ve1, ViewEdge *&ve2)
ViewEdge *&ve1, {
ViewEdge *&ve2) FEdge *fe1, *fe2;
{ getFEdges(it, fe1, fe2);
FEdge * fe1, *fe2; ve1 = fe1->viewedge();
getFEdges(it, fe1, fe2); if (fe2 != NULL) {
ve1 = fe1->viewedge(); ve2 = fe2->viewedge();
if(fe2 != 0) if (ve2 == ve1)
{ ve2 = NULL;
ve2 = fe2->viewedge(); }
if(ve2 == ve1) else {
ve2 = 0; ve2 = NULL;
} }
else }
ve2 = 0;
}
ViewShape* getShapeF0D(Interface0DIterator& it) ViewShape *getShapeF0D(Interface0DIterator& it)
{ {
ViewEdge *ve1, *ve2; ViewEdge *ve1, *ve2;
getViewEdges(it, ve1, ve2); getViewEdges(it, ve1, ve2);
return ve1->viewShape(); return ve1->viewShape();
} }
void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders){ void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders)
ViewEdge * ve1, *ve2; {
getViewEdges(it, ve1, ve2); ViewEdge *ve1, *ve2;
occluder_container::const_iterator oit = ve1->occluders_begin(); getViewEdges(it, ve1, ve2);
occluder_container::const_iterator oitend = ve1->occluders_end(); occluder_container::const_iterator oit = ve1->occluders_begin();
occluder_container::const_iterator oitend = ve1->occluders_end();
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)
oOccluders.insert((*oit)); oOccluders.insert((*oit));
} }
} }
ViewShape * getOccludeeF0D(Interface0DIterator& it){ ViewShape *getOccludeeF0D(Interface0DIterator& it)
ViewEdge * ve1, *ve2; {
getViewEdges(it, ve1, ve2); ViewEdge *ve1, *ve2;
ViewShape *aShape = ve1->aShape(); getViewEdges(it, ve1, ve2);
return aShape; ViewShape *aShape = ve1->aShape();
} return aShape;
}
//
int VertexOrientation2DF0D::operator()(Interface0DIterator& iter) {
Vec2f A,C;
Vec2f B(iter->getProjectedX(), iter->getProjectedY());
if(iter.isBegin())
A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
else
{
Interface0DIterator previous = iter;
--previous ;
A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
}
Interface0DIterator next = iter;
++next ;
if(next.isEnd())
C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
else
C = Vec2f(next->getProjectedX(), next->getProjectedY());
Vec2f AB(B-A); //
if(AB.norm() != 0) int VertexOrientation2DF0D::operator()(Interface0DIterator& iter)
AB.normalize(); {
Vec2f BC(C-B); Vec2f A, C;
if(BC.norm() != 0) Vec2f B(iter->getProjectedX(), iter->getProjectedY());
BC.normalize(); if (iter.isBegin()) {
result = AB + BC; A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
if(result.norm() != 0) }
result.normalize(); else {
return 0; Interface0DIterator previous = iter;
} --previous ;
A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
}
Interface0DIterator next = iter;
++next;
if (next.isEnd())
C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
else
C = Vec2f(next->getProjectedX(), next->getProjectedY());
int VertexOrientation3DF0D::operator()(Interface0DIterator& iter) { Vec2f AB(B - A);
Vec3r A,C; if (AB.norm() != 0)
Vec3r B(iter->getX(), iter->getY(), iter->getZ()); AB.normalize();
if(iter.isBegin()) Vec2f BC(C - B);
A = Vec3r(iter->getX(), iter->getY(), iter->getZ()); if (BC.norm() != 0)
else BC.normalize();
{ result = AB + BC;
if (result.norm() != 0)
result.normalize();
return 0;
}
int VertexOrientation3DF0D::operator()(Interface0DIterator& iter)
{
Vec3r A, C;
Vec3r B(iter->getX(), iter->getY(), iter->getZ());
if (iter.isBegin()) {
A = Vec3r(iter->getX(), iter->getY(), iter->getZ());
}
else {
Interface0DIterator previous = iter; Interface0DIterator previous = iter;
--previous ; --previous ;
A = Vec3r(previous->getX(), previous->getY(), previous->getZ()); A = Vec3r(previous->getX(), previous->getY(), previous->getZ());
} }
Interface0DIterator next = iter; Interface0DIterator next = iter;
++next ; ++next ;
if(next.isEnd()) if (next.isEnd())
C = Vec3r(iter->getX(), iter->getY(), iter->getZ()); C = Vec3r(iter->getX(), iter->getY(), iter->getZ());
else else
C = Vec3r(next->getX(), next->getY(), next->getZ()); C = Vec3r(next->getX(), next->getY(), next->getZ());
Vec3r AB(B-A); Vec3r AB(B - A);
if(AB.norm() != 0) if (AB.norm() != 0)
AB.normalize(); AB.normalize();
Vec3r BC(C-B); Vec3r BC(C - B);
if(BC.norm() != 0) if (BC.norm() != 0)
BC.normalize(); BC.normalize();
result = AB + BC; result = AB + BC;
if(result.norm() != 0) if (result.norm() != 0)
result.normalize(); result.normalize();
return 0; return 0;
} }
int Curvature2DAngleF0D::operator()(Interface0DIterator& iter) { int Curvature2DAngleF0D::operator()(Interface0DIterator& iter)
Interface0DIterator tmp1 = iter, tmp2 = iter; {
++tmp2; Interface0DIterator tmp1 = iter, tmp2 = iter;
unsigned count = 1;
while((!tmp1.isBegin()) && (count < 3))
{
--tmp1;
++count;
}
while((!tmp2.isEnd()) && (count < 3))
{
++tmp2; ++tmp2;
++count; unsigned count = 1;
} while ((!tmp1.isBegin()) && (count < 3)) {
if(count < 3) { --tmp1;
// if we only have 2 vertices ++count;
result = 0; }
return 0; while ((!tmp2.isEnd()) && (count < 3)) {
++tmp2;
++count;
}
if (count < 3) {
// if we only have 2 vertices
result = 0;
return 0;
} }
Interface0DIterator v = iter; Interface0DIterator v = iter;
if(iter.isBegin()) if (iter.isBegin())
++v; ++v;
Interface0DIterator next=v; Interface0DIterator next = v;
++next; ++next;
if(next.isEnd()) if (next.isEnd()) {
{ next = v;
next = v; --v;
--v; }
} Interface0DIterator prev = v;
Interface0DIterator prev=v; --prev;
--prev;
Vec2r A(prev->getProjectedX(), prev->getProjectedY()); Vec2r A(prev->getProjectedX(), prev->getProjectedY());
Vec2r B(v->getProjectedX(), v->getProjectedY()); Vec2r B(v->getProjectedX(), v->getProjectedY());
Vec2r C(next->getProjectedX(), next->getProjectedY()); Vec2r C(next->getProjectedX(), next->getProjectedY());
Vec2r AB(B-A); Vec2r AB(B - A);
Vec2r BC(C-B); Vec2r BC(C - B);
Vec2r N1(-AB[1], AB[0]); Vec2r N1(-AB[1], AB[0]);
if(N1.norm() != 0) if (N1.norm() != 0)
N1.normalize(); N1.normalize();
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; }
} double cosin = N1 * N2;
double cosin = N1*N2; if (cosin > 1)
if(cosin > 1) cosin = 1;
cosin = 1; if (cosin < -1)
if(cosin < -1) cosin = -1;
cosin = -1; result = acos(cosin);
result = acos(cosin);
return 0; return 0;
} }
int ZDiscontinuityF0D::operator()(Interface0DIterator& iter) { int ZDiscontinuityF0D::operator()(Interface0DIterator& iter)
FEdge *fe1, *fe2; {
getFEdges(iter, fe1, fe2); FEdge *fe1, *fe2;
result = fe1->z_discontinuity(); getFEdges(iter, fe1, fe2);
if(fe2!=0){ result = fe1->z_discontinuity();
result += fe2->z_discontinuity(); if (fe2 != NULL) {
result /= 2.f; result += fe2->z_discontinuity();
} result /= 2.0f;
return 0; }
}
int Normal2DF0D::operator()(Interface0DIterator& iter) {
FEdge *fe1, *fe2;
getFEdges(iter,fe1,fe2);
Vec3f e1(fe1->orientation2d());
Vec2f n1(e1[1], -e1[0]);
Vec2f n(n1);
if(fe2 != 0)
{
Vec3f e2(fe2->orientation2d());
Vec2f n2(e2[1], -e2[0]);
n += n2;
}
n.normalize();
result = n;
return 0; return 0;
} }
int MaterialF0D::operator()(Interface0DIterator& iter) { int Normal2DF0D::operator()(Interface0DIterator& iter)
FEdge *fe1, *fe2; {
getFEdges(iter,fe1,fe2); FEdge *fe1, *fe2;
if(fe1 == 0) getFEdges(iter, fe1, fe2);
return -1; Vec3f e1(fe1->orientation2d());
if(fe1->isSmooth()) Vec2f n1(e1[1], -e1[0]);
result = ((FEdgeSmooth*)fe1)->frs_material(); Vec2f n(n1);
else if (fe2 != NULL) {
result = ((FEdgeSharp*)fe1)->bFrsMaterial(); Vec3f e2(fe2->orientation2d());
// const SShape * sshape = getShapeF0D(iter); Vec2f n2(e2[1], -e2[0]);
// return sshape->material(); n += n2;
return 0; }
} n.normalize();
result = n;
int ShapeIdF0D::operator()(Interface0DIterator& iter) {
ViewShape * vshape = getShapeF0D(iter);
result = vshape->getId();
return 0; return 0;
} }
int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter) { int MaterialF0D::operator()(Interface0DIterator& iter)
ViewEdge * ve1, *ve2; {
getViewEdges(iter,ve1,ve2); FEdge *fe1, *fe2;
unsigned int qi1, qi2; getFEdges(iter, fe1, fe2);
qi1 = ve1->qi(); if (fe1 == NULL)
if(ve2 != 0){ return -1;
qi2 = ve2->qi(); if (fe1->isSmooth())
if(qi2!=qi1) result = ((FEdgeSmooth*)fe1)->frs_material();
cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl; else
} result = ((FEdgeSharp*)fe1)->bFrsMaterial();
result = qi1; #if 0
const SShape *sshape = getShapeF0D(iter);
return sshape->material();
#endif
return 0; return 0;
} }
int CurveNatureF0D::operator()(Interface0DIterator& iter) { int ShapeIdF0D::operator()(Interface0DIterator& iter)
Nature::EdgeNature nat = 0; {
ViewEdge * ve1, *ve2; ViewShape *vshape = getShapeF0D(iter);
getViewEdges(iter, ve1, ve2); result = vshape->getId();
nat |= ve1->getNature();
if(ve2!=0)
nat |= ve2->getNature();
result = nat;
return 0; return 0;
} }
int GetOccludersF0D::operator()(Interface0DIterator& iter) { int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter)
set<ViewShape*> occluders; {
getOccludersF0D(iter,occluders); ViewEdge *ve1, *ve2;
getViewEdges(iter, ve1, ve2);
unsigned int qi1, qi2;
qi1 = ve1->qi();
if (ve2 != NULL) {
qi2 = ve2->qi();
if (qi2 != qi1)
cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
}
result = qi1;
return 0;
}
int CurveNatureF0D::operator()(Interface0DIterator& iter)
{
Nature::EdgeNature nat = 0;
ViewEdge *ve1, *ve2;
getViewEdges(iter, ve1, ve2);
nat |= ve1->getNature();
if (ve2 != NULL)
nat |= ve2->getNature();
result = nat;
return 0;
}
int GetOccludersF0D::operator()(Interface0DIterator& iter)
{
set<ViewShape*> 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; result.push_back((*it));
++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;
} }
} // end of namespace Functions0D } // end of namespace Functions0D

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 #include <set>
# define FUNCTIONS0D_H #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"
# include "../system/Precision.h"
# include "Interface0D.h"
# include "../geometry/Geom.h"
# include "../system/Exception.h"
# include "../scene_graph/FrsMaterial.h"
# include <set>
# include <vector>
class FEdge; class 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,433 +74,459 @@ 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. */
UnaryFunction0D() { py_uf0D = 0;}
/*! Destructor; */
virtual ~UnaryFunction0D() {}
/*! Returns the string "UnaryFunction0D" */
virtual string getName() const {
return "UnaryFunction0D";
}
/*! The operator ().
* \param iter
* An Interface0DIterator pointing onto
* the point at which we wish to evaluate
* the function.
* \return the result of the function of type T.
*/
virtual int operator()(Interface0DIterator& iter) {
return Director_BPy_UnaryFunction0D___call__( this, py_uf0D, iter );
}
/*! Default constructor. */
UnaryFunction0D()
{
py_uf0D = NULL;
}
/*! Destructor; */
virtual ~UnaryFunction0D() {}
/*! Returns the string "UnaryFunction0D" */
virtual string getName() const
{
return "UnaryFunction0D";
}
/*! The operator ().
* \param iter
* An Interface0DIterator pointing onto the point at which we wish to evaluate the function.
* \return the result of the function of type T.
*/
virtual int operator()(Interface0DIterator& iter)
{
return Director_BPy_UnaryFunction0D___call__(this, py_uf0D, iter);
}
}; };
# ifdef SWIG #ifdef SWIG
%feature("director") UnaryFunction0D<void>; %feature("director") UnaryFunction0D<void>;
%feature("director") UnaryFunction0D<unsigned>; %feature("director") UnaryFunction0D<unsigned>;
%feature("director") UnaryFunction0D<float>; %feature("director") UnaryFunction0D<float>;
%feature("director") UnaryFunction0D<double>; %feature("director") UnaryFunction0D<double>;
%feature("director") UnaryFunction0D<Vec2f>; %feature("director") UnaryFunction0D<Vec2f>;
%feature("director") UnaryFunction0D<Vec3f>; %feature("director") UnaryFunction0D<Vec3f>;
%feature("director") UnaryFunction0D<Id>; %feature("director") UnaryFunction0D<Id>;
%template(UnaryFunction0DVoid) UnaryFunction0D<void>;
%template(UnaryFunction0DUnsigned) UnaryFunction0D<unsigned>;
%template(UnaryFunction0DFloat) UnaryFunction0D<float>;
%template(UnaryFunction0DDouble) UnaryFunction0D<double>;
%template(UnaryFunction0DVec2f) UnaryFunction0D<Vec2f>;
%template(UnaryFunction0DVec3f) UnaryFunction0D<Vec3f>;
%template(UnaryFunction0DId) UnaryFunction0D<Id>;
%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
# endif // SWIG
%template(UnaryFunction0DVoid) UnaryFunction0D<void>;
%template(UnaryFunction0DUnsigned) UnaryFunction0D<unsigned>;
%template(UnaryFunction0DFloat) UnaryFunction0D<float>;
%template(UnaryFunction0DDouble) UnaryFunction0D<double>;
%template(UnaryFunction0DVec2f) UnaryFunction0D<Vec2f>;
%template(UnaryFunction0DVec3f) UnaryFunction0D<Vec3f>;
%template(UnaryFunction0DId) UnaryFunction0D<Id>;
%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
#endif // SWIG
// //
// Functions definitions // Functions definitions
// //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
class ViewShape; class ViewShape;
namespace Functions0D { namespace Functions0D {
// GetXF0D // GetXF0D
/*! Returns the X 3D coordinate of an Interface0D. */ /*! Returns the X 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real> class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
{ {
public: public:
/*! Returns the string "GetXF0D"*/ /*! Returns the string "GetXF0D" */
string getName() const { string getName() const
return "GetXF0D"; {
} return "GetXF0D";
/*! the () operator.*/ }
int operator()(Interface0DIterator& iter) {
result = iter->getX();
return 0;
}
};
// GetYF0D /*! the () operator. */
/*! Returns the Y 3D coordinate of an Interface0D. */ int operator()(Interface0DIterator& iter)
class LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real> {
{ result = iter->getX();
public: return 0;
/*! Returns the string "GetYF0D"*/ }
string getName() const { };
return "GetYF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter->getY();
return 0;
}
};
// GetZF0D // GetYF0D
/*! Returns the Z 3D coordinate of an Interface0D. */ /*! Returns the Y 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real> class LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real>
{ {
public: public:
/*! Returns the string "GetZF0D"*/ /*! Returns the string "GetYF0D" */
string getName() const { string getName() const
return "GetZF0D"; {
} return "GetYF0D";
/*! the () operator.*/ }
int operator()(Interface0DIterator& iter) {
result = iter->getZ();
return 0;
}
};
// GetProjectedXF0D /*! the () operator. */
/*! Returns the X 3D projected coordinate of an Interface0D. */ int operator()(Interface0DIterator& iter)
class LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real> {
{ result = iter->getY();
public: return 0;
/*! Returns the string "GetProjectedXF0D"*/ }
string getName() const { };
return "GetProjectedXF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter->getProjectedX();
return 0;
}
};
// GetProjectedYF0D // GetZF0D
/*! Returns the Y projected 3D coordinate of an Interface0D. */ /*! Returns the Z 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real> class LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real>
{ {
public: public:
/*! Returns the string "GetProjectedYF0D"*/ /*! Returns the string "GetZF0D" */
string getName() const { string getName() const
return "GetProjectedYF0D"; {
} return "GetZF0D";
/*! the () operator.*/ }
int operator()(Interface0DIterator& iter) {
result = iter->getProjectedY();
return 0;
}
};
// GetProjectedZF0D /*! the () operator. */
/*! Returns the Z projected 3D coordinate of an Interface0D. */ int operator()(Interface0DIterator& iter)
class LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real> {
{ result = iter->getZ();
public: return 0;
/*! Returns the string "GetProjectedZF0D"*/ }
string getName() const { };
return "GetProjectedZF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter->getProjectedZ();
return 0;
}
};
// GetCurvilinearAbscissaF0D // GetProjectedXF0D
/*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */ /*! Returns the X 3D projected coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetCurvilinearAbscissaF0D : public UnaryFunction0D<float> class LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real>
{ {
public: public:
/*! Returns the string "GetCurvilinearAbscissaF0D"*/ /*! Returns the string "GetProjectedXF0D" */
string getName() const { string getName() const
return "GetCurvilinearAbscissaF0D"; {
} return "GetProjectedXF0D";
/*! the () operator.*/ }
int operator()(Interface0DIterator& iter) {
result = iter.t();
return 0;
}
};
// GetParameterF0D /*! the () operator. */
/*! Returns the parameter of an Interface0D in the context of its 1D element. */ int operator()(Interface0DIterator& iter)
class LIB_VIEW_MAP_EXPORT GetParameterF0D : public UnaryFunction0D<float> {
{ result = iter->getProjectedX();
public: return 0;
/*! Returns the string "GetCurvilinearAbscissaF0D"*/ }
string getName() const { };
return "GetParameterF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter.u();
return 0;
}
};
// VertexOrientation2DF0D // GetProjectedYF0D
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element /*! Returns the Y projected 3D coordinate of an Interface0D. */
* to which the Interface0DIterator& belongs to and class LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real>
* evaluated at the Interface0D pointed by this Interface0DIterator&. {
*/ public:
class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f> /*! Returns the string "GetProjectedYF0D" */
{ string getName() const
public: {
/*! Returns the string "VertexOrientation2DF0D"*/ return "GetProjectedYF0D";
string getName() const { }
return "VertexOrientation2DF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// VertexOrientation3DF0D /*! the () operator. */
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element int operator()(Interface0DIterator& iter)
* to which the Interface0DIterator& belongs to and {
* evaluated at the Interface0D pointed by this Interface0DIterator&. result = iter->getProjectedY();
*/ return 0;
class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f> }
{ };
public:
/*! Returns the string "VertexOrientation3DF0D"*/
string getName() const {
return "VertexOrientation3DF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// Curvature2DAngleF0D // GetProjectedZF0D
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element /*! Returns the Z projected 3D coordinate of an Interface0D. */
* to which the Interface0DIterator& belongs to and class LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real>
* evaluated at the Interface0D pointed by this Interface0DIterator&. {
*/ public:
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real> /*! Returns the string "GetProjectedZF0D" */
{ string getName() const
public: {
/*! Returns the string "Curvature2DAngleF0D"*/ return "GetProjectedZF0D";
string getName() const { }
return "Curvature2DAngleF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// ZDiscontinuity /*! the () operator. */
/*! Returns a real giving the distance between int operator()(Interface0DIterator& iter)
* and Interface0D and the shape that lies behind (occludee). {
* This distance is evaluated in the camera space and normalized result = iter->getProjectedZ();
* between 0 and 1. Therefore, if no oject is occluded by the return 0;
* shape to which the Interface0D belongs to, 1 is returned. }
*/ };
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "ZDiscontinuityF0D"*/
string getName() const {
return "ZDiscontinuityF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// Normal2DF0D // GetCurvilinearAbscissaF0D
/*! Returns a Vec2f giving the normalized 2D normal to the 1D element /*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
* to which the Interface0DIterator& belongs to and class LIB_VIEW_MAP_EXPORT GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
* evaluated at the Interface0D pointed by this Interface0DIterator&. {
*/ public:
class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f> /*! Returns the string "GetCurvilinearAbscissaF0D" */
{ string getName() const
public: {
/*! Returns the string "Normal2DF0D"*/ return "GetCurvilinearAbscissaF0D";
string getName() const { }
return "Normal2DF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// MaterialF0D /*! the () operator. */
/*! Returns the material of the object evaluated at the Interface0D. int operator()(Interface0DIterator& iter)
* This evaluation can be ambiguous (in the case of a TVertex for example. {
* This functor tries to remove this ambiguity using the context result = iter.t();
* offered by the 1D element to which the Interface0DIterator& belongs return 0;
* to and by arbitrary chosing the material of the face }
* that lies on its left when following the 1D element if there };
* are two different materials on each side of the point.
* However, there still can be problematic cases, and the user willing
* to deal with this cases in a specific way should implement
* its own getMaterial functor.
*/
class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
{
public:
/*! Returns the string "MaterialF0D"*/
string getName() const {
return "MaterialF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// ShapeIdF0D // GetParameterF0D
/*! Returns the Id of the Shape the Interface0D belongs to. /*! Returns the parameter of an Interface0D in the context of its 1D element. */
* This evaluation can be ambiguous (in the case of a TVertex for example). class LIB_VIEW_MAP_EXPORT GetParameterF0D : public UnaryFunction0D<float>
* This functor tries to remove this ambiguity using the context {
* offered by the 1D element to which the Interface0DIterator& belongs public:
* to. /*! Returns the string "GetCurvilinearAbscissaF0D" */
* However, there still can be problematic cases, and the user willing string getName() const
* to deal with this cases in a specific way should implement {
* its own getShapeIdF0D functor. return "GetParameterF0D";
*/ }
class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
{
public:
/*! Returns the string "ShapeIdF0D"*/
string getName() const {
return "ShapeIdF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// QiF0D /*! the () operator. */
/*! Returns the quantitative invisibility of this Interface0D. int operator()(Interface0DIterator& iter)
* This evaluation can be ambiguous (in the case of a TVertex for example). {
* This functor tries to remove this ambiguity using the context result = iter.u();
* offered by the 1D element to which the Interface0DIterator& belongs return 0;
* to. }
* However, there still can be problematic cases, and the user willing };
* to deal with this cases in a specific way should implement
* its own getQIF0D functor.
*/
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
{
public:
/*! Returns the string "QuantitativeInvisibilityF0D"*/
string getName() const {
return "QuantitativeInvisibilityF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// CurveNatureF0D // VertexOrientation2DF0D
/*! Returns the Nature::EdgeNature of the 1D element the /*! Returns a Vec2r giving the 2D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* Interface0DIterator& belongs to. * evaluated at the Interface0D pointed by this Interface0DIterator&.
*/ */
class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature> class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
{ {
public: public:
/*! Returns the string "QuantitativeInvisibilityF0D"*/ /*! Returns the string "VertexOrientation2DF0D" */
string getName() const { string getName() const
return "CurveNatureF0D"; {
} return "VertexOrientation2DF0D";
/*! the () operator.*/ }
int operator()(Interface0DIterator& iter);
};
// GetShapeF0D
/*! Returns the ViewShape*
* containing the Interface0D
*/
class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*>
{
public:
/*! Returns the string "GetShapeF0D"*/
string getName() const {
return "GetShapeF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// GetOccludersF0D /*! the () operator. */
/*! Returns a vector containing the ViewShape* int operator()(Interface0DIterator& iter);
* occluding the Interface0D };
*/
class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
{
public:
/*! Returns the string "GetOccludersF0D"*/
string getName() const {
return "GetOccludersF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// GetOccludeeF0D // VertexOrientation3DF0D
/*! Returns the ViewShape* /*! Returns a Vec3r giving the 3D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* "occluded" by the Interface0D * evaluated at the Interface0D pointed by this Interface0DIterator&.
*/ */
class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*> class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
{ {
public: public:
/*! Returns the string "GetOccludeeF0D"*/ /*! Returns the string "VertexOrientation3DF0D" */
string getName() const { string getName() const
return "GetOccludeeF0D"; {
} return "VertexOrientation3DF0D";
/*! the () operator.*/ }
int operator()(Interface0DIterator& iter);
};
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
/////////////////////////// Internal //////////////////////////// // Curvature2DAngleF0D
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element to which the Interface0DIterator&
* belongs to and evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "Curvature2DAngleF0D" */
string getName() const
{
return "Curvature2DAngleF0D";
}
// getFEdge /*! the () operator. */
LIB_VIEW_MAP_EXPORT int operator()(Interface0DIterator& iter);
FEdge* getFEdge(Interface0D& it1, Interface0D& it2); };
// getFEdges // ZDiscontinuity
LIB_VIEW_MAP_EXPORT /*! Returns a real giving the distance between and Interface0D and the shape that lies behind (occludee).
void getFEdges(Interface0DIterator& it, * This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no oject is occluded
FEdge*& fe1, * by the shape to which the Interface0D belongs to, 1 is returned.
FEdge*& fe2); */
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "ZDiscontinuityF0D" */
string getName() const
{
return "ZDiscontinuityF0D";
}
// getViewEdges /*! the () operator. */
LIB_VIEW_MAP_EXPORT int operator()(Interface0DIterator& iter);
void getViewEdges(Interface0DIterator& it, };
ViewEdge *&ve1,
ViewEdge *&ve2);
// getShapeF0D // Normal2DF0D
LIB_VIEW_MAP_EXPORT /*! Returns a Vec2f giving the normalized 2D normal to the 1D element to which the Interface0DIterator& belongs to and
ViewShape* getShapeF0D(Interface0DIterator& it); * evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f>
{
public:
/*! Returns the string "Normal2DF0D" */
string getName() const
{
return "Normal2DF0D";
}
// getOccludersF0D /*! the () operator. */
LIB_VIEW_MAP_EXPORT int operator()(Interface0DIterator& iter);
void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders); };
// getOccludeeF0D // MaterialF0D
LIB_VIEW_MAP_EXPORT /*! Returns the material of the object evaluated at the Interface0D.
ViewShape* getOccludeeF0D(Interface0DIterator& it); * This evaluation can be ambiguous (in the case of a TVertex for example.
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
* Interface0DIterator& belongs to and by arbitrary chosing the material of the face that lies on its left when
* following the 1D element if there are two different materials on each side of the point.
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getMaterial functor.
*/
class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
{
public:
/*! Returns the string "MaterialF0D" */
string getName() const
{
return "MaterialF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// ShapeIdF0D
/*! Returns the Id of the Shape the Interface0D belongs to.
* This evaluation can be ambiguous (in the case of a TVertex for example).
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
* Interface0DIterator& belongs to.
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getShapeIdF0D functor.
*/
class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
{
public:
/*! Returns the string "ShapeIdF0D" */
string getName() const
{
return "ShapeIdF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// QiF0D
/*! Returns the quantitative invisibility of this Interface0D.
* This evaluation can be ambiguous (in the case of a TVertex for example).
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
* Interface0DIterator& belongs to.
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getQIF0D functor.
*/
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
{
public:
/*! Returns the string "QuantitativeInvisibilityF0D" */
string getName() const
{
return "QuantitativeInvisibilityF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// CurveNatureF0D
/*! Returns the Nature::EdgeNature of the 1D element the Interface0DIterator& belongs to. */
class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
{
public:
/*! Returns the string "QuantitativeInvisibilityF0D" */
string getName() const
{
return "CurveNatureF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// GetShapeF0D
/*! Returns the ViewShape* containing the Interface0D */
class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*>
{
public:
/*! Returns the string "GetShapeF0D" */
string getName() const
{
return "GetShapeF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// GetOccludersF0D
/*! Returns a vector containing the ViewShape* occluding the Interface0D */
class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
{
public:
/*! Returns the string "GetOccludersF0D" */
string getName() const
{
return "GetOccludersF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// GetOccludeeF0D
/*! Returns the ViewShape* "occluded" by the Interface0D */
class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
{
public:
/*! Returns the string "GetOccludeeF0D" */
string getName() const
{
return "GetOccludeeF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
/////////////////////////// Internal ////////////////////////////
// getFEdge
LIB_VIEW_MAP_EXPORT
FEdge *getFEdge(Interface0D& it1, Interface0D& it2);
// getFEdges
LIB_VIEW_MAP_EXPORT
void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
// getViewEdges
LIB_VIEW_MAP_EXPORT
void getViewEdges(Interface0DIterator& it, ViewEdge *&ve1, ViewEdge *&ve2);
// getShapeF0D
LIB_VIEW_MAP_EXPORT
ViewShape *getShapeF0D(Interface0DIterator& it);
// getOccludersF0D
LIB_VIEW_MAP_EXPORT
void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
// getOccludeeF0D
LIB_VIEW_MAP_EXPORT
ViewShape *getOccludeeF0D(Interface0DIterator& it);
} // end of namespace Functions0D } // end of namespace Functions0D
#endif // FUNCTIONS0D_H #endif // __FREESTYLE_FUNCTIONS_0D_H__

View File

@@ -1,231 +1,271 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
// /** \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); {
if(fe){ FEdge *fe = dynamic_cast<FEdge*>(&inter);
Vec3r res = fe->orientation2d();
result = Vec2f(res[0], res[1]);
} else {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
}
return 0;
}
int Orientation3DF1D::operator()(Interface1D& inter) {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
int ZDiscontinuityF1D::operator()(Interface1D& inter) {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
int QuantitativeInvisibilityF1D::operator()(Interface1D& inter) {
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
result = ve->qi();
return 0;
}
FEdge *fe = dynamic_cast<FEdge*>(&inter);
if (fe) { if (fe) {
result = ve->qi(); Vec3r res = fe->orientation2d();
return 0; result = Vec2f(res[0], res[1]);
}
else {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
} }
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int CurveNatureF1D::operator()(Interface1D& inter) { int Orientation3DF1D::operator()(Interface1D& inter)
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); {
if (ve) result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
result = ve->getNature();
else{
// we return a nature that contains every
// natures of the viewedges spanned by the chain.
Nature::EdgeNature nat = Nature::NO_FEATURE;
Interface0DIterator it = inter.verticesBegin();
while(!it.isEnd()){
nat |= _func(it);
++it;
}
result = nat;
}
return 0; return 0;
} }
int TimeStampF1D::operator()(Interface1D& inter) { int ZDiscontinuityF1D::operator()(Interface1D& inter)
TimeStamp *timestamp = TimeStamp::instance(); {
inter.setTimeStamp(timestamp->getTimeStamp()); result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int ChainingTimeStampF1D::operator()(Interface1D& inter) { int QuantitativeInvisibilityF1D::operator()(Interface1D& inter)
TimeStamp *timestamp = TimeStamp::instance(); {
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if(ve) if (ve) {
ve->setChainingTimeStamp(timestamp->getTimeStamp()); result = ve->qi();
return 0;
}
FEdge *fe = dynamic_cast<FEdge*>(&inter);
if (fe) {
result = ve->qi();
return 0;
}
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0; return 0;
} }
int IncrementChainingTimeStampF1D::operator()(Interface1D& inter) { int CurveNatureF1D::operator()(Interface1D& inter)
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); {
if(ve) ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1); if (ve) {
result = ve->getNature();
}
else {
// we return a nature that contains every natures of the viewedges spanned by the chain.
Nature::EdgeNature nat = Nature::NO_FEATURE;
Interface0DIterator it = inter.verticesBegin();
while (!it.isEnd()) {
nat |= _func(it);
++it;
}
result = nat;
}
return 0; return 0;
} }
int GetShapeF1D::operator()(Interface1D& inter) { int TimeStampF1D::operator()(Interface1D& inter)
vector<ViewShape*> shapesVector; {
set<ViewShape*> shapesSet; TimeStamp *timestamp = TimeStamp::instance();
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); inter.setTimeStamp(timestamp->getTimeStamp());
if (ve){
shapesVector.push_back(ve->viewShape());
}else{
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
for(;it!=itend;++it)
shapesSet.insert(Functions0D::getShapeF0D(it));
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
}
result = shapesVector;
return 0; return 0;
} }
int GetOccludersF1D::operator()(Interface1D& inter) { int ChainingTimeStampF1D::operator()(Interface1D& inter)
vector<ViewShape*> shapesVector; {
set<ViewShape*> shapesSet; TimeStamp *timestamp = TimeStamp::instance();
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve){ if (ve)
result = ve->occluders(); ve->setChainingTimeStamp(timestamp->getTimeStamp());
}else{
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
for(;it!=itend;++it){
Functions0D::getOccludersF0D(it, shapesSet);
}
shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
result = shapesVector;
}
return 0; return 0;
} }
int GetOccludeeF1D::operator()(Interface1D& inter) { int IncrementChainingTimeStampF1D::operator()(Interface1D& inter)
vector<ViewShape*> shapesVector; {
set<ViewShape*> shapesSet; ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); if (ve)
if (ve){ ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1);
ViewShape * aShape = ve->aShape();
shapesVector.push_back(aShape);
}else{
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
for(;it!=itend;++it){
shapesSet.insert(Functions0D::getOccludeeF0D(it));
}
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
}
result = shapesVector;
return 0; return 0;
} }
// Internal
////////////
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes){ int GetShapeF1D::operator()(Interface1D& inter)
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); {
if (ve){ vector<ViewShape*> shapesVector;
ViewShape * aShape = ve->aShape(); set<ViewShape*> shapesSet;
if(aShape == 0){ ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
oShapes.insert(0); if (ve) {
return; shapesVector.push_back(ve->viewShape());
} }
oShapes.insert(aShape); else {
} Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
else{ for (; it != itend; ++it)
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd(); shapesSet.insert(Functions0D::getShapeF0D(it));
for(;it!=itend;++it) shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
oShapes.insert(Functions0D::getOccludeeF0D(it)); }
} result = shapesVector;
} return 0;
}
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes){ int GetOccludersF1D::operator()(Interface1D& inter)
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); {
if (ve){ vector<ViewShape*> shapesVector;
vector<ViewShape*>& occluders = ve->occluders(); set<ViewShape*> shapesSet;
oShapes.insert<vector<ViewShape*>::iterator>(occluders.begin(), occluders.end()); ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
} if (ve) {
else{ result = ve->occluders();
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd(); }
for(;it!=itend;++it){ else {
set<ViewShape*> shapes; Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
Functions0D::getOccludersF0D(it, shapes); for (; it != itend; ++it) {
for(set<ViewShape*>::iterator s=shapes.begin(), send=shapes.end(); Functions0D::getOccludersF0D(it, shapesSet);
s!=send; }
++s) shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
oShapes.insert(*s); result = shapesVector;
} }
} return 0;
} }
int GetOccludeeF1D::operator()(Interface1D& inter)
{
vector<ViewShape*> shapesVector;
set<ViewShape*> shapesSet;
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
ViewShape *aShape = ve->aShape();
shapesVector.push_back(aShape);
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it) {
shapesSet.insert(Functions0D::getOccludeeF0D(it));
}
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
}
result = shapesVector;
return 0;
}
// Internal
////////////
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
ViewShape *aShape = ve->aShape();
if (aShape == 0) {
oShapes.insert(0);
return;
}
oShapes.insert(aShape);
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it)
oShapes.insert(Functions0D::getOccludeeF0D(it));
}
}
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
vector<ViewShape*>& occluders = ve->occluders();
oShapes.insert<vector<ViewShape*>::iterator>(occluders.begin(), occluders.end());
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it) {
set<ViewShape*> shapes;
Functions0D::getOccludersF0D(it, shapes);
for (set<ViewShape*>::iterator s = shapes.begin(), send = shapes.end(); s != send; ++s)
oShapes.insert(*s);
}
}
}
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
oShapes.insert(ve->viewShape());
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it)
oShapes.insert(Functions0D::getShapeF0D(it));
}
}
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes){
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
if (ve){
oShapes.insert(ve->viewShape());
}else{
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
for(;it!=itend;++it)
oShapes.insert(Functions0D::getShapeF0D(it));
}
}
} // end of namespace Functions1D } // end of namespace Functions1D

File diff suppressed because it is too large Load Diff

View File

@@ -1,93 +1,108 @@
// /*
// 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];
proscenium[0] = proscenium[1] = initialPoint[0]; proscenium[0] = proscenium[1] = initialPoint[0];
proscenium[2] = proscenium[3] = initialPoint[1]; proscenium[2] = proscenium[3] = initialPoint[1];
while ( source.isValid() ) { while (source.isValid()) {
GridHelpers::expandProscenium (proscenium, source.getGridSpacePolygon()); GridHelpers::expandProscenium (proscenium, source.getGridSpacePolygon());
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,74 +1,84 @@
// /*
// 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"
HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces) HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces)
: sizeFactor(sizeFactor), numFaces(numFaces) : sizeFactor(sizeFactor), numFaces(numFaces)
{ {
} }
HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory () {} HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory() {}
auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4]) auto_ptr<GridDensityProvider>
HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{ {
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor)); auto_ptr<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;
} }
} }
auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source) auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{ {
real proscenium[4]; real proscenium[4];
GridDensityProvider::calculateOptimalProscenium(source, proscenium); GridDensityProvider::calculateOptimalProscenium(source, proscenium);
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;
} }
} }

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 //#include <memory> // provided by GridDensityProvider.h
#define HEURISTICGRIDDENSITYPROVIDERFACTORY_H
// #include <memory> // provided by GridDensityProvider.h
// #include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
#include "Pow23GridDensityProvider.h"
#include "AverageAreaGridDensityProvider.h" #include "AverageAreaGridDensityProvider.h"
//#include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
#include "Pow23GridDensityProvider.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 #include <iostream>
# define INTERFACE0D_H #include <Python.h>
#include <string>
# include <Python.h> #include "../geometry/Geom.h"
# include <string>
# include <iostream>
# include "../system/Id.h"
# include "../system/Precision.h"
# include "../winged_edge/Nature.h"
# include "../geometry/Geom.h"
using namespace std;
#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 */
Interface0D() {}
virtual ~Interface0D() {}; //soc
/*! Default constructor */ /*! Returns the string "Interface0D". */
Interface0D() {} virtual string getExactTypeName() const
virtual ~Interface0D() {}; //soc {
return "Interface0D";
/*! Returns the string "Interface0D".*/ }
virtual string getExactTypeName() const {
return "Interface0D";
}
// Data access methods // Data access methods
/*! Returns the 3D x coordinate of the point. */ /*! 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
} return 0;
}
/*! Returns the FEdge that lies between this Interface0D and the
* Interface0D given as argument. */
virtual FEdge* getFEdge(Interface0D&) {
PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
return 0;
}
/*! Returns the Id of the point. */ /*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */
virtual Id getId() const { virtual FEdge* getFEdge(Interface0D&)
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden"); {
return 0; PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
} return 0;
}
/*! Returns the nature of the point. */ /*! Returns the Id of the point. */
virtual Nature::VertexNature getNature() const { virtual Id getId() const
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden"); {
return Nature::POINT; PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
} return 0;
}
/*! Returns the nature of the point. */
virtual Nature::VertexNature getNature() const
{
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
return Nature::POINT;
}
/*! Cast the Interface0D in SVertex if it can be. */ /*! Cast the Interface0D in SVertex if it can be. */
virtual SVertex * castToSVertex(){ virtual SVertex *castToSVertex()
PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden"); {
return 0; PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
} 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"); {
return 0; PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
} return 0;
}
}; };
@@ -170,39 +192,42 @@ public:
class Interface0DIteratorNested : public Iterator class Interface0DIteratorNested : public Iterator
{ {
public: public:
virtual ~Interface0DIteratorNested() {}
virtual ~Interface0DIteratorNested() {} virtual string getExactTypeName() const
{
return "Interface0DIteratorNested";
}
virtual string getExactTypeName() const { virtual Interface0D& operator*() = 0;
return "Interface0DIteratorNested";
}
virtual Interface0D& operator*() = 0; virtual Interface0D* operator->()
{
return &(operator*());
}
virtual Interface0D* operator->() { virtual int increment() = 0;
return &(operator*());
}
virtual int increment() = 0; virtual int decrement() = 0;
virtual int decrement() = 0; virtual bool isBegin() const = 0;
virtual bool isBegin() const = 0; virtual bool isEnd() const = 0;
virtual bool isEnd() const = 0; virtual bool operator==(const Interface0DIteratorNested& it) const = 0;
virtual bool operator==(const Interface0DIteratorNested& it) const = 0; virtual bool operator!=(const Interface0DIteratorNested& it) const
{
return !(*this == it);
}
virtual bool operator!=(const Interface0DIteratorNested& it) const { /*! Returns the curvilinear abscissa */
return !(*this == it); virtual float t() const = 0;
}
/*! Returns the curvilinear abscissa */ /*! Returns the point parameter 0<u<1 */
virtual float t() const = 0; virtual float u() const = 0;
/*! Returns the point parameter 0<u<1 */
virtual float u() const = 0;
virtual Interface0DIteratorNested* copy() const = 0; virtual Interface0DIteratorNested* copy() const = 0;
}; };
@@ -212,149 +237,154 @@ public:
////////////////////////////////////////////////// //////////////////////////////////////////////////
/*! Class defining an iterator over Interface0D elements. /*! 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)
{
_iterator = it;
}
Interface0DIterator(Interface0DIteratorNested* it = NULL) { /*! Copy constructor */
_iterator = it; Interface0DIterator(const Interface0DIterator& it)
} {
_iterator = it._iterator->copy();
}
/*! Copy constructor */ /*! Destructor */
Interface0DIterator(const Interface0DIterator& it) { virtual ~Interface0DIterator()
_iterator = it._iterator->copy(); {
} if (_iterator)
delete _iterator;
}
/*! Destructor */ /*! Operator =
virtual ~Interface0DIterator() { * \attention In the scripting language, you must call \code it2 = Interface0DIterator(it1) \endcode instead of
if (_iterator) * \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
delete _iterator; * Otherwise, incrementing \a it1 will also increment \a it2.
} */
Interface0DIterator& operator=(const Interface0DIterator& it)
{
if(_iterator)
delete _iterator;
_iterator = it._iterator->copy();
return *this;
}
/*! Operator = /*! Returns the string "Interface0DIterator". */
* \attention In the scripting language, you must call virtual string getExactTypeName() const
* \code it2 = Interface0DIterator(it1) \endcode instead of \code it2 = it1 \endcode {
* where \a it1 and \a it2 are 2 Interface0DIterator. if (!_iterator)
* Otherwise, incrementing \a it1 will also increment \a it2. return "Interface0DIterator";
*/ return _iterator->getExactTypeName() + "Proxy";
Interface0DIterator& operator=(const Interface0DIterator& it) { }
if(_iterator)
delete _iterator;
_iterator = it._iterator->copy();
return *this;
}
/*! Returns the string "Interface0DIterator". */ // FIXME test it != 0 (exceptions ?)
virtual string getExactTypeName() const {
if (!_iterator)
return "Interface0DIterator";
return _iterator->getExactTypeName() + "Proxy";
}
// FIXME test it != 0 (exceptions ?) /*! Returns a reference to the pointed Interface0D.
* In the scripting language, you must call "getObject()" instead using this operator.
*/
Interface0D& operator*()
{
return _iterator->operator*();
}
/*! Returns a reference to the pointed Interface0D. /*! Returns a pointer to the pointed Interface0D.
* In the scripting language, you must call * Can't be called in the scripting language.
* "getObject()" instead using this operator. */
*/ Interface0D *operator->()
Interface0D& operator*() { {
return _iterator->operator*(); return &(operator*());
} }
/*! Returns a pointer to the pointed Interface0D. /*! Increments. In the scripting language, call "increment()". */
* Can't be called in the scripting language. Interface0DIterator& operator++()
*/ {
Interface0D* operator->() { _iterator->increment();
return &(operator*()); return *this;
} }
/*! Increments. In the scripting language, call /*! Increments. In the scripting language, call "increment()". */
* "increment()". Interface0DIterator operator++(int)
*/ {
Interface0DIterator& operator++() { Interface0DIterator ret(*this);
_iterator->increment(); _iterator->increment();
return *this; return ret;
} }
/*! Increments. In the scripting language, call /*! Decrements. In the scripting language, call "decrement()". */
* "increment()". Interface0DIterator& operator--()
*/ {
Interface0DIterator operator++(int) { _iterator->decrement();
Interface0DIterator ret(*this); return *this;
_iterator->increment(); }
return ret;
}
/*! Decrements. In the scripting language, call /*! Decrements. In the scripting language, call "decrement()". */
* "decrement()". Interface0DIterator operator--(int)
*/ {
Interface0DIterator& operator--() { Interface0DIterator ret(*this);
_iterator->decrement(); _iterator->decrement();
return *this; return ret;
} }
/*! Decrements. In the scripting language, call /*! Increments. */
* "decrement()". virtual int increment()
*/ {
Interface0DIterator operator--(int) { return _iterator->increment();
Interface0DIterator ret(*this); }
_iterator->decrement();
return ret;
}
/*! Increments. */ /*! Decrements. */
virtual int increment() { virtual int decrement()
return _iterator->increment(); {
} return _iterator->decrement();
}
/*! Decrements. */
virtual int 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. */
inline float t() const
{
return _iterator->t();
}
/*! Returns the point parameter in the curve 0<=u<=1. */
inline float u() const
{
return _iterator->u();
}
/*! Returns the curvilinear abscissa. */
inline float t() const {
return _iterator->t();
}
/*! Returns the point parameter in the curve 0<=u<=1. */
inline float u() const {
return _iterator->u();
}
protected: protected:
Interface0DIteratorNested *_iterator;
Interface0DIteratorNested* _iterator;
}; };
#endif // INTERFACE0D_H #endif // __FREESTYLE_INTERFACE_0D_H__

View File

@@ -1,125 +1,126 @@
// /*
// 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 #include <float.h>
# define INTERFACE1D_H #include <iostream>
#include <Python.h>
#include <string>
# include <Python.h> #include "Functions0D.h"
# include <string>
# include <iostream> #include "../system/Id.h"
# include <float.h> #include "../system/Precision.h"
# include "../system/Id.h"
# include "../system/Precision.h" #include "../winged_edge/Nature.h"
# include "../winged_edge/Nature.h"
# include "Functions0D.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 {
MEAN,/*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/ MEAN, /*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/
MIN,/*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/ MIN, /*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/
MAX,/*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/ MAX, /*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/
FIRST,/*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/ FIRST, /*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/
LAST/*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/ 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;
res = fun.result;++it; ++it;
for (; !it.isEnd(); ++it) { for (; !it.isEnd(); ++it) {
fun(it); fun(it);
if (fun.result < res) if (fun.result < res)
res = fun.result; res = fun.result;
} }
break; break;
case MAX: case MAX:
fun(it); fun(it);
res = fun.result;++it; res = fun.result;
for (; !it.isEnd(); ++it) { ++it;
fun(it); for (; !it.isEnd(); ++it) {
if (fun.result > res) fun(it);
res = fun.result; if (fun.result > res)
} res = fun.result;
break; }
case FIRST: break;
fun(it); case FIRST:
res = fun.result; fun(it);
break; res = fun.result;
case LAST: break;
fun(--it_end); case LAST:
res = fun.result; fun(--it_end);
break; res = fun.result;
case MEAN: break;
default: case MEAN:
fun(it); default:
res = fun.result;++it; fun(it);
for (size = 1; !it.isEnd(); ++it, ++size) { res = fun.result;
fun(it); ++it;
res += fun.result; for (size = 1; !it.isEnd(); ++it, ++size) {
fun(it);
res += fun.result;
}
res /= (size ? size : 1);
break;
} }
res /= (size ? size : 1); return res;
break;
}
return res;
} }
// //
@@ -131,96 +132,99 @@ T integrate(UnaryFunction0D<T>& fun,
class Interface1D class Interface1D
{ {
public: public:
/*! Default constructor */
Interface1D()
{
_timeStamp = 0;
}
/*! Default constructor */ virtual ~Interface1D() {}; //soc
Interface1D() {_timeStamp=0;}
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,
* pointing after the last vertex.
*/
virtual Interface0DIterator verticesEnd(){
PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
return Interface0DIterator();
}
/*! Returns an iterator over the Interface1D points, /*! Returns an iterator over the Interface1D vertices, pointing after the last vertex. */
* pointing to the first point. The difference with virtual Interface0DIterator verticesEnd()
* verticesBegin() is that here we can iterate over {
* points of the 1D element at a any given sampling. PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
* Indeed, for each iteration, a virtual point is created. return Interface0DIterator();
* \param t }
* The sampling with which we want to iterate over points of
* this 1D element.
*/
virtual Interface0DIterator pointsBegin(float t=0.f) {
PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
return Interface0DIterator();
}
/*! Returns an iterator over the Interface1D points, /*! Returns an iterator over the Interface1D points, pointing to the first point. The difference with
* pointing after the last point. The difference with * verticesBegin() 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 * Indeed, for each iteration, a virtual point is created.
* points of the 1D element at a any given sampling. * \param t
* Indeed, for each iteration, a virtual point is created. * The sampling with which we want to iterate over points of this 1D element.
* \param t */
* The sampling with which we want to iterate over points of virtual Interface0DIterator pointsBegin(float t = 0.0f)
* this 1D element. {
*/ PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
virtual Interface0DIterator pointsEnd(float t=0.f) { return Interface0DIterator();
PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden"); }
return Interface0DIterator();
}
// Data access methods /*! Returns an iterator over the Interface1D points, pointing after the last point. The difference with
* verticesEnd() is that here we can iterate over points of the 1D element at a any given sampling.
* Indeed, for each iteration, a virtual point is created.
* \param t
* The sampling with which we want to iterate over points of this 1D element.
*/
virtual Interface0DIterator pointsEnd(float t = 0.0f)
{
PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
return Interface0DIterator();
}
/*! Returns the 2D length of the 1D element. */ // Data access methods
virtual real getLength2D() const {
PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
return 0;
}
/*! Returns the Id of the 1D element .*/ /*! Returns the 2D length of the 1D element. */
virtual Id getId() const { virtual real getLength2D() const
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden"); {
return Id(0, 0); PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
} return 0;
}
/*! Returns the Id of the 1D element. */
virtual Id getId() const
{
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
return Id(0, 0);
}
// FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D) // 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"); {
return Nature::NO_FEATURE; PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
} return Nature::NO_FEATURE;
}
/*! Returns the time stamp of the 1D element. Mainly used for selection. */
virtual unsigned getTimeStamp() const { /*! Returns the time stamp of the 1D element. Mainly used for selection. */
return _timeStamp; virtual unsigned getTimeStamp() const
} {
return _timeStamp;
/*! Sets the time stamp for the 1D element. */ }
inline void setTimeStamp(unsigned iTimeStamp){
_timeStamp = iTimeStamp; /*! Sets the time stamp for the 1D element. */
} inline void setTimeStamp(unsigned iTimeStamp)
{
_timeStamp = iTimeStamp;
}
protected: protected:
unsigned _timeStamp; unsigned _timeStamp;
}; };
#endif // INTERFACE1D_H #endif // __FREESTYLE_INTERFACE_1D_H__

View File

@@ -1,65 +1,73 @@
// /*
// 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);
// so we have to do: // so we have to do:
for ( vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i ) { for (vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i) {
(*i) = transform(*i); (*i) = transform(*i);
} }
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();
valid = false; valid = false;
if ( currentShape != shapesEnd ) { if (currentShape != shapesEnd) {
vector<WFace*>& wFaces = (*currentShape)->GetFaceList(); vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
currentFace = wFaces.begin(); currentFace = wFaces.begin();
facesEnd = wFaces.end(); facesEnd = wFaces.end();
if ( currentFace != facesEnd ) { if (currentFace != facesEnd) {
buildCachedPolygon(); buildCachedPolygon();
valid = true; valid = true;
} }
@@ -67,14 +75,15 @@ void OccluderSource::begin() {
} }
bool OccluderSource::next() { bool OccluderSource::next() {
if ( valid ) { if (valid) {
++currentFace; ++currentFace;
while ( currentFace == facesEnd ) { while (currentFace == facesEnd) {
++currentShape; ++currentShape;
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,40 +95,47 @@ 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];
proscenium[2] = proscenium[3] = initialPoint[1]; proscenium[2] = proscenium[3] = initialPoint[1];
while ( isValid() ) { while (isValid()) {
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()) {
Vec3r min, max; Vec3r min, max;
cachedPolygon.getBBox(min, max); cachedPolygon.getBBox(min, max);
area += (max[0] - min[0]) * (max[1] - min[1]); area += (max[0] - min[0]) * (max[1] - min[1]);
@@ -128,5 +144,3 @@ real OccluderSource::averageOccluderArea() {
area /= numFaces; area /= numFaces;
return area; return area;
} }

View File

@@ -1,53 +1,59 @@
// /*
// 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);
public: public:
OccluderSource (const GridHelpers::Transform& transform, WingedEdge& we); OccluderSource(const GridHelpers::Transform& transform, WingedEdge& we);
virtual ~OccluderSource(); virtual ~OccluderSource();
void begin(); void begin();
virtual bool next(); virtual bool next();
bool isValid(); bool isValid();
WFace* getWFace(); WFace *getWFace();
Polygon3r getCameraSpacePolygon(); Polygon3r getCameraSpacePolygon();
Polygon3r& getGridSpacePolygon(); Polygon3r& getGridSpacePolygon();
@@ -67,4 +73,4 @@ protected:
void buildCachedPolygon(); void buildCachedPolygon();
}; };
#endif // OCCLUDERSOURCE_H #endif // __FREESTYLE_OCCLUDER_SOURCE_H__

View File

@@ -1,52 +1,57 @@
// /*
// 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"
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces) Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces)
: GridDensityProvider(source), numFaces(numFaces) : GridDensityProvider(source), numFaces(numFaces)
{ {
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,
: GridDensityProvider(source), numFaces(numFaces) const GridHelpers::Transform& transform, unsigned numFaces)
: GridDensityProvider(source), numFaces(numFaces)
{ {
real proscenium[4]; real proscenium[4];
calculateQuickProscenium(transform, bbox, proscenium); calculateQuickProscenium(transform, bbox, proscenium);
initialize (proscenium); initialize (proscenium);
} }
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces) Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces)
: GridDensityProvider(source), numFaces(numFaces) : GridDensityProvider(source), numFaces(numFaces)
{ {
real proscenium[4]; real proscenium[4];
calculateOptimalProscenium(source, proscenium); calculateOptimalProscenium(source, proscenium);
@@ -56,7 +61,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsig
Pow23GridDensityProvider::~Pow23GridDensityProvider () {} Pow23GridDensityProvider::~Pow23GridDensityProvider () {}
void Pow23GridDensityProvider::initialize (const real proscenium[4]) void Pow23GridDensityProvider::initialize(const real proscenium[4])
{ {
float prosceniumWidth = (proscenium[1] - proscenium[0]); float prosceniumWidth = (proscenium[1] - proscenium[0]);
float prosceniumHeight = (proscenium[3] - proscenium[2]); float prosceniumHeight = (proscenium[3] - proscenium[2]);
@@ -71,10 +76,10 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
// Make sure the grid exceeds the proscenium by a small amount // Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1; float safetyZone = 0.1;
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;
} }
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) { if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize; _cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
} }
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl; cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
@@ -85,25 +90,26 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
} }
Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFaces) Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFaces)
: numFaces(numFaces) : numFaces(numFaces)
{ {
} }
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));
} }
auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source) auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{ {
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces)); return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
} }

View File

@@ -1,67 +1,75 @@
// /*
// 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();
protected: protected:
unsigned numFaces; unsigned numFaces;
private: 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,370 +1,414 @@
/*
* ***** 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"
/**********************************/ /**********************************/
/* */ /* */
/* */ /* */
/* SVertex */ /* SVertex */
/* */ /* */
/* */ /* */
/**********************************/ /**********************************/
Nature::VertexNature SVertex::getNature() const { Nature::VertexNature SVertex::getNature() const
Nature::VertexNature nature = Nature::S_VERTEX;
if (_pViewVertex)
nature |= _pViewVertex->getNature();
return nature;
}
SVertex * SVertex::castToSVertex(){
return this;
}
ViewVertex * SVertex::castToViewVertex(){
return _pViewVertex;
}
NonTVertex * SVertex::castToNonTVertex(){
return dynamic_cast<NonTVertex*>(_pViewVertex);
}
TVertex * SVertex::castToTVertex(){
return dynamic_cast<TVertex*>(_pViewVertex);
}
float SVertex::shape_importance() const
{ {
return shape()->importance(); Nature::VertexNature nature = Nature::S_VERTEX;
} if (_pViewVertex)
nature |= _pViewVertex->getNature();
//Material SVertex::material() const {return _Shape->material();} return nature;
Id SVertex::shape_id() const {return _Shape->getId();}
const SShape * SVertex::shape() const {return _Shape;}
const int SVertex::qi() const
{
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->qi();
} }
occluder_container::const_iterator SVertex::occluders_begin() const SVertex *SVertex::castToSVertex()
{ {
if (getNature() & Nature::T_VERTEX) return this;
Exception::raiseException();
return (_FEdges[0])->occluders_begin();
} }
occluder_container::const_iterator SVertex::occluders_end() const ViewVertex *SVertex::castToViewVertex()
{ {
if (getNature() & Nature::T_VERTEX) return _pViewVertex;
Exception::raiseException();
return (_FEdges[0])->occluders_end();
} }
bool SVertex::occluders_empty() const NonTVertex *SVertex::castToNonTVertex()
{ {
if (getNature() & Nature::T_VERTEX) return dynamic_cast<NonTVertex*>(_pViewVertex);
Exception::raiseException();
return (_FEdges[0])->occluders_empty();
} }
int SVertex::occluders_size() const TVertex *SVertex::castToTVertex()
{ {
if (getNature() & Nature::T_VERTEX) return dynamic_cast<TVertex*>(_pViewVertex);
Exception::raiseException();
return (_FEdges[0])->occluders_size();
} }
const Polygon3r& SVertex::occludee() const float SVertex::shape_importance() const
{ {
if (getNature() & Nature::T_VERTEX) return shape()->importance();
Exception::raiseException();
return (_FEdges[0])->occludee();
} }
const SShape* SVertex::occluded_shape() const #if 0
Material SVertex::material() const
{ {
if (getNature() & Nature::T_VERTEX) return _Shape->material();
Exception::raiseException(); }
return (_FEdges[0])->occluded_shape(); #endif
Id SVertex::shape_id() const
{
return _Shape->getId();
} }
const bool SVertex::occludee_empty() const const SShape *SVertex::shape() const
{ {
if (getNature() & Nature::T_VERTEX) return _Shape;
Exception::raiseException();
return (_FEdges[0])->occludee_empty();
} }
real SVertex::z_discontinuity() const const int SVertex::qi() const
{ {
if (getNature() & Nature::T_VERTEX) if (getNature() & Nature::T_VERTEX)
Exception::raiseException(); Exception::raiseException();
return (_FEdges[0])->z_discontinuity(); return (_FEdges[0])->qi();
} }
FEdge* SVertex::fedge() occluder_container::const_iterator SVertex::occluders_begin() const
{ {
if (getNature() & Nature::T_VERTEX) if (getNature() & Nature::T_VERTEX)
return 0; Exception::raiseException();
return _FEdges[0]; return (_FEdges[0])->occluders_begin();
} }
FEdge* SVertex::getFEdge(Interface0D& inter) occluder_container::const_iterator SVertex::occluders_end() const
{ {
FEdge * result = 0; if (getNature() & Nature::T_VERTEX)
SVertex* iVertexB = dynamic_cast<SVertex*>(&inter); Exception::raiseException();
if (!iVertexB) return (_FEdges[0])->occluders_end();
return result; }
vector<FEdge*>::const_iterator fe=_FEdges.begin(), feend=_FEdges.end();
for(; bool SVertex::occluders_empty() const
fe!=feend; {
++fe) if (getNature() & Nature::T_VERTEX)
{ Exception::raiseException();
if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB)) return (_FEdges[0])->occluders_empty();
|| (((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB))) }
result = (*fe);
} int SVertex::occluders_size() const
if((result == 0) && (getNature() & Nature::T_VERTEX)) {
{ if (getNature() & Nature::T_VERTEX)
SVertex *brother; Exception::raiseException();
ViewVertex *vvertex = viewvertex(); return (_FEdges[0])->occluders_size();
TVertex * tvertex = dynamic_cast<TVertex*>(vvertex); }
if(tvertex)
{ const Polygon3r& SVertex::occludee() const
brother = tvertex->frontSVertex(); {
if(this == brother) if (getNature() & Nature::T_VERTEX)
brother = tvertex->backSVertex(); Exception::raiseException();
const vector<FEdge*>& fedges = brother->fedges(); return (_FEdges[0])->occludee();
for(fe=fedges.begin(),feend=fedges.end(); }
fe!=feend;
++fe) const SShape *SVertex::occluded_shape() const
{ {
if( (((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB)) if (getNature() & Nature::T_VERTEX)
|| (((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB))) Exception::raiseException();
result = (*fe); return (_FEdges[0])->occluded_shape();
} }
}
} const bool SVertex::occludee_empty() const
if((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) {
{ if (getNature() & Nature::T_VERTEX)
SVertex *brother; Exception::raiseException();
ViewVertex *vvertex = iVertexB->viewvertex(); return (_FEdges[0])->occludee_empty();
TVertex * tvertex = dynamic_cast<TVertex*>(vvertex); }
if(tvertex)
{ real SVertex::z_discontinuity() const
brother = tvertex->frontSVertex(); {
if(iVertexB == brother) if (getNature() & Nature::T_VERTEX)
brother = tvertex->backSVertex(); Exception::raiseException();
for(fe=_FEdges.begin(),feend=_FEdges.end(); return (_FEdges[0])->z_discontinuity();
fe!=feend; }
++fe)
{ FEdge *SVertex::fedge()
if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother)) {
|| (((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother))) if (getNature() & Nature::T_VERTEX)
result = (*fe); return NULL;
} return _FEdges[0];
} }
}
FEdge *SVertex::getFEdge(Interface0D& inter)
return result; {
FEdge *result = NULL;
SVertex *iVertexB = dynamic_cast<SVertex*>(&inter);
if (!iVertexB)
return result;
vector<FEdge*>::const_iterator fe = _FEdges.begin(), feend = _FEdges.end();
for (; fe != feend; ++fe) {
if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB)) ||
(((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB)))
result = (*fe);
}
if ((result == 0) && (getNature() & Nature::T_VERTEX)) {
SVertex *brother;
ViewVertex *vvertex = viewvertex();
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
if (tvertex) {
brother = tvertex->frontSVertex();
if (this == brother)
brother = tvertex->backSVertex();
const vector<FEdge*>& fedges = brother->fedges();
for (fe = fedges.begin(), feend = fedges.end(); fe != feend; ++fe) {
if ((((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB)) ||
(((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB)))
result = (*fe);
}
}
}
if ((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) {
SVertex *brother;
ViewVertex *vvertex = iVertexB->viewvertex();
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
if (tvertex) {
brother = tvertex->frontSVertex();
if (iVertexB == brother)
brother = tvertex->backSVertex();
for (fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; ++fe) {
if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother)) ||
(((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother)))
result = (*fe);
}
}
}
return result;
} }
/**********************************/ /**********************************/
/* */ /* */
/* */ /* */
/* FEdge */ /* FEdge */
/* */ /* */
/* */ /* */
/**********************************/ /**********************************/
int FEdge::viewedge_nature() const {return _ViewEdge->getNature();} int FEdge::viewedge_nature() const
//float FEdge::viewedge_length() const {return _ViewEdge->viewedge_length();}
const SShape* FEdge::occluded_shape() const
{ {
ViewShape * aShape = _ViewEdge->aShape(); return _ViewEdge->getNature();
if(aShape == 0)
return 0;
return aShape->sshape();
} }
float FEdge::shape_importance() const #if 0
float FEdge::viewedge_length() const
{ {
return _VertexA->shape()->importance(); return _ViewEdge->viewedge_length();
} }
#endif
int FEdge::invisibility() const const SShape *FEdge::occluded_shape() const
{ {
return _ViewEdge->qi(); ViewShape *aShape = _ViewEdge->aShape();
if (aShape == 0)
return 0;
return aShape->sshape();
}
float FEdge::shape_importance() const
{
return _VertexA->shape()->importance();
}
int FEdge::invisibility() const
{
return _ViewEdge->qi();
}
occluder_container::const_iterator FEdge::occluders_begin() const
{
return _ViewEdge->occluders_begin();
}
occluder_container::const_iterator FEdge::occluders_end() const
{
return _ViewEdge->occluders_end();
}
bool FEdge::occluders_empty() const
{
return _ViewEdge->occluders_empty();
}
int FEdge::occluders_size() const
{
return _ViewEdge->occluders_size();
} }
occluder_container::const_iterator FEdge::occluders_begin() const {return _ViewEdge->occluders_begin();}
occluder_container::const_iterator FEdge::occluders_end() const {return _ViewEdge->occluders_end();}
bool FEdge::occluders_empty() const {return _ViewEdge->occluders_empty();}
int FEdge::occluders_size() const {return _ViewEdge->occluders_size();}
const bool FEdge::occludee_empty() const 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();
} }
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; }
}
BBox<Vec3r> box = ViewMap::getInstance()->getScene3dBBox(); BBox<Vec3r> box = ViewMap::getInstance()->getScene3dBBox();
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 1.0;
//return bboxsize;
}
{ #if 0
//return FLT_MAX; real result;
z_discontinuity_functor<SVertex> _functor;
Evaluate<SVertex, z_discontinuity_functor<SVertex> >(&_functor, iCombination, result);
#endif
Vec3r middle((_VertexB->point3d() - _VertexA->point3d()));
middle /= 2;
Vec3r disc_vec(middle - _occludeeIntersection);
real res = disc_vec.norm() / bboxsize;
return 1.0; return res;
//return fabs((middle.z() - _occludeeIntersection.z()));
//return bboxsize;
}
// real result;
// z_discontinuity_functor<SVertex> _functor;
// Evaluate<SVertex,z_discontinuity_functor<SVertex> >(&_functor, iCombination, result )
Vec3r middle((_VertexB->point3d()-_VertexA->point3d()));
middle /= 2;
Vec3r disc_vec(middle - _occludeeIntersection);
real res = disc_vec.norm() / bboxsize;
return res;
//return fabs((middle.z()-_occludeeIntersection.z()));
} }
#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;
// local_average_depth_functor<SVertex> functor;
// Evaluate(&functor, iCombination, result);
//
// return result;
//}
//float FEdge::local_depth_variance(int iCombination ) const
//{
// float result;
//
// local_depth_variance_functor<SVertex> functor;
//
// Evaluate(&functor, iCombination, result);
//
// return result;
//}
//
//
//real FEdge::local_average_density( float sigma, int iCombination) const
//{
// float result;
//
// density_functor<SVertex> functor(sigma);
//
// Evaluate(&functor, iCombination, result);
//
// return result;
//}
//
////Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */)
////{
//// Vec3r Na = _VertexA->normal(oException);
//// if(oException != Exception::NO_EXCEPTION)
//// return Na;
//// Vec3r Nb = _VertexB->normal(oException);
//// if(oException != Exception::NO_EXCEPTION)
//// return Nb;
//// return (Na+Nb)/2.0;
////}
//
//Vec3r FEdge::curvature2d_as_vector(int iCombination) const
//{
// Vec3r result;
// curvature2d_as_vector_functor<SVertex> _functor;
// Evaluate<Vec3r,curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result );
// return result;
//}
//
//real FEdge::curvature2d_as_angle(int iCombination) const
//{
// real result;
// curvature2d_as_angle_functor<SVertex> _functor;
// Evaluate<real,curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result );
// return result;
//}
/**********************************/
/* */
/* */
/* FEdgeSharp */
/* */
/* */
/**********************************/
//Material FEdge::material() const
//{
// return _VertexA->shape()->material();
//}
const FrsMaterial& FEdgeSharp::aFrsMaterial() const {
return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
} }
const FrsMaterial& FEdgeSharp::bFrsMaterial() const { float FEdge::local_depth_variance(int iCombination ) const
return _VertexA->shape()->frs_material(_bFrsMaterialIndex); {
float result;
local_depth_variance_functor<SVertex> functor;
Evaluate(&functor, iCombination, result);
return result;
} }
/**********************************/ real FEdge::local_average_density( float sigma, int iCombination) const
/* */ {
/* */ float result;
/* FEdgeSmooth */
/* */
/* */
/**********************************/
const FrsMaterial& FEdgeSmooth::frs_material() const { density_functor<SVertex> functor(sigma);
return _VertexA->shape()->frs_material(_FrsMaterialIndex);
Evaluate(&functor, iCombination, result);
return result;
}
Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */)
{
Vec3r Na = _VertexA->normal(oException);
if (oException != Exception::NO_EXCEPTION)
return Na;
Vec3r Nb = _VertexB->normal(oException);
if (oException != Exception::NO_EXCEPTION)
return Nb;
return (Na + Nb) / 2.0;
}
Vec3r FEdge::curvature2d_as_vector(int iCombination) const
{
Vec3r result;
curvature2d_as_vector_functor<SVertex> _functor;
Evaluate<Vec3r, curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result);
return result;
}
real FEdge::curvature2d_as_angle(int iCombination) const
{
real result;
curvature2d_as_angle_functor<SVertex> _functor;
Evaluate<real, curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result);
return result;
}
#endif
/**********************************/
/* */
/* */
/* FEdgeSharp */
/* */
/* */
/**********************************/
#if 0
Material FEdge::material() const
{
return _VertexA->shape()->material();
}
#endif
const FrsMaterial& FEdgeSharp::aFrsMaterial() const
{
return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
}
const FrsMaterial& FEdgeSharp::bFrsMaterial() const
{
return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
}
/**********************************/
/* */
/* */
/* FEdgeSmooth */
/* */
/* */
/**********************************/
const FrsMaterial& FEdgeSmooth::frs_material() const
{
return _VertexA->shape()->frs_material(_FrsMaterialIndex);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,163 +1,191 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
// /** \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] = {
{0,1,0,0}, {1, 0, 0, 0},
{0,0,1,0}, {0, 1, 0, 0},
{0,0,0,1}}; {0, 0, 1, 0},
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {{1,0,0,0}, {0, 0, 0, 1}
{0,1,0,0}, };
{0,0,1,0}, real SilhouetteGeomEngine::_projectionMatrix[4][4] = {
{0,0,0,1}}; {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 real SilhouetteGeomEngine::_transform[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
int SilhouetteGeomEngine::_viewport[4] = {1, 1, 1, 1};
real SilhouetteGeomEngine::_Focal = 0.0; real SilhouetteGeomEngine::_Focal = 0.0;
real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {{1,0,0,0}, real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {
{0,1,0,0}, {1, 0, 0, 0},
{0,0,1,0}, {0, 1, 0, 0},
{0,0,0,1}}; {0, 0, 1, 0},
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {{1,0,0,0}, {0, 0, 0, 1}
{0,1,0,0}, };
{0,0,1,0}, real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {
{0,0,0,1}}; {1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
real SilhouetteGeomEngine::_znear = 0.0; real SilhouetteGeomEngine::_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];
_translation[1] = iModelViewMatrix[3][1]; _translation[1] = iModelViewMatrix[3][1];
_translation[2] = iModelViewMatrix[3][2]; _translation[2] = iModelViewMatrix[3][2];
for(i=0; i<4; i++){
for(j=0; j<4; j++)
{
_modelViewMatrix[i][j] = iModelViewMatrix[j][i];
_glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
}
}
for(i=0; i<4; i++){ for (i = 0; i < 4; i++) {
for(j=0; j<4; j++) for (j = 0; j < 4; j++) {
{ _modelViewMatrix[i][j] = iModelViewMatrix[j][i];
_projectionMatrix[i][j] = iProjectionMatrix[j][i]; _glModelViewMatrix[i][j] = iModelViewMatrix[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++) _projectionMatrix[i][j] = iProjectionMatrix[j][i];
{ _glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
_transform[i][j] = 0; }
for(unsigned int k=0; k<4; k++) }
_transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
} for (i = 0; i < 4; i++) {
} for (j = 0; j < 4; j++) {
_transform[i][j] = 0;
for(i=0; i<4; i++){ for (unsigned int k = 0; k < 4; k++)
_viewport[i] = iViewport[i]; _transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
} }
_Focal = iFocal; }
for (i = 0; i < 4; i++) {
_viewport[i] = iViewport[i];
}
_Focal = iFocal;
_isOrthographicProjection = (iProjectionMatrix[3][3] != 0.0); _isOrthographicProjection = (iProjectionMatrix[3][3] != 0.0);
} }
void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar) void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
{ {
_znear = iZNear; _znear = iZNear;
_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;
vector<SVertex*>::iterator sv, svend; real max = -HUGE;
const real depth = _zfar - _znear; #endif
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth; vector<SVertex*>::iterator sv, svend;
const real depth = _zfar - _znear;
for(sv=ioVertices.begin(), svend=ioVertices.end(); const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
sv!=svend;
sv++) for (sv = ioVertices.begin(), svend = ioVertices.end(); 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); #if 0
//cerr << (*sv)->point2d().z() << " "; cerr << (*sv)->point2d().z() << " ";
// real d=(*sv)->point2d()[2]; real d = (*sv)->point2d()[2];
// if (d>max) max =d; if (d > max)
// if (d<min) min =d; max =d;
} if (d < min)
// for(sv=ioVertices.begin(), svend=ioVertices.end(); min =d;
// sv!=svend; #endif
// sv++) }
// { #if 0
// Vec3r P((*sv)->point2d()); for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
// (*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;
vector<SVertex*>::iterator sv, svend; real max = -HUGE;
const real depth = _zfar - _znear; vector<SVertex*>::iterator sv, svend;
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth; #endif
GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport); const real depth = _zfar - _znear;
newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1 const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
ioVertex->setPoint2D(newPoint); GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
ioVertex->setPoint2D(newPoint);
} }
real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t) 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 < 1.0e-6) ? 1.0 : 1.0 / depth;
const real fac = (depth < 1e-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,41 +1,46 @@
// /*
// 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 #include <vector>
# define SILHOUETTEGEOMENGINE_H
# include <vector> #include "../geometry/Geom.h"
# include "../system/FreestyleConfig.h"
# include "../geometry/Geom.h" #include "../system/FreestyleConfig.h"
using namespace Geometry; using namespace Geometry;
@@ -45,79 +50,87 @@ 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 real _translation[3]; static Vec3r _Viewpoint;
static real _modelViewMatrix[4][4]; // the model view matrix (_modelViewMatrix[i][j] means element of line i and column j) static real _translation[3];
static real _projectionMatrix[4][4]; // the projection matrix (_projectionMatrix[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 _transform[4][4]; // the global transformation from world to screen (projection included) (_transform[i][j] means element of line i and column j) static real _modelViewMatrix[4][4];
static int _viewport[4]; // the viewport // the projection matrix (_projectionMatrix[i][j] means element of line i and column j)
static real _Focal; static real _projectionMatrix[4][4];
// the global transformation from world to screen (projection included)
static real _znear; // (_transform[i][j] means element of line i and column j)
static real _zfar; static real _transform[4][4];
// the viewport
static int _viewport[4];
static real _Focal;
static real _glProjectionMatrix[4][4]; // GL style (column major) projection matrix static real _znear;
static real _glModelViewMatrix[4][4]; // GL style (column major) model view matrix static real _zfar;
// GL style (column major) projection matrix
static real _glProjectionMatrix[4][4];
// GL style (column major) model view matrix
static real _glModelViewMatrix[4][4];
static bool _isOrthographicProjection;
static SilhouetteGeomEngine *_pInstance;
static bool _isOrthographicProjection;
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
* The 4x4 model view matrix, in column major order (openGL like). * The 4x4 model view matrix, in column major order (openGL like).
* iProjection matrix * iProjection matrix
* The 4x4 projection matrix, in column major order (openGL like). * The 4x4 projection matrix, in column major order (openGL like).
* iViewport * iViewport
* The viewport. 4 real array: origin.x, origin.y, width, length * The viewport. 4 real array: origin.x, origin.y, width, length
* 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 */
static void retrieveViewport(int viewport[4]); static void retrieveViewport(int viewport[4]);
/*! 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);
/*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain /*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain
* the parameter giving the corresponding 3D intersection. * the parameter giving the corresponding 3D intersection.
* Returns the 3D parameter * Returns the 3D parameter
* fe * fe
* The edge * The edge
* t * t
* The parameter for the 2D intersection. * The parameter for the 2D intersection.
*/ */
static real ImageToWorldParameter(FEdge *fe, real t); static real ImageToWorldParameter(FEdge *fe, real t);
/*! From world to image */ /*! From world to image */
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
@@ -42,11 +47,12 @@ using namespace std;
// Cell // Cell
///////// /////////
SphericalGrid::Cell::Cell () {} SphericalGrid::Cell::Cell() {}
SphericalGrid::Cell::~Cell () {} SphericalGrid::Cell::~Cell() {}
void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) { void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
{
const real epsilon = 1.0e-06; 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);
} }
@@ -66,30 +75,29 @@ void SphericalGrid::Cell::indexPolygons() {
// Iterator // Iterator
////////////////// //////////////////
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;
#endif #endif
// Set iterator // Set iterator
_current = _cell->faces.begin(); _current = _cell->faces.begin();
} }
SphericalGrid::Iterator::~Iterator () {} 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();
@@ -115,20 +123,19 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
// Now allocate the cell table and fill it with default (empty) cells // Now allocate the cell table and fill it with default (empty) cells
_cells.resize(_cellsX * _cellsY); _cells.resize(_cellsX * _cellsY);
for ( cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) { for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
(*i) = NULL; (*i) = NULL;
} }
// Identify cells that will be used, and set the dimensions for each // Identify cells that will be used, and set the dimensions for each
ViewMap::fedges_container& fedges = viewMap->FEdges(); ViewMap::fedges_container& fedges = viewMap->FEdges();
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 = SphericalGrid::Transform::sphericalProjection((*f)->center3d()); Vec3r point = SphericalGrid::Transform::sphericalProjection((*f)->center3d());
unsigned i, j; unsigned 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,22 +152,23 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
} }
} }
void SphericalGrid::distributePolygons (OccluderSource& source) { void SphericalGrid::distributePolygons(OccluderSource& source)
{
unsigned long nFaces = 0; unsigned long nFaces = 0;
unsigned long nKeptFaces = 0; unsigned long nKeptFaces = 0;
for ( source.begin(); source.isValid(); source.next() ) { for (source.begin(); source.isValid(); source.next()) {
OccluderData* occluder = NULL; OccluderData *occluder = NULL;
try { try {
if ( insertOccluder(source, occluder) ) { if (insertOccluder(source, occluder)) {
_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,46 +178,53 @@ 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) {
(*i)->indexPolygons(); (*i)->indexPolygons();
} }
} }
} }
void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) { void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
{
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize)); 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,78 +1,86 @@
// /*
// 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);
explicit Cell (); explicit Cell();
~Cell (); ~Cell();
static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b); static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
void setDimensions(real x, real y, real sizeX, real sizeY); void setDimensions(real x, real y, real sizeX, real sizeY);
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder); void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
@@ -84,43 +92,37 @@ 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();
void nextOccluder (); void nextOccluder();
void nextOccludee (); void nextOccludee();
bool validBeforeTarget(); bool validBeforeTarget();
bool validAfterTarget(); bool validAfterTarget();
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);
Cell* _cell; Cell *_cell;
Vec3r _target; Vec3r _target;
bool _foundOccludee; bool _foundOccludee;
real _occludeeDepth; real _occludeeDepth;
@@ -128,33 +130,35 @@ 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);
Vec3r operator() (const Vec3r& point) const; Vec3r operator()(const Vec3r& point) const;
static Vec3r sphericalProjection(const Vec3r& M); static Vec3r sphericalProjection(const Vec3r& M);
}; };
private: 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();
Cell* findCell(const Vec3r& point); Cell *findCell(const Vec3r& point);
// Accessors: // Accessors:
bool orthographicProjection() const; bool orthographicProjection() const;
@@ -176,51 +180,52 @@ 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 sphericalgridlogging == 1 if (_foundOccludee) {
#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
while ( _current != _cell->faces.end() && ! testOccluder(true) ) { while (_current != _cell->faces.end() && !testOccluder(true)) {
++_current; ++_current;
} }
} }
inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) { inline bool SphericalGrid::Iterator::testOccluder(bool wantOccludee)
{
// End-of-list is not even a valid iterator position // 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();
@@ -230,16 +235,17 @@ 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 { }
if ( (*_current)->shallowest > _target[2] ) { else {
#if sphericalgridlogging == 1 if ((*_current)->shallowest > _target[2]) {
#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;
@@ -251,70 +257,73 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
// Check to see if target is in the 2D bounding box // Check to see if target is in the 2D bounding box
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;
} while ( _current != _cell->faces.end() && ! testOccluder(false) ); } while (_current != _cell->faces.end() && !testOccluder(false));
} }
} }
inline void SphericalGrid::Iterator::nextOccludee () { inline void SphericalGrid::Iterator::nextOccludee()
if ( _current != _cell->faces.end() ) { {
if (_current != _cell->faces.end()) {
do { do {
++_current; ++_current;
} while ( _current != _cell->faces.end() && ! testOccluder(true) ); } while (_current != _cell->faces.end() && !testOccluder(true));
} }
} }
inline bool SphericalGrid::Iterator::validBeforeTarget () { inline bool SphericalGrid::Iterator::validBeforeTarget()
{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2]; 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,17 +352,18 @@ 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;
} }
} }
} }
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) { inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
if ( GridHelpers::insideProscenium (boundary, poly) ) { {
if ( occluder == NULL) { if (GridHelpers::insideProscenium (boundary, poly)) {
if (occluder == NULL) {
// Disposal of occluder will be handled in SphericalGrid::distributePolygons(), // Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
// or automatically by SphericalGrid::_faces; // or automatically by SphericalGrid::_faces;
occluder = new OccluderData(source, poly); occluder = new OccluderData(source, poly);
@@ -362,7 +372,8 @@ inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3
} }
} }
inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) { inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
{
Polygon3r& poly(source.getGridSpacePolygon()); Polygon3r& poly(source.getGridSpacePolygon());
occluder = NULL; occluder = NULL;
@@ -373,9 +384,9 @@ 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,267 +1,298 @@
// /*
// 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;
_nbOrientations = nbOrientations;
_bound = cos(M_PI/(float)_nbOrientations); SteerableViewMap::SteerableViewMap(unsigned int nbOrientations)
for(unsigned i=0; i<_nbOrientations; ++i){ {
_directions.push_back(Vec2d(cos((float)i*M_PI/(float)_nbOrientations), sin((float)i*M_PI/(float)_nbOrientations))); _nbOrientations = nbOrientations;
} _bound = cos(M_PI/(float)_nbOrientations);
Build(); for (unsigned int i = 0; i < _nbOrientations; ++i) {
_directions.push_back(Vec2d(cos((float)i * M_PI / (float)_nbOrientations),
sin((float)i * M_PI / (float)_nbOrientations)));
}
Build();
} }
void SteerableViewMap::Build(){ void SteerableViewMap::Build()
_imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM {
memset((_imagesPyramids),0,(_nbOrientations+1)*sizeof(ImagePyramid*)); _imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
memset((_imagesPyramids), 0, (_nbOrientations + 1) * sizeof(ImagePyramid *));
} }
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){ SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother)
_nbOrientations = iBrother._nbOrientations; {
unsigned i; _nbOrientations = iBrother._nbOrientations;
_bound = iBrother._bound; unsigned int i;
_directions = iBrother._directions; _bound = iBrother._bound;
_mapping = iBrother._mapping; _directions = iBrother._directions;
_imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM _mapping = iBrother._mapping;
for(i=0;i<_nbOrientations+1;++i) _imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
_imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i]))); for (i = 0; i < _nbOrientations + 1; ++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; {
if(_imagesPyramids){ unsigned int i;
for(i=0; i<=_nbOrientations; ++i){ if (_imagesPyramids) {
if(_imagesPyramids[i]) for (i = 0; i <= _nbOrientations; ++i) {
delete (_imagesPyramids)[i]; if (_imagesPyramids[i])
} delete (_imagesPyramids)[i];
delete [] _imagesPyramids; }
_imagesPyramids = 0; delete[] _imagesPyramids;
} _imagesPyramids = 0;
if(!_mapping.empty()){ }
for(map<unsigned int, double*>::iterator m=_mapping.begin(), mend=_mapping.end(); if (!_mapping.empty()) {
m!=mend; for (map<unsigned int, double*>::iterator m = _mapping.begin(), mend = _mapping.end(); m != mend; ++m) {
++m){ delete[] (*m).second;
delete [] (*m).second; }
} _mapping.clear();
_mapping.clear(); }
}
} }
void SteerableViewMap::Reset(){ void SteerableViewMap::Reset()
Clear(); {
Build(); Clear();
Build();
} }
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i){ double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i)
double dotp = fabs(dir*_directions[i]); {
if(dotp < _bound) double dotp = fabs(dir * _directions[i]);
return 0; if (dotp < _bound)
if(dotp>1) return 0.0;
dotp = 1; if (dotp > 1.0)
dotp = 1.0;
return cos((float)_nbOrientations/2.0*acos(dotp)); return cos((float)_nbOrientations / 2.0 * acos(dotp));
} }
double * SteerableViewMap::AddFEdge(FEdge *iFEdge){ double *SteerableViewMap::AddFEdge(FEdge *iFEdge)
unsigned i; {
unsigned id = iFEdge->getId().getFirst(); unsigned i;
map<unsigned int, double* >::iterator o = _mapping.find(id); unsigned id = iFEdge->getId().getFirst();
if(o!=_mapping.end()){ map<unsigned int, double* >::iterator o = _mapping.find(id);
return (*o).second; if (o != _mapping.end()) {
} return (*o).second;
double * res = new double[_nbOrientations]; }
for(i=0; i<_nbOrientations; ++i){ double *res = new double[_nbOrientations];
res[i] = 0; for (i = 0; i < _nbOrientations; ++i) {
} res[i] = 0.0;
Vec3r o2d3 = iFEdge->orientation2d(); }
Vec2r o2d2(o2d3.x(), o2d3.y()); Vec3r o2d3 = iFEdge->orientation2d();
real norm = o2d2.norm(); Vec2r o2d2(o2d3.x(), o2d3.y());
if(norm < 1e-6){ real norm = o2d2.norm();
return res; if (norm < 1.0e-6) {
} return res;
o2d2/=norm; }
o2d2 /= norm;
for(i=0; i<_nbOrientations; ++i){ for (i = 0; i < _nbOrientations; ++i) {
res[i] = ComputeWeight(o2d2, i); res[i] = ComputeWeight(o2d2, i);
} }
_mapping[id] = res; _mapping[id] = res;
return res; return res;
} }
unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){ unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient)
Vec2f dir(orient); {
//soc unsigned res = 0; Vec2f dir(orient);
real norm = dir.norm(); //soc unsigned res = 0;
if(norm < 1e-6){ real norm = dir.norm();
return _nbOrientations+1; if (norm < 1.0e-6) {
} return _nbOrientations + 1;
dir/=norm; }
double maxw = 0.f; dir /= norm;
unsigned winner = _nbOrientations+1; double maxw = 0.0f;
for(unsigned i=0; i<_nbOrientations; ++i){ unsigned winner = _nbOrientations + 1;
double w = ComputeWeight(dir, i); for (unsigned int i = 0; i < _nbOrientations; ++i) {
if(w>maxw){ double w = ComputeWeight(dir, i);
maxw = w; if (w > maxw) {
winner = i; maxw = w;
} winner = i;
} }
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];
if(w>maxw){ if (w > maxw) {
maxw = w; maxw = w;
winner = i; winner = i;
} }
} }
return winner; return winner;
} }
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){ {
ImagePyramid * svm = (_imagesPyramids)[i]; for (unsigned int i = 0; i <= _nbOrientations; ++i) {
if(svm) ImagePyramid *svm = (_imagesPyramids)[i];
delete svm; if (svm)
if(copy) delete svm;
svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma); if (copy)
else svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma);
svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma); else
_imagesPyramids[i] = svm; svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma);
} _imagesPyramids[i] = svm;
}
} }
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]; {
if(pyramid==0){ ImagePyramid *pyramid = _imagesPyramids[iOrientation];
cout << "Warning: this steerable ViewMap level doesn't exist" << endl; if (pyramid == 0) {
return 0; cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
} return 0;
if((x<0) || (x>=pyramid->width()) || (y<0) || (y>=pyramid->height())) }
return 0; if ((x < 0) || (x >= pyramid->width()) || (y < 0) || (y >= pyramid->height()))
//float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)*255.f; return 0;
float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)/32.f; // we encode both the directionality and the lines counting on 8 bits //float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) * 255.0f;
// (because of frame buffer). Thus, we allow until 8 lines to pass through // We encode both the directionality and the lines counting on 8 bits (because of frame buffer). Thus, we allow
// the same pixel, so that we can discretize the Pi/_nbOrientations angle into // until 8 lines to pass through the same pixel, so that we can discretize the Pi/_nbOrientations angle into
// 32 slices. Therefore, for example, in the vertical direction, a vertical line // 32 slices. Therefore, for example, in the vertical direction, a vertical line will have the value 32 on
// will have the value 32 on each pixel it passes through. // each pixel it passes through.
return v; float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) / 32.0f;
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]) {
return _imagesPyramids[0]->getNumberOfLevels(); if (_imagesPyramids[0])
return 0; return _imagesPyramids[0]->getNumberOfLevels();
return 0;
} }
void SteerableViewMap::saveSteerableViewMap() const { void SteerableViewMap::saveSteerableViewMap() const
for(unsigned i=0; i<=_nbOrientations; ++i){ {
if(_imagesPyramids[i] == 0){ for (unsigned int i = 0; i <= _nbOrientations; ++i) {
cerr << "SteerableViewMap warning: orientation " << i <<" of steerable View Map whas not been computed yet" << endl; if (_imagesPyramids[i] == 0) {
continue; cerr << "SteerableViewMap warning: orientation " << i
} << " of steerable View Map whas not been computed yet" << endl;
int ow = _imagesPyramids[i]->width(0); continue;
int oh = _imagesPyramids[i]->height(0); }
int ow = _imagesPyramids[i]->width(0);
int oh = _imagesPyramids[i]->height(0);
//soc QString base("SteerableViewMap"); //soc QString base("SteerableViewMap");
string base("SteerableViewMap"); string base("SteerableViewMap");
stringstream filename; stringstream filename;
for(int j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ //soc
float coeff = 1;//1/255.f; //100*255;//*pow(2,j);
//soc QImage qtmp(ow, oh, QImage::Format_RGB32);
ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
int rowbytes = ow*4;
char *pix;
for(int y=0;y<oh;++y){ //soc
for(int x=0;x<ow;++x){ //soc
int c = (int)(coeff*_imagesPyramids[i]->pixel(x,y,j));
if(c>255)
c=255;
//int c = (int)(_imagesPyramids[i]->pixel(x,y,j));
//soc qtmp.setPixel(x,y,qRgb(c,c,c));
pix = (char*)ibuf->rect + y*rowbytes + x*4;
pix[0] = pix [1] = pix[2] = c;
}
}
//soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG"); for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc
filename << base; float coeff = 1.0f; // 1 / 255.0f; // 100 * 255; // * pow(2, j);
filename << i << "-" << j << ".png"; //soc QImage qtmp(ow, oh, QImage::Format_RGB32);
ibuf->ftype= PNG; ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0); int rowbytes = ow * 4;
char *pix;
}
// QString base("SteerableViewMap"); for (int y = 0; y < oh; ++y) { //soc
// for(unsigned j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ for (int x = 0; x < ow; ++x) { //soc
// GrayImage * img = _imagesPyramids[i]->getLevel(j); int c = (int)(coeff * _imagesPyramids[i]->pixel(x, y, j));
// int ow = img->width(); if (c > 255)
// int oh = img->height(); c = 255;
// float coeff = 1; //100*255;//*pow(2,j); //int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
// QImage qtmp(ow, oh, 32);
// for(unsigned y=0;y<oh;++y){ //soc qtmp.setPixel(x, y, qRgb(c, c, c));
// for(unsigned x=0;x<ow;++x){ pix = (char*)ibuf->rect + y * rowbytes + x * 4;
// int c = (int)(coeff*img->pixel(x,y)); pix[0] = pix [1] = pix[2] = c;
// if(c>255) }
// c=255; }
// //int c = (int)(_imagesPyramids[i]->pixel(x,y,j));
// qtmp.setPixel(x,y,qRgb(c,c,c)); //soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
// } filename << base;
// } filename << i << "-" << j << ".png";
// qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG"); ibuf->ftype = PNG;
// } IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0);
// }
} #if 0
QString base("SteerableViewMap");
for (unsigned j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) {
GrayImage *img = _imagesPyramids[i]->getLevel(j);
int ow = img->width();
int oh = img->height();
float coeff = 1.0f; // 100 * 255; // * pow(2, j);
QImage qtmp(ow, oh, 32);
for (unsigned int y = 0; y < oh; ++y) {
for (unsigned int x = 0; x < ow; ++x) {
int c = (int)(coeff * img->pixel(x, y));
if (c > 255)
c = 255;
//int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
qtmp.setPixel(x, y, qRgb(c, c, c));
}
}
qtmp.save(base + QString::number(i) + "-" + QString::number(j) + ".png", "PNG");
}
#endif
}
} }

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
* \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
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef STEERABLEVIEWMAP_H
# define STEERABLEVIEWMAP_H
#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,114 +48,107 @@ 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 information from the FEdge Id
*/
class LIB_VIEW_MAP_EXPORT SteerableViewMap{
protected:
map<unsigned int, double* > _mapping; // for each vector the list of nbOrientations weigths corresponding to its contributions to the nbOrientations directional maps
unsigned _nbOrientations;
ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM
// internal /*! This class checks for every FEdge in which steerable it belongs and stores the mapping allowing to retrieve
double _bound; // cos(Pi/N) * this information from the FEdge Id.
vector<Vec2d> _directions; */
class LIB_VIEW_MAP_EXPORT SteerableViewMap
{
protected:
// for each vector the list of nbOrientations weigths corresponding to its contributions
// to the nbOrientations directional maps
map<unsigned int, double*> _mapping;
unsigned _nbOrientations;
ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM
// internal
double _bound; // cos(Pi/N)
vector<Vec2d> _directions;
public: public:
SteerableViewMap(unsigned int nbOrientations = 4); SteerableViewMap(unsigned int nbOrientations = 4);
SteerableViewMap(const SteerableViewMap& iBrother); SteerableViewMap(const SteerableViewMap& iBrother);
virtual ~SteerableViewMap(); virtual ~SteerableViewMap();
/*! Resets everything */ /*! Resets everything */
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 we're intersted in.
* The First element of the Id struct of the FEdge */
* 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 pyramid.
* The _nbOrientations+1 images constituing the basis for the steerable * \param copy
* pyramid. * If false, the data is not duplicated, and Canvas deals with the memory management of these
* \param copy * _nbOrientations+1 images. If true, data is copied, and it's up to the caller to delete the images.
* If false, the data is not duplicated, and Canvas deals * \params iNbLevels
* with the memory management of these _nbOrientations+1 images. If true, data * The number of levels desired for each pyramid.
* is copied, and it's up to the caller to delete the images. * If iNbLevels == 0, the complete pyramid is built.
* \params iNbLevels * \param iSigma
* The number of levels desired for each pyramid. * The sigma that will be used for the gaussian blur
* If iNbLevels == 0, the complete pyramid is built. */
* \param iSigma void buildImagesPyramids(GrayImage **steerableBases, bool copy = false, unsigned iNbLevels = 4,
* The sigma that will be used for the gaussian blur float iSigma = 1.0f);
*/
void buildImagesPyramids(GrayImage **steerableBases, bool copy = false, unsigned iNbLevels=4, float iSigma = 1.f);
/*! Reads a pixel value in one of the VewMap density steerable pyramids. /*! 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.
* \param iOrientation * \param iOrientation
* the number telling which orientation we need to check. * the number telling which orientation we need to check.
* There are _nbOrientations+1 oriented ViewMaps: * There are _nbOrientations+1 oriented ViewMaps:
* 0 -> the ViewMap containing every horizontal lines * 0 -> the ViewMap containing every horizontal lines
* 1 -> the ViewMap containing every lines whose orientation is around PI/4 * 1 -> the ViewMap containing every lines whose orientation is around PI/4
* 2 -> the ViewMap containing every vertical lines * 2 -> the ViewMap containing every vertical lines
* 3 -> the ViewMap containing every lines whose orientation is around 3PI/4 * 3 -> the ViewMap containing every lines whose orientation is around 3PI/4
* 4 -> the complete ViewMap * 4 -> the complete ViewMap
* \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 system. The origin is the lower left corner.
* The ordinate of the desired pixel specified in level0 coordinate */
* system. The origin is the lower left corner. float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y);
*/
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 * Returns a value between 0 and 1.
* ViewMap. * Equivalent to : readSteerableViewMapPixel(nbOrientations, x, y)
* Returns a value between 0 and 1. */
* Equivalent to : readSteerableViewMapPixel(nbOrientations, x,y) float readCompleteViewMapPixel(int iLevel, int x, int y);
*/
float readCompleteViewMapPixel(int iLevel, int x, int y);
/*! Returns the number of levels in the pyramids */ /*! Returns the number of levels in the pyramids */
unsigned int getNumberOfPyramidLevels() const; unsigned int getNumberOfPyramidLevels() const;
/*! Returns the number of orientations */
unsigned int getNumberOfOrientations() const{
return _nbOrientations;
}
/*! for debug purposes */ /*! Returns the number of orientations */
void saveSteerableViewMap() const ; unsigned int getNumberOfOrientations() const
{
return _nbOrientations;
}
/*! for debug purposes */
void saveSteerableViewMap() const;
protected: protected:
void Clear(); void Clear();
void Build(); void Build();
}; };
#endif // STEERABLEVIEWMAP_H #endif // __FREESTYLE_STEERABLE_VIEW_MAP_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,73 +1,87 @@
// /*
// 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 #include <map>
# define VIEWEDGEXBUILDER_H #include <utility>
#include <vector>
# include <map> #if 0 // soc
# include <utility> #if defined(__GNUC__) && (__GNUC__ >= 3)
# include <vector> //hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
# include <hash_map.h>
#else
# include <hash_map>
#endif
#endif
// soc #include "Interface1D.h"
// # if defined(__GNUC__) && (__GNUC__ >= 3)
// //hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
// # include <hash_map.h>
// # else
// # include <hash_map>
// # endif
# include "../system/FreestyleConfig.h" #include "../geometry/Geom.h"
# include "../geometry/Geom.h"
# include "Interface1D.h" #include "../system/FreestyleConfig.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; {
res = ((res + (unsigned long) (p[1]) * _MUL)) % _MOD; size_t res = ((unsigned long)(p[0] * _MUL)) % _MOD;
return ((res +(unsigned long) (p[2]) * _MUL)) % _MOD; res = ((res + (unsigned long)(p[1]) * _MUL)) % _MOD;
} return ((res +(unsigned long)(p[2]) * _MUL)) % _MOD;
}
#undef _MUL
#undef _MOD
}; };
// Key_compare predicate for hash_map. In particular, return false if equal. // 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{ {
real norm = (v1-v2).norm(); bool operator()(const Vec3r& v1, const Vec3r& v2) const
return (norm<1e-06); {
} real norm = (v1 - v2).norm();
return (norm < 1.0e-06);
}
}; };
@@ -75,47 +89,81 @@ struct epsilonEquals{
typedef map<Vec3r , SVertex*> SVertexMap; typedef map<Vec3r , SVertex*> SVertexMap;
class WXFaceLayer; class WXFaceLayer;
/*! class to describe an oriented smooth edge */
class OWXFaceLayer{
public:
WXFaceLayer * fl;
bool order;
OWXFaceLayer() {fl=0;order=true;} /*! class to describe an oriented smooth edge */
OWXFaceLayer(WXFaceLayer *ifl, bool iOrder=true){fl = ifl;order=iOrder;} class OWXFaceLayer
OWXFaceLayer& operator=(const OWXFaceLayer& iBrother){ {
fl = iBrother.fl; public:
order = iBrother.order; WXFaceLayer *fl;
return *this; bool order;
}
bool operator==(const OWXFaceLayer& b){ OWXFaceLayer()
return ((fl == b.fl) && (order == b.order)); {
} fl = NULL;
bool operator!=(const OWXFaceLayer& b){ order = true;
return !(*this==b); }
}
OWXFaceLayer(WXFaceLayer *ifl, bool iOrder = true)
{
fl = ifl;
order = iOrder;
}
OWXFaceLayer& operator=(const OWXFaceLayer& iBrother)
{
fl = iBrother.fl;
order = iBrother.order;
return *this;
}
bool operator==(const OWXFaceLayer& b)
{
return ((fl == b.fl) && (order == b.order));
}
bool operator!=(const OWXFaceLayer& b)
{
return !(*this == b);
}
}; };
class WXEdge; class WXEdge;
/*! class to describe an oriented sharp edge */
class OWXEdge{
public:
WXEdge * e;
bool order;
OWXEdge() {e=0;order=true;} /*! class to describe an oriented sharp edge */
OWXEdge(WXEdge *ie, bool iOrder=true){e = ie;order=iOrder;} class OWXEdge
OWXEdge& operator=(const OWXEdge& iBrother){ {
e = iBrother.e; public:
order = iBrother.order; WXEdge *e;
return *this; bool order;
}
bool operator==(const OWXEdge& b){ OWXEdge()
return ((e == b.e) && (order == b.order)); {
} e = NULL;
bool operator!=(const OWXEdge& b){ order = true;
return !(*this==b); }
}
OWXEdge(WXEdge *ie, bool iOrder = true)
{
e = ie;
order = iOrder;
}
OWXEdge& operator=(const OWXEdge& iBrother)
{
e = iBrother.e;
order = iBrother.order;
return *this;
}
bool operator==(const OWXEdge& b)
{
return ((e == b.e) && (order == b.order));
}
bool operator!=(const OWXEdge& b)
{
return !(*this == b);
}
}; };
class WOEdge; class WOEdge;
@@ -126,93 +174,115 @@ 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:
inline ViewEdgeXBuilder()
{_currentViewId = 1;_currentFId=0;_currentSVertexId=0;}
virtual ~ViewEdgeXBuilder(){}
/*! Builds a view shape from a WXShape in which the feature edges
* are flagged
* Builds chains of feature edges (so ViewEdges) from a WXShape
* iWShape
* The Winged Edge structure in which all silhouette edges
* and vertices are flagged.
* oViewShape
* The Silhouette Shape in which the chains must be added.
* ioVEdges
* The list of new ViewEdges.
* ioVVertices
* THe new ViewVertices
* ioFEdges
* A list in which all new FEdges are added
* ioSVertices
* A list of SVertex where all created SVertex are added.
*/
virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape,
std::vector<ViewEdge*>& ioVEdges,
std::vector<ViewVertex*>& ioVVertices,
std::vector<FEdge*>& ioFEdges,
std::vector<SVertex*>& ioSVertices) ;
/*! Builds a smooth view edge, starting the face iFace.*/
ViewEdge * BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer);
/*! Makes a sharp viewedge
*/
ViewEdge * BuildSharpViewEdge(const OWXEdge& iWEdge) ;
public: public:
/*! accessors */ inline ViewEdgeXBuilder()
inline int currentViewId() const { return _currentViewId; } {
inline int currentFId() const { return _currentFId; } _currentViewId = 1;
inline int currentSVertexId() const { return _currentSVertexId; } _currentFId = 0;
/*! modifiers */ _currentSVertexId = 0;
inline void setCurrentViewId(int id) { _currentViewId = id; } }
inline void setCurrentFId(int id) { _currentFId = id; }
inline void setCurrentSVertexId(int id) { _currentSVertexId = id; } virtual ~ViewEdgeXBuilder() {}
/*! Builds a view shape from a WXShape in which the feature edges are flagged
* Builds chains of feature edges (so ViewEdges) from a WXShape
* iWShape
* The Winged Edge structure in which all silhouette edges and vertices are flagged.
* oViewShape
* The Silhouette Shape in which the chains must be added.
* ioVEdges
* The list of new ViewEdges.
* ioVVertices
* THe new ViewVertices
* ioFEdges
* A list in which all new FEdges are added
* ioSVertices
* A list of SVertex where all created SVertex are added.
*/
virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, std::vector<ViewEdge*>& ioVEdges,
std::vector<ViewVertex*>& ioVVertices, std::vector<FEdge*>& ioFEdges,
std::vector<SVertex*>& ioSVertices);
/*! Builds a smooth view edge, starting the face iFace. */
ViewEdge *BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer);
/*! Makes a sharp viewedge */
ViewEdge *BuildSharpViewEdge(const OWXEdge& iWEdge);
public:
/*! accessors */
inline int currentViewId() const
{
return _currentViewId;
}
inline int currentFId() const
{
return _currentFId;
}
inline int currentSVertexId() const
{
return _currentSVertexId;
}
/*! modifiers */
inline void setCurrentViewId(int id)
{
_currentViewId = id;
}
inline void setCurrentFId(int id)
{
_currentFId = id;
}
inline void setCurrentSVertexId(int id)
{
_currentSVertexId = id;
}
protected: protected:
/*! Init the view edges building */ /*! Init the view edges building */
virtual void Init(ViewShape *oVShape) ; virtual void Init(ViewShape *oVShape);
// SMOOTH // // SMOOTH //
/*! checks whether a face has already been processed or not */ /*! checks whether a face has already been processed or not */
bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer); bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer);
OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer& iFaceLayer); OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer& iFaceLayer);
OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer); OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer);
FEdge * BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl); FEdge *BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl);
// SHARP // // SHARP //
/*! checks whether a WEdge has already been processed or not */ /*! checks whether a WEdge has already been processed or not */
bool stopSharpViewEdge(WXEdge *iFace); bool stopSharpViewEdge(WXEdge *iFace);
int retrieveFaceMarks(WXEdge *iEdge); int retrieveFaceMarks(WXEdge *iEdge);
OWXEdge FindNextWEdge(const OWXEdge& iEdge); OWXEdge FindNextWEdge(const OWXEdge& iEdge);
OWXEdge FindPreviousWEdge(const OWXEdge& iEdge); OWXEdge FindPreviousWEdge(const OWXEdge& iEdge);
FEdge * BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe); FEdge *BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe);
// GENERAL // // GENERAL //
/*! Instanciate a SVertex */ /*! Instanciate a SVertex */
SVertex * MakeSVertex(Vec3r& iPoint); SVertex *MakeSVertex(Vec3r& iPoint);
/*! Instanciate a SVertex if it hasn't been already created */ /*! Instanciate a SVertex if it hasn't been already created */
SVertex * MakeSVertex(Vec3r& iPoint, bool shared); SVertex *MakeSVertex(Vec3r& iPoint, bool shared);
/*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */ /*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */
ViewVertex * MakeViewVertex(SVertex *iSVertex); ViewVertex *MakeViewVertex(SVertex *iSVertex);
//oldtmp values //oldtmp values
// IdHashTable _hashtable; //IdHashTable _hashtable;
// VVIdHashTable _multivertexHashTable; //VVIdHashTable _multivertexHashTable;
SVertexMap _SVertexMap; SVertexMap _SVertexMap;
SShape *_pCurrentSShape; SShape *_pCurrentSShape;
ViewShape * _pCurrentVShape; ViewShape *_pCurrentVShape;
}; };
#endif #endif // __FREESTYLE_VIEW_EDGE_X_BUILDER_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,248 +1,257 @@
// /*
// 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 #include <vector>
# define VIEWMAPBUILDER_H
# include "Silhouette.h" #include "GridDensityProvider.h"
# include <vector> #include "Silhouette.h"
# include "../system/FreestyleConfig.h" #include "SilhouetteGeomEngine.h"
# include "../geometry/Geom.h" #include "ViewEdgeXBuilder.h"
# include "../scene_graph/NodeGroup.h" #include "ViewMap.h"
# include "../winged_edge/WXEdge.h"
# include "../geometry/GeomUtils.h" #include "../geometry/Geom.h"
# include "../geometry/Grid.h" #include "../geometry/GeomUtils.h"
# include "../system/ProgressBar.h" #include "../geometry/Grid.h"
# include "../system/RenderMonitor.h" #include "../geometry/SweepLine.h"
# include "../geometry/SweepLine.h"
# include "ViewMap.h" #include "../scene_graph/NodeGroup.h"
# include "SilhouetteGeomEngine.h" #include "../scene_graph/TriangleRep.h"
# include "../scene_graph/TriangleRep.h"
# include "../winged_edge/WEdge.h" #include "../system/FreestyleConfig.h"
# include "ViewEdgeXBuilder.h" #include "../system/ProgressBar.h"
# include "../system/TimeUtils.h" #include "../system/RenderMonitor.h"
# include "GridDensityProvider.h" #include "../system/TimeUtils.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
//SilhouetteGeomEngine _GeomEngine;
ProgressBar *_pProgressBar;
RenderMonitor *_pRenderMonitor;
Vec3r _viewpoint;
bool _orthographicProjection;
Grid *_Grid;
ViewEdgeXBuilder *_pViewEdgeBuilder;
bool _EnableQI;
double _epsilon;
ViewMap * _ViewMap; // result // tmp values:
//SilhouetteGeomEngine _GeomEngine; int _currentId;
ProgressBar *_pProgressBar; int _currentFId;
RenderMonitor *_pRenderMonitor; int _currentSVertexId;
Vec3r _viewpoint;
bool _orthographicProjection;
Grid* _Grid;
ViewEdgeXBuilder *_pViewEdgeBuilder;
bool _EnableQI;
double _epsilon;
// tmp values:
int _currentId;
int _currentFId;
int _currentSVertexId;
public: public:
typedef enum {
sweep_line,
} intersection_algo;
typedef enum { typedef enum {
sweep_line ray_casting,
} intersection_algo; ray_casting_fast,
ray_casting_very_fast,
ray_casting_culled_adaptive_traditional,
ray_casting_adaptive_traditional,
ray_casting_culled_adaptive_cumulative,
ray_casting_adaptive_cumulative,
} visibility_algo;
typedef enum { inline ViewMapBuilder()
ray_casting, {
ray_casting_fast, _pProgressBar = NULL;
ray_casting_very_fast, _pRenderMonitor = NULL;
ray_casting_culled_adaptive_traditional, _Grid = NULL;
ray_casting_adaptive_traditional, _currentId = 1;
ray_casting_culled_adaptive_cumulative, _currentFId = 0;
ray_casting_adaptive_cumulative _currentSVertexId = 0;
} visibility_algo; _pViewEdgeBuilder = new ViewEdgeXBuilder;
_EnableQI = true;
}
inline ViewMapBuilder() inline ~ViewMapBuilder()
{ {
_pProgressBar = 0; if (_pViewEdgeBuilder) {
_pRenderMonitor = 0; delete _pViewEdgeBuilder;
_Grid = 0; _pViewEdgeBuilder = NULL;
_currentId = 1; }
_currentFId = 0; }
_currentSVertexId = 0;
_pViewEdgeBuilder = new ViewEdgeXBuilder;
_EnableQI = true;
}
inline ~ViewMapBuilder() /* Build Grid for ray casting */
{ /*! Build non-culled Grid in camera space for ray casting */
if(_pViewEdgeBuilder){ void BuildGrid(WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces);
delete _pViewEdgeBuilder;
_pViewEdgeBuilder = 0;
}
}
/* Build Grid for ray casting */ /*! Compute Shapes from a WingedEdge containing a list of WShapes */
/*! Build non-culled Grid in camera space for ray casting */ void computeInitialViewEdges(WingedEdge&);
void BuildGrid(WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces);
/*! Compute Shapes from a WingedEdge containing a list of WShapes */ /*! Compute Cusps */
void computeInitialViewEdges(WingedEdge&); void computeCusps(ViewMap *ioViewMap);
/*! Compute Cusps */ /*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of each cusp SVertex
void computeCusps(ViewMap *ioViewMap); * We use a hysteresis approach to avoid noise.
/*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of */
* each cusp SVertex void DetectCusps(ViewEdge *ioEdge);
* We use a hysteresis approach to avoid noise.
*/
void DetectCusps(ViewEdge *ioEdge);
/*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp)
{
_viewpoint = ivp;
SilhouetteGeomEngine::setViewpoint(ivp);
}
/*! Sets the current viewpoint */ /*! Sets the current transformation
inline void setViewpoint(const Vec3r& ivp) {_viewpoint = ivp; SilhouetteGeomEngine::setViewpoint(ivp);} * iModelViewMatrix
* The 4x4 model view matrix, in column major order (openGL like).
* iProjection matrix
* The 4x4 projection matrix, in column major order (openGL like).
* iViewport
* The viewport. 4 real array: origin.x, origin.y, width, length
*/
inline void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
const int iViewport[4], real iFocalLength, real iAspect, real iFovy)
{
_orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
}
/*! Sets the current transformation inline void setFrustum(real iZnear, real iZfar)
* iModelViewMatrix {
* The 4x4 model view matrix, in column major order (openGL like). SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
* iProjection matrix }
* The 4x4 projection matrix, in column major order (openGL like).
* iViewport
* The viewport. 4 real array: origin.x, origin.y, width, length
*/
inline void setTransform(const real iModelViewMatrix[4][4],
const real iProjectionMatrix[4][4],
const int iViewport[4],
real iFocalLength,
real iAspect,
real iFovy) {
_orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
}
inline void setFrustum(real iZnear, real iZfar) {
SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
}
/*! Builds the scene view map /*! 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
* feature edges of the scene.
* ioViewMap
* The view map. It is modified by the method.
* The list of all features edges of the scene.
* Each time an intersection is found, the 2 intersecting
* edges are splitted (creating 2 new vertices)
* At the end, this list is updated with the adding
* of all new created edges (resulting from splitting).
* iAlgo
* The algo to use for computing the intersections
*/
void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon=1e-06);
/*! Computes the 2D scene silhouette edges visibility /*! computes the intersection between all 2D feature edges of the scene.
* iGrid * ioViewMap
* For the Ray Casting algorithm. * The view map. It is modified by the method.
*/ * The list of all features edges of the scene.
void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces, * Each time an intersection is found, the 2 intersecting edges are splitted (creating 2 new vertices)
visibility_algo iAlgo= ray_casting, real epsilon=1e-6); * At the end, this list is updated with the adding of all new created edges (resulting from splitting).
* iAlgo
* The algo to use for computing the intersections
*/
void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon = 1.0e-06);
void setGrid(Grid *iGrid) {_Grid = iGrid;} /*! Computes the 2D scene silhouette edges visibility
* iGrid
/*! accessors */ * For the Ray Casting algorithm.
*/
/*! Modifiers */ void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces,
inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;} visibility_algo iAlgo = ray_casting, real epsilon = 1.0e-6);
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;}
inline void setEnableQI(bool iBool) {_EnableQI = iBool;} void setGrid(Grid *iGrid)
{
_Grid = iGrid;
}
/*! accessors */
/*! Modifiers */
inline void setProgressBar(ProgressBar *iProgressBar)
{
_pProgressBar = iProgressBar;
}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
{
_pRenderMonitor = iRenderMonitor;
}
inline void setEnableQI(bool iBool)
{
_EnableQI = iBool;
}
protected: 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); * ioViewMap
* The view map.
* The 2D scene silhouette edges as FEdges.
* These edges have already been splitted at their intersections points.
* Thus, these edges do not intersect anymore.
* The visibility corresponding to each edge of ioScene is set is this edge.
*/
void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
/*! Computes the 2D scene silhouette edges visibility void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
* using a ray casting. On each edge, a ray is cast bool cull, GridDensityProviderFactory& factory);
* to check its quantitative invisibility. The list void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
* of occluders are each time stored in the tested edge. bool cull, GridDensityProviderFactory& factory);
* ioViewMap
* The view map.
* The 2D scene silhouette edges as FEdges.
* These edges have already been splitted at their intersections points.
* Thus, these edges do not intersect anymore.
* The visibility corresponding to each edge of ioScene is set is this
* edge.
*/
void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we,
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory);
void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we,
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory);
/*! Compute the visibility for the FEdge fe.
* The occluders are added to fe occluders list.
* fe
* The FEdge
* iGrid
* The grid used to compute the ray casting visibility
* epsilon
* The epsilon used for computation
* oShapeId
* fe is the border (in 2D) between 2 2D spaces.
* if fe is a silhouette,
* One of these 2D spaces is occupied by the shape
* to which fe belongs (on its left) and the other one is either occupied
* by another shape or empty or occupied by the same shape.
* We use this ray csating operation to determine which shape
* lies on fe's right.
* The result is the shape id stored in oShapeId
*/
int ComputeRayCastingVisibility(FEdge *fe, Grid* iGrid, real epsilon, set<ViewShape*>& oOccluders,
Polygon3r** oaPolygon, unsigned timestamp);
// FIXME
void FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp);
void FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp,
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
/*! Compute the visibility for the FEdge fe.
* The occluders are added to fe occluders list.
* fe
* The FEdge
* iGrid
* The grid used to compute the ray casting visibility
* epsilon
* The epsilon used for computation
* oShapeId
* fe is the border (in 2D) between 2 2D spaces.
* if fe is a silhouette, One of these 2D spaces is occupied by the shape to which fe belongs (on its left)
* and the other one is either occupied by another shape or empty or occupied by the same shape.
* We use this ray csating operation to determine which shape lies on fe's right.
* The result is the shape id stored in oShapeId
*/
int ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
Polygon3r **oaPolygon, unsigned timestamp);
// FIXME
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
}; };
#endif // VIEWMAPBUILDER_H #endif // __FREESTYLE_VIEW_MAP_BUILDER_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,116 +1,129 @@
// /*
// 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 #include <fstream>
# define VIEWMAPIO_H #include <string>
# include "ViewMap.h" #include "ViewMap.h"
# include <fstream>
# include <string> #include "../system/FreestyleConfig.h"
# include "../system/FreestyleConfig.h" #include "../system/ProgressBar.h"
# include "../system/ProgressBar.h"
namespace ViewMapIO { namespace ViewMapIO {
static const unsigned ZERO = UINT_MAX; static const unsigned ZERO = UINT_MAX;
LIB_VIEW_MAP_EXPORT LIB_VIEW_MAP_EXPORT
int load(istream& in, ViewMap* vm, ProgressBar* pb = NULL); int load(istream& in, ViewMap *vm, ProgressBar *pb = NULL);
LIB_VIEW_MAP_EXPORT LIB_VIEW_MAP_EXPORT
int save(ostream& out, ViewMap* vm, ProgressBar* pb = NULL); int save(ostream& out, ViewMap *vm, ProgressBar *pb = NULL);
namespace Options { namespace Options {
static const unsigned char FLOAT_VECTORS = 1;
static const unsigned char NO_OCCLUDERS = 2;
LIB_VIEW_MAP_EXPORT
void setFlags(const unsigned char flags);
LIB_VIEW_MAP_EXPORT
void addFlags(const unsigned char flags);
LIB_VIEW_MAP_EXPORT static const unsigned char FLOAT_VECTORS = 1;
void rmFlags(const unsigned char flags); static const unsigned char NO_OCCLUDERS = 2;
LIB_VIEW_MAP_EXPORT LIB_VIEW_MAP_EXPORT
unsigned char getFlags(); void setFlags(const unsigned char flags);
LIB_VIEW_MAP_EXPORT
void setModelsPath(const string& path);
LIB_VIEW_MAP_EXPORT LIB_VIEW_MAP_EXPORT
string getModelsPath(); void addFlags(const unsigned char flags);
}; // End of namepace Options LIB_VIEW_MAP_EXPORT
void rmFlags(const unsigned char flags);
# ifdef IRIX LIB_VIEW_MAP_EXPORT
unsigned char getFlags();
namespace Internal {
template <unsigned S>
ostream& write(ostream& out, const char* str) {
out.put(str[S - 1]);
return write<S - 1>(out, str);
}
template<>
ostream& write<1>(ostream& out, const char* str) {
return out.put(str[0]);
}
template<> LIB_VIEW_MAP_EXPORT
ostream& write<0>(ostream& out, const char*) { void setModelsPath(const string& path);
return out;
}
template <unsigned S> LIB_VIEW_MAP_EXPORT
istream& read(istream& in, char* str) { string getModelsPath();
in.get(str[S - 1]);
return read<S - 1>(in, str);
}
template<>
istream& read<1>(istream& in, char* str) {
return in.get(str[0]);
}
template<> }; // End of namepace Options
istream& read<0>(istream& in, char*) {
return in;
}
} // End of namespace Internal
# endif // IRIX #ifdef IRIX
namespace Internal {
template <unsigned S>
ostream& write(ostream& out, const char *str)
{
out.put(str[S - 1]);
return write<S - 1>(out, str);
}
template<>
ostream& write<1>(ostream& out, const char *str)
{
return out.put(str[0]);
}
template<>
ostream& write<0>(ostream& out, const char*)
{
return out;
}
template <unsigned S>
istream& read(istream& in, char *str)
{
in.get(str[S - 1]);
return read<S - 1>(in, str);
}
template<>
istream& read<1>(istream& in, char *str)
{
return in.get(str[0]);
}
template<>
istream& read<0>(istream& in, char*)
{
return in;
}
} // End of namespace Internal
#endif // IRIX
} // End of namespace ViewMapIO } // End of namespace ViewMapIO
#endif // VIEWMAPIO_H #endif // __FREESTYLE_VIEW_MAP_IO_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +1,49 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
// /** \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"
NodeGroup* ViewMapTesselator::Tesselate(ViewMap *iViewMap) NodeGroup *ViewMapTesselator::Tesselate(ViewMap *iViewMap)
{ {
if(0 == iViewMap->ViewEdges().size()) if (0 == iViewMap->ViewEdges().size())
return NULL; return NULL;
const vector<ViewEdge*>& viewedges = iViewMap->ViewEdges(); const vector<ViewEdge*>& viewedges = iViewMap->ViewEdges();
return Tesselate(viewedges.begin(), viewedges.end()); return Tesselate(viewedges.begin(), viewedges.end());
} }
NodeGroup* ViewMapTesselator::Tesselate(WShape *) NodeGroup *ViewMapTesselator::Tesselate(WShape *)
{ {
return NULL; return NULL;
} }

View File

@@ -1,44 +1,50 @@
// /*
// 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 #include "Silhouette.h"
# define VIEWMAPTESSELATOR_H #include "ViewMap.h"
# include "Silhouette.h" #include "../scene_graph/LineRep.h"
# include "ViewMap.h" #include "../scene_graph/NodeShape.h"
# include "../scene_graph/NodeShape.h" #include "../scene_graph/NodeGroup.h"
# include "../winged_edge/WEdge.h" #include "../scene_graph/OrientedLineRep.h"
# include "../scene_graph/NodeGroup.h" #include "../scene_graph/VertexRep.h"
# include "../scene_graph/LineRep.h"
# include "../scene_graph/OrientedLineRep.h" #include "../winged_edge/WEdge.h"
# include "../scene_graph/VertexRep.h"
class NodeShape; class NodeShape;
class NodeGroup; class NodeGroup;
@@ -48,68 +54,83 @@ 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)
inline void setNature(Nature::EdgeNature iNature) {_nature = iNature;} {
inline void setFrsMaterial(const FrsMaterial& iMaterial) {_FrsMaterial=iMaterial;_overloadFrsMaterial=true;} _nature = iNature;
inline Nature::EdgeNature nature() {return _nature;} }
inline const FrsMaterial& frs_material() const {return _FrsMaterial;}
inline void setFrsMaterial(const FrsMaterial& iMaterial)
{
_FrsMaterial = iMaterial;
_overloadFrsMaterial = true;
}
inline Nature::EdgeNature nature()
{
return _nature;
}
inline const FrsMaterial& frs_material() const
{
return _FrsMaterial;
}
protected: protected:
virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0; virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
private: private:
Nature::EdgeNature _nature; Nature::EdgeNature _nature;
FrsMaterial _FrsMaterial; FrsMaterial _FrsMaterial;
bool _overloadFrsMaterial; bool _overloadFrsMaterial;
}; };
/*! Class to tesselate the 2D projected silhouette */ /*! Class to tesselate the 2D projected silhouette */
class ViewMapTesselator2D : public ViewMapTesselator class ViewMapTesselator2D : public ViewMapTesselator
{ {
public: public:
inline ViewMapTesselator2D() : ViewMapTesselator() {} inline ViewMapTesselator2D() : ViewMapTesselator() {}
virtual ~ViewMapTesselator2D() {} virtual ~ViewMapTesselator2D() {}
protected: protected:
virtual void AddVertexToLine(LineRep *iLine, SVertex *v) virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
{ {
iLine->AddVertex(v->point2D()); iLine->AddVertex(v->point2D());
} }
}; };
/*! Class to tesselate the 3D silhouette */ /*! Class to tesselate the 3D silhouette */
class ViewMapTesselator3D : public ViewMapTesselator class ViewMapTesselator3D : public ViewMapTesselator
{ {
public: public:
inline ViewMapTesselator3D() : ViewMapTesselator() {} inline ViewMapTesselator3D() : ViewMapTesselator() {}
virtual ~ViewMapTesselator3D() {} virtual ~ViewMapTesselator3D() {}
protected: protected:
virtual void AddVertexToLine(LineRep *iLine, SVertex *v) virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
{ {
iLine->AddVertex(v->point3D()); iLine->AddVertex(v->point3D());
} }
}; };
// //
@@ -118,79 +139,73 @@ protected:
/////////////////////////////////////////////// ///////////////////////////////////////////////
template<class ViewEdgesIterator> template<class ViewEdgesIterator>
NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end) NodeGroup *ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
{ {
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 *nextFEdge, *currentEdge;
FEdge *firstEdge; int id = 0;
FEdge *nextFEdge, *currentEdge; //for (vector<ViewEdge*>::const_iterator c = viewedges.begin(), cend = viewedges.end(); c != cend; c++)
for (ViewEdgesIterator c = begin, cend = end; c != cend; c++) {
int id=0; #if 0
// for(vector<ViewEdge*>::const_iterator c=viewedges.begin(),cend=viewedges.end(); if ((*c)->qi() > 0) {
// c!=cend; continue;
// c++) }
for(ViewEdgesIterator c=begin, cend=end; if (!((*c)->nature() & (_nature))) {
c!=cend; continue;
c++) }
{ #endif
// if((*c)->qi() > 0){ firstEdge = (*c)->fedgeA();
// continue;
// }
// if(!((*c)->nature() & (_nature)))
// continue;
//
firstEdge = (*c)->fedgeA();
// if(firstEdge->invisibility() > 0) #if 0
// continue; if (firstEdge->invisibility() > 0)
continue;
line = new OrientedLineRep(); #endif
if(_overloadFrsMaterial)
line->setFrsMaterial(_FrsMaterial);
// there might be chains containing a single element line = new OrientedLineRep();
if(0 == (firstEdge)->nextEdge()) if (_overloadFrsMaterial)
{ line->setFrsMaterial(_FrsMaterial);
line->setStyle(LineRep::LINES);
// line->AddVertex((*c)->vertexA()->point3D());
// line->AddVertex((*c)->vertexB()->point3D());
AddVertexToLine(line, firstEdge->vertexA());
AddVertexToLine(line, firstEdge->vertexB());
}
else
{
line->setStyle(LineRep::LINE_STRIP);
//firstEdge = (*c); // there might be chains containing a single element
nextFEdge = firstEdge; if (0 == (firstEdge)->nextEdge()) {
currentEdge = firstEdge; line->setStyle(LineRep::LINES);
do //line->AddVertex((*c)->vertexA()->point3D());
{ //line->AddVertex((*c)->vertexB()->point3D());
//line->AddVertex(nextFEdge->vertexA()->point3D()); AddVertexToLine(line, firstEdge->vertexA());
AddVertexToLine(line, nextFEdge->vertexA()); AddVertexToLine(line, firstEdge->vertexB());
currentEdge = nextFEdge; }
nextFEdge = nextFEdge->nextEdge(); else {
}while((nextFEdge != NULL) && (nextFEdge != firstEdge)); line->setStyle(LineRep::LINE_STRIP);
// Add the last vertex
//line->AddVertex(currentEdge->vertexB()->point3D());
AddVertexToLine(line, currentEdge->vertexB());
}
line->setId((*c)->getId().getFirst()); //firstEdge = (*c);
line->ComputeBBox(); nextFEdge = firstEdge;
tshape->AddRep(line); currentEdge = firstEdge;
id++; do {
} //line->AddVertex(nextFEdge->vertexA()->point3D());
AddVertexToLine(line, nextFEdge->vertexA());
return group; currentEdge = nextFEdge;
nextFEdge = nextFEdge->nextEdge();
} while ((nextFEdge != NULL) && (nextFEdge != firstEdge));
// Add the last vertex
//line->AddVertex(currentEdge->vertexB()->point3D());
AddVertexToLine(line, currentEdge->vertexB());
}
line->setId((*c)->getId().getFirst());
line->ComputeBBox();
tshape->AddRep(line);
id++;
}
return group;
} }
#endif // VIEWMAPTESSELATOR_H #endif // __FREESTYLE_VIEW_MAP_TESSELATOR_H__

File diff suppressed because it is too large Load Diff

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/Precision.h"
# include "../system/FreestyleConfig.h"
# include "../system/Precision.h"
# include "../geometry/Geom.h"
using namespace Geometry; using namespace Geometry;
class WVertex; class WVertex;
@@ -31,126 +61,83 @@ class WVertex;
class LIB_WINGED_EDGE_EXPORT CurvatureInfo class LIB_WINGED_EDGE_EXPORT CurvatureInfo
{ {
public: public:
CurvatureInfo()
{
K1 = 0.0;
K2 = 0.0;
e1 = Vec3r(0.0, 0.0, 0.0);
e2 = Vec3r(0.0, 0.0, 0.0);
Kr = 0.0;
dKr = 0.0;
er = Vec3r(0.0, 0.0, 0.0);
}
CurvatureInfo() CurvatureInfo(const CurvatureInfo& iBrother)
{ {
K1 = 0.0; K1 = iBrother.K1;
K2 = 0.0; K2 = iBrother.K2;
e1 = Vec3r(0.0,0.0,0.0); e1 = iBrother.e1;
e2 = Vec3r(0.0,0.0,0.0); e2 = iBrother.e2;
Kr = 0.0; Kr = iBrother.Kr;
dKr = 0.0; dKr = iBrother.dKr;
er = Vec3r(0.0,0.0,0.0); er = iBrother.er;
} }
CurvatureInfo(const CurvatureInfo& iBrother){ CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t)
K1 = iBrother.K1; {
K2 = iBrother.K2; K1 = ca.K1 + t * (cb.K1 - ca.K1);
e1 = iBrother.e1; K2 = ca.K2 + t * (cb.K2 - ca.K2);
e2 = iBrother.e2; e1 = ca.e1 + t * (cb.e1 - ca.e1);
Kr = iBrother.Kr; e2 = ca.e2 + t * (cb.e2 - ca.e2);
dKr = iBrother.dKr; Kr = ca.Kr + t * (cb.Kr - ca.Kr);
er = iBrother.er; dKr = ca.dKr + t * (cb.dKr - ca.dKr);
} er = ca.er + t * (cb.er - ca.er);
}
CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t) { real K1; // maximum curvature
K1 = ca.K1 + t * (cb.K1 - ca.K1); real K2; // minimum curvature
K2 = ca.K2 + t * (cb.K2 - ca.K2); Vec3r e1; // maximum curvature direction
e1 = ca.e1 + t * (cb.e1 - ca.e1); Vec3r e2; // minimum curvature direction
e2 = ca.e2 + t * (cb.e2 - ca.e2); real Kr; // radial curvature
Kr = ca.Kr + t * (cb.Kr - ca.Kr); real dKr; // radial curvature
dKr = ca.dKr + t * (cb.dKr - ca.dKr); Vec3r er; // radial curvature direction
er = ca.er + t * (cb.er - ca.er);
}
real K1; // maximum curvature
real K2; // minimum curvature
Vec3r e1; // maximum curvature direction
Vec3r e2; // minimum curvature direction
real Kr; // radial curvature
real dKr; // radial curvature
Vec3r er; // radial curvature direction
}; };
class Face_Curvature_Info{ class Face_Curvature_Info
{
public: public:
Face_Curvature_Info() {} Face_Curvature_Info() {}
~Face_Curvature_Info(){
for(vector<CurvatureInfo*>::iterator ci=vec_curvature_info.begin(), ciend=vec_curvature_info.end(); ~Face_Curvature_Info()
ci!=ciend; {
++ci){ for (vector<CurvatureInfo*>::iterator ci = vec_curvature_info.begin(), ciend = vec_curvature_info.end();
delete (*ci); ci != ciend;
} ++ci)
vec_curvature_info.clear(); {
} delete (*ci);
vector<CurvatureInfo *> vec_curvature_info; }
vec_curvature_info.clear();
}
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);
/* namespace OGF {
* 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 {
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,79 +1,79 @@
// /*
// 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;
/*! true for any 0D element */ /* XXX Why not using enums??? */
static const VertexNature POINT = 0; // 0
/*! true for SVertex */
static const VertexNature S_VERTEX = (1 << 0); // 1
/*! true for ViewVertex */
static const VertexNature VIEW_VERTEX = (1 << 1); // 2
/*! true for NonTVertex */
static const VertexNature NON_T_VERTEX = (1 << 2); // 4
/*! true for TVertex */
static const VertexNature T_VERTEX = (1 << 3); // 8
/*! true for CUSP */
static const VertexNature CUSP = (1 << 4); // 16
typedef unsigned short EdgeNature; typedef unsigned short VertexNature;
/*! true for non feature edges (always false for 1D elements of the ViewMap) */ /*! true for any 0D element */
static const EdgeNature NO_FEATURE = 0; // 0 static const VertexNature POINT = 0; // 0
/*! true for silhouettes */ /*! true for SVertex */
static const EdgeNature SILHOUETTE = (1 << 0); // 1 static const VertexNature S_VERTEX = (1 << 0); // 1
/*! true for borders */ /*! true for ViewVertex */
static const EdgeNature BORDER = (1 << 1); // 2 static const VertexNature VIEW_VERTEX = (1 << 1); // 2
/*! true for creases */ /*! true for NonTVertex */
static const EdgeNature CREASE = (1 << 2); // 4 static const VertexNature NON_T_VERTEX = (1 << 2); // 4
/*! true for ridges */ /*! true for TVertex */
static const EdgeNature RIDGE = (1 << 3); // 8 static const VertexNature T_VERTEX = (1 << 3); // 8
/*! true for valleys */ /*! true for CUSP */
static const EdgeNature VALLEY = (1 << 4); // 16 static const VertexNature CUSP = (1 << 4); // 16
/*! true for suggestive contours */
static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32 typedef unsigned short EdgeNature;
/*! true for material boundaries */ /*! true for non feature edges (always false for 1D elements of the ViewMap) */
static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64 static const EdgeNature NO_FEATURE = 0; // 0
/*! true for user-defined edge marks */ /*! true for silhouettes */
static const EdgeNature EDGE_MARK = (1 << 7); // 128 static const EdgeNature SILHOUETTE = (1 << 0); // 1
/*! true for borders */
static const EdgeNature BORDER = (1 << 1); // 2
/*! true for creases */
static const EdgeNature CREASE = (1 << 2); // 4
/*! true for ridges */
static const EdgeNature RIDGE = (1 << 3); // 8
/*! true for valleys */
static const EdgeNature VALLEY = (1 << 4); // 16
/*! true for suggestive contours */
static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32
/*! true for material boundaries */
static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64
/*! true for user-defined edge marks */
static const EdgeNature EDGE_MARK = (1 << 7); // 128
} // end of namespace Nature } // end of namespace Nature
#endif // NATURE_H #endif // __FREESTYLE_NATURE_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,60 +1,68 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
// /** \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) {
return; if (!_winged_edge || !_grid)
return;
vector<WShape*> wshapes = _winged_edge->getWShapes(); vector<WShape *> wshapes = _winged_edge->getWShapes();
vector<WVertex*> fvertices; vector<WVertex *> fvertices;
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(); faces = (*it)->GetFaceList();
it++) {
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)->RetrieveVertexList(fvertices);
f++) {
(*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(); vectors.push_back(Vec3r((*wv)->GetVertex()));
wv++)
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); vectors.clear();
vectors.clear(); fvertices.clear();
fvertices.clear(); }
} faces.clear();
faces.clear(); }
} }
}

View File

@@ -1,80 +1,88 @@
// /*
// 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)
{
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
}
inline WFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) { virtual ~WFillGrid() {}
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
}
virtual ~WFillGrid() {} void fillGrid();
void fillGrid(); /*! Accessors */
WingedEdge *getWingedEdge()
{
return _winged_edge;
}
/*! Accessors */ Grid *getGrid()
WingedEdge* getWingedEdge() { {
return _winged_edge; return _grid;
} }
Grid* getGrid() { /*! Modifiers */
return _grid; void setWingedEdge(WingedEdge *winged_edge)
} {
if (winged_edge)
_winged_edge = winged_edge;
}
/*! Modifiers */ void setGrid(Grid *grid)
void setWingedEdge(WingedEdge* winged_edge) { {
if (winged_edge) if (grid)
_winged_edge = winged_edge; _grid = grid;
} }
void setGrid(Grid* grid) {
if (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,60 +1,67 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
// /** \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) {
return; if (!_winged_edge || !_grid)
return;
vector<WShape*> wshapes = _winged_edge->getWShapes(); vector<WShape *> wshapes = _winged_edge->getWShapes();
vector<WVertex*> fvertices; vector<WVertex *> fvertices;
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(); faces = (*it)->GetFaceList();
it++) {
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)->RetrieveVertexList(fvertices);
f++) {
(*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(); vectors.push_back(Vec3r((*wv)->GetVertex()));
wv++)
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); vectors.clear();
vectors.clear(); fvertices.clear();
fvertices.clear(); }
} faces.clear();
faces.clear(); }
} }
}

View File

@@ -1,79 +1,87 @@
// /*
// 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)
{
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
}
inline WSFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) { virtual ~WSFillGrid() {}
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
}
virtual ~WSFillGrid() {} void fillGrid();
void fillGrid(); /*! Accessors */
WingedEdge *getWingedEdge()
{
return _winged_edge;
}
/*! Accessors */ Grid *getGrid()
WingedEdge* getWingedEdge() { {
return _winged_edge; return _grid;
} }
Grid* getGrid() { /*! Modifiers */
return _grid; void setWingedEdge(WingedEdge *winged_edge)
} {
if (winged_edge)
_winged_edge = winged_edge;
}
/*! Modifiers */ void setGrid(Grid *grid)
void setWingedEdge(WingedEdge* winged_edge) { {
if (winged_edge) if (grid)
_winged_edge = winged_edge; _grid = grid;
} }
void setGrid(Grid* grid) {
if (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,296 +1,298 @@
// /*
// 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 nEdges = _pWXFace->numberOfEdges(); int i = 0;
for(i=0; i<nEdges; ++i){ int nEdges = _pWXFace->numberOfEdges();
if(_DotP[i] == 0){ for (i = 0; i < nEdges; ++i) {
return i; if (_DotP[i] == 0) {
} return i;
} }
return -1; }
return -1;
} }
unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{ unsigned int WXFaceLayer::GetSmoothEdgeIndex() const
int i = 0; {
int nEdges = _pWXFace->numberOfEdges(); int i = 0;
for(i=0; i<nEdges; ++i){ int nEdges = _pWXFace->numberOfEdges();
if((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)){ for (i = 0; i < nEdges; ++i) {
return i; if ((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)) {
} return i;
} }
return -1; }
return -1;
} }
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){ void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges)
int i = 0; {
int nEdges = _pWXFace->numberOfEdges(); int i = 0;
for(i=0; i<nEdges; ++i){ int nEdges = _pWXFace->numberOfEdges();
if(_DotP[i]*_DotP[(i+1)%nEdges] < 0){ for (i = 0; i < nEdges; ++i) {
// we got one if (_DotP[i] * _DotP[(i + 1) % nEdges] < 0) {
oCuspEdges.push_back(i); // we got one
} oCuspEdges.push_back(i);
} }
}
} }
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);
bool ok = false; bool ok = false;
vector<int> cuspEdgesIndices; vector<int> cuspEdgesIndices;
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 opposite signs for each extremity
// We retrieve the 2 edges for which we have RetrieveCuspEdgesIndices(cuspEdgesIndices);
// opposite signs for each extremity if (cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges
RetrieveCuspEdgesIndices(cuspEdgesIndices); return 0;
if(cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges
return 0; // let us determine which cusp edge corresponds to the starting:
// We can do that because we defined that a silhouette edge had the back facing part on its right.
// let us determine which cusp edge corresponds to the starting: // So if the WOEdge woea is such that woea[0].dotp > 0 and woea[1].dotp < 0, it is the starting edge.
// We can do that because we defined that //-------------------------------------------
// a silhouette edge had the back facing part on its right.
// So if the WOEdge woea is such that woea[0].dotp > 0 and if (_DotP[cuspEdgesIndices[0]] > 0) {
// woea[1].dotp < 0, it is the starting edge. woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
//------------------------------------------- woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
indexStart = cuspEdgesIndices[0];
if(_DotP[cuspEdgesIndices[0]] > 0){ indexEnd = cuspEdgesIndices[1];
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); }
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]); else {
indexStart = cuspEdgesIndices[0]; woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
indexEnd = cuspEdgesIndices[1]; woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
}else{ indexStart = cuspEdgesIndices[1];
woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]); indexEnd = cuspEdgesIndices[0];
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); }
indexStart = cuspEdgesIndices[1];
indexEnd = cuspEdgesIndices[0]; // Compute the interpolation:
} ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
// Compute the interpolation: ok = true;
ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]); }
tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]); else if (_nNullDotP == 1) {
ok = true; // that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex of the mesh
}else if(_nNullDotP == 1){ if ((_nPosDotP == 2) || (_nPosDotP == 0)) {
// that means that we have exactly one of the _pSmoothEdge = NULL;
// 2 extremities of our silhouette edge is return _pSmoothEdge;
// a vertex of the mesh }
if((_nPosDotP == 2) || (_nPosDotP == 0)){ RetrieveCuspEdgesIndices(cuspEdgesIndices);
_pSmoothEdge = 0; // We should have only one EdgeCusp:
return _pSmoothEdge; if (cuspEdgesIndices.size() != 1) {
} cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl;
RetrieveCuspEdgesIndices(cuspEdgesIndices); _pSmoothEdge = NULL;
// We should have only one EdgeCusp: return NULL;
if(cuspEdgesIndices.size() != 1){ }
cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl; unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
_pSmoothEdge = 0; unsigned nedges = _pWXFace->numberOfEdges();
return 0; if (_DotP[cuspEdgesIndices[0]] > 0) {
} woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index woeb = _pWXFace->GetOEdge(index0);
unsigned nedges = _pWXFace->numberOfEdges(); indexStart = cuspEdgesIndices[0];
if(_DotP[cuspEdgesIndices[0]] > 0){ ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); tb = 0.0;
woeb = _pWXFace->GetOEdge(index0); }
indexStart = cuspEdgesIndices[0]; else {
ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]); woea = _pWXFace->GetOEdge(index0);
tb = 0.0; woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
}else{ indexEnd = cuspEdgesIndices[0];
woea = _pWXFace->GetOEdge(index0); ta = 0.0;
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
indexEnd = cuspEdgesIndices[0]; }
ta = 0.0; ok = true;
tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]); }
} else if (_nNullDotP == 2) {
ok = true; // that means that the silhouette edge is an edge of the mesh
}else if(_nNullDotP == 2){ int index = GetSmoothEdgeIndex();
// that means that the silhouette edge if (!_pWXFace->front()) { // is it in the right order ?
// is an edge of the mesh // the order of the WOEdge index is wrong
int index = GetSmoothEdgeIndex(); woea = _pWXFace->GetOEdge((index + 1) % nedges);
if(!_pWXFace->front()) {// is it in the right order ? woeb = _pWXFace->GetOEdge((index - 1) % nedges);
// the order of the WOEdge index is wrong ta = 0;
woea = _pWXFace->GetOEdge((index+1)%nedges); tb = 1;
woeb = _pWXFace->GetOEdge((index-1)%nedges); ok = true;
ta = 0; }
tb = 1; else {
ok = true; // here it's not good, our edge is a single point -> skip that face
}else{ ok = false;
// here it's not good, our edge is a single point -> skip that face #if 0
ok = false; // 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) {
_pSmoothEdge = new WXSmoothEdge; _pSmoothEdge = new WXSmoothEdge;
_pSmoothEdge->setWOeA(woea); _pSmoothEdge->setWOeA(woea);
_pSmoothEdge->setWOeB(woeb); _pSmoothEdge->setWOeB(woeb);
_pSmoothEdge->setTa(ta); _pSmoothEdge->setTa(ta);
_pSmoothEdge->setTb(tb); _pSmoothEdge->setTb(tb);
if(_Nature & Nature::SILHOUETTE){ if (_Nature & Nature::SILHOUETTE) {
if(_nNullDotP != 2){ if (_nNullDotP != 2) {
if(_DotP[_ClosestPointIndex] + 0.01 > 0) if (_DotP[_ClosestPointIndex] + 0.01 > 0)
_pSmoothEdge->setFront(true); _pSmoothEdge->setFront(true);
else else
_pSmoothEdge->setFront(false); _pSmoothEdge->setFront(false);
} }
} }
} }
// 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); return _pSmoothEdge;
// _pSmoothEdge->setTb(tb);
//
// return _pSmoothEdge;
// }
// }
//}
return _pSmoothEdge;
} }
void WXFace::ComputeCenter() 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; center += (*wv)->GetVertex();
wv++) }
{ center /= (real)iVertexList.size();
center += (*wv)->GetVertex(); setCenter(center);
}
center /= (real)iVertexList.size();
setCenter(center);
} }
/**********************************/ /**********************************
/* */ * *
/* */ * *
/* WXShape */ * WXShape *
/* */ * *
/* */ * *
/**********************************/ **********************************/
WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
{ {
WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex); WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
if(0 == face) if (!face)
return 0; return NULL;
Vec3r center;
for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
wv!=wvend;
wv++)
{
center += (*wv)->GetVertex();
}
center /= (real)iVertexList.size();
((WXFace*)face)->setCenter(center);
return face; Vec3r center;
for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
center += (*wv)->GetVertex();
}
center /= (real)iVertexList.size();
((WXFace *)face)->setCenter(center);
return face;
} }
WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex) WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
{ {
WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex); WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
// Vec3r center;
// for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
// wv!=wvend;
// wv++)
// {
// center += (*wv)->GetVertex();
// }
// center /= (real)iVertexList.size();
// ((WSFace*)face)->setCenter(center);
return face; #if 0
} Vec3r center;
for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
center += (*wv)->GetVertex();
}
center /= (real)iVertexList.size();
((WSFace *)face)->setCenter(center);
#endif
return face;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +1,58 @@
// /*
// 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)
{ {
if (_pRenderMonitor && _pRenderMonitor->testBreak()) if (_pRenderMonitor && _pRenderMonitor->testBreak())
return; return;
WXShape *shape = new WXShape; WXShape *shape = new WXShape;
buildWShape(*shape, ifs); buildWShape(*shape, ifs);
shape->setId(ifs.getId().getFirst()); shape->setId(ifs.getId().getFirst());
shape->setName(ifs.getName()); shape->setName(ifs.getName());
//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 int i = 0; i < vsize; i += 3) {
for (unsigned i = 0; i < vsize; i += 3) { vertex = new WXVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
vertex = new WXVertex(Vec3r(vertices[i], vertex->setId(i / 3);
vertices[i + 1], shape.AddVertex(vertex);
vertices[i + 2])); }
vertex->setId(i / 3); }
shape.AddVertex(vertex);
}
}

View File

@@ -1,51 +1,54 @@
#ifndef WXEDGEBUILDER_H /*
# define WXEDGEBUILDER_H * ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
// #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
* \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 "WingedEdgeBuilder.h"
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
# include "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
{ {
public: public:
WXEdgeBuilder() : WingedEdgeBuilder() {} WXEdgeBuilder() : WingedEdgeBuilder() {}
virtual ~WXEdgeBuilder() {} virtual ~WXEdgeBuilder() {}
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,386 +1,373 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
// /** \file blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
// 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()) {
return; if (_pRenderMonitor && _pRenderMonitor->testBreak())
WShape *shape = new WShape; return;
buildWShape(*shape, ifs); WShape *shape = new WShape;
shape->setId(ifs.getId().getFirst()); buildWShape(*shape, ifs);
//ifs.setId(shape->GetId()); shape->setId(ifs.getId().getFirst());
//ifs.setId(shape->GetId());
} }
void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) { void WingedEdgeBuilder::visitNodeShape(NodeShape& ns)
//Sets the current material to iShapeode->material: {
_current_frs_material = &(ns.frs_material()); //Sets the current material to iShapeode->material:
_current_frs_material = &(ns.frs_material());
} }
void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) { void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn)
if(!_current_matrix) { {
_current_matrix = new Matrix44r(tn.matrix()); if (!_current_matrix) {
return; _current_matrix = new Matrix44r(tn.matrix());
} return;
}
_matrices_stack.push_back(_current_matrix); _matrices_stack.push_back(_current_matrix);
Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix()); Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix());
_current_matrix = new_matrix; _current_matrix = new_matrix;
} }
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) { void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&)
if(_current_matrix) {
delete _current_matrix; if (_current_matrix)
delete _current_matrix;
if(_matrices_stack.empty()) { if (_matrices_stack.empty()) {
_current_matrix = NULL; _current_matrix = NULL;
return; return;
} }
_current_matrix = _matrices_stack.back(); _current_matrix = _matrices_stack.back();
_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();
//soc unused - unsigned tsize = ifs.tsize(); unsigned int nsize = ifs.nsize();
//soc unused - unsigned tsize = ifs.tsize();
const real* vertices = ifs.vertices(); const real *vertices = ifs.vertices();
const real* normals = ifs.normals(); const real *normals = ifs.normals();
const real* texCoords = ifs.texCoords(); const real *texCoords = ifs.texCoords();
real* new_vertices; real *new_vertices;
real* new_normals; real *new_normals;
new_vertices = new real[vsize]; new_vertices = new real[vsize];
new_normals = new real[nsize]; new_normals = new real[nsize];
// transform coordinates from local to world system // transform coordinates from local to world system
if(_current_matrix) { if (_current_matrix) {
transformVertices(vertices, vsize, *_current_matrix, new_vertices); transformVertices(vertices, vsize, *_current_matrix, new_vertices);
transformNormals(normals, nsize, *_current_matrix, new_normals); transformNormals(normals, nsize, *_current_matrix, new_normals);
} }
else { else {
memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices)); memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices));
memcpy(new_normals, normals, nsize * sizeof(*new_normals)); memcpy(new_normals, normals, nsize * sizeof(*new_normals));
} }
const IndexedFaceSet::TRIANGLES_STYLE* faceStyle = ifs.trianglesStyle(); const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle();
vector<FrsMaterial> frs_materials; vector<FrsMaterial> frs_materials;
if(ifs.msize()){ if (ifs.msize()) {
const FrsMaterial*const* mats = ifs.frs_materials(); const FrsMaterial *const *mats = ifs.frs_materials();
for(unsigned i=0; i<ifs.msize(); ++i) for (unsigned i = 0; i < ifs.msize(); ++i)
frs_materials.push_back(*(mats[i])); frs_materials.push_back(*(mats[i]));
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
_current_wshape = &shape;
// sets the current WShape to shape // create a WVertex for each vertex
_current_wshape = &shape; buildWVertices(shape, new_vertices, vsize);
// create a WVertex for each vertex const unsigned int *vindices = ifs.vindices();
buildWVertices(shape, new_vertices, vsize); const unsigned int *nindices = ifs.nindices();
const unsigned int *tindices = NULL;
const unsigned* vindices = ifs.vindices(); if (ifs.tsize()) {
const unsigned* nindices = ifs.nindices(); tindices = ifs.tindices();
const unsigned* tindices = 0; }
if(ifs.tsize()){
tindices = ifs.tindices(); const unsigned int *mindices = NULL;
} if (ifs.msize())
const unsigned *mindices = 0;
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, break;
texCoords, case IndexedFaceSet::TRIANGLE_FAN:
faceEdgeMarks, buildTriangleFan(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
vindices, nindices, mindices, tindices, numVertexPerFace[index]);
nindices, break;
mindices, case IndexedFaceSet::TRIANGLES:
tindices, buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
numVertexPerFace[index]); nindices, mindices, tindices, numVertexPerFace[index]);
break; break;
case IndexedFaceSet::TRIANGLE_FAN: }
buildTriangleFan(new_vertices, vindices += numVertexPerFace[index];
new_normals, nindices += numVertexPerFace[index];
frs_materials, if (mindices)
texCoords,
faceEdgeMarks,
vindices,
nindices,
mindices,
tindices,
numVertexPerFace[index]);
break;
case IndexedFaceSet::TRIANGLES:
buildTriangles(new_vertices,
new_normals,
frs_materials,
texCoords,
faceEdgeMarks,
vindices,
nindices,
mindices,
tindices,
numVertexPerFace[index]);
break;
}
vindices += numVertexPerFace[index];
nindices += numVertexPerFace[index];
if(mindices)
mindices += numVertexPerFace[index]; mindices += numVertexPerFace[index];
if(tindices) if (tindices)
tindices += numVertexPerFace[index]; tindices += numVertexPerFace[index];
faceEdgeMarks++; faceEdgeMarks++;
} }
delete[] new_vertices; delete[] new_vertices;
delete[] new_normals; delete[] new_normals;
// compute bbox // compute bbox
shape.ComputeBBox(); shape.ComputeBBox();
// compute mean edge size: // compute mean edge size:
shape.ComputeMeanEdgeSize(); shape.ComputeMeanEdgeSize();
// 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; if ((*wv)->isBoundary())
++wv){ continue;
if((*wv)->isBoundary()) if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
continue; continue;
if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.) normalsSet.clear();
continue; WVertex::face_iterator fit = (*wv)->faces_begin();
normalsSet.clear(); WVertex::face_iterator fitend = (*wv)->faces_end();
WVertex::face_iterator fit = (*wv)->faces_begin(); for (; fit != fitend; ++fit) {
WVertex::face_iterator fitend = (*wv)->faces_end(); WFace *face = *fit;
while(fit!=fitend){ normalsSet.insert(face->GetVertexNormal(*wv));
WFace *face = *fit; if (normalsSet.size() != 1) {
normalsSet.insert(face->GetVertexNormal(*wv)); break;
if(normalsSet.size()!=1){ }
break; }
} if (normalsSet.size() !=1 ) {
++fit; (*wv)->setSmooth(false);
} }
if(normalsSet.size()!=1){ }
(*wv)->setSmooth(false); // Adds the new WShape to the WingedEdge structure
} _winged_edge->addWShape(&shape);
}
// Adds the new WShape to the WingedEdge structure
_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 int i = 0; i < vsize; i += 3) {
for (unsigned i = 0; i < vsize; i += 3) { vertex = new WVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
vertex = new WVertex(Vec3r(vertices[i], vertex->setId(i / 3);
vertices[i + 1], shape.AddVertex(vertex);
vertices[i + 2])); }
vertex->setId(i / 3);
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, unsigned nDoneVertices = 2; // number of vertices already treated
const unsigned *nindices, unsigned nTriangle = 0; // number of the triangle currently being treated
const unsigned *mindices, //int nVertex = 0; // vertex number
const unsigned *tindices,
const unsigned nvertices) {
unsigned nDoneVertices = 2; // number of vertices already treated
unsigned nTriangle = 0; // number of the triangle currently being treated
//int nVertex = 0; // vertex number
WShape* currentShape = _current_wshape; // the current shape being built WShape *currentShape = _current_wshape; // the current shape being built
vector<WVertex *> triangleVertices; vector<WVertex *> triangleVertices;
vector<Vec3r> triangleNormals; vector<Vec3r> triangleNormals;
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 + 1] / 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+1]/3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]);
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2])); triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], 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 }
{ }
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]); else { // if nTriangle is odd
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/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 + 2] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2])); triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], 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::EDGE_MARK_V1V2) != 0); }
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
if(mindices) triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[nTriangle/3]); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
else if (mindices) {
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
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 }
nTriangle++; nDoneVertices++; // with a strip, each triangle is one vertex more
} 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, // Nothing to be done
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices) {
// 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, WShape *currentShape = _current_wshape; // the current shape begin built
const unsigned *nindices, vector<WVertex *> triangleVertices;
const unsigned *mindices, vector<Vec3r> triangleNormals;
const unsigned *tindices, vector<Vec2r> triangleTexCoords;
const unsigned nvertices) { vector<bool> triangleFaceEdgeMarks;
WShape * currentShape = _current_wshape; // the current shape begin built
vector<WVertex *> triangleVertices;
vector<Vec3r> triangleNormals;
vector<Vec2r> triangleTexCoords;
vector<bool> triangleFaceEdgeMarks;
// Each triplet of vertices is considered as an independent triangle // 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]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+1]],texCoords[tindices[3*i+1]+1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+2]], texCoords[tindices[3*i+2]+1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 2]], texCoords[tindices[3 * i + 2] + 1]));
} }
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
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, const real *v = vertices;
real *res) { real *pv = res;
const real *v = vertices;
real *pv = res; for (unsigned int i = 0; i < vsize / 3; i++) {
HVec3r hv_tmp(v[0], v[1], v[2]);
for (unsigned i = 0; i < vsize / 3; i++) { HVec3r hv(transform * hv_tmp);
HVec3r hv_tmp(v[0], v[1], v[2]); for (unsigned int j = 0; j < 3; j++)
HVec3r hv(transform * hv_tmp); pv[j] = hv[j] / hv[3];
for (unsigned j = 0; j < 3; j++) v += 3;
pv[j] = hv[j] / hv[3]; pv += 3;
v += 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, const real *n = normals;
real* res) { real *pn = res;
const real *n = normals;
real *pn = res; for (unsigned int i = 0; i < nsize / 3; i++) {
Vec3r hn(n[0], n[1], n[2]);
for (unsigned i = 0; i < nsize / 3; i++) { hn = GeomUtils::rotateVector(transform, hn);
Vec3r hn(n[0], n[1], n[2]); for (unsigned int j = 0; j < 3; j++)
hn = GeomUtils::rotateVector(transform, hn); pn[j] = hn[j];
for (unsigned j = 0; j < 3; j++) n += 3;
pn[j] = hn[j]; pn += 3;
n += 3; }
pn += 3; }
}
}

View File

@@ -1,171 +1,157 @@
// /*
// 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 "../system/FreestyleConfig.h" #include "../scene_graph/IndexedFaceSet.h"
# include "../system/RenderMonitor.h" #include "../scene_graph/NodeTransform.h"
# include "../scene_graph/SceneVisitor.h" #include "../scene_graph/SceneVisitor.h"
# include "WEdge.h"
# include "../scene_graph/IndexedFaceSet.h" #include "../system/FreestyleConfig.h"
# include "../scene_graph/NodeTransform.h" #include "../system/RenderMonitor.h"
class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
{ {
public: public:
inline WingedEdgeBuilder() : SceneVisitor()
{
_current_wshape = NULL;
_current_frs_material = NULL;
_current_matrix = NULL;
_winged_edge = new WingedEdge; // Not deleted by the destructor
_pRenderMonitor = NULL;
}
inline WingedEdgeBuilder() : SceneVisitor() { virtual ~WingedEdgeBuilder()
_current_wshape = NULL; {
_current_frs_material = NULL; for (vector<Matrix44r*>::iterator it = _matrices_stack.begin(); it != _matrices_stack.end(); ++it)
_current_matrix = NULL; delete *it;
_winged_edge = new WingedEdge; // Not deleted by the destructor _matrices_stack.clear();
_pRenderMonitor = NULL; }
}
virtual ~WingedEdgeBuilder() { VISIT_DECL(IndexedFaceSet)
for (vector<Matrix44r*>::iterator it = _matrices_stack.begin(); VISIT_DECL(NodeShape)
it != _matrices_stack.end(); VISIT_DECL(NodeTransform)
it++)
delete *it;
_matrices_stack.clear();
}
VISIT_DECL(IndexedFaceSet) virtual void visitNodeTransformAfter(NodeTransform&);
VISIT_DECL(NodeShape)
VISIT_DECL(NodeTransform)
virtual void visitNodeTransformAfter(NodeTransform&); //
// Accessors
//
/////////////////////////////////////////////////////////////////////////////
// inline WingedEdge *getWingedEdge()
// Accessors {
// return _winged_edge;
///////////////////////////////////////////////////////////////////////////// }
inline WingedEdge* getWingedEdge() { inline WShape *getCurrentWShape()
return _winged_edge; {
} return _current_wshape;
}
inline WShape* getCurrentWShape() { inline FrsMaterial *getCurrentFrsMaterial()
return _current_wshape; {
} return _current_frs_material;
}
inline FrsMaterial* getCurrentFrsMaterial() {
return _current_frs_material;
}
inline Matrix44r* getCurrentMatrix() { inline Matrix44r *getCurrentMatrix()
return _current_matrix; {
} return _current_matrix;
}
// //
// Modifiers // Modifiers
// //
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
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 buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs); RenderMonitor *_pRenderMonitor;
virtual void buildWVertices(WShape& shape,
const real *vertices,
unsigned vsize);
RenderMonitor *_pRenderMonitor; private:
void buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const unsigned *tindices, const unsigned nvertices);
private: void buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const unsigned *tindices, const unsigned nvertices);
void buildTriangleStrip(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 buildTriangleFan(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 buildTriangles(const real *vertices, void transformNormals(const real *normals, unsigned nsize, 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, WShape *_current_wshape;
unsigned vsize, FrsMaterial *_current_frs_material;
const Matrix44r& transform, WingedEdge *_winged_edge;
real *res); Matrix44r *_current_matrix;
vector<Matrix44r *> _matrices_stack;
void transformNormals(const real *normals,
unsigned nsize,
const Matrix44r& transform,
real *res);
WShape* _current_wshape;
FrsMaterial* _current_frs_material;
WingedEdge* _winged_edge;
Matrix44r* _current_matrix;
vector<Matrix44r*> _matrices_stack;
}; };
#endif // WINGED_EDGE_BUILDER_H #endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__