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,43 +1,49 @@
//
// Filename : ArbitraryGridDensityProvider.cpp
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-2-5
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-5
*/
#include "ArbitraryGridDensityProvider.h"
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells)
: GridDensityProvider(source), numCells(numCells)
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4],
unsigned numCells)
: GridDensityProvider(source), numCells(numCells)
{
initialize (proscenium);
}
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numCells)
: GridDensityProvider(source), numCells(numCells)
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, unsigned numCells)
: GridDensityProvider(source), numCells(numCells)
{
real proscenium[4];
calculateQuickProscenium(transform, bbox, proscenium);
@@ -46,7 +52,7 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& sourc
}
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells)
: GridDensityProvider(source), numCells(numCells)
: GridDensityProvider(source), numCells(numCells)
{
real proscenium[4];
calculateOptimalProscenium(source, proscenium);
@@ -54,9 +60,9 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& sourc
initialize (proscenium);
}
ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider () {}
ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider() {}
void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
void ArbitraryGridDensityProvider::initialize(const real proscenium[4])
{
float prosceniumWidth = (proscenium[1] - proscenium[0]);
float prosceniumHeight = (proscenium[3] - proscenium[2]);
@@ -70,11 +76,11 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
// Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1;
if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
float safetyZone = 0.1f;
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
}
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
}
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
@@ -85,18 +91,21 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
}
ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigned numCells)
: numCells(numCells)
: numCells(numCells)
{
}
ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory () {}
ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory() {}
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source,
const real proscenium[4])
{
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, proscenium, numCells));
}
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
auto_ptr<GridDensityProvider>
ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform)
{
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
}
@@ -105,4 +114,3 @@ auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensit
{
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
}

View File

@@ -1,48 +1,54 @@
//
// Filename : ArbitraryGridDensityProvider.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-2-5
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
#define __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef ARBITRARYGRIDDENSITYPROVIDER_H
#define ARBITRARYGRIDDENSITYPROVIDER_H
/** \file blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-5
*/
#include "GridDensityProvider.h"
class ArbitraryGridDensityProvider : public GridDensityProvider {
class ArbitraryGridDensityProvider : public GridDensityProvider
{
// Disallow copying and assignment
ArbitraryGridDensityProvider (const ArbitraryGridDensityProvider& other);
ArbitraryGridDensityProvider& operator= (const ArbitraryGridDensityProvider& other);
ArbitraryGridDensityProvider(const ArbitraryGridDensityProvider& other);
ArbitraryGridDensityProvider& operator=(const ArbitraryGridDensityProvider& other);
public:
ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells);
ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numCells);
ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, unsigned numCells);
ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells);
virtual ~ArbitraryGridDensityProvider ();
virtual ~ArbitraryGridDensityProvider();
protected:
unsigned numCells;
@@ -51,17 +57,19 @@ private:
void initialize (const real proscenium[4]);
};
class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory {
class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory
{
public:
ArbitraryGridDensityProviderFactory(unsigned numCells);
~ArbitraryGridDensityProviderFactory ();
~ArbitraryGridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
unsigned numCells;
};
#endif // ARBITRARYGRIDDENSITYPROVIDER_H
#endif // __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__

View File

@@ -1,69 +1,75 @@
//
// Filename : AverageAreaGridDensityProvider.cpp
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-2-9
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-9
*/
#include "AverageAreaGridDensityProvider.h"
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor)
: GridDensityProvider(source)
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4],
real sizeFactor)
: GridDensityProvider(source)
{
initialize (proscenium, sizeFactor);
}
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, real sizeFactor)
: GridDensityProvider(source)
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, real sizeFactor)
: GridDensityProvider(source)
{
real proscenium[4];
calculateQuickProscenium(transform, bbox, proscenium);
initialize (proscenium, sizeFactor);
initialize(proscenium, sizeFactor);
}
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor)
: GridDensityProvider(source)
: GridDensityProvider(source)
{
real proscenium[4];
calculateOptimalProscenium(source, proscenium);
initialize (proscenium, sizeFactor);
initialize(proscenium, sizeFactor);
}
AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider () {}
AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider() {}
void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real sizeFactor)
void AverageAreaGridDensityProvider::initialize(const real proscenium[4], real sizeFactor)
{
float prosceniumWidth = (proscenium[1] - proscenium[0]);
float prosceniumHeight = (proscenium[3] - proscenium[2]);
real cellArea = 0.0;
unsigned numFaces = 0;
for ( source.begin(); source.isValid(); source.next() ) {
for (source.begin(); source.isValid(); source.next()) {
Polygon3r& poly(source.getGridSpacePolygon());
Vec3r min, max;
poly.getBBox(min, max);
@@ -82,11 +88,11 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
// Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1;
if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
float safetyZone = 0.1f;
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
}
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
}
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
@@ -97,18 +103,21 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
}
AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(real sizeFactor)
: sizeFactor(sizeFactor)
: sizeFactor(sizeFactor)
{
}
AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory () {}
AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory() {}
auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
auto_ptr<GridDensityProvider>
AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
}
auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
auto_ptr<GridDensityProvider>
AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform)
{
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
}
@@ -117,4 +126,3 @@ auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDens
{
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
}

View File

@@ -1,67 +1,72 @@
//
// Filename : AverageAreaGridDensityProvider.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-2-9
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
#define __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef AVERAGEAREAGRIDDENSITYPROVIDER_H
#define AVERAGEAREAGRIDDENSITYPROVIDER_H
/** \file blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-9
*/
#include "GridDensityProvider.h"
class AverageAreaGridDensityProvider : public GridDensityProvider {
class AverageAreaGridDensityProvider : public GridDensityProvider
{
// Disallow copying and assignment
AverageAreaGridDensityProvider (const AverageAreaGridDensityProvider& other);
AverageAreaGridDensityProvider& operator= (const AverageAreaGridDensityProvider& other);
AverageAreaGridDensityProvider(const AverageAreaGridDensityProvider& other);
AverageAreaGridDensityProvider& operator=(const AverageAreaGridDensityProvider& other);
public:
AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor);
AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, real sizeFactor);
AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, real sizeFactor);
AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor);
virtual ~AverageAreaGridDensityProvider ();
protected:
virtual ~AverageAreaGridDensityProvider();
private:
void initialize (const real proscenium[4], real sizeFactor);
};
class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory {
class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory
{
public:
AverageAreaGridDensityProviderFactory(real sizeFactor);
~AverageAreaGridDensityProviderFactory ();
~AverageAreaGridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
real sizeFactor;
};
#endif // AVERAGEAREAGRIDDENSITYPROVIDER_H
#endif // __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__

View File

@@ -1,37 +1,42 @@
//
// Filename : BoxGrid.cpp
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-1-29
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/BoxGrid.cpp
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-1-29
*/
#include <algorithm>
#include <stdexcept>
#include "BoxGrid.h"
#include <stdexcept>
#include <algorithm>
using namespace std;
// Helper Classes
@@ -42,11 +47,12 @@ using namespace std;
// Cell
/////////
BoxGrid::Cell::Cell () {}
BoxGrid::Cell::Cell() {}
BoxGrid::Cell::~Cell () {}
BoxGrid::Cell::~Cell() {}
void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
{
const real epsilon = 1.0e-06;
boundary[0] = x - epsilon;
boundary[1] = x + sizeX + epsilon;
@@ -54,11 +60,13 @@ void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
boundary[3] = y + sizeY + epsilon;
}
bool BoxGrid::Cell::compareOccludersByShallowestPoint (const BoxGrid::OccluderData* a, const BoxGrid::OccluderData* b) {
bool BoxGrid::Cell::compareOccludersByShallowestPoint(const BoxGrid::OccluderData *a, const BoxGrid::OccluderData *b)
{
return a->shallowest < b->shallowest;
}
void BoxGrid::Cell::indexPolygons() {
void BoxGrid::Cell::indexPolygons()
{
// Sort occluders by their shallowest points.
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
}
@@ -67,46 +75,48 @@ void BoxGrid::Cell::indexPolygons() {
//////////////////
BoxGrid::Iterator::Iterator (BoxGrid& grid, Vec3r& center, real epsilon)
: _target(grid.transform(center)),
_foundOccludee(false)
: _target(grid.transform(center)), _foundOccludee(false)
{
// Find target cell
_cell = grid.findCell(_target);
#if boxgridlogging == 1
#if BOX_GRID_LOGGING
cout << "Searching for occluders of edge centered at " << _target << " in cell ["
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
#endif
// Set iterator
_current = _cell->faces.begin();
}
BoxGrid::Iterator::~Iterator () {}
BoxGrid::Iterator::~Iterator() {}
// BoxGrid
/////////////////
BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI)
: _viewpoint(viewpoint),
_enableQI(enableQI)
BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
bool enableQI)
: _viewpoint(viewpoint), _enableQI(enableQI)
{
cout << "Generate Cell structure" << endl;
// Generate Cell structure
cout << "Generate Cell structure" << endl;
assignCells(source, density, viewMap);
cout << "Distribute occluders" << endl;
// Fill Cells
cout << "Distribute occluders" << endl;
distributePolygons(source);
cout << "Reorganize cells" << endl;
// Reorganize Cells
cout << "Reorganize cells" << endl;
reorganizeCells();
cout << "Ready to use BoxGrid" << endl;
}
BoxGrid::~BoxGrid () {
}
BoxGrid::~BoxGrid() {}
void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap) {
void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap)
{
_cellSize = density.cellSize();
_cellsX = density.cellsX();
_cellsY = density.cellsY();
@@ -115,20 +125,19 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
// Now allocate the cell table and fill it with default (empty) cells
_cells.resize(_cellsX * _cellsY);
for ( cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
(*i) = NULL;
}
// Identify cells that will be used, and set the dimensions for each
ViewMap::fedges_container& fedges = viewMap->FEdges();
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f ) {
if ( (*f)->isInImage() ) {
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
if ((*f)->isInImage()) {
Vec3r point = transform((*f)->center3d());
unsigned i, j;
unsigned int i, j;
getCellCoordinates(point, i, j);
if ( _cells[i * _cellsY + j] == NULL ) {
if (_cells[i * _cellsY + j] == NULL) {
// This is an uninitialized cell
real x, y, width, height;
x = _cellOrigin[0] + _cellSize * i;
@@ -145,19 +154,21 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
}
}
void BoxGrid::distributePolygons (OccluderSource& source) {
void BoxGrid::distributePolygons(OccluderSource& source)
{
unsigned long nFaces = 0;
unsigned long nKeptFaces = 0;
for ( source.begin(); source.isValid(); source.next() ) {
OccluderData* occluder = NULL;
for (source.begin(); source.isValid(); source.next()) {
OccluderData *occluder = NULL;
try {
if ( insertOccluder(source, occluder) ) {
if (insertOccluder(source, occluder)) {
_faces.push_back(occluder);
++nKeptFaces;
}
} catch (...) {
}
catch (...) {
// If an exception was thrown, _faces.push_back() cannot have succeeded.
// occluder is not owned by anyone, and must be deleted.
// If the exception was thrown before or during new OccluderData(), then
@@ -170,41 +181,47 @@ void BoxGrid::distributePolygons (OccluderSource& source) {
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
}
void BoxGrid::reorganizeCells () {
void BoxGrid::reorganizeCells()
{
// Sort the occluders by shallowest point
for ( vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
if ( *i != NULL ) {
for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
if (*i != NULL) {
(*i)->indexPolygons();
}
}
}
void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) {
void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
{
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
}
BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point) {
unsigned x, y;
BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point)
{
unsigned int x, y;
getCellCoordinates(point, x, y);
return _cells[x * _cellsY + y];
}
bool BoxGrid::orthographicProjection () const {
bool BoxGrid::orthographicProjection() const
{
return true;
}
const Vec3r& BoxGrid::viewpoint() const {
const Vec3r& BoxGrid::viewpoint() const
{
return _viewpoint;
}
bool BoxGrid::enableQI() const {
bool BoxGrid::enableQI() const
{
return _enableQI;
}
BoxGrid::Transform::Transform () : GridHelpers::Transform() {}
BoxGrid::Transform::Transform() : GridHelpers::Transform() {}
Vec3r BoxGrid::Transform::operator() (const Vec3r& point) const {
Vec3r BoxGrid::Transform::operator()(const Vec3r& point) const
{
return Vec3r(point[0], point[1], -point[2]);
}

View File

@@ -1,78 +1,87 @@
//
// Filename : BoxGrid.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-1-29
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_BOX_GRID_H__
#define __FREESTYLE_BOX_GRID_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/BoxGrid.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-1-29
*/
#ifndef BOXGRID_H
#define BOXGRID_H
#define boxgridlogging 0
#define BOX_GRID_LOGGING FALSE
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector>
// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
// so it should be a safe fall-back.
//#include <vector>
//#include <deque>
#include "GridDensityProvider.h"
#include "OccluderSource.h"
#include "ViewMap.h"
#include "../winged_edge/WEdge.h"
#include "../geometry/Polygon.h"
#include "../system/PointerSequence.h"
#include "../geometry/BBox.h"
#include "../geometry/GridHelpers.h"
#include "OccluderSource.h"
#include "GridDensityProvider.h"
#include "../geometry/Polygon.h"
#include "../system/PointerSequence.h"
#include "../winged_edge/WEdge.h"
class BoxGrid
{
public:
// Helper classes
struct OccluderData {
explicit OccluderData (OccluderSource& source, Polygon3r& p);
struct OccluderData
{
explicit OccluderData(OccluderSource& source, Polygon3r& p);
Polygon3r poly;
Polygon3r cameraSpacePolygon;
real shallowest, deepest;
// N.B. We could, of course, store face in poly's userdata
// member, like the old ViewMapBuilder code does. However,
// code comments make it clear that userdata is deprecated,
// so we avoid the temptation to save 4 or 8 bytes.
// N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
// However, code comments make it clear that userdata is deprecated, so we avoid the temptation
// to save 4 or 8 bytes.
WFace* face;
};
private:
struct Cell {
struct Cell
{
// Can't store Cell in a vector without copy and assign
//Cell(const Cell& other);
//Cell& operator= (const Cell& other);
// Cell(const Cell& other);
// Cell& operator=(const Cell& other);
explicit Cell ();
~Cell ();
explicit Cell();
~Cell();
static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b);
static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
void setDimensions(real x, real y, real sizeX, real sizeY);
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
@@ -84,43 +93,37 @@ private:
};
public:
/*****
Iterator needs to allow the user to avoid full 3D comparison in
two cases:
(1) Where (*current)->deepest < target[2], where the occluder is
unambiguously in front of the target point.
(2) Where (*current)->shallowest > target[2], where the occluder
is unambiguously in back of the target point.
In addition, when used by OptimizedFindOccludee, Iterator should
stop iterating as soon as it has an occludee candidate and
(*current)->shallowest > candidate[2], because at that point forward
no new occluder could possibly be a better occludee.
*****/
class Iterator {
/* Iterator needs to allow the user to avoid full 3D comparison in two cases:
*
* (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
*
* (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
*
* In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an
* occludee candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder
* could possibly be a better occludee.
*/
class Iterator
{
public:
// epsilon is not used in this class, but other grids with the same interface may need an epsilon
explicit Iterator (BoxGrid& grid, Vec3r& center, real epsilon=1e-06);
~Iterator ();
void initBeforeTarget ();
void initAfterTarget ();
void nextOccluder ();
void nextOccludee ();
explicit Iterator(BoxGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
~Iterator();
void initBeforeTarget();
void initAfterTarget();
void nextOccluder();
void nextOccludee();
bool validBeforeTarget();
bool validAfterTarget();
WFace* getWFace() const;
Polygon3r* getCameraSpacePolygon();
WFace *getWFace() const;
Polygon3r *getCameraSpacePolygon();
void reportDepth(Vec3r origin, Vec3r u, real t);
private:
bool testOccluder(bool wantOccludee);
void markCurrentOccludeeCandidate(real depth);
Cell* _cell;
Cell *_cell;
Vec3r _target;
bool _foundOccludee;
real _occludeeDepth;
@@ -128,32 +131,34 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate;
};
class Transform : public GridHelpers::Transform {
class Transform : public GridHelpers::Transform
{
public:
explicit Transform ();
explicit Transform (Transform& other);
Vec3r operator() (const Vec3r& point) const;
explicit Transform();
explicit Transform(Transform& other);
Vec3r operator()(const Vec3r& point) const;
};
private:
// Prevent implicit copies and assignments.
BoxGrid(const BoxGrid& other);
BoxGrid& operator= (const BoxGrid& other);
BoxGrid& operator=(const BoxGrid& other);
public:
explicit BoxGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
explicit BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
bool enableQI);
virtual ~BoxGrid();
// Generate Cell structure
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
// Fill Cells
void distributePolygons(OccluderSource& source);
// Insert one polygon into each matching cell,
// return true if any cell consumes the polygon
// Insert one polygon into each matching cell, return true if any cell consumes the polygon
bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
// Sort occluders in each cell
void reorganizeCells();
Cell* findCell(const Vec3r& point);
Cell *findCell(const Vec3r& point);
// Accessors:
bool orthographicProjection() const;
@@ -176,51 +181,52 @@ private:
bool _enableQI;
};
inline void BoxGrid::Iterator::initBeforeTarget () {
inline void BoxGrid::Iterator::initBeforeTarget()
{
_current = _cell->faces.begin();
while ( _current != _cell->faces.end() && ! testOccluder(false) ) {
while (_current != _cell->faces.end() && !testOccluder(false)) {
++_current;
}
}
inline void BoxGrid::Iterator::initAfterTarget () {
if ( _foundOccludee ) {
#if boxgridlogging == 1
inline void BoxGrid::Iterator::initAfterTarget()
{
if (_foundOccludee) {
#if BOX_GRID_LOGGING
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
#endif
_current = _occludeeCandidate;
return;
}
#if boxgridlogging == 1
#if BOX_GRID_LOGGING
std::cout << "\tStarting occludee search from current position" << std::endl;
#endif
while ( _current != _cell->faces.end() && ! testOccluder(true) ) {
while (_current != _cell->faces.end() && !testOccluder(true)) {
++_current;
}
}
inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
inline bool BoxGrid::Iterator::testOccluder(bool wantOccludee)
{
// End-of-list is not even a valid iterator position
if ( _current == _cell->faces.end() ) {
// Returning true seems strange, but it will break us out of whatever loop
// is calling testOccluder, and _current=_cell->face.end() will make
// the calling routine give up.
if (_current == _cell->faces.end()) {
// Returning true seems strange, but it will break us out of whatever loop is calling testOccluder,
// and _current = _cell->face.end() will make the calling routine give up.
return true;
}
#if boxgridlogging == 1
#if BOX_GRID_LOGGING
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
for ( unsigned i = 1; i < (*_current)->poly.getVertices().size(); ++i ) {
for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
std::cout << ", " << (*_current)->poly.getVertices()[i];
}
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
#endif
// If we have an occluder candidate and we are unambiguously after it, abort
if ( _foundOccludee && (*_current)->shallowest > _occludeeDepth ) {
#if boxgridlogging == 1
if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
#if BOX_GRID_LOGGING
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
#endif
_current = _cell->faces.end();
@@ -230,16 +236,17 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
}
// Specific continue or stop conditions when searching for each type
if ( wantOccludee ) {
if ( (*_current)->deepest < _target[2] ) {
#if boxgridlogging == 1
if (wantOccludee) {
if ((*_current)->deepest < _target[2]) {
#if BOX_GRID_LOGGING
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
#endif
return false;
}
} else {
if ( (*_current)->shallowest > _target[2] ) {
#if boxgridlogging == 1
}
else {
if ((*_current)->shallowest > _target[2]) {
#if BOX_GRID_LOGGING
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
#endif
return true;
@@ -251,67 +258,73 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
// Check to see if target is in the 2D bounding box
Vec3r bbMin, bbMax;
(*_current)->poly.getBBox(bbMin, bbMax);
if ( _target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1] ) {
#if boxgridlogging == 1
if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
#if BOX_GRID_LOGGING
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
#endif
return false;
}
// We've done all the corner cutting we can.
// Let the caller work out whether or not
// the geometry is correct.
// Let the caller work out whether or not the geometry is correct.
return true;
}
inline void BoxGrid::Iterator::reportDepth (Vec3r origin, Vec3r u, real t) {
inline void BoxGrid::Iterator::reportDepth(Vec3r origin, Vec3r u, real t)
{
// The reported depth is the length of a ray in camera space
// We need to convert it into a Z-value in grid space
real depth = -(origin + (u * t))[2];
#if boxgridlogging == 1
#if BOX_GRID_LOGGING
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
#endif
if ( depth > _target[2] ) {
#if boxgridlogging == 1
if (depth > _target[2]) {
#if BOX_GRID_LOGGING
std::cout << " is deeper than target" << std::endl;
#endif
// If the current occluder is the best occludee so far, save it.
if ( ! _foundOccludee || _occludeeDepth > depth ) {
if (! _foundOccludee || _occludeeDepth > depth) {
markCurrentOccludeeCandidate(depth);
}
} else {
#if boxgridlogging == 1
}
else {
#if BOX_GRID_LOGGING
std::cout << std::endl;
#endif
}
}
inline void BoxGrid::Iterator::nextOccluder () {
if ( _current != _cell->faces.end() ) {
inline void BoxGrid::Iterator::nextOccluder()
{
if (_current != _cell->faces.end()) {
do {
++_current;
} while ( _current != _cell->faces.end() && ! testOccluder(false) );
} while (_current != _cell->faces.end() && ! testOccluder(false));
}
}
inline void BoxGrid::Iterator::nextOccludee () {
if ( _current != _cell->faces.end() ) {
inline void BoxGrid::Iterator::nextOccludee()
{
if (_current != _cell->faces.end()) {
do {
++_current;
} while ( _current != _cell->faces.end() && ! testOccluder(true) );
} while (_current != _cell->faces.end() && ! testOccluder(true));
}
}
inline bool BoxGrid::Iterator::validBeforeTarget () {
inline bool BoxGrid::Iterator::validBeforeTarget()
{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
}
inline bool BoxGrid::Iterator::validAfterTarget () {
inline bool BoxGrid::Iterator::validAfterTarget()
{
return _current != _cell->faces.end();
}
inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
#if boxgridlogging == 1
inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth)
{
#if BOX_GRID_LOGGING
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
#endif
_occludeeCandidate = _current;
@@ -319,18 +332,20 @@ inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
_foundOccludee = true;
}
inline WFace* BoxGrid::Iterator::getWFace() const {
inline WFace* BoxGrid::Iterator::getWFace() const
{
return (*_current)->face;
}
inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon() {
inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon()
{
return &((*_current)->cameraSpacePolygon);
}
inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
: poly(p),
cameraSpacePolygon(source.getCameraSpacePolygon()),
face(source.getWFace())
inline BoxGrid::OccluderData::OccluderData(OccluderSource& source, Polygon3r& p)
: poly(p),
cameraSpacePolygon(source.getCameraSpacePolygon()),
face(source.getWFace())
{
// Set shallowest and deepest based on bbox
Vec3r min, max;
@@ -339,9 +354,10 @@ inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p
deepest = max[2];
}
inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
if ( GridHelpers::insideProscenium (boundary, poly) ) {
if ( occluder == NULL) {
inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
{
if (GridHelpers::insideProscenium (boundary, poly)) {
if (occluder == NULL) {
// Disposal of occluder will be handled in BoxGrid::distributePolygons(),
// or automatically by BoxGrid::_faces;
occluder = new OccluderData(source, poly);
@@ -350,7 +366,8 @@ inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& pol
}
}
inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) {
inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
{
Polygon3r& poly(source.getGridSpacePolygon());
occluder = NULL;
@@ -361,9 +378,9 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
getCellCoordinates(bbMin, startX, startY);
getCellCoordinates(bbMax, endX, endY);
for ( unsigned i = startX; i <= endX; ++i ) {
for ( unsigned j = startY; j <= endY; ++j ) {
if ( _cells[i * _cellsY + j] != NULL ) {
for (unsigned int i = startX; i <= endX; ++i) {
for (unsigned int j = startY; j <= endY; ++j) {
if (_cells[i * _cellsY + j] != NULL) {
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
}
}
@@ -372,5 +389,4 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
return occluder != NULL;
}
#endif // BOXGRID_H
#endif // __FREESTYLE_BOX_GRID_H__

View File

@@ -1,67 +1,74 @@
//
// Filename : CulledOccluderSource.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2010-12-21
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/CulledOccluderSource.cpp
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2010-12-21
*/
#include "CulledOccluderSource.h"
#include "../geometry/GridHelpers.h"
#include "FRS_freestyle.h"
CulledOccluderSource::CulledOccluderSource (const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap, bool extensiveFEdgeSearch)
: OccluderSource(t, we),
rejected(0),
gridSpaceOccluderProsceniumInitialized(false)
#include "../geometry/GridHelpers.h"
CulledOccluderSource::CulledOccluderSource(const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap,
bool extensiveFEdgeSearch)
: OccluderSource(t, we), rejected(0), gridSpaceOccluderProsceniumInitialized(false)
{
cullViewEdges(viewMap, extensiveFEdgeSearch);
// If we have not found any visible FEdges during our cull, then there is nothing
// to iterate over. Short-circuit everything.
// If we have not found any visible FEdges during our cull, then there is nothing to iterate over.
// Short-circuit everything.
valid = gridSpaceOccluderProsceniumInitialized;
if ( valid && ! testCurrent() ) {
if (valid && ! testCurrent()) {
next();
}
}
CulledOccluderSource::~CulledOccluderSource() {
}
CulledOccluderSource::~CulledOccluderSource() {}
bool CulledOccluderSource::testCurrent() {
if ( valid ) {
bool CulledOccluderSource::testCurrent()
{
if (valid) {
// The test for gridSpaceOccluderProsceniumInitialized should not be necessary
return gridSpaceOccluderProsceniumInitialized && GridHelpers::insideProscenium (gridSpaceOccluderProscenium, cachedPolygon);
return gridSpaceOccluderProsceniumInitialized &&
GridHelpers::insideProscenium(gridSpaceOccluderProscenium, cachedPolygon);
}
return false;
}
bool CulledOccluderSource::next() {
while ( OccluderSource::next() ) {
if ( testCurrent() ) {
bool CulledOccluderSource::next()
{
while (OccluderSource::next()) {
if (testCurrent()) {
++rejected;
return true;
}
@@ -70,17 +77,20 @@ bool CulledOccluderSource::next() {
return false;
}
void CulledOccluderSource::getOccluderProscenium(real proscenium[4]) {
for ( unsigned i = 0; i < 4; ++i ) {
void CulledOccluderSource::getOccluderProscenium(real proscenium[4])
{
for (unsigned int i = 0; i < 4; ++i) {
proscenium[i] = gridSpaceOccluderProscenium[i];
}
}
static inline real distance2D(const Vec3r & point, const real origin[2]) {
static inline real distance2D(const Vec3r & point, const real origin[2])
{
return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
}
static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
static inline bool crossesProscenium(real proscenium[4], FEdge *fe)
{
Vec2r min(proscenium[0], proscenium[2]);
Vec2r max(proscenium[1], proscenium[3]);
Vec2r A(fe->vertexA()->getProjectedX(), fe->vertexA()->getProjectedY());
@@ -89,20 +99,20 @@ static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
return GeomUtils::intersect2dSeg2dArea (min, max, A, B);
}
static inline bool insideProscenium(real proscenium[4], const Vec3r& point) {
return ! ( point[0] < proscenium[0] || point[0] > proscenium[1] || point[1] < proscenium[2] || point[1] > proscenium[3] );
static inline bool insideProscenium(real proscenium[4], const Vec3r& point)
{
return !(point[0] < proscenium[0] || point[0] > proscenium[1] ||
point[1] < proscenium[2] || point[1] > proscenium[3]);
}
void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch) {
void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch)
{
// Cull view edges by marking them as non-displayable.
// This avoids the complications of trying to delete
// edges from the ViewMap.
// This avoids the complications of trying to delete edges from the ViewMap.
// Non-displayable view edges will be skipped over during
// visibility calculation.
// Non-displayable view edges will be skipped over during visibility calculation.
// View edges will be culled according to their position
// w.r.t. the viewport proscenium (viewport + 5% border,
// View edges will be culled according to their position w.r.t. the viewport proscenium (viewport + 5% border,
// or some such).
// Get proscenium boundary for culling
@@ -112,34 +122,30 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
cout << "Proscenium culling:" << endl;
cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2] << ", " << viewProscenium[3] << "]"<< endl;
cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2]
<< ", " << viewProscenium[3] << "]"<< endl;
cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]"<< endl;
// A separate occluder proscenium will also be maintained,
// starting out the same as the viewport proscenium, and
// expanding as necessary so that it encompasses the center
// point of at least one feature edge in each retained view
// edge.
// The occluder proscenium will be used later to cull occluding
// triangles before they are inserted into the Grid.
// The occluder proscenium starts out the same size as the view
// proscenium
// A separate occluder proscenium will also be maintained, starting out the same as the viewport proscenium, and
// expanding as necessary so that it encompasses the center point of at least one feature edge in each
// retained view edge.
// The occluder proscenium will be used later to cull occluding triangles before they are inserted into the Grid.
// The occluder proscenium starts out the same size as the view proscenium
GridHelpers::getDefaultViewProscenium(occluderProscenium);
// N.B. Freestyle is inconsistent in its use of ViewMap::viewedges_container
// and vector<ViewEdge*>::iterator. Probably all occurences of vector<ViewEdge*>::iterator
// should be replaced ViewMap::viewedges_container throughout the code.
// XXX Freestyle is inconsistent in its use of ViewMap::viewedges_container and vector<ViewEdge*>::iterator.
// Probably all occurences of vector<ViewEdge*>::iterator should be replaced ViewMap::viewedges_container
// throughout the code.
// For each view edge
ViewMap::viewedges_container::iterator ve, veend;
for(ve=viewMap.ViewEdges().begin(), veend=viewMap.ViewEdges().end(); ve!=veend; ve++) {
for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
// Overview:
// Search for a visible feature edge
// If none: mark view edge as non-displayable
// Otherwise:
// Find a feature edge with center point inside occluder proscenium.
// If none exists, find the feature edge with center point
// closest to viewport origin.
// If none exists, find the feature edge with center point closest to viewport origin.
// Expand occluder proscenium to enclose center point.
// For each feature edge, while bestOccluderTarget not found and view edge not visibile
@@ -151,28 +157,27 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// All ViewEdges start culled
(*ve)->setIsInImage(false);
// For simple visibility calculation: mark a feature edge
// that is known to have a center point inside the occluder proscenium.
// Cull all other feature edges.
// For simple visibility calculation: mark a feature edge that is known to have a center point inside
// the occluder proscenium. Cull all other feature edges.
do {
// All FEdges start culled
fe->setIsInImage(false);
// Look for the visible edge that can most easily be included
// in the occluder proscenium.
if ( ! bestOccluderTargetFound ) {
// Look for the visible edge that can most easily be included in the occluder proscenium.
if (!bestOccluderTargetFound) {
// If center point is inside occluder proscenium,
if ( insideProscenium(occluderProscenium, fe->center2d()) ) {
if (insideProscenium(occluderProscenium, fe->center2d())) {
// Use this feature edge for visibility deterimination
fe->setIsInImage(true);
expandGridSpaceOccluderProscenium(fe);
// Mark bestOccluderTarget as found
bestOccluderTargetFound = true;
bestOccluderTarget = fe;
} else {
}
else {
real d = distance2D(fe->center2d(), prosceniumOrigin);
// If center point is closer to viewport origin than current target
if ( bestOccluderTarget == NULL || d < bestOccluderDistance ) {
if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
// Then store as bestOccluderTarget
bestOccluderDistance = d;
bestOccluderTarget = fe;
@@ -181,33 +186,35 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
}
// If feature edge crosses the view proscenium
if ( ! (*ve)->isInImage() && crossesProscenium(viewProscenium, fe) ) {
if (!(*ve)->isInImage() && crossesProscenium(viewProscenium, fe)) {
// Then the view edge will be included in the image
(*ve)->setIsInImage(true);
}
fe = fe->nextEdge();
} while ( fe != NULL && fe != festart && ! ( bestOccluderTargetFound && (*ve)->isInImage() ) );
} while (fe != NULL && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));
// Either we have run out of FEdges, or we already have the one edge we need to determine visibility
// Cull all remaining edges.
while ( fe != NULL && fe != festart ) {
while (fe != NULL && fe != festart) {
fe->setIsInImage(false);
fe = fe->nextEdge();
}
// If bestOccluderTarget was not found inside the occluder proscenium,
// we need to expand the occluder proscenium to include it.
if ( (*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound ) {
if ((*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound) {
// Expand occluder proscenium to enclose bestOccluderTarget
Vec3r point = bestOccluderTarget->center2d();
if ( point[0] < occluderProscenium[0] ) {
if (point[0] < occluderProscenium[0]) {
occluderProscenium[0] = point[0];
} else if ( point[0] > occluderProscenium[1] ) {
}
else if (point[0] > occluderProscenium[1]) {
occluderProscenium[1] = point[0];
}
if ( point[1] < occluderProscenium[2] ) {
if (point[1] < occluderProscenium[2]) {
occluderProscenium[2] = point[1];
} else if ( point[1] > occluderProscenium[3] ) {
}
else if (point[1] > occluderProscenium[3]) {
occluderProscenium[3] = point[1];
}
// Use bestOccluderTarget for visibility determination
@@ -225,22 +232,18 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// For "Normal" or "Fast" style visibility computation only:
// For more detailed visibility calculation, make a second pass through
// the view map, marking all feature edges with center points inside
// the final occluder proscenium. All of these feature edges can be
// considered during visibility calculation.
// For more detailed visibility calculation, make a second pass through the view map, marking all feature edges
// with center points inside the final occluder proscenium. All of these feature edges can be considered during
// visibility calculation.
// So far we have only found one FEdge per ViewEdge. The "Normal" and
// "Fast" styles of visibility computation want to consider many
// FEdges for each ViewEdge.
// Here we re-scan the view map to find any usable FEdges that we
// skipped on the first pass, or that have become usable because the
// occluder proscenium has been expanded since the edge was visited
// on the first pass.
if ( extensiveFEdgeSearch ) {
// So far we have only found one FEdge per ViewEdge. The "Normal" and "Fast" styles of visibility computation
// want to consider many FEdges for each ViewEdge.
// Here we re-scan the view map to find any usable FEdges that we skipped on the first pass, or that have become
// usable because the occluder proscenium has been expanded since the edge was visited on the first pass.
if (extensiveFEdgeSearch) {
// For each view edge,
for(ve=viewMap.ViewEdges().begin(), veend=viewMap.ViewEdges().end(); ve!=veend; ve++) {
if ( ! (*ve)->isInImage() ) {
for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
if (!(*ve)->isInImage()) {
continue;
}
// For each feature edge,
@@ -248,30 +251,31 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
FEdge *fe = festart;
do {
// If not (already) visible and center point inside occluder proscenium,
if ( ! fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d()) ) {
if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
// Use the feature edge for visibility determination
fe->setIsInImage(true);
expandGridSpaceOccluderProscenium(fe);
}
fe = fe->nextEdge();
} while ( fe != NULL && fe != festart );
} while (fe != NULL && fe != festart);
}
}
// Up until now, all calculations have been done in camera space.
// However, the occluder source's iteration and the grid that consumes the occluders
// both work in gridspace, so we need a version of the occluder proscenium in gridspace.
// However, the occluder source's iteration and the grid that consumes the occluders both work in gridspace,
// so we need a version of the occluder proscenium in gridspace.
// Set the gridspace occlude proscenium
}
void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge* fe) {
if ( gridSpaceOccluderProsceniumInitialized ) {
GridHelpers::expandProscenium (gridSpaceOccluderProscenium, transform(fe->center3d()));
} else {
void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge *fe)
{
if (gridSpaceOccluderProsceniumInitialized) {
GridHelpers::expandProscenium(gridSpaceOccluderProscenium, transform(fe->center3d()));
}
else {
const Vec3r& point = transform(fe->center3d());
gridSpaceOccluderProscenium[0] = gridSpaceOccluderProscenium[1] = point[0];
gridSpaceOccluderProscenium[2] = gridSpaceOccluderProscenium[3] = point[1];
gridSpaceOccluderProsceniumInitialized = true;
}
}

View File

@@ -1,46 +1,52 @@
//
// Filename : CulledOccluderSource.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2010-12-21
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
#define __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef CULLEDOCCLUDERSOURCE_H
#define CULLEDOCCLUDERSOURCE_H
/** \file blender/freestyle/intern/view_map/CulledOccluderSource.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2010-12-21
*/
#include "OccluderSource.h"
#include "ViewMap.h"
class CulledOccluderSource : public OccluderSource {
class CulledOccluderSource : public OccluderSource
{
// Disallow copying and assignment
CulledOccluderSource (const CulledOccluderSource& other);
CulledOccluderSource& operator= (const CulledOccluderSource& other);
CulledOccluderSource(const CulledOccluderSource& other);
CulledOccluderSource& operator=(const CulledOccluderSource& other);
public:
CulledOccluderSource (const GridHelpers::Transform& transform, WingedEdge& we, ViewMap& viewMap, bool extensiveFEdgeSearch = true);
CulledOccluderSource(const GridHelpers::Transform& transform, WingedEdge& we, ViewMap& viewMap,
bool extensiveFEdgeSearch = true);
virtual ~CulledOccluderSource();
void cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch);
@@ -51,7 +57,7 @@ public:
private:
bool testCurrent();
void expandGridSpaceOccluderProscenium(FEdge* fe);
void expandGridSpaceOccluderProscenium(FEdge *fe);
real occluderProscenium[4];
real gridSpaceOccluderProscenium[4];
@@ -60,4 +66,4 @@ private:
bool gridSpaceOccluderProsceniumInitialized;
};
#endif // CULLEDOCCLUDERSOURCE_H
#endif // __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,203 +1,241 @@
//
// Filename : FEdgeXDetector.h
// Author(s) : Stephane Grabli
// Purpose : Detects/flags/builds extended features edges on the
// WXEdge structure
// Date of creation : 26/10/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** 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_FEDGE_X_DETECTOR_H__
#define __FREESTYLE_FEDGE_X_DETECTOR_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/FEdgeXDetector.h
* \ingroup freestyle
* \brief Detects/flags/builds extended features edges on the WXEdge structure
* \author Stephane Grabli
* \date 26/10/2003
*/
#include <vector>
#ifndef FEDGEXDETECTOR_H
# define FEDGEXDETECTOR_H
#include "../geometry/Geom.h"
# include <vector>
# include "../system/FreestyleConfig.h"
# include "../geometry/Geom.h"
# include "../winged_edge/WXEdge.h"
# include "../winged_edge/Curvature.h"
# include "../system/ProgressBar.h"
# include "../system/RenderMonitor.h"
#include "../system/FreestyleConfig.h"
#include "../system/ProgressBar.h"
#include "../system/RenderMonitor.h"
#include "../winged_edge/Curvature.h"
#include "../winged_edge/WXEdge.h"
using namespace Geometry;
/*! This class takes as input a WXEdge structure and fills it
*/
/*! This class takes as input a WXEdge structure and fills it */
class LIB_VIEW_MAP_EXPORT FEdgeXDetector
{
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() {
_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() {}
virtual ~FEdgeXDetector() {}
/*! Process shapes from a WingedEdge containing a list of WShapes */
virtual void processShapes(WingedEdge&);
/*! Process shapes from a WingedEdge containing a list of WShapes */
virtual void processShapes(WingedEdge&);
// GENERAL STUFF
virtual void preProcessShape(WXShape* iShape);
virtual void preProcessFace(WXFace* iFace);
virtual void computeCurvatures(WXVertex *iVertex);
// GENERAL STUFF
virtual void preProcessShape(WXShape *iShape);
virtual void preProcessFace(WXFace *iFace);
virtual void computeCurvatures(WXVertex *iVertex);
// SILHOUETTE
virtual void processSilhouetteShape(WXShape* iShape);
virtual void ProcessSilhouetteFace(WXFace *iFace);
virtual void ProcessSilhouetteEdge(WXEdge *iEdge);
// SILHOUETTE
virtual void processSilhouetteShape(WXShape *iShape);
virtual void ProcessSilhouetteFace(WXFace *iFace);
virtual void ProcessSilhouetteEdge(WXEdge *iEdge);
// CREASE
virtual void processCreaseShape(WXShape* iShape);
virtual void ProcessCreaseEdge(WXEdge *iEdge);
/*! Sets the minimum angle for detecting crease edges
* \param angle
* The angular threshold in degrees (between 0 and 180) for detecting crease
* edges. An edge is considered a crease edge if the angle between two faces
* sharing the edge is smaller than the given threshold.
*/
inline void setCreaseAngle(real angle) {
if (angle < 0.0)
angle = 0.0;
else if (angle > 180.0)
angle = 180.0;
angle = cos(M_PI * (180.0 - angle) / 180.0);
if (angle != _creaseAngle){
_creaseAngle = angle;
_changes = true;
}
}
// CREASE
virtual void processCreaseShape(WXShape *iShape);
virtual void ProcessCreaseEdge(WXEdge *iEdge);
// BORDER
virtual void processBorderShape(WXShape* iShape);
virtual void ProcessBorderEdge(WXEdge *iEdge);
/*! Sets the minimum angle for detecting crease edges
* \param angle
* The angular threshold in degrees (between 0 and 180) for detecting crease edges. An edge is considered
* a crease edge if the angle between two faces sharing the edge is smaller than the given threshold.
*/
// XXX angle should be in radian...
inline void setCreaseAngle(real angle)
{
if (angle < 0.0)
angle = 0.0;
else if (angle > 180.0)
angle = 180.0;
angle = cos(M_PI * (180.0 - angle) / 180.0);
if (angle != _creaseAngle) {
_creaseAngle = angle;
_changes = true;
}
}
// RIDGES AND VALLEYS
virtual void processRidgesAndValleysShape(WXShape* iShape);
virtual void ProcessRidgeFace(WXFace *iFace);
// BORDER
virtual void processBorderShape(WXShape *iShape);
virtual void ProcessBorderEdge(WXEdge *iEdge);
// SUGGESTIVE CONTOURS
virtual void processSuggestiveContourShape(WXShape* iShape);
virtual void ProcessSuggestiveContourFace(WXFace *iFace);
virtual void postProcessSuggestiveContourShape(WXShape* iShape);
virtual void postProcessSuggestiveContourFace(WXFace *iFace);
/*! Sets the minimal derivative of the radial curvature for suggestive contours
* \param dkr
* The minimal derivative of the radial curvature
*/
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr) {
if (dkr != _kr_derivative_epsilon){
_kr_derivative_epsilon = dkr;
_changes = true;
}
}
// RIDGES AND VALLEYS
virtual void processRidgesAndValleysShape(WXShape *iShape);
virtual void ProcessRidgeFace(WXFace *iFace);
// MATERIAL BOUNDARY
virtual void processMaterialBoundaryShape(WXShape* iWShape);
virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge);
// SUGGESTIVE CONTOURS
virtual void processSuggestiveContourShape(WXShape *iShape);
virtual void ProcessSuggestiveContourFace(WXFace *iFace);
virtual void postProcessSuggestiveContourShape(WXShape *iShape);
virtual void postProcessSuggestiveContourFace(WXFace *iFace);
/*! Sets the minimal derivative of the radial curvature for suggestive contours
* \param dkr
* The minimal derivative of the radial curvature
*/
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr)
{
if (dkr != _kr_derivative_epsilon) {
_kr_derivative_epsilon = dkr;
_changes = true;
}
}
// EDGE MARKS
virtual void processEdgeMarksShape(WXShape* iShape);
virtual void ProcessEdgeMarks(WXEdge *iEdge);
// MATERIAL BOUNDARY
virtual void processMaterialBoundaryShape(WXShape *iWShape);
virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge);
// EVERYBODY
virtual void buildSmoothEdges(WXShape* iShape);
// EDGE MARKS
virtual void processEdgeMarksShape(WXShape *iShape);
virtual void ProcessEdgeMarks(WXEdge *iEdge);
/*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;}
inline void enableOrthographicProjection(bool b) {_orthographicProjection = b;}
inline void enableRidgesAndValleysFlag(bool b) {_computeRidgesAndValleys = b;}
inline void enableSuggestiveContours(bool b) {_computeSuggestiveContours = b;}
inline void enableMaterialBoundaries(bool b) {_computeMaterialBoundaries = b;}
inline void enableFaceSmoothness(bool b) {
if (b != _faceSmoothness) {
_faceSmoothness = b;
_changes=true;
}
}
inline void enableFaceMarks(bool b) {
if (b != _faceMarks) {
_faceMarks = b;
_changes=true;
}
}
/*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation)
* \param r
* The radius of the sphere expressed as a ratio of the mean edge size
*/
inline void setSphereRadius(real r) {
if(r!=_sphereRadius){
_sphereRadius = r;
_changes=true;
}
}
// EVERYBODY
virtual void buildSmoothEdges(WXShape *iShape);
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:
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;
real _bbox_diagonal; // diagonal of the current processed shape bbox
//oldtmp values
bool _computeViewIndependant;
real _meanK1;
real _meanKr;
real _minK1;
real _minKr;
real _maxK1;
real _maxKr;
unsigned _nPoints;
real _meanEdgeSize;
bool _orthographicProjection;
bool _computeRidgesAndValleys;
bool _computeSuggestiveContours;
bool _computeMaterialBoundaries;
bool _faceSmoothness;
bool _faceMarks;
real _sphereRadius; // expressed as a ratio of the mean edge size
real _creaseAngle; // [-1, 1] compared with the inner product of face normals
bool _changes;
bool _computeRidgesAndValleys;
bool _computeSuggestiveContours;
bool _computeMaterialBoundaries;
bool _faceSmoothness;
bool _faceMarks;
real _sphereRadius; // expressed as a ratio of the mean edge size
real _creaseAngle; // [-1, 1] compared with the inner product of face normals
bool _changes;
real _kr_derivative_epsilon;
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 *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/Functions0D.cpp
* \ingroup freestyle
* \brief Functions taking 0D input
* \author Stephane Grabli
* \author Emmanuel Turquin
* \date 01/07/2003
*/
# include "Functions0D.h"
# include "ViewMap.h"
#include "Functions0D.h"
#include "ViewMap.h"
using namespace std;
namespace Functions0D {
// Internal function
FEdge* getFEdge(Interface0D& it1, Interface0D& it2){
return it1.getFEdge(it2);
}
// Internal function
FEdge *getFEdge(Interface0D& it1, Interface0D& it2)
{
return it1.getFEdge(it2);
}
void getFEdges(Interface0DIterator& it,
FEdge*& fe1,
FEdge*& fe2) {
// count number of vertices
Interface0DIterator prev = it, next = it;
++next;
int count = 1;
if (!it.isBegin() && !next.isEnd()) {
count = 3;
}
if(count < 3)
{
// if we only have 2 vertices
FEdge * fe = 0;
Interface0DIterator tmp = it;
if(it.isBegin())
{
++tmp;
fe = it->getFEdge(*tmp);
}
else
{
--tmp;
fe = it->getFEdge(*tmp);
}
fe1 = fe;
fe2 = 0;
}
else
{
// we have more than 2 vertices
bool begin=false,last=false;
Interface0DIterator previous = it;
if(!previous.isBegin())
--previous;
else
begin=true;
Interface0DIterator next = it;
++next;
if(next.isEnd())
last = true;
if(begin)
{
fe1 = it->getFEdge(*next);
fe2 = 0;
}
else if(last)
{
fe1 = previous->getFEdge(*it);
fe2 = 0;
}
else
{
fe1 = previous->getFEdge(*it);
fe2 = it->getFEdge(*next);
}
}
}
void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2)
{
// count number of vertices
Interface0DIterator prev = it, next = it;
++next;
int count = 1;
if (!it.isBegin() && !next.isEnd()) {
count = 3;
}
if (count < 3) {
// if we only have 2 vertices
FEdge *fe = 0;
Interface0DIterator tmp = it;
if (it.isBegin()) {
++tmp;
fe = it->getFEdge(*tmp);
}
else {
--tmp;
fe = it->getFEdge(*tmp);
}
fe1 = fe;
fe2 = NULL;
}
else {
// we have more than 2 vertices
bool begin = false, last = false;
Interface0DIterator previous = it;
if (!previous.isBegin())
--previous;
else
begin = true;
Interface0DIterator next = it;
++next;
if (next.isEnd())
last = true;
if (begin) {
fe1 = it->getFEdge(*next);
fe2 = NULL;
}
else if (last) {
fe1 = previous->getFEdge(*it);
fe2 = NULL;
}
else {
fe1 = previous->getFEdge(*it);
fe2 = it->getFEdge(*next);
}
}
}
void getViewEdges(Interface0DIterator &it,
ViewEdge *&ve1,
ViewEdge *&ve2)
{
FEdge * fe1, *fe2;
getFEdges(it, fe1, fe2);
ve1 = fe1->viewedge();
if(fe2 != 0)
{
ve2 = fe2->viewedge();
if(ve2 == ve1)
ve2 = 0;
}
else
ve2 = 0;
}
void getViewEdges(Interface0DIterator &it, ViewEdge *&ve1, ViewEdge *&ve2)
{
FEdge *fe1, *fe2;
getFEdges(it, fe1, fe2);
ve1 = fe1->viewedge();
if (fe2 != NULL) {
ve2 = fe2->viewedge();
if (ve2 == ve1)
ve2 = NULL;
}
else {
ve2 = NULL;
}
}
ViewShape* getShapeF0D(Interface0DIterator& it)
{
ViewEdge *ve1, *ve2;
getViewEdges(it, ve1, ve2);
return ve1->viewShape();
}
ViewShape *getShapeF0D(Interface0DIterator& it)
{
ViewEdge *ve1, *ve2;
getViewEdges(it, ve1, ve2);
return ve1->viewShape();
}
void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders){
ViewEdge * ve1, *ve2;
getViewEdges(it, ve1, ve2);
occluder_container::const_iterator oit = ve1->occluders_begin();
occluder_container::const_iterator oitend = ve1->occluders_end();
void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders)
{
ViewEdge *ve1, *ve2;
getViewEdges(it, ve1, ve2);
occluder_container::const_iterator oit = ve1->occluders_begin();
occluder_container::const_iterator oitend = ve1->occluders_end();
for(;oit!=oitend; ++oit)
oOccluders.insert((*oit));
for (; oit != oitend; ++oit)
oOccluders.insert((*oit));
if(ve2!=0){
oit = ve2->occluders_begin();
oitend = ve2->occluders_end();
for(;oit!=oitend; ++oit)
oOccluders.insert((*oit));
}
}
if (ve2 != NULL) {
oit = ve2->occluders_begin();
oitend = ve2->occluders_end();
for (; oit != oitend; ++oit)
oOccluders.insert((*oit));
}
}
ViewShape * getOccludeeF0D(Interface0DIterator& it){
ViewEdge * ve1, *ve2;
getViewEdges(it, ve1, ve2);
ViewShape *aShape = ve1->aShape();
return aShape;
}
ViewShape *getOccludeeF0D(Interface0DIterator& it)
{
ViewEdge *ve1, *ve2;
getViewEdges(it, ve1, ve2);
ViewShape *aShape = ve1->aShape();
return aShape;
}
//
int VertexOrientation2DF0D::operator()(Interface0DIterator& iter) {
Vec2f A,C;
Vec2f B(iter->getProjectedX(), iter->getProjectedY());
if(iter.isBegin())
A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
else
{
Interface0DIterator previous = iter;
--previous ;
A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
}
Interface0DIterator next = iter;
++next ;
if(next.isEnd())
C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
else
C = Vec2f(next->getProjectedX(), next->getProjectedY());
//
int VertexOrientation2DF0D::operator()(Interface0DIterator& iter)
{
Vec2f A, C;
Vec2f B(iter->getProjectedX(), iter->getProjectedY());
if (iter.isBegin()) {
A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
}
else {
Interface0DIterator previous = iter;
--previous ;
A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
}
Interface0DIterator next = iter;
++next;
if (next.isEnd())
C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
else
C = Vec2f(next->getProjectedX(), next->getProjectedY());
Vec2f AB(B-A);
if(AB.norm() != 0)
AB.normalize();
Vec2f BC(C-B);
if(BC.norm() != 0)
BC.normalize();
result = AB + BC;
if(result.norm() != 0)
result.normalize();
return 0;
}
Vec2f AB(B - A);
if (AB.norm() != 0)
AB.normalize();
Vec2f BC(C - B);
if (BC.norm() != 0)
BC.normalize();
result = AB + BC;
if (result.norm() != 0)
result.normalize();
return 0;
}
int VertexOrientation3DF0D::operator()(Interface0DIterator& iter) {
Vec3r A,C;
Vec3r B(iter->getX(), iter->getY(), iter->getZ());
if(iter.isBegin())
A = Vec3r(iter->getX(), iter->getY(), iter->getZ());
else
{
int VertexOrientation3DF0D::operator()(Interface0DIterator& iter)
{
Vec3r A, C;
Vec3r B(iter->getX(), iter->getY(), iter->getZ());
if (iter.isBegin()) {
A = Vec3r(iter->getX(), iter->getY(), iter->getZ());
}
else {
Interface0DIterator previous = iter;
--previous ;
A = Vec3r(previous->getX(), previous->getY(), previous->getZ());
}
Interface0DIterator next = iter;
++next ;
if(next.isEnd())
C = Vec3r(iter->getX(), iter->getY(), iter->getZ());
else
C = Vec3r(next->getX(), next->getY(), next->getZ());
}
Interface0DIterator next = iter;
++next ;
if (next.isEnd())
C = Vec3r(iter->getX(), iter->getY(), iter->getZ());
else
C = Vec3r(next->getX(), next->getY(), next->getZ());
Vec3r AB(B-A);
if(AB.norm() != 0)
AB.normalize();
Vec3r BC(C-B);
if(BC.norm() != 0)
BC.normalize();
result = AB + BC;
if(result.norm() != 0)
result.normalize();
return 0;
}
Vec3r AB(B - A);
if (AB.norm() != 0)
AB.normalize();
Vec3r BC(C - B);
if (BC.norm() != 0)
BC.normalize();
result = AB + BC;
if (result.norm() != 0)
result.normalize();
return 0;
}
int Curvature2DAngleF0D::operator()(Interface0DIterator& iter) {
Interface0DIterator tmp1 = iter, tmp2 = iter;
++tmp2;
unsigned count = 1;
while((!tmp1.isBegin()) && (count < 3))
{
--tmp1;
++count;
}
while((!tmp2.isEnd()) && (count < 3))
{
int Curvature2DAngleF0D::operator()(Interface0DIterator& iter)
{
Interface0DIterator tmp1 = iter, tmp2 = iter;
++tmp2;
++count;
}
if(count < 3) {
// if we only have 2 vertices
result = 0;
return 0;
unsigned count = 1;
while ((!tmp1.isBegin()) && (count < 3)) {
--tmp1;
++count;
}
while ((!tmp2.isEnd()) && (count < 3)) {
++tmp2;
++count;
}
if (count < 3) {
// if we only have 2 vertices
result = 0;
return 0;
}
Interface0DIterator v = iter;
if(iter.isBegin())
++v;
Interface0DIterator next=v;
++next;
if(next.isEnd())
{
next = v;
--v;
}
Interface0DIterator prev=v;
--prev;
Interface0DIterator v = iter;
if (iter.isBegin())
++v;
Interface0DIterator next = v;
++next;
if (next.isEnd()) {
next = v;
--v;
}
Interface0DIterator prev = v;
--prev;
Vec2r A(prev->getProjectedX(), prev->getProjectedY());
Vec2r B(v->getProjectedX(), v->getProjectedY());
Vec2r C(next->getProjectedX(), next->getProjectedY());
Vec2r AB(B-A);
Vec2r BC(C-B);
Vec2r N1(-AB[1], AB[0]);
if(N1.norm() != 0)
N1.normalize();
Vec2r N2(-BC[1], BC[0]);
if(N2.norm() != 0)
N2.normalize();
if((N1.norm() == 0) && (N2.norm() == 0))
{
Exception::raiseException();
result = 0;
return -1;
}
double cosin = N1*N2;
if(cosin > 1)
cosin = 1;
if(cosin < -1)
cosin = -1;
result = acos(cosin);
Vec2r A(prev->getProjectedX(), prev->getProjectedY());
Vec2r B(v->getProjectedX(), v->getProjectedY());
Vec2r C(next->getProjectedX(), next->getProjectedY());
Vec2r AB(B - A);
Vec2r BC(C - B);
Vec2r N1(-AB[1], AB[0]);
if (N1.norm() != 0)
N1.normalize();
Vec2r N2(-BC[1], BC[0]);
if (N2.norm() != 0)
N2.normalize();
if ((N1.norm() == 0) && (N2.norm() == 0)) {
Exception::raiseException();
result = 0;
return -1;
}
double cosin = N1 * N2;
if (cosin > 1)
cosin = 1;
if (cosin < -1)
cosin = -1;
result = acos(cosin);
return 0;
}
}
int ZDiscontinuityF0D::operator()(Interface0DIterator& iter) {
FEdge *fe1, *fe2;
getFEdges(iter, fe1, fe2);
result = fe1->z_discontinuity();
if(fe2!=0){
result += fe2->z_discontinuity();
result /= 2.f;
}
return 0;
}
int Normal2DF0D::operator()(Interface0DIterator& iter) {
FEdge *fe1, *fe2;
getFEdges(iter,fe1,fe2);
Vec3f e1(fe1->orientation2d());
Vec2f n1(e1[1], -e1[0]);
Vec2f n(n1);
if(fe2 != 0)
{
Vec3f e2(fe2->orientation2d());
Vec2f n2(e2[1], -e2[0]);
n += n2;
}
n.normalize();
result = n;
int ZDiscontinuityF0D::operator()(Interface0DIterator& iter)
{
FEdge *fe1, *fe2;
getFEdges(iter, fe1, fe2);
result = fe1->z_discontinuity();
if (fe2 != NULL) {
result += fe2->z_discontinuity();
result /= 2.0f;
}
return 0;
}
}
int MaterialF0D::operator()(Interface0DIterator& iter) {
FEdge *fe1, *fe2;
getFEdges(iter,fe1,fe2);
if(fe1 == 0)
return -1;
if(fe1->isSmooth())
result = ((FEdgeSmooth*)fe1)->frs_material();
else
result = ((FEdgeSharp*)fe1)->bFrsMaterial();
// const SShape * sshape = getShapeF0D(iter);
// return sshape->material();
return 0;
}
int ShapeIdF0D::operator()(Interface0DIterator& iter) {
ViewShape * vshape = getShapeF0D(iter);
result = vshape->getId();
int Normal2DF0D::operator()(Interface0DIterator& iter)
{
FEdge *fe1, *fe2;
getFEdges(iter, fe1, fe2);
Vec3f e1(fe1->orientation2d());
Vec2f n1(e1[1], -e1[0]);
Vec2f n(n1);
if (fe2 != NULL) {
Vec3f e2(fe2->orientation2d());
Vec2f n2(e2[1], -e2[0]);
n += n2;
}
n.normalize();
result = n;
return 0;
}
}
int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter) {
ViewEdge * ve1, *ve2;
getViewEdges(iter,ve1,ve2);
unsigned int qi1, qi2;
qi1 = ve1->qi();
if(ve2 != 0){
qi2 = ve2->qi();
if(qi2!=qi1)
cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
}
result = qi1;
int MaterialF0D::operator()(Interface0DIterator& iter)
{
FEdge *fe1, *fe2;
getFEdges(iter, fe1, fe2);
if (fe1 == NULL)
return -1;
if (fe1->isSmooth())
result = ((FEdgeSmooth*)fe1)->frs_material();
else
result = ((FEdgeSharp*)fe1)->bFrsMaterial();
#if 0
const SShape *sshape = getShapeF0D(iter);
return sshape->material();
#endif
return 0;
}
}
int CurveNatureF0D::operator()(Interface0DIterator& iter) {
Nature::EdgeNature nat = 0;
ViewEdge * ve1, *ve2;
getViewEdges(iter, ve1, ve2);
nat |= ve1->getNature();
if(ve2!=0)
nat |= ve2->getNature();
result = nat;
int ShapeIdF0D::operator()(Interface0DIterator& iter)
{
ViewShape *vshape = getShapeF0D(iter);
result = vshape->getId();
return 0;
}
}
int GetOccludersF0D::operator()(Interface0DIterator& iter) {
set<ViewShape*> occluders;
getOccludersF0D(iter,occluders);
int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter)
{
ViewEdge *ve1, *ve2;
getViewEdges(iter, ve1, ve2);
unsigned int qi1, qi2;
qi1 = ve1->qi();
if (ve2 != NULL) {
qi2 = ve2->qi();
if (qi2 != qi1)
cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
}
result = qi1;
return 0;
}
int CurveNatureF0D::operator()(Interface0DIterator& iter)
{
Nature::EdgeNature nat = 0;
ViewEdge *ve1, *ve2;
getViewEdges(iter, ve1, ve2);
nat |= ve1->getNature();
if (ve2 != NULL)
nat |= ve2->getNature();
result = nat;
return 0;
}
int GetOccludersF0D::operator()(Interface0DIterator& iter)
{
set<ViewShape*> occluders;
getOccludersF0D(iter, occluders);
result.clear();
// vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end());
for(set<ViewShape*>::iterator it=occluders.begin(), itend=occluders.end();
it!=itend;
++it){
result.push_back((*it));
}
//vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end());
for (set<ViewShape*>::iterator it = occluders.begin(), itend = occluders.end(); it != itend; ++it) {
result.push_back((*it));
}
return 0;
}
}
int GetShapeF0D::operator()(Interface0DIterator& iter) {
result = getShapeF0D(iter);
int GetShapeF0D::operator()(Interface0DIterator& iter)
{
result = getShapeF0D(iter);
return 0;
}
}
int GetOccludeeF0D::operator()(Interface0DIterator& iter) {
result = getOccludeeF0D(iter);
int GetOccludeeF0D::operator()(Interface0DIterator& iter)
{
result = getOccludeeF0D(iter);
return 0;
}
}
} // end of namespace Functions0D

View File

@@ -1,64 +1,70 @@
//
// Filename : Functions0D.h
// Author(s) : Stephane Grabli, Emmanuel Turquin
// Purpose : Functions taking 0D input
// Date of creation : 01/07/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_FUNCTIONS_0D_H__
#define __FREESTYLE_FUNCTIONS_0D_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/Functions0D.h
* \ingroup freestyle
* \brief Functions taking 0D input
* \author Stephane Grabli
* \author Emmanuel Turquin
* \date 01/07/2003
*/
#ifndef FUNCTIONS0D_H
# define FUNCTIONS0D_H
#include <set>
#include <vector>
#include "Interface0D.h"
#include "../geometry/Geom.h"
#include "../python/Director.h"
#include "../scene_graph/FrsMaterial.h"
#include "../system/Exception.h"
#include "../system/Precision.h"
# include "../system/Precision.h"
# include "Interface0D.h"
# include "../geometry/Geom.h"
# include "../system/Exception.h"
# include "../scene_graph/FrsMaterial.h"
# include <set>
# include <vector>
class FEdge;
class ViewEdge;
class SShape;
using namespace Geometry;
#include "../python/Director.h"
//
// UnaryFunction0D (base class for functions in 0D)
//
///////////////////////////////////////////////////////////
template <class T>
/*! Base class for Unary Functions (functors) working
* on Interface0DIterator.
* A unary function will be used by calling
* its operator() on an Interface0DIterator.
* \attention In the scripting language, there exists
* several prototypes depending on the returned value type.
* For example, you would inherit from a UnaryFunction0DDouble
* if you wish to define a function that returns a double.
/*! Base class for Unary Functions (functors) working on Interface0DIterator.
* A unary function will be used by calling its operator() on an Interface0DIterator.
* \attention In the scripting language, there exists several prototypes depending on the returned value type.
* For example, you would inherit from a UnaryFunction0DDouble if you wish to define a function that returns a double.
* The different existing prototypes are:
* - UnaryFunction0DVoid
* - UnaryFunction0DUnsigned
@@ -68,433 +74,459 @@ template <class T>
* - UnaryFunction0DVec2f
* - UnaryFunction0DVec3f
*/
template <class T>
class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction0D
{
public:
T result;
PyObject *py_uf0D;
/*! The type of the value
* returned by the functor.
*/
typedef T ReturnedValueType;
/*! Default constructor. */
UnaryFunction0D() { py_uf0D = 0;}
/*! Destructor; */
virtual ~UnaryFunction0D() {}
/*! Returns the string "UnaryFunction0D" */
virtual string getName() const {
return "UnaryFunction0D";
}
/*! The operator ().
* \param iter
* An Interface0DIterator pointing onto
* the point at which we wish to evaluate
* the function.
* \return the result of the function of type T.
*/
virtual int operator()(Interface0DIterator& iter) {
return Director_BPy_UnaryFunction0D___call__( this, py_uf0D, iter );
}
/*! The type of the value returned by the functor. */
typedef T ReturnedValueType;
/*! Default constructor. */
UnaryFunction0D()
{
py_uf0D = NULL;
}
/*! Destructor; */
virtual ~UnaryFunction0D() {}
/*! Returns the string "UnaryFunction0D" */
virtual string getName() const
{
return "UnaryFunction0D";
}
/*! The operator ().
* \param iter
* An Interface0DIterator pointing onto the point at which we wish to evaluate the function.
* \return the result of the function of type T.
*/
virtual int operator()(Interface0DIterator& iter)
{
return Director_BPy_UnaryFunction0D___call__(this, py_uf0D, iter);
}
};
# ifdef SWIG
%feature("director") UnaryFunction0D<void>;
%feature("director") UnaryFunction0D<unsigned>;
%feature("director") UnaryFunction0D<float>;
%feature("director") UnaryFunction0D<double>;
%feature("director") UnaryFunction0D<Vec2f>;
%feature("director") UnaryFunction0D<Vec3f>;
%feature("director") UnaryFunction0D<Id>;
%template(UnaryFunction0DVoid) UnaryFunction0D<void>;
%template(UnaryFunction0DUnsigned) UnaryFunction0D<unsigned>;
%template(UnaryFunction0DFloat) UnaryFunction0D<float>;
%template(UnaryFunction0DDouble) UnaryFunction0D<double>;
%template(UnaryFunction0DVec2f) UnaryFunction0D<Vec2f>;
%template(UnaryFunction0DVec3f) UnaryFunction0D<Vec3f>;
%template(UnaryFunction0DId) UnaryFunction0D<Id>;
%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
# endif // SWIG
#ifdef SWIG
%feature("director") UnaryFunction0D<void>;
%feature("director") UnaryFunction0D<unsigned>;
%feature("director") UnaryFunction0D<float>;
%feature("director") UnaryFunction0D<double>;
%feature("director") UnaryFunction0D<Vec2f>;
%feature("director") UnaryFunction0D<Vec3f>;
%feature("director") UnaryFunction0D<Id>;
%template(UnaryFunction0DVoid) UnaryFunction0D<void>;
%template(UnaryFunction0DUnsigned) UnaryFunction0D<unsigned>;
%template(UnaryFunction0DFloat) UnaryFunction0D<float>;
%template(UnaryFunction0DDouble) UnaryFunction0D<double>;
%template(UnaryFunction0DVec2f) UnaryFunction0D<Vec2f>;
%template(UnaryFunction0DVec3f) UnaryFunction0D<Vec3f>;
%template(UnaryFunction0DId) UnaryFunction0D<Id>;
%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
#endif // SWIG
//
// Functions definitions
//
///////////////////////////////////////////////////////////
class ViewShape;
namespace Functions0D {
// GetXF0D
/*! Returns the X 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetXF0D"*/
string getName() const {
return "GetXF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter->getX();
return 0;
}
};
// GetXF0D
/*! Returns the X 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetXF0D" */
string getName() const
{
return "GetXF0D";
}
// GetYF0D
/*! Returns the Y 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetYF0D"*/
string getName() const {
return "GetYF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter->getY();
return 0;
}
};
/*! the () operator. */
int operator()(Interface0DIterator& iter)
{
result = iter->getX();
return 0;
}
};
// GetZF0D
/*! Returns the Z 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetZF0D"*/
string getName() const {
return "GetZF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter->getZ();
return 0;
}
};
// GetYF0D
/*! Returns the Y 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetYF0D" */
string getName() const
{
return "GetYF0D";
}
// GetProjectedXF0D
/*! Returns the X 3D projected coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetProjectedXF0D"*/
string getName() const {
return "GetProjectedXF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter->getProjectedX();
return 0;
}
};
/*! the () operator. */
int operator()(Interface0DIterator& iter)
{
result = iter->getY();
return 0;
}
};
// GetProjectedYF0D
/*! Returns the Y projected 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetProjectedYF0D"*/
string getName() const {
return "GetProjectedYF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter->getProjectedY();
return 0;
}
};
// GetZF0D
/*! Returns the Z 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetZF0D" */
string getName() const
{
return "GetZF0D";
}
// GetProjectedZF0D
/*! Returns the Z projected 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetProjectedZF0D"*/
string getName() const {
return "GetProjectedZF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter->getProjectedZ();
return 0;
}
};
/*! the () operator. */
int operator()(Interface0DIterator& iter)
{
result = iter->getZ();
return 0;
}
};
// GetCurvilinearAbscissaF0D
/*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
class LIB_VIEW_MAP_EXPORT GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
{
public:
/*! Returns the string "GetCurvilinearAbscissaF0D"*/
string getName() const {
return "GetCurvilinearAbscissaF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter.t();
return 0;
}
};
// GetProjectedXF0D
/*! Returns the X 3D projected coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetProjectedXF0D" */
string getName() const
{
return "GetProjectedXF0D";
}
// GetParameterF0D
/*! Returns the parameter of an Interface0D in the context of its 1D element. */
class LIB_VIEW_MAP_EXPORT GetParameterF0D : public UnaryFunction0D<float>
{
public:
/*! Returns the string "GetCurvilinearAbscissaF0D"*/
string getName() const {
return "GetParameterF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter) {
result = iter.u();
return 0;
}
};
/*! the () operator. */
int operator()(Interface0DIterator& iter)
{
result = iter->getProjectedX();
return 0;
}
};
// VertexOrientation2DF0D
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element
* to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
{
public:
/*! Returns the string "VertexOrientation2DF0D"*/
string getName() const {
return "VertexOrientation2DF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// GetProjectedYF0D
/*! Returns the Y projected 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetProjectedYF0D" */
string getName() const
{
return "GetProjectedYF0D";
}
// VertexOrientation3DF0D
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element
* to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
{
public:
/*! Returns the string "VertexOrientation3DF0D"*/
string getName() const {
return "VertexOrientation3DF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
/*! the () operator. */
int operator()(Interface0DIterator& iter)
{
result = iter->getProjectedY();
return 0;
}
};
// Curvature2DAngleF0D
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element
* to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "Curvature2DAngleF0D"*/
string getName() const {
return "Curvature2DAngleF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// GetProjectedZF0D
/*! Returns the Z projected 3D coordinate of an Interface0D. */
class LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "GetProjectedZF0D" */
string getName() const
{
return "GetProjectedZF0D";
}
// ZDiscontinuity
/*! Returns a real giving the distance between
* and Interface0D and the shape that lies behind (occludee).
* This distance is evaluated in the camera space and normalized
* between 0 and 1. Therefore, if no oject is occluded by the
* shape to which the Interface0D belongs to, 1 is returned.
*/
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "ZDiscontinuityF0D"*/
string getName() const {
return "ZDiscontinuityF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
/*! the () operator. */
int operator()(Interface0DIterator& iter)
{
result = iter->getProjectedZ();
return 0;
}
};
// Normal2DF0D
/*! Returns a Vec2f giving the normalized 2D normal to the 1D element
* to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f>
{
public:
/*! Returns the string "Normal2DF0D"*/
string getName() const {
return "Normal2DF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
// GetCurvilinearAbscissaF0D
/*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
class LIB_VIEW_MAP_EXPORT GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
{
public:
/*! Returns the string "GetCurvilinearAbscissaF0D" */
string getName() const
{
return "GetCurvilinearAbscissaF0D";
}
// MaterialF0D
/*! Returns the material of the object evaluated at the Interface0D.
* This evaluation can be ambiguous (in the case of a TVertex for example.
* This functor tries to remove this ambiguity using the context
* offered by the 1D element to which the Interface0DIterator& belongs
* to and by arbitrary chosing the material of the face
* that lies on its left when following the 1D element if there
* are two different materials on each side of the point.
* However, there still can be problematic cases, and the user willing
* to deal with this cases in a specific way should implement
* its own getMaterial functor.
*/
class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
{
public:
/*! Returns the string "MaterialF0D"*/
string getName() const {
return "MaterialF0D";
}
/*! the () operator.*/
int operator()(Interface0DIterator& iter);
};
/*! the () operator. */
int operator()(Interface0DIterator& iter)
{
result = iter.t();
return 0;
}
};
// 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);
};
// GetParameterF0D
/*! Returns the parameter of an Interface0D in the context of its 1D element. */
class LIB_VIEW_MAP_EXPORT GetParameterF0D : public UnaryFunction0D<float>
{
public:
/*! Returns the string "GetCurvilinearAbscissaF0D" */
string getName() const
{
return "GetParameterF0D";
}
// 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);
};
/*! the () operator. */
int operator()(Interface0DIterator& iter)
{
result = iter.u();
return 0;
}
};
// 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);
};
// VertexOrientation2DF0D
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
{
public:
/*! Returns the string "VertexOrientation2DF0D" */
string getName() const
{
return "VertexOrientation2DF0D";
}
// 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);
};
/*! 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);
};
// VertexOrientation3DF0D
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
{
public:
/*! Returns the string "VertexOrientation3DF0D" */
string getName() const
{
return "VertexOrientation3DF0D";
}
// 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);
};
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// Curvature2DAngleF0D
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element to which the Interface0DIterator&
* belongs to and evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "Curvature2DAngleF0D" */
string getName() const
{
return "Curvature2DAngleF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// ZDiscontinuity
/*! Returns a real giving the distance between and Interface0D and the shape that lies behind (occludee).
* This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no oject is occluded
* by the shape to which the Interface0D belongs to, 1 is returned.
*/
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
{
public:
/*! Returns the string "ZDiscontinuityF0D" */
string getName() const
{
return "ZDiscontinuityF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// Normal2DF0D
/*! Returns a Vec2f giving the normalized 2D normal to the 1D element to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f>
{
public:
/*! Returns the string "Normal2DF0D" */
string getName() const
{
return "Normal2DF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// MaterialF0D
/*! Returns the material of the object evaluated at the Interface0D.
* This evaluation can be ambiguous (in the case of a TVertex for example.
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
* Interface0DIterator& belongs to and by arbitrary chosing the material of the face that lies on its left when
* following the 1D element if there are two different materials on each side of the point.
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getMaterial functor.
*/
class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
{
public:
/*! Returns the string "MaterialF0D" */
string getName() const
{
return "MaterialF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// ShapeIdF0D
/*! Returns the Id of the Shape the Interface0D belongs to.
* This evaluation can be ambiguous (in the case of a TVertex for example).
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
* Interface0DIterator& belongs to.
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getShapeIdF0D functor.
*/
class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
{
public:
/*! Returns the string "ShapeIdF0D" */
string getName() const
{
return "ShapeIdF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// QiF0D
/*! Returns the quantitative invisibility of this Interface0D.
* This evaluation can be ambiguous (in the case of a TVertex for example).
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
* Interface0DIterator& belongs to.
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getQIF0D functor.
*/
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
{
public:
/*! Returns the string "QuantitativeInvisibilityF0D" */
string getName() const
{
return "QuantitativeInvisibilityF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// CurveNatureF0D
/*! Returns the Nature::EdgeNature of the 1D element the Interface0DIterator& belongs to. */
class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
{
public:
/*! Returns the string "QuantitativeInvisibilityF0D" */
string getName() const
{
return "CurveNatureF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// GetShapeF0D
/*! Returns the ViewShape* containing the Interface0D */
class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*>
{
public:
/*! Returns the string "GetShapeF0D" */
string getName() const
{
return "GetShapeF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// GetOccludersF0D
/*! Returns a vector containing the ViewShape* occluding the Interface0D */
class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
{
public:
/*! Returns the string "GetOccludersF0D" */
string getName() const
{
return "GetOccludersF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// GetOccludeeF0D
/*! Returns the ViewShape* "occluded" by the Interface0D */
class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
{
public:
/*! Returns the string "GetOccludeeF0D" */
string getName() const
{
return "GetOccludeeF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
/////////////////////////// Internal ////////////////////////////
/////////////////////////// Internal ////////////////////////////
// getFEdge
LIB_VIEW_MAP_EXPORT
FEdge *getFEdge(Interface0D& it1, Interface0D& it2);
// getFEdge
LIB_VIEW_MAP_EXPORT
FEdge* getFEdge(Interface0D& it1, Interface0D& it2);
// getFEdges
LIB_VIEW_MAP_EXPORT
void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
// 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);
// getViewEdges
LIB_VIEW_MAP_EXPORT
void getViewEdges(Interface0DIterator& it,
ViewEdge *&ve1,
ViewEdge *&ve2);
// getShapeF0D
LIB_VIEW_MAP_EXPORT
ViewShape *getShapeF0D(Interface0DIterator& it);
// getShapeF0D
LIB_VIEW_MAP_EXPORT
ViewShape* getShapeF0D(Interface0DIterator& it);
// getOccludersF0D
LIB_VIEW_MAP_EXPORT
void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
// getOccludersF0D
LIB_VIEW_MAP_EXPORT
void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
// getOccludeeF0D
LIB_VIEW_MAP_EXPORT
ViewShape* getOccludeeF0D(Interface0DIterator& it);
// getOccludeeF0D
LIB_VIEW_MAP_EXPORT
ViewShape *getOccludeeF0D(Interface0DIterator& it);
} // 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 *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/Functions1D.cpp
* \ingroup freestyle
* \brief Functions taking 1D input
* \author Stephane Grabli
* \author Emmanuel Turquin
* \date 01/07/2003
*/
# include "Functions1D.h"
using namespace std;
namespace Functions1D {
int GetXF1D::operator()(Interface1D& inter) {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
int GetXF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
}
int GetYF1D::operator()(Interface1D& inter) {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
int GetYF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
}
int GetZF1D::operator()(Interface1D& inter) {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
int GetZF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
}
int GetProjectedXF1D::operator()(Interface1D& inter) {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
int GetProjectedXF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
}
int GetProjectedYF1D::operator()(Interface1D& inter) {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
int GetProjectedYF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
}
int GetProjectedZF1D::operator()(Interface1D& inter) {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
int GetProjectedZF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
}
int Orientation2DF1D::operator()(Interface1D& inter) {
FEdge * fe = dynamic_cast<FEdge*>(&inter);
if(fe){
Vec3r res = fe->orientation2d();
result = Vec2f(res[0], res[1]);
} else {
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
}
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);
int Orientation2DF1D::operator()(Interface1D& inter)
{
FEdge *fe = dynamic_cast<FEdge*>(&inter);
if (fe) {
result = ve->qi();
return 0;
Vec3r res = fe->orientation2d();
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;
}
}
int CurveNatureF1D::operator()(Interface1D& inter) {
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
if (ve)
result = ve->getNature();
else{
// we return a nature that contains every
// natures of the viewedges spanned by the chain.
Nature::EdgeNature nat = Nature::NO_FEATURE;
Interface0DIterator it = inter.verticesBegin();
while(!it.isEnd()){
nat |= _func(it);
++it;
}
result = nat;
}
int Orientation3DF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
}
int TimeStampF1D::operator()(Interface1D& inter) {
TimeStamp *timestamp = TimeStamp::instance();
inter.setTimeStamp(timestamp->getTimeStamp());
int ZDiscontinuityF1D::operator()(Interface1D& inter)
{
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
}
int ChainingTimeStampF1D::operator()(Interface1D& inter) {
TimeStamp *timestamp = TimeStamp::instance();
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if(ve)
ve->setChainingTimeStamp(timestamp->getTimeStamp());
int QuantitativeInvisibilityF1D::operator()(Interface1D& inter)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
result = ve->qi();
return 0;
}
FEdge *fe = dynamic_cast<FEdge*>(&inter);
if (fe) {
result = ve->qi();
return 0;
}
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
return 0;
}
}
int IncrementChainingTimeStampF1D::operator()(Interface1D& inter) {
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if(ve)
ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1);
int CurveNatureF1D::operator()(Interface1D& inter)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
result = ve->getNature();
}
else {
// we return a nature that contains every natures of the viewedges spanned by the chain.
Nature::EdgeNature nat = Nature::NO_FEATURE;
Interface0DIterator it = inter.verticesBegin();
while (!it.isEnd()) {
nat |= _func(it);
++it;
}
result = nat;
}
return 0;
}
}
int GetShapeF1D::operator()(Interface1D& inter) {
vector<ViewShape*> shapesVector;
set<ViewShape*> shapesSet;
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
if (ve){
shapesVector.push_back(ve->viewShape());
}else{
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
for(;it!=itend;++it)
shapesSet.insert(Functions0D::getShapeF0D(it));
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
}
result = shapesVector;
int TimeStampF1D::operator()(Interface1D& inter)
{
TimeStamp *timestamp = TimeStamp::instance();
inter.setTimeStamp(timestamp->getTimeStamp());
return 0;
}
}
int GetOccludersF1D::operator()(Interface1D& inter) {
vector<ViewShape*> shapesVector;
set<ViewShape*> shapesSet;
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
if (ve){
result = ve->occluders();
}else{
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
for(;it!=itend;++it){
Functions0D::getOccludersF0D(it, shapesSet);
}
shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
result = shapesVector;
}
int ChainingTimeStampF1D::operator()(Interface1D& inter)
{
TimeStamp *timestamp = TimeStamp::instance();
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve)
ve->setChainingTimeStamp(timestamp->getTimeStamp());
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;
int IncrementChainingTimeStampF1D::operator()(Interface1D& inter)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve)
ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1);
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));
}
}
int GetShapeF1D::operator()(Interface1D& inter)
{
vector<ViewShape*> shapesVector;
set<ViewShape*> shapesSet;
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
shapesVector.push_back(ve->viewShape());
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it)
shapesSet.insert(Functions0D::getShapeF0D(it));
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
}
result = shapesVector;
return 0;
}
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);
}
}
}
int GetOccludersF1D::operator()(Interface1D& inter)
{
vector<ViewShape*> shapesVector;
set<ViewShape*> shapesSet;
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
result = ve->occluders();
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it) {
Functions0D::getOccludersF0D(it, shapesSet);
}
shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
result = shapesVector;
}
return 0;
}
int GetOccludeeF1D::operator()(Interface1D& inter)
{
vector<ViewShape*> shapesVector;
set<ViewShape*> shapesSet;
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
ViewShape *aShape = ve->aShape();
shapesVector.push_back(aShape);
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it) {
shapesSet.insert(Functions0D::getOccludeeF0D(it));
}
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
}
result = shapesVector;
return 0;
}
// Internal
////////////
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
ViewShape *aShape = ve->aShape();
if (aShape == 0) {
oShapes.insert(0);
return;
}
oShapes.insert(aShape);
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it)
oShapes.insert(Functions0D::getOccludeeF0D(it));
}
}
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
vector<ViewShape*>& occluders = ve->occluders();
oShapes.insert<vector<ViewShape*>::iterator>(occluders.begin(), occluders.end());
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it) {
set<ViewShape*> shapes;
Functions0D::getOccludersF0D(it, shapes);
for (set<ViewShape*>::iterator s = shapes.begin(), send = shapes.end(); s != send; ++s)
oShapes.insert(*s);
}
}
}
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
{
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
if (ve) {
oShapes.insert(ve->viewShape());
}
else {
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
for (; it != itend; ++it)
oShapes.insert(Functions0D::getShapeF0D(it));
}
}
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

File diff suppressed because it is too large Load Diff

View File

@@ -1,93 +1,108 @@
//
// Filename : GridDensityProvider.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-2-5
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_GRID_DENSITY_PROVIDER_H__
#define __FREESTYLE_GRID_DENSITY_PROVIDER_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GRIDDENSITYPROVIDER_H
#define GRIDDENSITYPROVIDER_H
/** \file blender/freestyle/intern/view_map/GridDensityProvider.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-5
*/
#include <stdexcept>
#include <memory>
#include "OccluderSource.h"
#include "../geometry/BBox.h"
class GridDensityProvider {
class GridDensityProvider
{
// Disallow copying and assignment
GridDensityProvider (const GridDensityProvider& other);
GridDensityProvider& operator= (const GridDensityProvider& other);
GridDensityProvider(const GridDensityProvider& other);
GridDensityProvider& operator=(const GridDensityProvider& other);
public:
GridDensityProvider (OccluderSource& source)
: source(source) {
}
GridDensityProvider(OccluderSource& source) : source(source) {}
virtual ~GridDensityProvider() {};
float cellSize() {
float cellSize()
{
return _cellSize;
}
unsigned cellsX() {
unsigned cellsX()
{
return _cellsX;
}
unsigned cellsY() {
unsigned cellsY()
{
return _cellsY;
}
float cellOrigin(int index) {
if ( index < 2 ) {
float cellOrigin(int index)
{
if (index < 2) {
return _cellOrigin[index];
} else {
}
else {
throw new out_of_range("GridDensityProvider::cellOrigin can take only indexes of 0 or 1.");
}
}
static void calculateOptimalProscenium(OccluderSource& source, real proscenium[4]) {
static void calculateOptimalProscenium(OccluderSource& source, real proscenium[4])
{
source.begin();
if ( source.isValid() ) {
if (source.isValid()) {
const Vec3r& initialPoint = source.getGridSpacePolygon().getVertices()[0];
proscenium[0] = proscenium[1] = initialPoint[0];
proscenium[2] = proscenium[3] = initialPoint[1];
while ( source.isValid() ) {
while (source.isValid()) {
GridHelpers::expandProscenium (proscenium, source.getGridSpacePolygon());
source.next();
}
}
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << ")" << endl;
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2]
<< ", " << proscenium[3] << ")" << endl;
}
static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox, real proscenium[4]) {
static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox,
real proscenium[4])
{
real z;
// We want to use the z-coordinate closest to the camera to determine the proscenium face
if ( ::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2]) ) {
if (::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2])) {
z = bbox.getMin()[2];
} else {
}
else {
z = bbox.getMax()[2];
}
// Now calculate the proscenium according to the min and max values of the x and y coordinates
@@ -98,7 +113,8 @@ public:
proscenium[1] = std::max(minPoint[0], maxPoint[0]);
proscenium[2] = std::min(minPoint[1], maxPoint[1]);
proscenium[3] = std::max(minPoint[1], maxPoint[1]);
cout << "Proscenium : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << endl;
cout << "Proscenium : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", "
<< proscenium[3] << endl;
}
protected:
@@ -108,24 +124,23 @@ protected:
float _cellOrigin[2];
};
class GridDensityProviderFactory {
class GridDensityProviderFactory
{
// Disallow copying and assignment
GridDensityProviderFactory (const GridDensityProviderFactory& other);
GridDensityProviderFactory& operator= (const GridDensityProviderFactory& other);
public:
GridDensityProviderFactory()
{
}
GridDensityProviderFactory() {}
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) =0;
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) = 0;
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform) =0;
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform) = 0;
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) =0;
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) = 0;
virtual ~GridDensityProviderFactory () {}
};
#endif // GRIDDENSITYPROVIDER_H
#endif // __FREESTYLE_GRID_DENSITY_PROVIDER_H__

View File

@@ -1,60 +1,70 @@
//
// Filename : HeuristicGridDensityProviderFactory.cpp
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-2-8
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-8
*/
#include "HeuristicGridDensityProviderFactory.h"
HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces)
: sizeFactor(sizeFactor), numFaces(numFaces)
: sizeFactor(sizeFactor), numFaces(numFaces)
{
}
HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory () {}
HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory() {}
auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
auto_ptr<GridDensityProvider>
HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
if ( avg->cellSize() > p23->cellSize() ) {
if (avg->cellSize() > p23->cellSize()) {
return (auto_ptr<GridDensityProvider>) p23;
} else {
}
else {
return (auto_ptr<GridDensityProvider>) avg;
}
}
auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
auto_ptr<GridDensityProvider>
HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform)
{
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox,
transform, sizeFactor));
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
if ( avg->cellSize() > p23->cellSize() ) {
if (avg->cellSize() > p23->cellSize()) {
return (auto_ptr<GridDensityProvider>) p23;
} else {
}
else {
return (auto_ptr<GridDensityProvider>) avg;
}
}
@@ -65,10 +75,10 @@ auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensit
GridDensityProvider::calculateOptimalProscenium(source, proscenium);
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
if ( avg->cellSize() > p23->cellSize() ) {
if (avg->cellSize() > p23->cellSize()) {
return (auto_ptr<GridDensityProvider>) p23;
} else {
}
else {
return (auto_ptr<GridDensityProvider>) avg;
}
}

View File

@@ -1,48 +1,55 @@
//
// Filename : HeuristicGridDensityProviderFactory.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-2-8
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
#define __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-8
*/
#ifndef HEURISTICGRIDDENSITYPROVIDERFACTORY_H
#define HEURISTICGRIDDENSITYPROVIDERFACTORY_H
//#include <memory> // provided by GridDensityProvider.h
// #include <memory> // provided by GridDensityProvider.h
// #include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
#include "Pow23GridDensityProvider.h"
#include "AverageAreaGridDensityProvider.h"
//#include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
#include "Pow23GridDensityProvider.h"
class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory {
class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory
{
public:
HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
~HeuristicGridDensityProviderFactory ();
~HeuristicGridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
@@ -50,5 +57,4 @@ protected:
unsigned numFaces;
};
#endif // HEURISTICGRIDDENSITYPROVIDERFACTORY_H
#endif // __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__

View File

@@ -1,45 +1,53 @@
//
// Filename : Interface0D.h
// Author(s) : Emmanuel Turquin
// Purpose : Interface to 0D elts
// Date of creation : 01/07/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_INTERFACE_0D_H__
#define __FREESTYLE_INTERFACE_0D_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/Interface0D.h
* \ingroup freestyle
* \brief Interface to 0D elts
* \author Emmanuel Turquin
* \date 01/07/2003
*/
#ifndef INTERFACE0D_H
# define INTERFACE0D_H
#include <iostream>
#include <Python.h>
#include <string>
# include <Python.h>
# include <string>
# include <iostream>
# include "../system/Id.h"
# include "../system/Precision.h"
# include "../winged_edge/Nature.h"
# include "../geometry/Geom.h"
using namespace std;
#include "../geometry/Geom.h"
#include "../system/Id.h"
#include "../system/Iterator.h" //soc
#include "../system/Precision.h"
#include "../winged_edge/Nature.h"
using namespace std;
//
// Interface0D
@@ -51,114 +59,128 @@ class SVertex;
class ViewVertex;
class NonTVertex;
class TVertex;
/*! Base class for any 0D element. */
class Interface0D
{
public:
/*! Default constructor */
Interface0D() {}
virtual ~Interface0D() {}; //soc
/*! Default constructor */
Interface0D() {}
virtual ~Interface0D() {}; //soc
/*! Returns the string "Interface0D". */
virtual string getExactTypeName() const
{
return "Interface0D";
}
/*! Returns the string "Interface0D".*/
virtual string getExactTypeName() const {
return "Interface0D";
}
// Data access methods
// Data access methods
/*! Returns the 3D x coordinate of the point. */
virtual real getX() const
{
PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
return 0;
}
/*! Returns the 3D x coordinate of the point. */
virtual real getX() const {
PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
return 0;
}
/*! Returns the 3D y coordinate of the point. */
virtual real getY() const
{
PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
return 0;
}
/*! Returns the 3D y coordinate of the point. */
virtual real getY() const {
PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
return 0;
}
/*! Returns the 3D z coordinate of the point. */
virtual real getZ() const
{
PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
return 0;
}
/*! Returns the 3D z coordinate of the point. */
virtual real getZ() const {
PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
return 0;
}
/*! Returns the 3D point. */
virtual Geometry::Vec3f getPoint3D() const
{
PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
return 0;
}
/*! Returns the 3D point. */
virtual Geometry::Vec3f getPoint3D() const {
PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
return 0;
}
/*! Returns the 2D x coordinate of the point. */
virtual real getProjectedX() const
{
PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
return 0;
}
/*! Returns the 2D x coordinate of the point. */
virtual real getProjectedX() const {
PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
return 0;
}
/*! Returns the 2D y coordinate of the point. */
virtual real getProjectedY() const
{
PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
return 0;
}
/*! Returns the 2D y coordinate of the point. */
virtual real getProjectedY() const {
PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
return 0;
}
/*! Returns the 2D z coordinate of the point. */
virtual real getProjectedZ() const
{
PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
return 0;
}
/*! Returns the 2D z coordinate of the point. */
virtual real getProjectedZ() const {
PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
return 0;
}
/*! Returns the 2D point. */
virtual Geometry::Vec2f getPoint2D() const
{
PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
return 0;
}
/*! Returns the 2D point. */
virtual Geometry::Vec2f getPoint2D() const {
PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
return 0;
}
/*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */
virtual FEdge* getFEdge(Interface0D&)
{
PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
return 0;
}
/*! Returns the FEdge that lies between this Interface0D and the
* Interface0D given as argument. */
virtual FEdge* getFEdge(Interface0D&) {
PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
return 0;
}
/*! Returns the Id of the point. */
virtual Id getId() const
{
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
return 0;
}
/*! Returns the Id of the point. */
virtual Id getId() const {
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
return 0;
}
/*! Returns the nature of the point. */
virtual Nature::VertexNature getNature() const {
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
return Nature::POINT;
}
/*! Returns the nature of the point. */
virtual Nature::VertexNature getNature() const
{
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
return Nature::POINT;
}
/*! Cast the Interface0D in SVertex if it can be. */
virtual SVertex * castToSVertex(){
PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
return 0;
}
/*! Cast the Interface0D in SVertex if it can be. */
virtual SVertex *castToSVertex()
{
PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
return 0;
}
/*! Cast the Interface0D in ViewVertex if it can be. */
virtual ViewVertex * castToViewVertex(){
PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
return 0;
}
/*! Cast the Interface0D in ViewVertex if it can be. */
virtual ViewVertex * castToViewVertex()
{
PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
return 0;
}
/*! Cast the Interface0D in NonTVertex if it can be. */
virtual NonTVertex * castToNonTVertex(){
PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
return 0;
}
/*! Cast the Interface0D in TVertex if it can be. */
virtual TVertex * castToTVertex(){
PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
return 0;
}
/*! Cast the Interface0D in NonTVertex if it can be. */
virtual NonTVertex *castToNonTVertex()
{
PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
return 0;
}
/*! Cast the Interface0D in TVertex if it can be. */
virtual TVertex *castToTVertex()
{
PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
return 0;
}
};
@@ -170,39 +192,42 @@ public:
class Interface0DIteratorNested : public Iterator
{
public:
virtual ~Interface0DIteratorNested() {}
virtual ~Interface0DIteratorNested() {}
virtual string getExactTypeName() const
{
return "Interface0DIteratorNested";
}
virtual string getExactTypeName() const {
return "Interface0DIteratorNested";
}
virtual Interface0D& operator*() = 0;
virtual Interface0D& operator*() = 0;
virtual Interface0D* operator->()
{
return &(operator*());
}
virtual Interface0D* operator->() {
return &(operator*());
}
virtual int increment() = 0;
virtual int increment() = 0;
virtual int decrement() = 0;
virtual int decrement() = 0;
virtual bool isBegin() const = 0;
virtual bool isBegin() const = 0;
virtual bool isEnd() const = 0;
virtual bool isEnd() const = 0;
virtual bool operator==(const Interface0DIteratorNested& it) const = 0;
virtual bool operator==(const Interface0DIteratorNested& it) const = 0;
virtual bool operator!=(const Interface0DIteratorNested& it) const
{
return !(*this == it);
}
virtual bool operator!=(const Interface0DIteratorNested& it) const {
return !(*this == it);
}
/*! Returns the curvilinear abscissa */
virtual float t() const = 0;
/*! Returns the curvilinear abscissa */
virtual float t() const = 0;
/*! Returns the point parameter 0<u<1 */
virtual float u() const = 0;
/*! Returns the point parameter 0<u<1 */
virtual float u() const = 0;
virtual Interface0DIteratorNested* copy() const = 0;
virtual Interface0DIteratorNested* copy() const = 0;
};
@@ -212,149 +237,154 @@ public:
//////////////////////////////////////////////////
/*! Class defining an iterator over Interface0D elements.
* An instance of this iterator is always obtained
* from a 1D element.
* \attention In the scripting language, you must call
* \code it2 = Interface0DIterator(it1) \endcode instead of \code it2 = it1 \endcode
* where \a it1 and \a it2 are 2 Interface0DIterator.
* An instance of this iterator is always obtained from a 1D element.
* \attention In the scripting language, you must call \code it2 = Interface0DIterator(it1) \endcode instead of
* \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
* Otherwise, incrementing \a it1 will also increment \a it2.
*/
class Interface0DIterator : public Iterator
{
public:
Interface0DIterator(Interface0DIteratorNested* it = NULL)
{
_iterator = it;
}
Interface0DIterator(Interface0DIteratorNested* it = NULL) {
_iterator = it;
}
/*! Copy constructor */
Interface0DIterator(const Interface0DIterator& it)
{
_iterator = it._iterator->copy();
}
/*! Copy constructor */
Interface0DIterator(const Interface0DIterator& it) {
_iterator = it._iterator->copy();
}
/*! Destructor */
virtual ~Interface0DIterator()
{
if (_iterator)
delete _iterator;
}
/*! Destructor */
virtual ~Interface0DIterator() {
if (_iterator)
delete _iterator;
}
/*! Operator =
* \attention In the scripting language, you must call \code it2 = Interface0DIterator(it1) \endcode instead of
* \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
* Otherwise, incrementing \a it1 will also increment \a it2.
*/
Interface0DIterator& operator=(const Interface0DIterator& it)
{
if(_iterator)
delete _iterator;
_iterator = it._iterator->copy();
return *this;
}
/*! Operator =
* \attention In the scripting language, you must call
* \code it2 = Interface0DIterator(it1) \endcode instead of \code it2 = it1 \endcode
* where \a it1 and \a it2 are 2 Interface0DIterator.
* Otherwise, incrementing \a it1 will also increment \a it2.
*/
Interface0DIterator& operator=(const Interface0DIterator& it) {
if(_iterator)
delete _iterator;
_iterator = it._iterator->copy();
return *this;
}
/*! Returns the string "Interface0DIterator". */
virtual string getExactTypeName() const
{
if (!_iterator)
return "Interface0DIterator";
return _iterator->getExactTypeName() + "Proxy";
}
/*! Returns the string "Interface0DIterator". */
virtual string getExactTypeName() const {
if (!_iterator)
return "Interface0DIterator";
return _iterator->getExactTypeName() + "Proxy";
}
// FIXME test it != 0 (exceptions ?)
// 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.
* In the scripting language, you must call
* "getObject()" instead using this operator.
*/
Interface0D& operator*() {
return _iterator->operator*();
}
/*! Returns a pointer to the pointed Interface0D.
* Can't be called in the scripting language.
*/
Interface0D *operator->()
{
return &(operator*());
}
/*! Returns a pointer to the pointed Interface0D.
* Can't be called in the scripting language.
*/
Interface0D* operator->() {
return &(operator*());
}
/*! Increments. In the scripting language, call "increment()". */
Interface0DIterator& operator++()
{
_iterator->increment();
return *this;
}
/*! Increments. In the scripting language, call
* "increment()".
*/
Interface0DIterator& operator++() {
_iterator->increment();
return *this;
}
/*! Increments. In the scripting language, call "increment()". */
Interface0DIterator operator++(int)
{
Interface0DIterator ret(*this);
_iterator->increment();
return ret;
}
/*! Increments. In the scripting language, call
* "increment()".
*/
Interface0DIterator operator++(int) {
Interface0DIterator ret(*this);
_iterator->increment();
return ret;
}
/*! Decrements. In the scripting language, call "decrement()". */
Interface0DIterator& operator--()
{
_iterator->decrement();
return *this;
}
/*! Decrements. In the scripting language, call
* "decrement()".
*/
Interface0DIterator& operator--() {
_iterator->decrement();
return *this;
}
/*! Decrements. In the scripting language, call "decrement()". */
Interface0DIterator operator--(int)
{
Interface0DIterator ret(*this);
_iterator->decrement();
return ret;
}
/*! Decrements. In the scripting language, call
* "decrement()".
*/
Interface0DIterator operator--(int) {
Interface0DIterator ret(*this);
_iterator->decrement();
return ret;
}
/*! Increments. */
virtual int increment()
{
return _iterator->increment();
}
/*! Increments. */
virtual int increment() {
return _iterator->increment();
}
/*! Decrements. */
virtual int decrement()
{
return _iterator->decrement();
}
/*! Decrements. */
virtual int decrement() {
return _iterator->decrement();
}
/*! Returns true if the pointed Interface0D is the first of the 1D element containing the points over which
* we're iterating.
*/
virtual bool isBegin() const
{
return _iterator->isBegin();
}
/*! Returns true if the pointed Interface0D is the
* first of the 1D element containing the points over
* which we're iterating.
*/
virtual bool isBegin() const {
return _iterator->isBegin();
}
/*! Returns true if the pointed Interface0D is after the after the last point of the 1D element we're
* iterating from. */
virtual bool isEnd() const
{
return _iterator->isEnd();
}
/*! Returns true if the pointed Interface0D is after the
* after the last point of the 1D element we're iterating from.
*/
virtual bool isEnd() const {
return _iterator->isEnd();
}
/*! operator == . */
bool operator==(const Interface0DIterator& it) const
{
return _iterator->operator==(*(it._iterator));
}
/*! operator == . */
bool operator==(const Interface0DIterator& it) const {
return _iterator->operator==(*(it._iterator));
}
/*! operator != . */
bool operator!=(const Interface0DIterator& it) const
{
return !(*this == it);
}
/*! operator != . */
bool operator!=(const Interface0DIterator& it) const {
return !(*this == it);
}
/*! Returns the curvilinear abscissa. */
inline float t() const
{
return _iterator->t();
}
/*! Returns the point parameter in the curve 0<=u<=1. */
inline float u() const
{
return _iterator->u();
}
/*! Returns the curvilinear abscissa. */
inline float t() const {
return _iterator->t();
}
/*! Returns the point parameter in the curve 0<=u<=1. */
inline float u() const {
return _iterator->u();
}
protected:
Interface0DIteratorNested* _iterator;
Interface0DIteratorNested *_iterator;
};
#endif // INTERFACE0D_H
#endif // __FREESTYLE_INTERFACE_0D_H__

View File

@@ -1,125 +1,126 @@
//
// Filename : Interface1D.h
// Author(s) : Emmanuel Turquin
// Purpose : Interface to 1D elts
// Date of creation : 01/07/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_INTERFACE_1D_H__
#define __FREESTYLE_INTERFACE_1D_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/Interface1D.h
* \ingroup freestyle
* \brief Interface 1D and related tools definitions
* \author Emmanuel Turquin
* \date 01/07/2003
*/
#ifndef INTERFACE1D_H
# define INTERFACE1D_H
#include <float.h>
#include <iostream>
#include <Python.h>
#include <string>
# include <Python.h>
# include <string>
# include <iostream>
# include <float.h>
# include "../system/Id.h"
# include "../system/Precision.h"
# include "../winged_edge/Nature.h"
# include "Functions0D.h"
#include "Functions0D.h"
#include "../system/Id.h"
#include "../system/Precision.h"
#include "../winged_edge/Nature.h"
using namespace std;
/*! \file Interface1D.h
* Interface1D and related tools definitions
*/
// Integration method
/*! The different integration
* methods that can be invoked
* to integrate into a single value the set of values obtained
/*! The different integration methods that can be invoked to integrate into a single value the set of values obtained
* from each 0D element of a 1D element.
*/
typedef enum {
MEAN,/*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/
MIN,/*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/
MAX,/*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/
FIRST,/*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/
LAST/*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/
MEAN, /*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/
MIN, /*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/
MAX, /*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/
FIRST, /*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/
LAST /*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/
} IntegrationType;
/*! Returns a single
* value from a set of values evaluated at each 0D element
* of this 1D element.
/*! Returns a single value from a set of values evaluated at each 0D element of this 1D element.
* \param fun
* The UnaryFunction0D used to compute a value at each Interface0D.
* \param it
* The Interface0DIterator used to iterate over the 0D elements of
* this 1D element. The integration will occur over the 0D elements
* starting from the one pointed by it.
* The Interface0DIterator used to iterate over the 0D elements of this 1D element. The integration will occur
* over the 0D elements starting from the one pointed by it.
* \param it_end
* The Interface0DIterator pointing the end of the 0D elements of the
* 1D element.
* The Interface0DIterator pointing the end of the 0D elements of the 1D element.
* \param integration_type
* The integration method used to compute a single value from
* a set of values.
* The integration method used to compute a single value from a set of values.
* \return the single value obtained for the 1D element.
*/
template <class T>
T integrate(UnaryFunction0D<T>& fun,
Interface0DIterator it,
Interface0DIterator it_end,
IntegrationType integration_type = MEAN) {
T res;
unsigned size;
switch (integration_type) {
case MIN:
fun(it);
res = fun.result;++it;
for (; !it.isEnd(); ++it) {
fun(it);
if (fun.result < res)
res = fun.result;
}
break;
case MAX:
fun(it);
res = fun.result;++it;
for (; !it.isEnd(); ++it) {
fun(it);
if (fun.result > res)
res = fun.result;
}
break;
case FIRST:
fun(it);
res = fun.result;
break;
case LAST:
fun(--it_end);
res = fun.result;
break;
case MEAN:
default:
fun(it);
res = fun.result;++it;
for (size = 1; !it.isEnd(); ++it, ++size) {
fun(it);
res += fun.result;
T integrate(UnaryFunction0D<T>& fun, Interface0DIterator it, Interface0DIterator it_end,
IntegrationType integration_type = MEAN)
{
T res;
unsigned size;
switch (integration_type) {
case MIN:
fun(it);
res = fun.result;
++it;
for (; !it.isEnd(); ++it) {
fun(it);
if (fun.result < res)
res = fun.result;
}
break;
case MAX:
fun(it);
res = fun.result;
++it;
for (; !it.isEnd(); ++it) {
fun(it);
if (fun.result > res)
res = fun.result;
}
break;
case FIRST:
fun(it);
res = fun.result;
break;
case LAST:
fun(--it_end);
res = fun.result;
break;
case MEAN:
default:
fun(it);
res = fun.result;
++it;
for (size = 1; !it.isEnd(); ++it, ++size) {
fun(it);
res += fun.result;
}
res /= (size ? size : 1);
break;
}
res /= (size ? size : 1);
break;
}
return res;
return res;
}
//
@@ -131,96 +132,99 @@ T integrate(UnaryFunction0D<T>& fun,
class Interface1D
{
public:
/*! Default constructor */
Interface1D()
{
_timeStamp = 0;
}
/*! Default constructor */
Interface1D() {_timeStamp=0;}
virtual ~Interface1D() {}; //soc
virtual ~Interface1D() {}; //soc
/*! Returns the string "Interface1D" .*/
virtual string getExactTypeName() const {
return "Interface1D";
}
/*! Returns the string "Interface1D". */
virtual string getExactTypeName() const
{
return "Interface1D";
}
// Iterator access
// Iterator access
/*! Returns an iterator over the Interface1D vertices,
* pointing to the first vertex.
*/
virtual Interface0DIterator verticesBegin() {
PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
return Interface0DIterator();
}
/*! Returns an iterator over the Interface1D vertices, pointing to the first vertex. */
virtual Interface0DIterator verticesBegin()
{
PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
return Interface0DIterator();
}
/*! Returns an iterator over the Interface1D vertices,
* pointing after the last vertex.
*/
virtual Interface0DIterator verticesEnd(){
PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
return Interface0DIterator();
}
/*! Returns an iterator over the Interface1D vertices, pointing after the last vertex. */
virtual Interface0DIterator verticesEnd()
{
PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
return Interface0DIterator();
}
/*! Returns an iterator over the Interface1D points,
* pointing to the first point. The difference with
* verticesBegin() is that here we can iterate over
* points of the 1D element at a any given sampling.
* Indeed, for each iteration, a virtual point is created.
* \param t
* The sampling with which we want to iterate over points of
* this 1D element.
*/
virtual Interface0DIterator pointsBegin(float t=0.f) {
PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
return Interface0DIterator();
}
/*! Returns an iterator over the Interface1D points, pointing to the first point. The difference with
* verticesBegin() is that here we can iterate over points of the 1D element at a any given sampling.
* Indeed, for each iteration, a virtual point is created.
* \param t
* The sampling with which we want to iterate over points of this 1D element.
*/
virtual Interface0DIterator pointsBegin(float t = 0.0f)
{
PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
return Interface0DIterator();
}
/*! Returns an iterator over the Interface1D points,
* pointing after the last point. The difference with
* verticesEnd() is that here we can iterate over
* points of the 1D element at a any given sampling.
* Indeed, for each iteration, a virtual point is created.
* \param t
* The sampling with which we want to iterate over points of
* this 1D element.
*/
virtual Interface0DIterator pointsEnd(float t=0.f) {
PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
return Interface0DIterator();
}
/*! Returns an iterator over the Interface1D points, pointing after the last point. The difference with
* verticesEnd() is that here we can iterate over points of the 1D element at a any given sampling.
* Indeed, for each iteration, a virtual point is created.
* \param t
* The sampling with which we want to iterate over points of this 1D element.
*/
virtual Interface0DIterator pointsEnd(float t = 0.0f)
{
PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
return Interface0DIterator();
}
// Data access methods
// Data access methods
/*! Returns the 2D length of the 1D element. */
virtual real getLength2D() const {
PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
return 0;
}
/*! Returns the 2D length of the 1D element. */
virtual real getLength2D() const
{
PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
return 0;
}
/*! Returns the Id of the 1D element .*/
virtual Id getId() const {
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
return Id(0, 0);
}
/*! Returns the Id of the 1D element. */
virtual Id getId() const
{
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
return Id(0, 0);
}
// FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D)
/*! Returns the nature of the 1D element. */
virtual Nature::EdgeNature getNature() const {
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
return Nature::NO_FEATURE;
}
// FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D)
/*! Returns the nature of the 1D element. */
virtual Nature::EdgeNature getNature() const
{
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
return Nature::NO_FEATURE;
}
/*! Returns the time stamp of the 1D element. Mainly used for selection. */
virtual unsigned getTimeStamp() const {
return _timeStamp;
}
/*! Returns the time stamp of the 1D element. Mainly used for selection. */
virtual unsigned getTimeStamp() const
{
return _timeStamp;
}
/*! Sets the time stamp for the 1D element. */
inline void setTimeStamp(unsigned iTimeStamp){
_timeStamp = iTimeStamp;
}
/*! Sets the time stamp for the 1D element. */
inline void setTimeStamp(unsigned iTimeStamp)
{
_timeStamp = iTimeStamp;
}
protected:
unsigned _timeStamp;
unsigned _timeStamp;
};
#endif // INTERFACE1D_H
#endif // __FREESTYLE_INTERFACE_1D_H__

View File

@@ -1,65 +1,73 @@
//
// Filename : OccluderSource.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2010-12-21
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/freestyle/intern/view_map/OccluderSource.cpp
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2010-12-21
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#include "OccluderSource.h"
#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();
}
OccluderSource::~OccluderSource() {
}
OccluderSource::~OccluderSource() {}
void OccluderSource::buildCachedPolygon() {
void OccluderSource::buildCachedPolygon()
{
vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()));
// This doesn't work, because our functor's polymorphism won't survive the copy:
// std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform);
// so we have to do:
for ( vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i ) {
for (vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i) {
(*i) = transform(*i);
}
cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
}
void OccluderSource::begin() {
vector<WShape*>& wshapes = wingedEdge.getWShapes();
void OccluderSource::begin()
{
vector<WShape*>& wshapes = wingedEdge.getWShapes();
currentShape = wshapes.begin();
shapesEnd = wshapes.end();
valid = false;
if ( currentShape != shapesEnd ) {
if (currentShape != shapesEnd) {
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
currentFace = wFaces.begin();
facesEnd = wFaces.end();
if ( currentFace != facesEnd ) {
if (currentFace != facesEnd) {
buildCachedPolygon();
valid = true;
}
@@ -67,14 +75,15 @@ void OccluderSource::begin() {
}
bool OccluderSource::next() {
if ( valid ) {
if (valid) {
++currentFace;
while ( currentFace == facesEnd ) {
while (currentFace == facesEnd) {
++currentShape;
if ( currentShape == shapesEnd ) {
if (currentShape == shapesEnd) {
valid = false;
return false;
} else {
}
else {
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
currentFace = wFaces.begin();
facesEnd = wFaces.end();
@@ -86,40 +95,47 @@ bool OccluderSource::next() {
return false;
}
bool OccluderSource::isValid() {
bool OccluderSource::isValid()
{
// Or:
// return currentShapes != shapesEnd && currentFace != facesEnd;
return valid;
}
WFace* OccluderSource::getWFace() {
WFace *OccluderSource::getWFace()
{
return valid ? *currentFace : NULL;
}
Polygon3r OccluderSource::getCameraSpacePolygon() {
Polygon3r OccluderSource::getCameraSpacePolygon()
{
return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()), (*currentFace)->GetNormal());
}
Polygon3r& OccluderSource::getGridSpacePolygon() {
Polygon3r& OccluderSource::getGridSpacePolygon()
{
return cachedPolygon;
}
void OccluderSource::getOccluderProscenium(real proscenium[4]) {
void OccluderSource::getOccluderProscenium(real proscenium[4])
{
begin();
const Vec3r& initialPoint = cachedPolygon.getVertices()[0];
proscenium[0] = proscenium[1] = initialPoint[0];
proscenium[2] = proscenium[3] = initialPoint[1];
while ( isValid() ) {
while (isValid()) {
GridHelpers::expandProscenium (proscenium, cachedPolygon);
next();
}
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << ")" << endl;
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", "
<< proscenium[3] << ")" << endl;
}
real OccluderSource::averageOccluderArea() {
real OccluderSource::averageOccluderArea()
{
real area = 0.0;
unsigned numFaces = 0;
for ( begin(); isValid(); next() ) {
for (begin(); isValid(); next()) {
Vec3r min, max;
cachedPolygon.getBBox(min, max);
area += (max[0] - min[0]) * (max[1] - min[1]);
@@ -128,5 +144,3 @@ real OccluderSource::averageOccluderArea() {
area /= numFaces;
return area;
}

View File

@@ -1,53 +1,59 @@
//
// Filename : OccluderSource.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2010-12-21
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_OCCLUDER_SOURCE_H__
#define __FREESTYLE_OCCLUDER_SOURCE_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/OccluderSource.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2010-12-21
*/
#ifndef OCCLUDERSOURCE_H
#define OCCLUDERSOURCE_H
#include "../winged_edge/WEdge.h"
#include "../geometry/GridHelpers.h"
class OccluderSource {
#include "../winged_edge/WEdge.h"
class OccluderSource
{
// Disallow copying and assignment
OccluderSource (const OccluderSource& other);
OccluderSource& operator= (const OccluderSource& other);
OccluderSource(const OccluderSource& other);
OccluderSource& operator=(const OccluderSource& other);
public:
OccluderSource (const GridHelpers::Transform& transform, WingedEdge& we);
OccluderSource(const GridHelpers::Transform& transform, WingedEdge& we);
virtual ~OccluderSource();
void begin();
virtual bool next();
bool isValid();
WFace* getWFace();
WFace *getWFace();
Polygon3r getCameraSpacePolygon();
Polygon3r& getGridSpacePolygon();
@@ -67,4 +73,4 @@ protected:
void buildCachedPolygon();
};
#endif // OCCLUDERSOURCE_H
#endif // __FREESTYLE_OCCLUDER_SOURCE_H__

View File

@@ -1,43 +1,48 @@
//
// Filename : Pow23GridDensityProvider.cpp
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-2-8
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-8
*/
#include "Pow23GridDensityProvider.h"
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces)
: GridDensityProvider(source), numFaces(numFaces)
: GridDensityProvider(source), numFaces(numFaces)
{
initialize (proscenium);
}
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numFaces)
: GridDensityProvider(source), numFaces(numFaces)
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, unsigned numFaces)
: GridDensityProvider(source), numFaces(numFaces)
{
real proscenium[4];
calculateQuickProscenium(transform, bbox, proscenium);
@@ -46,7 +51,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const
}
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces)
: GridDensityProvider(source), numFaces(numFaces)
: GridDensityProvider(source), numFaces(numFaces)
{
real proscenium[4];
calculateOptimalProscenium(source, proscenium);
@@ -56,7 +61,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsig
Pow23GridDensityProvider::~Pow23GridDensityProvider () {}
void Pow23GridDensityProvider::initialize (const real proscenium[4])
void Pow23GridDensityProvider::initialize(const real proscenium[4])
{
float prosceniumWidth = (proscenium[1] - proscenium[0]);
float prosceniumHeight = (proscenium[3] - proscenium[2]);
@@ -71,10 +76,10 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
// Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1;
if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
}
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
}
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
@@ -85,18 +90,21 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
}
Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFaces)
: numFaces(numFaces)
: numFaces(numFaces)
{
}
Pow23GridDensityProviderFactory::~Pow23GridDensityProviderFactory () {}
auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
auto_ptr<GridDensityProvider>
Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, proscenium, numFaces));
}
auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
auto_ptr<GridDensityProvider>
Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform)
{
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
}
@@ -105,5 +113,3 @@ auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityPro
{
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
}

View File

@@ -1,67 +1,75 @@
//
// Filename : Pow23GridDensityProvider.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2011-2-8
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
#define __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef POW23GRIDDENSITYPROVIDER_H
#define POW23GRIDDENSITYPROVIDER_H
/** \file blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-8
*/
#include "GridDensityProvider.h"
class Pow23GridDensityProvider : public GridDensityProvider {
class Pow23GridDensityProvider : public GridDensityProvider
{
// Disallow copying and assignment
Pow23GridDensityProvider (const Pow23GridDensityProvider& other);
Pow23GridDensityProvider& operator= (const Pow23GridDensityProvider& other);
Pow23GridDensityProvider(const Pow23GridDensityProvider& other);
Pow23GridDensityProvider& operator=(const Pow23GridDensityProvider& other);
public:
Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces);
Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numFaces);
Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform,
unsigned numFaces);
Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces);
virtual ~Pow23GridDensityProvider ();
virtual ~Pow23GridDensityProvider();
protected:
unsigned numFaces;
private:
void initialize (const real proscenium[4]);
void initialize(const real proscenium[4]);
};
class Pow23GridDensityProviderFactory : public GridDensityProviderFactory {
class Pow23GridDensityProviderFactory : public GridDensityProviderFactory
{
public:
Pow23GridDensityProviderFactory(unsigned numFaces);
~Pow23GridDensityProviderFactory ();
~Pow23GridDensityProviderFactory();
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform);
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
unsigned numFaces;
};
#endif // POW23GRIDDENSITYPROVIDER_H
#endif // __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__

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 *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/Silhouette.cpp
* \ingroup freestyle
* \brief Classes to define a silhouette structure
* \author Stephane Grabli
* \date 25/03/2002
*/
#include "Silhouette.h"
#include "ViewMap.h"
/**********************************/
/* */
/* */
/* SVertex */
/* */
/* */
/**********************************/
/**********************************/
/* */
/* */
/* SVertex */
/* */
/* */
/**********************************/
Nature::VertexNature SVertex::getNature() const {
Nature::VertexNature nature = Nature::S_VERTEX;
if (_pViewVertex)
nature |= _pViewVertex->getNature();
return nature;
Nature::VertexNature SVertex::getNature() const
{
Nature::VertexNature nature = Nature::S_VERTEX;
if (_pViewVertex)
nature |= _pViewVertex->getNature();
return nature;
}
SVertex * SVertex::castToSVertex(){
return this;
SVertex *SVertex::castToSVertex()
{
return this;
}
ViewVertex * SVertex::castToViewVertex(){
return _pViewVertex;
ViewVertex *SVertex::castToViewVertex()
{
return _pViewVertex;
}
NonTVertex * SVertex::castToNonTVertex(){
return dynamic_cast<NonTVertex*>(_pViewVertex);
NonTVertex *SVertex::castToNonTVertex()
{
return dynamic_cast<NonTVertex*>(_pViewVertex);
}
TVertex * SVertex::castToTVertex(){
return dynamic_cast<TVertex*>(_pViewVertex);
TVertex *SVertex::castToTVertex()
{
return dynamic_cast<TVertex*>(_pViewVertex);
}
float SVertex::shape_importance() const
{
return shape()->importance();
return shape()->importance();
}
//Material SVertex::material() const {return _Shape->material();}
Id SVertex::shape_id() const {return _Shape->getId();}
const SShape * SVertex::shape() const {return _Shape;}
#if 0
Material SVertex::material() const
{
return _Shape->material();
}
#endif
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();
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->qi();
}
occluder_container::const_iterator SVertex::occluders_begin() const
{
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluders_begin();
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluders_begin();
}
occluder_container::const_iterator SVertex::occluders_end() const
{
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluders_end();
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluders_end();
}
bool SVertex::occluders_empty() const
{
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluders_empty();
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluders_empty();
}
int SVertex::occluders_size() const
{
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluders_size();
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluders_size();
}
const Polygon3r& SVertex::occludee() const
{
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occludee();
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occludee();
}
const SShape* SVertex::occluded_shape() const
const SShape *SVertex::occluded_shape() const
{
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluded_shape();
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occluded_shape();
}
const bool SVertex::occludee_empty() const
const bool SVertex::occludee_empty() const
{
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occludee_empty();
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->occludee_empty();
}
real SVertex::z_discontinuity() const
{
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->z_discontinuity();
if (getNature() & Nature::T_VERTEX)
Exception::raiseException();
return (_FEdges[0])->z_discontinuity();
}
FEdge* SVertex::fedge()
FEdge *SVertex::fedge()
{
if (getNature() & Nature::T_VERTEX)
return 0;
return _FEdges[0];
if (getNature() & Nature::T_VERTEX)
return NULL;
return _FEdges[0];
}
FEdge* SVertex::getFEdge(Interface0D& inter)
FEdge *SVertex::getFEdge(Interface0D& inter)
{
FEdge * result = 0;
SVertex* iVertexB = dynamic_cast<SVertex*>(&inter);
if (!iVertexB)
return result;
vector<FEdge*>::const_iterator fe=_FEdges.begin(), feend=_FEdges.end();
for(;
fe!=feend;
++fe)
{
if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB))
|| (((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB)))
result = (*fe);
}
if((result == 0) && (getNature() & Nature::T_VERTEX))
{
SVertex *brother;
ViewVertex *vvertex = viewvertex();
TVertex * tvertex = dynamic_cast<TVertex*>(vvertex);
if(tvertex)
{
brother = tvertex->frontSVertex();
if(this == brother)
brother = tvertex->backSVertex();
const vector<FEdge*>& fedges = brother->fedges();
for(fe=fedges.begin(),feend=fedges.end();
fe!=feend;
++fe)
{
if( (((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB))
|| (((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB)))
result = (*fe);
}
}
}
if((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX))
{
SVertex *brother;
ViewVertex *vvertex = iVertexB->viewvertex();
TVertex * tvertex = dynamic_cast<TVertex*>(vvertex);
if(tvertex)
{
brother = tvertex->frontSVertex();
if(iVertexB == brother)
brother = tvertex->backSVertex();
for(fe=_FEdges.begin(),feend=_FEdges.end();
fe!=feend;
++fe)
{
if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother))
|| (((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother)))
result = (*fe);
}
}
}
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;
return result;
}
/**********************************/
/* */
/* */
/* FEdge */
/* */
/* */
/**********************************/
/**********************************/
/* */
/* */
/* FEdge */
/* */
/* */
/**********************************/
int FEdge::viewedge_nature() const {return _ViewEdge->getNature();}
//float FEdge::viewedge_length() const {return _ViewEdge->viewedge_length();}
const SShape* FEdge::occluded_shape() const
int FEdge::viewedge_nature() const
{
ViewShape * aShape = _ViewEdge->aShape();
if(aShape == 0)
return 0;
return aShape->sshape();
return _ViewEdge->getNature();
}
#if 0
float FEdge::viewedge_length() const
{
return _ViewEdge->viewedge_length();
}
#endif
const SShape *FEdge::occluded_shape() const
{
ViewShape *aShape = _ViewEdge->aShape();
if (aShape == 0)
return 0;
return aShape->sshape();
}
float FEdge::shape_importance() const
{
return _VertexA->shape()->importance();
return _VertexA->shape()->importance();
}
int FEdge::invisibility() const
{
return _ViewEdge->qi();
return _ViewEdge->qi();
}
occluder_container::const_iterator FEdge::occluders_begin() const
{
return _ViewEdge->occluders_begin();
}
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
{
return _ViewEdge->occludee_empty();
return _ViewEdge->occludee_empty();
}
Id FEdge::shape_id() const
{
return _VertexA->shape()->getId();
return _VertexA->shape()->getId();
}
const SShape* FEdge::shape() const
const SShape *FEdge::shape() const
{
return _VertexA->shape();
return _VertexA->shape();
}
real FEdge::z_discontinuity() const
{
if(!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER))
{
return 0;
}
if (!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) {
return 0;
}
BBox<Vec3r> box = ViewMap::getInstance()->getScene3dBBox();
BBox<Vec3r> box = ViewMap::getInstance()->getScene3dBBox();
Vec3r bbox_size_vec(box.getMax() - box.getMin());
real bboxsize = bbox_size_vec.norm();
if(occludee_empty())
Vec3r bbox_size_vec(box.getMax() - box.getMin());
real bboxsize = bbox_size_vec.norm();
if (occludee_empty()) {
//return FLT_MAX;
return 1.0;
//return bboxsize;
}
{
//return FLT_MAX;
#if 0
real result;
z_discontinuity_functor<SVertex> _functor;
Evaluate<SVertex, z_discontinuity_functor<SVertex> >(&_functor, iCombination, result);
#endif
Vec3r middle((_VertexB->point3d() - _VertexA->point3d()));
middle /= 2;
Vec3r disc_vec(middle - _occludeeIntersection);
real res = disc_vec.norm() / bboxsize;
return 1.0;
//return bboxsize;
}
// real result;
// z_discontinuity_functor<SVertex> _functor;
// Evaluate<SVertex,z_discontinuity_functor<SVertex> >(&_functor, iCombination, result )
Vec3r middle((_VertexB->point3d()-_VertexA->point3d()));
middle /= 2;
Vec3r disc_vec(middle - _occludeeIntersection);
real res = disc_vec.norm() / bboxsize;
return res;
//return fabs((middle.z()-_occludeeIntersection.z()));
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
//{
//
// 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);
return result;
}
const FrsMaterial& FEdgeSharp::bFrsMaterial() const {
return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
float FEdge::local_depth_variance(int iCombination ) const
{
float result;
local_depth_variance_functor<SVertex> functor;
Evaluate(&functor, iCombination, result);
return result;
}
/**********************************/
/* */
/* */
/* FEdgeSmooth */
/* */
/* */
/**********************************/
real FEdge::local_average_density( float sigma, int iCombination) const
{
float result;
const FrsMaterial& FEdgeSmooth::frs_material() const {
return _VertexA->shape()->frs_material(_FrsMaterialIndex);
density_functor<SVertex> functor(sigma);
Evaluate(&functor, iCombination, result);
return result;
}
Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */)
{
Vec3r Na = _VertexA->normal(oException);
if (oException != Exception::NO_EXCEPTION)
return Na;
Vec3r Nb = _VertexB->normal(oException);
if (oException != Exception::NO_EXCEPTION)
return Nb;
return (Na + Nb) / 2.0;
}
Vec3r FEdge::curvature2d_as_vector(int iCombination) const
{
Vec3r result;
curvature2d_as_vector_functor<SVertex> _functor;
Evaluate<Vec3r, curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result);
return result;
}
real FEdge::curvature2d_as_angle(int iCombination) const
{
real result;
curvature2d_as_angle_functor<SVertex> _functor;
Evaluate<real, curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result);
return result;
}
#endif
/**********************************/
/* */
/* */
/* FEdgeSharp */
/* */
/* */
/**********************************/
#if 0
Material FEdge::material() const
{
return _VertexA->shape()->material();
}
#endif
const FrsMaterial& FEdgeSharp::aFrsMaterial() const
{
return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
}
const FrsMaterial& FEdgeSharp::bFrsMaterial() const
{
return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
}
/**********************************/
/* */
/* */
/* FEdgeSmooth */
/* */
/* */
/**********************************/
const FrsMaterial& FEdgeSmooth::frs_material() const
{
return _VertexA->shape()->frs_material(_FrsMaterialIndex);
}

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 *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
* \ingroup freestyle
* \brief Class to perform all geometric operations dedicated to silhouette. That, for example, implies that
* this geom engine has as member data the viewpoint, transformations, projections...
* \author Stephane Grabli
* \date 03/09/2002
*/
#include "Silhouette.h"
#include "SilhouetteGeomEngine.h"
#include "../geometry/GeomUtils.h"
using namespace std;
Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0,0,0);
real SilhouetteGeomEngine::_translation[3] = {0,0,0};
real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {{1,0,0,0},
{0,1,0,0},
{0,0,1,0},
{0,0,0,1}};
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {{1,0,0,0},
{0,1,0,0},
{0,0,1,0},
{0,0,0,1}};
real SilhouetteGeomEngine::_transform[4][4] = {{1,0,0,0},
{0,1,0,0},
{0,0,1,0},
{0,0,0,1}};
int SilhouetteGeomEngine::_viewport[4] = {1,1,1,1}; // the viewport
Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0, 0, 0);
real SilhouetteGeomEngine::_translation[3] = {0, 0, 0};
real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
real SilhouetteGeomEngine::_transform[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
int SilhouetteGeomEngine::_viewport[4] = {1, 1, 1, 1};
real SilhouetteGeomEngine::_Focal = 0.0;
real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {{1,0,0,0},
{0,1,0,0},
{0,0,1,0},
{0,0,0,1}};
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {{1,0,0,0},
{0,1,0,0},
{0,0,1,0},
{0,0,0,1}};
real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
real SilhouetteGeomEngine::_znear = 0.0;
real SilhouetteGeomEngine::_zfar = 100.0;
bool SilhouetteGeomEngine::_isOrthographicProjection = false;
SilhouetteGeomEngine * SilhouetteGeomEngine::_pInstance = 0;
SilhouetteGeomEngine *SilhouetteGeomEngine::_pInstance = NULL;
void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocal)
void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
const int iViewport[4], real iFocal)
{
unsigned int i,j;
_translation[0] = iModelViewMatrix[3][0];
_translation[1] = iModelViewMatrix[3][1];
_translation[2] = iModelViewMatrix[3][2];
unsigned int i, j;
_translation[0] = iModelViewMatrix[3][0];
_translation[1] = iModelViewMatrix[3][1];
_translation[2] = iModelViewMatrix[3][2];
for(i=0; i<4; i++){
for(j=0; j<4; j++)
{
_modelViewMatrix[i][j] = iModelViewMatrix[j][i];
_glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
_modelViewMatrix[i][j] = iModelViewMatrix[j][i];
_glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
}
}
for(i=0; i<4; i++){
for(j=0; j<4; j++)
{
_projectionMatrix[i][j] = iProjectionMatrix[j][i];
_glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
_projectionMatrix[i][j] = iProjectionMatrix[j][i];
_glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
}
}
for(i=0; i<4; i++){
for(j=0; j<4; j++)
{
_transform[i][j] = 0;
for(unsigned int k=0; k<4; k++)
_transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
_transform[i][j] = 0;
for (unsigned int k = 0; k < 4; k++)
_transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
}
}
for(i=0; i<4; i++){
_viewport[i] = iViewport[i];
}
_Focal = iFocal;
for (i = 0; i < 4; i++) {
_viewport[i] = iViewport[i];
}
_Focal = iFocal;
_isOrthographicProjection = (iProjectionMatrix[3][3] != 0.0);
}
void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
{
_znear = iZNear;
_zfar = iZFar;
_znear = iZNear;
_zfar = iZFar;
}
void SilhouetteGeomEngine::retrieveViewport(int viewport[4]){
memcpy(viewport, _viewport, 4*sizeof(int));
void SilhouetteGeomEngine::retrieveViewport(int viewport[4])
{
memcpy(viewport, _viewport, 4 * sizeof(int));
}
//#define HUGE 1e9
//#define HUGE 1.0e9
void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices)
{
Vec3r newPoint;
// real min=HUGE;
// real max=-HUGE;
vector<SVertex*>::iterator sv, svend;
const real depth = _zfar - _znear;
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
Vec3r newPoint;
#if 0
real min = HUGE;
real max = -HUGE;
#endif
vector<SVertex*>::iterator sv, svend;
const real depth = _zfar - _znear;
const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
for(sv=ioVertices.begin(), svend=ioVertices.end();
sv!=svend;
sv++)
{
GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1
(*sv)->setPoint2D(newPoint);
//cerr << (*sv)->point2d().z() << " ";
// real d=(*sv)->point2d()[2];
// if (d>max) max =d;
// if (d<min) min =d;
}
// for(sv=ioVertices.begin(), svend=ioVertices.end();
// sv!=svend;
// sv++)
// {
// Vec3r P((*sv)->point2d());
// (*sv)->setPoint2D(Vec3r(P[0], P[1], 1.0-(P[2]-min)/(max-min)));
// //cerr<<(*sv)->point2d()[2]<<" ";
// }
for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
(*sv)->setPoint2D(newPoint);
#if 0
cerr << (*sv)->point2d().z() << " ";
real d = (*sv)->point2d()[2];
if (d > max)
max =d;
if (d < min)
min =d;
#endif
}
#if 0
for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
Vec3r P((*sv)->point2d());
(*sv)->setPoint2D(Vec3r(P[0], P[1], 1.0 - (P[2] - min) / (max - min)));
//cerr << (*sv)->point2d()[2] << " ";
}
#endif
}
void SilhouetteGeomEngine::ProjectSilhouette(SVertex* ioVertex)
void SilhouetteGeomEngine::ProjectSilhouette(SVertex *ioVertex)
{
Vec3r newPoint;
// real min=HUGE;
// real max=-HUGE;
vector<SVertex*>::iterator sv, svend;
const real depth = _zfar - _znear;
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1
ioVertex->setPoint2D(newPoint);
Vec3r newPoint;
#if 0
real min = HUGE;
real max = -HUGE;
vector<SVertex*>::iterator sv, svend;
#endif
const real depth = _zfar - _znear;
const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
ioVertex->setPoint2D(newPoint);
}
real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
{
if( _isOrthographicProjection )
if (_isOrthographicProjection)
return t;
// we need to compute for each parameter t the corresponding
// parameter T which gives the intersection in 3D.
// we need to compute for each parameter t the corresponding parameter T which gives the intersection in 3D.
real T;
// suffix w for world, c for camera, r for retina, i for image
@@ -184,44 +212,48 @@ real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
real m22 = _projectionMatrix[1][1];
real m23 = _projectionMatrix[1][2];
if (fabs(ABc[0]) > 1e-6) {
if (fabs(ABc[0]) > 1.0e-6) {
alpha = ABc[2] / ABc[0];
beta = Ac[2] - alpha * Ac[0];
denom = alpha * (Ir[0] + m13) + m11;
if (fabs(denom) < 1e-6)
if (fabs(denom) < 1.0e-6)
goto iter;
Ic[0] = -beta * (Ir[0] + m13) / denom;
// Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
// Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
#if 0
Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
#endif
T = (Ic[0] - Ac[0]) / ABc[0];
} else if (fabs(ABc[1]) > 1e-6) {
}
else if (fabs(ABc[1]) > 1.0e-6) {
alpha = ABc[2] / ABc[1];
beta = Ac[2] - alpha * Ac[1];
denom = alpha * (Ir[1] + m23) + m22;
if (fabs(denom) < 1e-6)
if (fabs(denom) < 1.0e-6)
goto iter;
Ic[1] = -beta * (Ir[1] + m23) / denom;
// Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
// Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
#if 0
Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
#endif
T = (Ic[1] - Ac[1]) / ABc[1];
} else {
iter: bool x_coords, less_than;
if (fabs(Bi[0] - Ai[0]) > 1e-6) {
}
else {
iter:
bool x_coords, less_than;
if (fabs(Bi[0] - Ai[0]) > 1.0e-6) {
x_coords = true;
less_than = Ai[0] < Bi[0];
} else {
}
else {
x_coords = false;
less_than = Ai[1] < Bi[1];
}
Vec3r Pc, Pr, Pi;
real T_sta = 0.0;
real T_end = 1.0;
real delta_x, delta_y, dist, dist_threshold = 1e-6;
real delta_x, delta_y, dist, dist_threshold = 1.0e-6;
int i, max_iters = 100;
for (i = 0; i < max_iters; i++) {
T = T_sta + 0.5 * (T_end - T_sta);
@@ -235,15 +267,30 @@ iter: bool x_coords, less_than;
break;
if (x_coords) {
if (less_than) {
if (Pi[0] < Ii[0]) { T_sta = T; } else { T_end = T; }
} else {
if (Pi[0] > Ii[0]) { T_sta = T; } else { T_end = T; }
if (Pi[0] < Ii[0])
T_sta = T;
else
T_end = T;
}
} else {
else {
if (Pi[0] > Ii[0])
T_sta = T;
else
T_end = T;
}
}
else {
if (less_than) {
if (Pi[1] < Ii[1]) { T_sta = T; } else { T_end = T; }
} else {
if (Pi[1] > Ii[1]) { T_sta = T; } else { T_end = T; }
if (Pi[1] < Ii[1])
T_sta = T;
else
T_end = T;
}
else {
if (Pi[1] > Ii[1])
T_sta = T;
else
T_end = T;
}
}
}
@@ -258,15 +305,11 @@ iter: bool x_coords, less_than;
}
Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r& M)
{
const real depth = _zfar - _znear;
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
Vec3r newPoint;
GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1
return newPoint;
const real depth = _zfar - _znear;
const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
Vec3r newPoint;
GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
return newPoint;
}

View File

@@ -1,41 +1,46 @@
//
// Filename : SilhouetteGeomEngine.h
// Author(s) : Stephane Grabli
// Purpose : Class to perform all geometric operations dedicated
// to silhouette. That, for example, implies that
// this geom engine has as member data the viewpoint,
// transformations, projections...
// Date of creation : 03/09/2002
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
#define __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
* \ingroup freestyle
* \brief Class to perform all geometric operations dedicated to silhouette. That, for example, implies that
* this geom engine has as member data the viewpoint, transformations, projections...
* \author Stephane Grabli
* \date 03/09/2002
*/
#ifndef SILHOUETTEGEOMENGINE_H
# define SILHOUETTEGEOMENGINE_H
#include <vector>
# include <vector>
# include "../system/FreestyleConfig.h"
# include "../geometry/Geom.h"
#include "../geometry/Geom.h"
#include "../system/FreestyleConfig.h"
using namespace Geometry;
@@ -45,79 +50,87 @@ class FEdge;
class LIB_VIEW_MAP_EXPORT SilhouetteGeomEngine
{
private:
static Vec3r _Viewpoint; // The viewpoint under which the silhouette has to be computed
static real _translation[3];
static real _modelViewMatrix[4][4]; // the model view matrix (_modelViewMatrix[i][j] means element of line i and column j)
static real _projectionMatrix[4][4]; // the projection matrix (_projectionMatrix[i][j] means element of line i and column j)
static real _transform[4][4]; // the global transformation from world to screen (projection included) (_transform[i][j] means element of line i and column j)
static int _viewport[4]; // the viewport
static real _Focal;
// The viewpoint under which the silhouette has to be computed
static Vec3r _Viewpoint;
static real _translation[3];
// the model view matrix (_modelViewMatrix[i][j] means element of line i and column j)
static real _modelViewMatrix[4][4];
// the projection matrix (_projectionMatrix[i][j] means element of line i and column j)
static real _projectionMatrix[4][4];
// the global transformation from world to screen (projection included)
// (_transform[i][j] means element of line i and column j)
static real _transform[4][4];
// the viewport
static int _viewport[4];
static real _Focal;
static real _znear;
static real _zfar;
static real _znear;
static real _zfar;
static real _glProjectionMatrix[4][4]; // GL style (column major) projection matrix
static real _glModelViewMatrix[4][4]; // GL style (column major) model view matrix
// 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 bool _isOrthographicProjection;
static SilhouetteGeomEngine *_pInstance;
static SilhouetteGeomEngine *_pInstance;
public:
/*! retrieves an instance on the singleton */
static SilhouetteGeomEngine *getInstance()
{
if(0 == _pInstance) {
_pInstance = new SilhouetteGeomEngine;
}
return _pInstance;
}
/*! retrieves an instance on the singleton */
static SilhouetteGeomEngine * getInstance()
{
if(0 == _pInstance)
{
_pInstance = new SilhouetteGeomEngine;
}
return _pInstance;
}
/*! Sets the current viewpoint */
static inline void setViewpoint(const Vec3r& ivp)
{
_Viewpoint = ivp;
}
/*! Sets the current viewpoint */
static inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;}
/*! Sets the current transformation
* iModelViewMatrix
* The 4x4 model view matrix, in column major order (openGL like).
* iProjection matrix
* The 4x4 projection matrix, in column major order (openGL like).
* iViewport
* The viewport. 4 real array: origin.x, origin.y, width, length
* iFocal
* The focal length
*/
static void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
const int iViewport[4], real iFocal);
/*! Sets the current transformation
* iModelViewMatrix
* The 4x4 model view matrix, in column major order (openGL like).
* iProjection matrix
* The 4x4 projection matrix, in column major order (openGL like).
* iViewport
* The viewport. 4 real array: origin.x, origin.y, width, length
* iFocal
* The focal length
*/
static void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocal) ;
/*! Sets the current znear and zfar */
static void setFrustum(real iZNear, real iZFar);
/*! Sets the current znear and zfar
*/
static void setFrustum(real iZNear, real iZFar) ;
/* accessors */
static void retrieveViewport(int viewport[4]);
/* accessors */
static void retrieveViewport(int viewport[4]);
/*! Projects the silhouette in camera coordinates
* This method modifies the ioEdges passed as argument.
* ioVertices
* The vertices to project. It is modified during the operation.
*/
static void ProjectSilhouette(std::vector<SVertex*>& ioVertices);
static void ProjectSilhouette(SVertex *ioVertex);
/*! Projects the silhouette in camera coordinates
* This method modifies the ioEdges passed as argument.
* ioVertices
* The vertices to project. It is modified during the
* operation.
*/
static void ProjectSilhouette(std::vector<SVertex*>& ioVertices);
static void ProjectSilhouette(SVertex* ioVertex);
/*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain
* the parameter giving the corresponding 3D intersection.
* Returns the 3D parameter
* fe
* The edge
* t
* The parameter for the 2D intersection.
*/
static real ImageToWorldParameter(FEdge *fe, real t);
/*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain
* the parameter giving the corresponding 3D intersection.
* Returns the 3D parameter
* fe
* The edge
* t
* The parameter for the 2D intersection.
*/
static real ImageToWorldParameter(FEdge *fe, real t);
/*! From world to image */
static Vec3r WorldToImage(const Vec3r& M);
/*! From world to image */
static Vec3r WorldToImage(const Vec3r& M);
};
#endif // SILHOUETTEGEOMENGINE_H
#endif // __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__

View File

@@ -1,37 +1,42 @@
//
// Filename : SphericalGrid.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2010-12-19
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/SphericalGrid.cpp
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2010-12-19
*/
#include <algorithm>
#include <stdexcept>
#include "SphericalGrid.h"
#include <stdexcept>
#include <algorithm>
using namespace std;
// Helper Classes
@@ -42,11 +47,12 @@ using namespace std;
// Cell
/////////
SphericalGrid::Cell::Cell () {}
SphericalGrid::Cell::Cell() {}
SphericalGrid::Cell::~Cell () {}
SphericalGrid::Cell::~Cell() {}
void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
{
const real epsilon = 1.0e-06;
boundary[0] = x - epsilon;
boundary[1] = x + sizeX + epsilon;
@@ -54,11 +60,14 @@ void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
boundary[3] = y + sizeY + epsilon;
}
bool SphericalGrid::Cell::compareOccludersByShallowestPoint (const SphericalGrid::OccluderData* a, const SphericalGrid::OccluderData* b) {
bool SphericalGrid::Cell::compareOccludersByShallowestPoint(const SphericalGrid::OccluderData *a,
const SphericalGrid::OccluderData *b)
{
return a->shallowest < b->shallowest;
}
void SphericalGrid::Cell::indexPolygons() {
void SphericalGrid::Cell::indexPolygons()
{
// Sort occluders by their shallowest points.
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
}
@@ -66,30 +75,29 @@ void SphericalGrid::Cell::indexPolygons() {
// Iterator
//////////////////
SphericalGrid::Iterator::Iterator (SphericalGrid& grid, Vec3r& center, real epsilon)
: _target(SphericalGrid::Transform::sphericalProjection(center)),
_foundOccludee(false)
SphericalGrid::Iterator::Iterator(SphericalGrid& grid, Vec3r& center, real epsilon)
: _target(SphericalGrid::Transform::sphericalProjection(center)), _foundOccludee(false)
{
// Find target cell
_cell = grid.findCell(_target);
#if sphericalgridlogging == 1
#if SPHERICAL_GRID_LOGGING
cout << "Searching for occluders of edge centered at " << _target << " in cell ["
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
#endif
// Set iterator
_current = _cell->faces.begin();
}
SphericalGrid::Iterator::~Iterator () {}
SphericalGrid::Iterator::~Iterator() {}
// SphericalGrid
/////////////////
SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI)
: _viewpoint(viewpoint),
_enableQI(enableQI)
SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
Vec3r& viewpoint, bool enableQI)
: _viewpoint(viewpoint), _enableQI(enableQI)
{
cout << "Generate Cell structure" << endl;
// Generate Cell structure
@@ -103,10 +111,10 @@ SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& densit
cout << "Ready to use SphericalGrid" << endl;
}
SphericalGrid::~SphericalGrid () {
}
SphericalGrid::~SphericalGrid() {}
void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap) {
void SphericalGrid::assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap)
{
_cellSize = density.cellSize();
_cellsX = density.cellsX();
_cellsY = density.cellsY();
@@ -115,20 +123,19 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
// Now allocate the cell table and fill it with default (empty) cells
_cells.resize(_cellsX * _cellsY);
for ( cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
(*i) = NULL;
}
// Identify cells that will be used, and set the dimensions for each
ViewMap::fedges_container& fedges = viewMap->FEdges();
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f ) {
if ( (*f)->isInImage() ) {
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
if ((*f)->isInImage()) {
Vec3r point = SphericalGrid::Transform::sphericalProjection((*f)->center3d());
unsigned i, j;
getCellCoordinates(point, i, j);
if ( _cells[i * _cellsY + j] == NULL ) {
if (_cells[i * _cellsY + j] == NULL) {
// This is an uninitialized cell
real x, y, width, height;
x = _cellOrigin[0] + _cellSize * i;
@@ -145,22 +152,23 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
}
}
void SphericalGrid::distributePolygons (OccluderSource& source) {
void SphericalGrid::distributePolygons(OccluderSource& source)
{
unsigned long nFaces = 0;
unsigned long nKeptFaces = 0;
for ( source.begin(); source.isValid(); source.next() ) {
OccluderData* occluder = NULL;
for (source.begin(); source.isValid(); source.next()) {
OccluderData *occluder = NULL;
try {
if ( insertOccluder(source, occluder) ) {
if (insertOccluder(source, occluder)) {
_faces.push_back(occluder);
++nKeptFaces;
}
} catch (...) {
// If an exception was thrown, _faces.push_back() cannot have succeeded.
// occluder is not owned by anyone, and must be deleted.
// If the exception was thrown before or during new OccluderData(), then
}
catch (...) {
// If an exception was thrown, _faces.push_back() cannot have succeeded. Occluder is not owned by anyone,
// and must be deleted. If the exception was thrown before or during new OccluderData(), then
// occluder is NULL, and this delete is harmless.
delete occluder;
throw;
@@ -170,46 +178,53 @@ void SphericalGrid::distributePolygons (OccluderSource& source) {
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
}
void SphericalGrid::reorganizeCells () {
void SphericalGrid::reorganizeCells()
{
// Sort the occluders by shallowest point
for ( vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
if ( *i != NULL ) {
for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
if (*i != NULL) {
(*i)->indexPolygons();
}
}
}
void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) {
void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
{
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
}
SphericalGrid::Cell* SphericalGrid::findCell(const Vec3r& point) {
SphericalGrid::Cell *SphericalGrid::findCell(const Vec3r& point)
{
unsigned x, y;
getCellCoordinates(point, x, y);
return _cells[x * _cellsY + y];
}
bool SphericalGrid::orthographicProjection () const {
bool SphericalGrid::orthographicProjection() const
{
return false;
}
const Vec3r& SphericalGrid::viewpoint() const {
const Vec3r& SphericalGrid::viewpoint() const
{
return _viewpoint;
}
bool SphericalGrid::enableQI() const {
bool SphericalGrid::enableQI() const
{
return _enableQI;
}
SphericalGrid::Transform::Transform () : GridHelpers::Transform() {
}
SphericalGrid::Transform::Transform () : GridHelpers::Transform() {}
Vec3r SphericalGrid::Transform::operator() (const Vec3r& point) const {
Vec3r SphericalGrid::Transform::operator()(const Vec3r& point) const
{
return sphericalProjection(point);
}
Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) {
Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M)
{
Vec3r newPoint;
newPoint[0] = ::atan(M[0] / M[2]);
@@ -218,4 +233,3 @@ Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) {
return newPoint;
}

View File

@@ -1,78 +1,86 @@
//
// Filename : SphericalGrid.h
// Author(s) : Alexander Beels
// Purpose : Class to define a cell grid surrounding
// the projected image of a scene
// Date of creation : 2010-12-19
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_SPHERICAL_GRID_H__
#define __FREESTYLE_SPHERICAL_GRID_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/SphericalGrid.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2010-12-19
*/
#ifndef SPHERICALGRID_H
#define SPHERICALGRID_H
#define SPHERICAL_GRID_LOGGING FALSE
#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 <deque>
#include "GridDensityProvider.h"
#include "OccluderSource.h"
#include "ViewMap.h"
#include "../winged_edge/WEdge.h"
#include "../geometry/Polygon.h"
#include "../system/PointerSequence.h"
#include "../geometry/BBox.h"
#include "../geometry/GridHelpers.h"
#include "OccluderSource.h"
#include "GridDensityProvider.h"
#include "../system/PointerSequence.h"
#include "../winged_edge/WEdge.h"
class SphericalGrid
{
public:
// Helper classes
struct OccluderData {
struct OccluderData
{
explicit OccluderData (OccluderSource& source, Polygon3r& p);
Polygon3r poly;
Polygon3r cameraSpacePolygon;
real shallowest, deepest;
// N.B. We could, of course, store face in poly's userdata
// member, like the old ViewMapBuilder code does. However,
// code comments make it clear that userdata is deprecated,
// so we avoid the temptation to save 4 or 8 bytes.
WFace* face;
// N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
// However, code comments make it clear that userdata is deprecated, so we avoid the temptation to save
// 4 or 8 bytes.
WFace *face;
};
private:
struct Cell {
struct Cell
{
// Can't store Cell in a vector without copy and assign
//Cell(const Cell& other);
//Cell& operator= (const Cell& other);
//Cell& operator=(const Cell& other);
explicit Cell ();
~Cell ();
explicit Cell();
~Cell();
static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b);
static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
void setDimensions(real x, real y, real sizeX, real sizeY);
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
@@ -84,43 +92,37 @@ private:
};
public:
/*****
/*! Iterator needs to allow the user to avoid full 3D comparison in two cases:
*
* (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
*
* (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
*
* In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an occludee
* candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder could
* possibly be a better occludee.
*/
Iterator needs to allow the user to avoid full 3D comparison in
two cases:
(1) Where (*current)->deepest < target[2], where the occluder is
unambiguously in front of the target point.
(2) Where (*current)->shallowest > target[2], where the occluder
is unambiguously in back of the target point.
In addition, when used by OptimizedFindOccludee, Iterator should
stop iterating as soon as it has an occludee candidate and
(*current)->shallowest > candidate[2], because at that point forward
no new occluder could possibly be a better occludee.
*****/
class Iterator {
class Iterator
{
public:
// epsilon is not used in this class, but other grids with the same interface may need an epsilon
explicit Iterator (SphericalGrid& grid, Vec3r& center, real epsilon=1e-06);
~Iterator ();
void initBeforeTarget ();
void initAfterTarget ();
void nextOccluder ();
void nextOccludee ();
explicit Iterator(SphericalGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
~Iterator();
void initBeforeTarget();
void initAfterTarget();
void nextOccluder();
void nextOccludee();
bool validBeforeTarget();
bool validAfterTarget();
WFace* getWFace() const;
Polygon3r* getCameraSpacePolygon();
WFace *getWFace() const;
Polygon3r *getCameraSpacePolygon();
void reportDepth(Vec3r origin, Vec3r u, real t);
private:
bool testOccluder(bool wantOccludee);
void markCurrentOccludeeCandidate(real depth);
Cell* _cell;
Cell *_cell;
Vec3r _target;
bool _foundOccludee;
real _occludeeDepth;
@@ -128,33 +130,35 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate;
};
class Transform : public GridHelpers::Transform {
class Transform : public GridHelpers::Transform
{
public:
explicit Transform ();
explicit Transform (Transform& other);
Vec3r operator() (const Vec3r& point) const;
explicit Transform();
explicit Transform(Transform& other);
Vec3r operator()(const Vec3r& point) const;
static Vec3r sphericalProjection(const Vec3r& M);
};
private:
// Prevent implicit copies and assignments.
SphericalGrid(const SphericalGrid& other);
SphericalGrid& operator= (const SphericalGrid& other);
SphericalGrid& operator=(const SphericalGrid& other);
public:
explicit SphericalGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
explicit SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
Vec3r& viewpoint, bool enableQI);
virtual ~SphericalGrid();
// Generate Cell structure
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
// Fill Cells
void distributePolygons(OccluderSource& source);
// Insert one polygon into each matching cell,
// return true if any cell consumes the polygon
// Insert one polygon into each matching cell, return true if any cell consumes the polygon
bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
// Sort occluders in each cell
void reorganizeCells();
Cell* findCell(const Vec3r& point);
Cell *findCell(const Vec3r& point);
// Accessors:
bool orthographicProjection() const;
@@ -176,51 +180,52 @@ private:
bool _enableQI;
};
inline void SphericalGrid::Iterator::initBeforeTarget () {
inline void SphericalGrid::Iterator::initBeforeTarget()
{
_current = _cell->faces.begin();
while ( _current != _cell->faces.end() && ! testOccluder(false) ) {
while (_current != _cell->faces.end() && !testOccluder(false)) {
++_current;
}
}
inline void SphericalGrid::Iterator::initAfterTarget () {
if ( _foundOccludee ) {
#if sphericalgridlogging == 1
inline void SphericalGrid::Iterator::initAfterTarget()
{
if (_foundOccludee) {
#if SPHERICAL_GRID_LOGGING
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
#endif
_current = _occludeeCandidate;
return;
}
#if sphericalgridlogging == 1
#if SPHERICAL_GRID_LOGGING
std::cout << "\tStarting occludee search from current position" << std::endl;
#endif
while ( _current != _cell->faces.end() && ! testOccluder(true) ) {
while (_current != _cell->faces.end() && !testOccluder(true)) {
++_current;
}
}
inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
inline bool SphericalGrid::Iterator::testOccluder(bool wantOccludee)
{
// End-of-list is not even a valid iterator position
if ( _current == _cell->faces.end() ) {
// Returning true seems strange, but it will break us out of whatever loop
// is calling testOccluder, and _current=_cell->face.end() will make
// the calling routine give up.
if (_current == _cell->faces.end()) {
// Returning true seems strange, but it will break us out of whatever loop is calling testOccluder, and
// _current=_cell->face.end() will make the calling routine give up.
return true;
}
#if sphericalgridlogging == 1
#if SPHERICAL_GRID_LOGGING
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
for ( unsigned i = 1; i < (*_current)->poly.getVertices().size(); ++i ) {
for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
std::cout << ", " << (*_current)->poly.getVertices()[i];
}
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
#endif
// If we have an occluder candidate and we are unambiguously after it, abort
if ( _foundOccludee && (*_current)->shallowest > _occludeeDepth ) {
#if sphericalgridlogging == 1
if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
#if SPHERICAL_GRID_LOGGING
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
#endif
_current = _cell->faces.end();
@@ -230,16 +235,17 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
}
// Specific continue or stop conditions when searching for each type
if ( wantOccludee ) {
if ( (*_current)->deepest < _target[2] ) {
#if sphericalgridlogging == 1
if (wantOccludee) {
if ((*_current)->deepest < _target[2]) {
#if SPHERICAL_GRID_LOGGING
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
#endif
return false;
}
} else {
if ( (*_current)->shallowest > _target[2] ) {
#if sphericalgridlogging == 1
}
else {
if ((*_current)->shallowest > _target[2]) {
#if SPHERICAL_GRID_LOGGING
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
#endif
return true;
@@ -251,70 +257,73 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
// Check to see if target is in the 2D bounding box
Vec3r bbMin, bbMax;
(*_current)->poly.getBBox(bbMin, bbMax);
if ( _target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1] ) {
#if sphericalgridlogging == 1
if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
#if SPHERICAL_GRID_LOGGING
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
#endif
return false;
}
// We've done all the corner cutting we can.
// Let the caller work out whether or not
// the geometry is correct.
// We've done all the corner cutting we can. Let the caller work out whether or not the geometry is correct.
return true;
}
inline void SphericalGrid::Iterator::reportDepth (Vec3r origin, Vec3r u, real t) {
// The reported depth is the length of a ray in camera space
// We need to convert it into the distance from viewpoint
// If origin is the viewpoint, depth == t
// A future optimization could allow the caller to tell us if origin is viewponit or target,
// at the cost of changing the OptimizedGrid API.
inline void SphericalGrid::Iterator::reportDepth(Vec3r origin, Vec3r u, real t)
{
// The reported depth is the length of a ray in camera space. We need to convert it into the distance from viewpoint
// If origin is the viewpoint, depth == t. A future optimization could allow the caller to tell us if origin is
// viewponit or target, at the cost of changing the OptimizedGrid API.
real depth = (origin + u * t).norm();
#if sphericalgridlogging == 1
#if SPHERICAL_GRID_LOGGING
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
#endif
if ( depth > _target[2] ) {
#if sphericalgridlogging == 1
if (depth > _target[2]) {
#if SPHERICAL_GRID_LOGGING
std::cout << " is deeper than target" << std::endl;
#endif
// If the current occluder is the best occludee so far, save it.
if ( ! _foundOccludee || _occludeeDepth > depth ) {
if (! _foundOccludee || _occludeeDepth > depth) {
markCurrentOccludeeCandidate(depth);
}
} else {
#if sphericalgridlogging == 1
}
else {
#if SPHERICAL_GRID_LOGGING
std::cout << std::endl;
#endif
}
}
inline void SphericalGrid::Iterator::nextOccluder () {
if ( _current != _cell->faces.end() ) {
inline void SphericalGrid::Iterator::nextOccluder()
{
if (_current != _cell->faces.end()) {
do {
++_current;
} while ( _current != _cell->faces.end() && ! testOccluder(false) );
} while (_current != _cell->faces.end() && !testOccluder(false));
}
}
inline void SphericalGrid::Iterator::nextOccludee () {
if ( _current != _cell->faces.end() ) {
inline void SphericalGrid::Iterator::nextOccludee()
{
if (_current != _cell->faces.end()) {
do {
++_current;
} while ( _current != _cell->faces.end() && ! testOccluder(true) );
} while (_current != _cell->faces.end() && !testOccluder(true));
}
}
inline bool SphericalGrid::Iterator::validBeforeTarget () {
inline bool SphericalGrid::Iterator::validBeforeTarget()
{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
}
inline bool SphericalGrid::Iterator::validAfterTarget () {
inline bool SphericalGrid::Iterator::validAfterTarget()
{
return _current != _cell->faces.end();
}
inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
#if sphericalgridlogging == 1
inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth)
{
#if SPHERICAL_GRID_LOGGING
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
#endif
_occludeeCandidate = _current;
@@ -322,18 +331,18 @@ inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
_foundOccludee = true;
}
inline WFace* SphericalGrid::Iterator::getWFace() const {
inline WFace *SphericalGrid::Iterator::getWFace() const
{
return (*_current)->face;
}
inline Polygon3r* SphericalGrid::Iterator::getCameraSpacePolygon() {
inline Polygon3r *SphericalGrid::Iterator::getCameraSpacePolygon()
{
return &((*_current)->cameraSpacePolygon);
}
inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
: poly(p),
cameraSpacePolygon(source.getCameraSpacePolygon()),
face(source.getWFace())
: poly(p), cameraSpacePolygon(source.getCameraSpacePolygon()), face(source.getWFace())
{
const Vec3r viewpoint(0, 0, 0);
// Get the point on the camera-space polygon that is closest to the viewpoint
@@ -343,17 +352,18 @@ inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygo
// Get the point on the camera-space polygon that is furthest from the viewpoint
// deepest is the distance from the viewpoint to that point
deepest = cameraSpacePolygon.getVertices()[2].norm();
for ( unsigned i = 0; i < 2; ++i ) {
for (unsigned int i = 0; i < 2; ++i) {
real t = cameraSpacePolygon.getVertices()[i].norm();
if ( t > deepest ) {
if (t > deepest) {
deepest = t;
}
}
}
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
if ( GridHelpers::insideProscenium (boundary, poly) ) {
if ( occluder == NULL) {
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
{
if (GridHelpers::insideProscenium (boundary, poly)) {
if (occluder == NULL) {
// Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
// or automatically by SphericalGrid::_faces;
occluder = new OccluderData(source, poly);
@@ -362,7 +372,8 @@ inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3
}
}
inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) {
inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
{
Polygon3r& poly(source.getGridSpacePolygon());
occluder = NULL;
@@ -373,9 +384,9 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
getCellCoordinates(bbMin, startX, startY);
getCellCoordinates(bbMax, endX, endY);
for ( unsigned i = startX; i <= endX; ++i ) {
for ( unsigned j = startY; j <= endY; ++j ) {
if ( _cells[i * _cellsY + j] != NULL ) {
for (unsigned int i = startX; i <= endX; ++i) {
for (unsigned int j = startY; j <= endY; ++j) {
if (_cells[i * _cellsY + j] != NULL) {
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
}
}
@@ -384,5 +395,4 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
return occluder != NULL;
}
#endif // SPHERICALGRID_H
#endif // __FREESTYLE_SPHERICAL_GRID_H__

View File

@@ -1,267 +1,298 @@
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/freestyle/intern/view_map/SteerbaleViewMap.cpp
* \ingroup freestyle
* \brief Convenient access to the steerable ViewMap to which any element of the ViewMap belongs to.
* \author Stephane Grabli
* \date 01/07/2003
*/
#include <math.h>
//soc #include <qimage.h>
//soc #include <qstring.h>
#include <sstream>
#include "Silhouette.h"
#include "SteerableViewMap.h"
#include "../geometry/Geom.h"
#include "../image/ImagePyramid.h"
#include "../image/Image.h"
#include <math.h>
#include "../geometry/Geom.h"
using namespace Geometry;
//soc #include <qstring.h>
//soc #include <qimage.h>
#include <sstream>
extern "C" {
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
}
SteerableViewMap::SteerableViewMap(unsigned int nbOrientations){
_nbOrientations = nbOrientations;
_bound = cos(M_PI/(float)_nbOrientations);
for(unsigned i=0; i<_nbOrientations; ++i){
_directions.push_back(Vec2d(cos((float)i*M_PI/(float)_nbOrientations), sin((float)i*M_PI/(float)_nbOrientations)));
}
Build();
using namespace Geometry;
SteerableViewMap::SteerableViewMap(unsigned int nbOrientations)
{
_nbOrientations = nbOrientations;
_bound = cos(M_PI/(float)_nbOrientations);
for (unsigned int i = 0; i < _nbOrientations; ++i) {
_directions.push_back(Vec2d(cos((float)i * M_PI / (float)_nbOrientations),
sin((float)i * M_PI / (float)_nbOrientations)));
}
Build();
}
void SteerableViewMap::Build(){
_imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM
memset((_imagesPyramids),0,(_nbOrientations+1)*sizeof(ImagePyramid*));
void SteerableViewMap::Build()
{
_imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
memset((_imagesPyramids), 0, (_nbOrientations + 1) * sizeof(ImagePyramid *));
}
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){
_nbOrientations = iBrother._nbOrientations;
unsigned i;
_bound = iBrother._bound;
_directions = iBrother._directions;
_mapping = iBrother._mapping;
_imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM
for(i=0;i<_nbOrientations+1;++i)
_imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother)
{
_nbOrientations = iBrother._nbOrientations;
unsigned int i;
_bound = iBrother._bound;
_directions = iBrother._directions;
_mapping = iBrother._mapping;
_imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
for (i = 0; i < _nbOrientations + 1; ++i)
_imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
}
SteerableViewMap::~SteerableViewMap(){
Clear();
SteerableViewMap::~SteerableViewMap()
{
Clear();
}
void SteerableViewMap::Clear(){
unsigned i;
if(_imagesPyramids){
for(i=0; i<=_nbOrientations; ++i){
if(_imagesPyramids[i])
delete (_imagesPyramids)[i];
}
delete [] _imagesPyramids;
_imagesPyramids = 0;
}
if(!_mapping.empty()){
for(map<unsigned int, double*>::iterator m=_mapping.begin(), mend=_mapping.end();
m!=mend;
++m){
delete [] (*m).second;
}
_mapping.clear();
}
void SteerableViewMap::Clear()
{
unsigned int i;
if (_imagesPyramids) {
for (i = 0; i <= _nbOrientations; ++i) {
if (_imagesPyramids[i])
delete (_imagesPyramids)[i];
}
delete[] _imagesPyramids;
_imagesPyramids = 0;
}
if (!_mapping.empty()) {
for (map<unsigned int, double*>::iterator m = _mapping.begin(), mend = _mapping.end(); m != mend; ++m) {
delete[] (*m).second;
}
_mapping.clear();
}
}
void SteerableViewMap::Reset(){
Clear();
Build();
void SteerableViewMap::Reset()
{
Clear();
Build();
}
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i){
double dotp = fabs(dir*_directions[i]);
if(dotp < _bound)
return 0;
if(dotp>1)
dotp = 1;
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i)
{
double dotp = fabs(dir * _directions[i]);
if (dotp < _bound)
return 0.0;
if (dotp > 1.0)
dotp = 1.0;
return cos((float)_nbOrientations/2.0*acos(dotp));
return cos((float)_nbOrientations / 2.0 * acos(dotp));
}
double * SteerableViewMap::AddFEdge(FEdge *iFEdge){
unsigned i;
unsigned id = iFEdge->getId().getFirst();
map<unsigned int, double* >::iterator o = _mapping.find(id);
if(o!=_mapping.end()){
return (*o).second;
}
double * res = new double[_nbOrientations];
for(i=0; i<_nbOrientations; ++i){
res[i] = 0;
}
Vec3r o2d3 = iFEdge->orientation2d();
Vec2r o2d2(o2d3.x(), o2d3.y());
real norm = o2d2.norm();
if(norm < 1e-6){
return res;
}
o2d2/=norm;
double *SteerableViewMap::AddFEdge(FEdge *iFEdge)
{
unsigned i;
unsigned id = iFEdge->getId().getFirst();
map<unsigned int, double* >::iterator o = _mapping.find(id);
if (o != _mapping.end()) {
return (*o).second;
}
double *res = new double[_nbOrientations];
for (i = 0; i < _nbOrientations; ++i) {
res[i] = 0.0;
}
Vec3r o2d3 = iFEdge->orientation2d();
Vec2r o2d2(o2d3.x(), o2d3.y());
real norm = o2d2.norm();
if (norm < 1.0e-6) {
return res;
}
o2d2 /= norm;
for(i=0; i<_nbOrientations; ++i){
res[i] = ComputeWeight(o2d2, i);
}
_mapping[id] = res;
return res;
for (i = 0; i < _nbOrientations; ++i) {
res[i] = ComputeWeight(o2d2, i);
}
_mapping[id] = res;
return res;
}
unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){
Vec2f dir(orient);
//soc unsigned res = 0;
real norm = dir.norm();
if(norm < 1e-6){
return _nbOrientations+1;
}
dir/=norm;
double maxw = 0.f;
unsigned winner = _nbOrientations+1;
for(unsigned i=0; i<_nbOrientations; ++i){
double w = ComputeWeight(dir, i);
if(w>maxw){
maxw = w;
winner = i;
}
}
return winner;
unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient)
{
Vec2f dir(orient);
//soc unsigned res = 0;
real norm = dir.norm();
if (norm < 1.0e-6) {
return _nbOrientations + 1;
}
dir /= norm;
double maxw = 0.0f;
unsigned winner = _nbOrientations + 1;
for (unsigned int i = 0; i < _nbOrientations; ++i) {
double w = ComputeWeight(dir, i);
if (w > maxw) {
maxw = w;
winner = i;
}
}
return winner;
}
unsigned SteerableViewMap::getSVMNumber(unsigned id){
map<unsigned int, double* >::iterator o = _mapping.find(id);
if(o!=_mapping.end()){
double* wvalues= (*o).second;
double maxw = 0.f;
unsigned winner = _nbOrientations+1;
for(unsigned i=0; i<_nbOrientations; ++i){
double w = wvalues[i];
if(w>maxw){
maxw = w;
winner = i;
}
}
return winner;
}
return _nbOrientations+1;
unsigned SteerableViewMap::getSVMNumber(unsigned id)
{
map<unsigned int, double* >::iterator o = _mapping.find(id);
if (o != _mapping.end()) {
double *wvalues = (*o).second;
double maxw = 0.0;
unsigned winner = _nbOrientations + 1;
for (unsigned i = 0; i < _nbOrientations; ++i) {
double w = wvalues[i];
if (w > maxw) {
maxw = w;
winner = i;
}
}
return winner;
}
return _nbOrientations + 1;
}
void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma){
for(unsigned i=0; i<=_nbOrientations; ++i){
ImagePyramid * svm = (_imagesPyramids)[i];
if(svm)
delete svm;
if(copy)
svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma);
else
svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma);
_imagesPyramids[i] = svm;
}
void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma)
{
for (unsigned int i = 0; i <= _nbOrientations; ++i) {
ImagePyramid *svm = (_imagesPyramids)[i];
if (svm)
delete svm;
if (copy)
svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma);
else
svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma);
_imagesPyramids[i] = svm;
}
}
float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y){
ImagePyramid *pyramid = _imagesPyramids[iOrientation];
if(pyramid==0){
cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
return 0;
}
if((x<0) || (x>=pyramid->width()) || (y<0) || (y>=pyramid->height()))
return 0;
//float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)*255.f;
float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)/32.f; // we encode both the directionality and the lines counting on 8 bits
// (because of frame buffer). Thus, we allow until 8 lines to pass through
// the same pixel, so that we can discretize the Pi/_nbOrientations angle into
// 32 slices. Therefore, for example, in the vertical direction, a vertical line
// will have the value 32 on each pixel it passes through.
return v;
float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y)
{
ImagePyramid *pyramid = _imagesPyramids[iOrientation];
if (pyramid == 0) {
cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
return 0;
}
if ((x < 0) || (x >= pyramid->width()) || (y < 0) || (y >= pyramid->height()))
return 0;
//float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) * 255.0f;
// We encode both the directionality and the lines counting on 8 bits (because of frame buffer). Thus, we allow
// until 8 lines to pass through the same pixel, so that we can discretize the Pi/_nbOrientations angle into
// 32 slices. Therefore, for example, in the vertical direction, a vertical line will have the value 32 on
// each pixel it passes through.
float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) / 32.0f;
return v;
}
float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y){
return readSteerableViewMapPixel(_nbOrientations,iLevel,x,y);
float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y)
{
return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y);
}
unsigned int SteerableViewMap::getNumberOfPyramidLevels() const{
if(_imagesPyramids[0])
return _imagesPyramids[0]->getNumberOfLevels();
return 0;
unsigned int SteerableViewMap::getNumberOfPyramidLevels() const
{
if (_imagesPyramids[0])
return _imagesPyramids[0]->getNumberOfLevels();
return 0;
}
void SteerableViewMap::saveSteerableViewMap() const {
for(unsigned i=0; i<=_nbOrientations; ++i){
if(_imagesPyramids[i] == 0){
cerr << "SteerableViewMap warning: orientation " << i <<" of steerable View Map whas not been computed yet" << endl;
continue;
}
int ow = _imagesPyramids[i]->width(0);
int oh = _imagesPyramids[i]->height(0);
void SteerableViewMap::saveSteerableViewMap() const
{
for (unsigned int i = 0; i <= _nbOrientations; ++i) {
if (_imagesPyramids[i] == 0) {
cerr << "SteerableViewMap warning: orientation " << i
<< " of steerable View Map whas not been computed yet" << endl;
continue;
}
int ow = _imagesPyramids[i]->width(0);
int oh = _imagesPyramids[i]->height(0);
//soc QString base("SteerableViewMap");
string base("SteerableViewMap");
stringstream filename;
//soc QString base("SteerableViewMap");
string base("SteerableViewMap");
stringstream filename;
for(int j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ //soc
float coeff = 1;//1/255.f; //100*255;//*pow(2,j);
//soc QImage qtmp(ow, oh, QImage::Format_RGB32);
ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
int rowbytes = ow*4;
char *pix;
for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc
float coeff = 1.0f; // 1 / 255.0f; // 100 * 255; // * pow(2, j);
//soc QImage qtmp(ow, oh, QImage::Format_RGB32);
ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
int rowbytes = ow * 4;
char *pix;
for(int y=0;y<oh;++y){ //soc
for(int x=0;x<ow;++x){ //soc
int c = (int)(coeff*_imagesPyramids[i]->pixel(x,y,j));
if(c>255)
c=255;
//int c = (int)(_imagesPyramids[i]->pixel(x,y,j));
for (int y = 0; y < oh; ++y) { //soc
for (int x = 0; x < ow; ++x) { //soc
int c = (int)(coeff * _imagesPyramids[i]->pixel(x, y, j));
if (c > 255)
c = 255;
//int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
//soc qtmp.setPixel(x,y,qRgb(c,c,c));
pix = (char*)ibuf->rect + y*rowbytes + x*4;
pix[0] = pix [1] = pix[2] = c;
}
}
//soc qtmp.setPixel(x, y, qRgb(c, c, c));
pix = (char*)ibuf->rect + y * rowbytes + x * 4;
pix[0] = pix [1] = pix[2] = c;
}
}
//soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
filename << base;
filename << i << "-" << j << ".png";
ibuf->ftype= PNG;
IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0);
}
// QString base("SteerableViewMap");
// for(unsigned j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){
// GrayImage * img = _imagesPyramids[i]->getLevel(j);
// int ow = img->width();
// int oh = img->height();
// float coeff = 1; //100*255;//*pow(2,j);
// QImage qtmp(ow, oh, 32);
// for(unsigned y=0;y<oh;++y){
// for(unsigned x=0;x<ow;++x){
// int c = (int)(coeff*img->pixel(x,y));
// if(c>255)
// c=255;
// //int c = (int)(_imagesPyramids[i]->pixel(x,y,j));
// qtmp.setPixel(x,y,qRgb(c,c,c));
// }
// }
// qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
// }
//
}
//soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
filename << base;
filename << i << "-" << j << ".png";
ibuf->ftype = PNG;
IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0);
}
#if 0
QString base("SteerableViewMap");
for (unsigned j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) {
GrayImage *img = _imagesPyramids[i]->getLevel(j);
int ow = img->width();
int oh = img->height();
float coeff = 1.0f; // 100 * 255; // * pow(2, j);
QImage qtmp(ow, oh, 32);
for (unsigned int y = 0; y < oh; ++y) {
for (unsigned int x = 0; x < ow; ++x) {
int c = (int)(coeff * img->pixel(x, y));
if (c > 255)
c = 255;
//int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
qtmp.setPixel(x, y, qRgb(c, c, c));
}
}
qtmp.save(base + QString::number(i) + "-" + QString::number(j) + ".png", "PNG");
}
#endif
}
}

View File

@@ -1,38 +1,46 @@
//
// Filename : SteerbaleViewMap.h
// Author(s) : Stephane Grabli
// Purpose : Convenient access to the steerable ViewMap
// to which any element of the ViewMap belongs to.
// Date of creation : 01/07/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_STEERABLE_VIEW_MAP_H__
#define __FREESTYLE_STEERABLE_VIEW_MAP_H__
//
// 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
/** \file blender/freestyle/intern/view_map/SteerbaleViewMap.h
* \ingroup freestyle
* \brief Convenient access to the steerable ViewMap to which any element of the ViewMap belongs to.
* \author Stephane Grabli
* \date 01/07/2003
*/
#include <map>
#include "../system/FreestyleConfig.h"
#include "../geometry/Geom.h"
#include "../system/FreestyleConfig.h"
using namespace Geometry;
using namespace std;
@@ -40,114 +48,107 @@ using namespace std;
class FEdge;
class ImagePyramid;
class GrayImage;
/*! This class checks for every FEdge in which steerable
* it belongs and stores the mapping allowing to retrieve
* this information from the FEdge Id
*/
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
double _bound; // cos(Pi/N)
vector<Vec2d> _directions;
/*! 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:
// 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:
SteerableViewMap(unsigned int nbOrientations = 4);
SteerableViewMap(const SteerableViewMap& iBrother);
virtual ~SteerableViewMap();
SteerableViewMap(unsigned int nbOrientations = 4);
SteerableViewMap(const SteerableViewMap& iBrother);
virtual ~SteerableViewMap();
/*! Resets everything */
virtual void Reset();
/*! Resets everything */
virtual void Reset();
/*! Adds a FEdge to steerable VM.
* Returns the nbOrientations weigths corresponding to
* the FEdge contributions to the nbOrientations directional maps.
*/
double* AddFEdge(FEdge *iFEdge);
/*! Adds a FEdge to steerable VM.
* Returns the nbOrientations weigths corresponding to the FEdge contributions to the nbOrientations
* directional maps.
*/
double *AddFEdge(FEdge *iFEdge);
/*! Compute the weight of direction dir for orientation iNOrientation */
double ComputeWeight(const Vec2d& dir, unsigned iNOrientation);
/*! Compute the weight of direction dir for orientation iNOrientation */
double ComputeWeight(const Vec2d& dir, unsigned iNOrientation);
/*! Returns the number of the SVM to which a direction belongs
* to.
* \param dir
* The direction
*/
unsigned getSVMNumber(const Vec2f& dir);
/*! Returns the number of the SVM to which a direction belongs to.
* \param dir
* The direction
*/
unsigned getSVMNumber(const Vec2f& dir);
/*! Returns the number of the SVM to which a FEdge belongs
* most.
* \param id
* The First element of the Id struct of the FEdge
* we're intersted in.
*/
unsigned getSVMNumber(unsigned id);
/*! Returns the number of the SVM to which a FEdge belongs most.
* \param id
* The First element of the Id struct of the FEdge we're intersted in.
*/
unsigned getSVMNumber(unsigned id);
/*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images
* of the steerable viewmap.
* \param steerableBases
* The _nbOrientations+1 images constituing the basis for the steerable
* pyramid.
* \param copy
* If false, the data is not duplicated, and Canvas deals
* with the memory management of these _nbOrientations+1 images. If true, data
* is copied, and it's up to the caller to delete the images.
* \params iNbLevels
* The number of levels desired for each pyramid.
* If iNbLevels == 0, the complete pyramid is built.
* \param iSigma
* The sigma that will be used for the gaussian blur
*/
void buildImagesPyramids(GrayImage **steerableBases, bool copy = false, unsigned iNbLevels=4, float iSigma = 1.f);
/*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images of the steerable viewmap.
* \param steerableBases
* The _nbOrientations+1 images constituing the basis for the steerable pyramid.
* \param copy
* If false, the data is not duplicated, and Canvas deals with the memory management of these
* _nbOrientations+1 images. If true, data is copied, and it's up to the caller to delete the images.
* \params iNbLevels
* The number of levels desired for each pyramid.
* If iNbLevels == 0, the complete pyramid is built.
* \param iSigma
* The sigma that will be used for the gaussian blur
*/
void buildImagesPyramids(GrayImage **steerableBases, bool copy = false, unsigned iNbLevels = 4,
float iSigma = 1.0f);
/*! Reads a pixel value in one of the VewMap density steerable pyramids.
* Returns a value between 0 and 1.
* \param iOrientation
* the number telling which orientation we need to check.
* There are _nbOrientations+1 oriented ViewMaps:
* 0 -> the ViewMap containing every horizontal lines
* 1 -> the ViewMap containing every lines whose orientation is around PI/4
* 2 -> the ViewMap containing every vertical lines
* 3 -> the ViewMap containing every lines whose orientation is around 3PI/4
* 4 -> the complete ViewMap
* \param iLevel
* The level of the pyramid we want to read
* \param x
* The abscissa of the desired pixel specified in level0 coordinate
* system. The origin is the lower left corner.
* \param y
* The ordinate of the desired pixel specified in level0 coordinate
* system. The origin is the lower left corner.
*/
float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y);
/*! Reads a pixel value in one of the VewMap density steerable pyramids.
* Returns a value between 0 and 1.
* \param iOrientation
* the number telling which orientation we need to check.
* There are _nbOrientations+1 oriented ViewMaps:
* 0 -> the ViewMap containing every horizontal lines
* 1 -> the ViewMap containing every lines whose orientation is around PI/4
* 2 -> the ViewMap containing every vertical lines
* 3 -> the ViewMap containing every lines whose orientation is around 3PI/4
* 4 -> the complete ViewMap
* \param iLevel
* The level of the pyramid we want to read
* \param x
* The abscissa of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
* \param y
* The ordinate of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
*/
float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y);
/*! Reads a pixel in the one of the level of the
* pyramid containing the images of the complete
* ViewMap.
* Returns a value between 0 and 1.
* Equivalent to : readSteerableViewMapPixel(nbOrientations, x,y)
*/
float readCompleteViewMapPixel(int iLevel, int x, int y);
/*! Reads a pixel in the one of the level of the pyramid containing the images of the complete ViewMap.
* Returns a value between 0 and 1.
* Equivalent to : readSteerableViewMapPixel(nbOrientations, x, y)
*/
float readCompleteViewMapPixel(int iLevel, int x, int y);
/*! Returns the number of levels in the pyramids */
unsigned int getNumberOfPyramidLevels() const;
/*! Returns the number of levels in the pyramids */
unsigned int getNumberOfPyramidLevels() const;
/*! Returns the number of orientations */
unsigned int getNumberOfOrientations() const{
return _nbOrientations;
}
/*! Returns the number of orientations */
unsigned int getNumberOfOrientations() const
{
return _nbOrientations;
}
/*! for debug purposes */
void saveSteerableViewMap() const ;
/*! for debug purposes */
void saveSteerableViewMap() const;
protected:
void Clear();
void Build();
void Clear();
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
// Author(s) : Stephane Grabli
// Purpose : Class to build view edges and the underlying chains
// of feature edges...
// Date of creation : 27/10/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
#define __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
* \ingroup freestyle
* \brief Class to build view edges and the underlying chains of feature edges...
* \author Stephane Grabli
* \date 27/10/2003
*/
#ifndef VIEWEDGEXBUILDER_H
# define VIEWEDGEXBUILDER_H
#include <map>
#include <utility>
#include <vector>
# include <map>
# include <utility>
# include <vector>
#if 0 // soc
#if defined(__GNUC__) && (__GNUC__ >= 3)
//hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
# include <hash_map.h>
#else
# include <hash_map>
#endif
#endif
// soc
// # if defined(__GNUC__) && (__GNUC__ >= 3)
// //hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
// # include <hash_map.h>
// # else
// # include <hash_map>
// # endif
#include "Interface1D.h"
# include "../system/FreestyleConfig.h"
# include "../geometry/Geom.h"
# include "Interface1D.h"
#include "../geometry/Geom.h"
#include "../system/FreestyleConfig.h"
using namespace Geometry;
using namespace std;
class SVertex;
/*! Defines a hash table used for searching the SVertex */
struct SVertexHasher {
struct SVertexHasher
{
#define _MUL 950706376UL
#define _MOD 2147483647UL
inline size_t operator() (const Vec3r& p) const {
size_t res = ((unsigned long) (p[0] * _MUL)) % _MOD;
res = ((res + (unsigned long) (p[1]) * _MUL)) % _MOD;
return ((res +(unsigned long) (p[2]) * _MUL)) % _MOD;
}
inline size_t operator()(const Vec3r& p) const
{
size_t res = ((unsigned long)(p[0] * _MUL)) % _MOD;
res = ((res + (unsigned long)(p[1]) * _MUL)) % _MOD;
return ((res +(unsigned long)(p[2]) * _MUL)) % _MOD;
}
#undef _MUL
#undef _MOD
};
// Key_compare predicate for hash_map. In particular, return false if equal.
struct epsilonEquals{
bool operator()(const Vec3r& v1, const Vec3r& v2) const{
real norm = (v1-v2).norm();
return (norm<1e-06);
}
struct epsilonEquals
{
bool operator()(const Vec3r& v1, const Vec3r& v2) const
{
real norm = (v1 - v2).norm();
return (norm < 1.0e-06);
}
};
@@ -75,47 +89,81 @@ struct epsilonEquals{
typedef map<Vec3r , SVertex*> SVertexMap;
class WXFaceLayer;
/*! class to describe an oriented smooth edge */
class OWXFaceLayer{
public:
WXFaceLayer * fl;
bool order;
OWXFaceLayer() {fl=0;order=true;}
OWXFaceLayer(WXFaceLayer *ifl, bool iOrder=true){fl = ifl;order=iOrder;}
OWXFaceLayer& operator=(const OWXFaceLayer& iBrother){
fl = iBrother.fl;
order = iBrother.order;
return *this;
}
bool operator==(const OWXFaceLayer& b){
return ((fl == b.fl) && (order == b.order));
}
bool operator!=(const OWXFaceLayer& b){
return !(*this==b);
}
/*! class to describe an oriented smooth edge */
class OWXFaceLayer
{
public:
WXFaceLayer *fl;
bool order;
OWXFaceLayer()
{
fl = NULL;
order = true;
}
OWXFaceLayer(WXFaceLayer *ifl, bool iOrder = true)
{
fl = ifl;
order = iOrder;
}
OWXFaceLayer& operator=(const OWXFaceLayer& iBrother)
{
fl = iBrother.fl;
order = iBrother.order;
return *this;
}
bool operator==(const OWXFaceLayer& b)
{
return ((fl == b.fl) && (order == b.order));
}
bool operator!=(const OWXFaceLayer& b)
{
return !(*this == b);
}
};
class WXEdge;
/*! class to describe an oriented sharp edge */
class OWXEdge{
public:
WXEdge * e;
bool order;
OWXEdge() {e=0;order=true;}
OWXEdge(WXEdge *ie, bool iOrder=true){e = ie;order=iOrder;}
OWXEdge& operator=(const OWXEdge& iBrother){
e = iBrother.e;
order = iBrother.order;
return *this;
}
bool operator==(const OWXEdge& b){
return ((e == b.e) && (order == b.order));
}
bool operator!=(const OWXEdge& b){
return !(*this==b);
}
/*! class to describe an oriented sharp edge */
class OWXEdge
{
public:
WXEdge *e;
bool order;
OWXEdge()
{
e = NULL;
order = true;
}
OWXEdge(WXEdge *ie, bool iOrder = true)
{
e = ie;
order = iOrder;
}
OWXEdge& operator=(const OWXEdge& iBrother)
{
e = iBrother.e;
order = iBrother.order;
return *this;
}
bool operator==(const OWXEdge& b)
{
return ((e == b.e) && (order == b.order));
}
bool operator!=(const OWXEdge& b)
{
return !(*this == b);
}
};
class WOEdge;
@@ -126,93 +174,115 @@ class FEdge;
class ViewVertex;
class ViewEdge;
class ViewShape;
class LIB_VIEW_MAP_EXPORT ViewEdgeXBuilder
{
protected:
int _currentViewId; // Id for view edges
int _currentFId; // Id for FEdges
int _currentSVertexId; // Id for SVertex
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) ;
int _currentViewId; // Id for view edges
int _currentFId; // Id for FEdges
int _currentSVertexId; // Id for SVertex
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; }
inline ViewEdgeXBuilder()
{
_currentViewId = 1;
_currentFId = 0;
_currentSVertexId = 0;
}
virtual ~ViewEdgeXBuilder() {}
/*! Builds a view shape from a WXShape in which the feature edges are flagged
* Builds chains of feature edges (so ViewEdges) from a WXShape
* iWShape
* The Winged Edge structure in which all silhouette edges and vertices are flagged.
* oViewShape
* The Silhouette Shape in which the chains must be added.
* ioVEdges
* The list of new ViewEdges.
* ioVVertices
* THe new ViewVertices
* ioFEdges
* A list in which all new FEdges are added
* ioSVertices
* A list of SVertex where all created SVertex are added.
*/
virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, std::vector<ViewEdge*>& ioVEdges,
std::vector<ViewVertex*>& ioVVertices, std::vector<FEdge*>& ioFEdges,
std::vector<SVertex*>& ioSVertices);
/*! Builds a smooth view edge, starting the face iFace. */
ViewEdge *BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer);
/*! Makes a sharp viewedge */
ViewEdge *BuildSharpViewEdge(const OWXEdge& iWEdge);
public:
/*! accessors */
inline int currentViewId() const
{
return _currentViewId;
}
inline int currentFId() const
{
return _currentFId;
}
inline int currentSVertexId() const
{
return _currentSVertexId;
}
/*! modifiers */
inline void setCurrentViewId(int id)
{
_currentViewId = id;
}
inline void setCurrentFId(int id)
{
_currentFId = id;
}
inline void setCurrentSVertexId(int id)
{
_currentSVertexId = id;
}
protected:
/*! Init the view edges building */
virtual void Init(ViewShape *oVShape) ;
/*! Init the view edges building */
virtual void Init(ViewShape *oVShape);
// SMOOTH //
/*! checks whether a face has already been processed or not */
bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer);
OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer& iFaceLayer);
OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer);
FEdge * BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl);
// SMOOTH //
/*! checks whether a face has already been processed or not */
bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer);
OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer& iFaceLayer);
OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer);
FEdge *BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl);
// SHARP //
/*! checks whether a WEdge has already been processed or not */
bool stopSharpViewEdge(WXEdge *iFace);
int retrieveFaceMarks(WXEdge *iEdge);
OWXEdge FindNextWEdge(const OWXEdge& iEdge);
OWXEdge FindPreviousWEdge(const OWXEdge& iEdge);
FEdge * BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe);
// SHARP //
/*! checks whether a WEdge has already been processed or not */
bool stopSharpViewEdge(WXEdge *iFace);
int retrieveFaceMarks(WXEdge *iEdge);
OWXEdge FindNextWEdge(const OWXEdge& iEdge);
OWXEdge FindPreviousWEdge(const OWXEdge& iEdge);
FEdge *BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe);
// GENERAL //
/*! Instanciate a SVertex */
SVertex * MakeSVertex(Vec3r& iPoint);
/*! Instanciate a SVertex if it hasn't been already created */
SVertex * MakeSVertex(Vec3r& iPoint, bool shared);
/*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */
ViewVertex * MakeViewVertex(SVertex *iSVertex);
// GENERAL //
/*! Instanciate a SVertex */
SVertex *MakeSVertex(Vec3r& iPoint);
/*! Instanciate a SVertex if it hasn't been already created */
SVertex *MakeSVertex(Vec3r& iPoint, bool shared);
/*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */
ViewVertex *MakeViewVertex(SVertex *iSVertex);
//oldtmp values
// IdHashTable _hashtable;
// VVIdHashTable _multivertexHashTable;
SVertexMap _SVertexMap;
SShape *_pCurrentSShape;
ViewShape * _pCurrentVShape;
//oldtmp values
//IdHashTable _hashtable;
//VVIdHashTable _multivertexHashTable;
SVertexMap _SVertexMap;
SShape *_pCurrentSShape;
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
// Author(s) : Stephane Grabli
// Purpose : Class to build silhouette edges from a
// Winged-Edge structure
// Date of creation : 25/03/2002
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_VIEW_MAP_BUILDER_H__
#define __FREESTYLE_VIEW_MAP_BUILDER_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/ViewMapBuilder.h
* \ingroup freestyle
* \brief Class to build silhouette edges from a Winged-Edge structure
* \author Stephane Grabli
* \date 25/03/2002
*/
#ifndef VIEWMAPBUILDER_H
# define VIEWMAPBUILDER_H
#include <vector>
# include "Silhouette.h"
# include <vector>
# include "../system/FreestyleConfig.h"
# include "../geometry/Geom.h"
# include "../scene_graph/NodeGroup.h"
# include "../winged_edge/WXEdge.h"
# include "../geometry/GeomUtils.h"
# include "../geometry/Grid.h"
# include "../system/ProgressBar.h"
# include "../system/RenderMonitor.h"
# include "../geometry/SweepLine.h"
# include "ViewMap.h"
# include "SilhouetteGeomEngine.h"
# include "../scene_graph/TriangleRep.h"
# include "../winged_edge/WEdge.h"
# include "ViewEdgeXBuilder.h"
# include "../system/TimeUtils.h"
# include "GridDensityProvider.h"
#include "GridDensityProvider.h"
#include "Silhouette.h"
#include "SilhouetteGeomEngine.h"
#include "ViewEdgeXBuilder.h"
#include "ViewMap.h"
#include "../geometry/Geom.h"
#include "../geometry/GeomUtils.h"
#include "../geometry/Grid.h"
#include "../geometry/SweepLine.h"
#include "../scene_graph/NodeGroup.h"
#include "../scene_graph/TriangleRep.h"
#include "../system/FreestyleConfig.h"
#include "../system/ProgressBar.h"
#include "../system/RenderMonitor.h"
#include "../system/TimeUtils.h"
#include "../winged_edge/WEdge.h"
#include "../winged_edge/WXEdge.h"
using namespace Geometry;
class LIB_VIEW_MAP_EXPORT ViewMapBuilder
{
private:
ViewMap *_ViewMap; // result
//SilhouetteGeomEngine _GeomEngine;
ProgressBar *_pProgressBar;
RenderMonitor *_pRenderMonitor;
Vec3r _viewpoint;
bool _orthographicProjection;
Grid *_Grid;
ViewEdgeXBuilder *_pViewEdgeBuilder;
bool _EnableQI;
double _epsilon;
ViewMap * _ViewMap; // result
//SilhouetteGeomEngine _GeomEngine;
ProgressBar *_pProgressBar;
RenderMonitor *_pRenderMonitor;
Vec3r _viewpoint;
bool _orthographicProjection;
Grid* _Grid;
ViewEdgeXBuilder *_pViewEdgeBuilder;
bool _EnableQI;
double _epsilon;
// tmp values:
int _currentId;
int _currentFId;
int _currentSVertexId;
// tmp values:
int _currentId;
int _currentFId;
int _currentSVertexId;
public:
typedef enum {
sweep_line,
} intersection_algo;
typedef enum {
sweep_line
} intersection_algo;
typedef enum {
ray_casting,
ray_casting_fast,
ray_casting_very_fast,
ray_casting_culled_adaptive_traditional,
ray_casting_adaptive_traditional,
ray_casting_culled_adaptive_cumulative,
ray_casting_adaptive_cumulative,
} visibility_algo;
typedef enum {
ray_casting,
ray_casting_fast,
ray_casting_very_fast,
ray_casting_culled_adaptive_traditional,
ray_casting_adaptive_traditional,
ray_casting_culled_adaptive_cumulative,
ray_casting_adaptive_cumulative
} visibility_algo;
inline ViewMapBuilder()
{
_pProgressBar = NULL;
_pRenderMonitor = NULL;
_Grid = NULL;
_currentId = 1;
_currentFId = 0;
_currentSVertexId = 0;
_pViewEdgeBuilder = new ViewEdgeXBuilder;
_EnableQI = true;
}
inline ViewMapBuilder()
{
_pProgressBar = 0;
_pRenderMonitor = 0;
_Grid = 0;
_currentId = 1;
_currentFId = 0;
_currentSVertexId = 0;
_pViewEdgeBuilder = new ViewEdgeXBuilder;
_EnableQI = true;
}
inline ~ViewMapBuilder()
{
if (_pViewEdgeBuilder) {
delete _pViewEdgeBuilder;
_pViewEdgeBuilder = NULL;
}
}
inline ~ViewMapBuilder()
{
if(_pViewEdgeBuilder){
delete _pViewEdgeBuilder;
_pViewEdgeBuilder = 0;
}
}
/* Build Grid for ray casting */
/*! Build non-culled Grid in camera space for ray casting */
void BuildGrid(WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces);
/* Build Grid for ray casting */
/*! Build non-culled Grid in camera space for ray casting */
void BuildGrid(WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces);
/*! Compute Shapes from a WingedEdge containing a list of WShapes */
void computeInitialViewEdges(WingedEdge&);
/*! Compute Shapes from a WingedEdge containing a list of WShapes */
void computeInitialViewEdges(WingedEdge&);
/*! Compute Cusps */
void computeCusps(ViewMap *ioViewMap);
/*! Compute Cusps */
void computeCusps(ViewMap *ioViewMap);
/*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of
* each cusp SVertex
* We use a hysteresis approach to avoid noise.
*/
void DetectCusps(ViewEdge *ioEdge);
/*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of each cusp SVertex
* We use a hysteresis approach to avoid noise.
*/
void DetectCusps(ViewEdge *ioEdge);
/*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp)
{
_viewpoint = ivp;
SilhouetteGeomEngine::setViewpoint(ivp);
}
/*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp) {_viewpoint = ivp; SilhouetteGeomEngine::setViewpoint(ivp);}
/*! Sets the current transformation
* iModelViewMatrix
* The 4x4 model view matrix, in column major order (openGL like).
* iProjection matrix
* The 4x4 projection matrix, in column major order (openGL like).
* iViewport
* The viewport. 4 real array: origin.x, origin.y, width, length
*/
inline void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
const int iViewport[4], real iFocalLength, real iAspect, real iFovy)
{
_orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
}
/*! Sets the current transformation
* iModelViewMatrix
* The 4x4 model view matrix, in column major order (openGL like).
* iProjection matrix
* The 4x4 projection matrix, in column major order (openGL like).
* iViewport
* The viewport. 4 real array: origin.x, origin.y, width, length
*/
inline void setTransform(const real iModelViewMatrix[4][4],
const real iProjectionMatrix[4][4],
const int iViewport[4],
real iFocalLength,
real iAspect,
real iFovy) {
_orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
}
inline void setFrustum(real iZnear, real iZfar)
{
SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
}
inline void setFrustum(real iZnear, real iZfar) {
SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
}
/*! Builds the scene view map returns the list the view map
* it is up to the caller to delete this ViewMap
* iWRoot
* The root group node containing the WEdge structured scene
*/
ViewMap *BuildViewMap(WingedEdge& we, visibility_algo iAlgo, real epsilon, const BBox<Vec3r>& bbox,
unsigned int sceneNumFaces);
/*! Builds the scene view map
* returns the list the view map
* it is up to the caller to delete this ViewMap
* iWRoot
* The root group node containing the WEdge structured scene
*/
void CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4],
bool extensiveFEdgeSearch = true);
ViewMap* BuildViewMap(WingedEdge& we, visibility_algo iAlgo, real epsilon,
const BBox<Vec3r>& bbox, unsigned int sceneNumFaces);
void CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4], bool extensiveFEdgeSearch = true);
/*! computes the intersection between all 2D
* feature edges of the scene.
* ioViewMap
* The view map. It is modified by the method.
* The list of all features edges of the scene.
* Each time an intersection is found, the 2 intersecting
* edges are splitted (creating 2 new vertices)
* At the end, this list is updated with the adding
* of all new created edges (resulting from splitting).
* iAlgo
* The algo to use for computing the intersections
*/
void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon=1e-06);
/*! computes the intersection between all 2D feature edges of the scene.
* ioViewMap
* The view map. It is modified by the method.
* The list of all features edges of the scene.
* Each time an intersection is found, the 2 intersecting edges are splitted (creating 2 new vertices)
* At the end, this list is updated with the adding of all new created edges (resulting from splitting).
* iAlgo
* The algo to use for computing the intersections
*/
void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon = 1.0e-06);
/*! Computes the 2D scene silhouette edges visibility
* iGrid
* For the Ray Casting algorithm.
*/
void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces,
visibility_algo iAlgo= ray_casting, real epsilon=1e-6);
/*! Computes the 2D scene silhouette edges visibility
* iGrid
* For the Ray Casting algorithm.
*/
void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces,
visibility_algo iAlgo = ray_casting, real epsilon = 1.0e-6);
void setGrid(Grid *iGrid) {_Grid = iGrid;}
void setGrid(Grid *iGrid)
{
_Grid = iGrid;
}
/*! accessors */
/*! accessors */
/*! Modifiers */
inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;}
inline void setEnableQI(bool iBool) {_EnableQI = iBool;}
/*! Modifiers */
inline void setProgressBar(ProgressBar *iProgressBar)
{
_pProgressBar = iProgressBar;
}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
{
_pRenderMonitor = iRenderMonitor;
}
inline void setEnableQI(bool iBool)
{
_EnableQI = iBool;
}
protected:
/*! Computes intersections on all edges of the scene using a sweep line algorithm */
void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1.0e-6);
/*! Computes intersections on all edges of the scene using a sweep line
* algorithm*/
void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1e-6);
/*! Computes the 2D scene silhouette edges visibility using a ray casting. On each edge, a ray is cast
* to check its quantitative invisibility. The list of occluders are each time stored in the tested edge.
* ioViewMap
* The view map.
* The 2D scene silhouette edges as FEdges.
* These edges have already been splitted at their intersections points.
* Thus, these edges do not intersect anymore.
* The visibility corresponding to each edge of ioScene is set is this edge.
*/
void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 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
* using a ray casting. On each edge, a ray is cast
* to check its quantitative invisibility. The list
* of occluders are each time stored in the tested edge.
* ioViewMap
* The view map.
* The 2D scene silhouette edges as FEdges.
* These edges have already been splitted at their intersections points.
* Thus, these edges do not intersect anymore.
* The visibility corresponding to each edge of ioScene is set is this
* edge.
*/
void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we,
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory);
void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we,
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory);
/*! Compute the visibility for the FEdge fe.
* The occluders are added to fe occluders list.
* fe
* The FEdge
* iGrid
* The grid used to compute the ray casting visibility
* epsilon
* The epsilon used for computation
* oShapeId
* fe is the border (in 2D) between 2 2D spaces.
* if fe is a silhouette,
* One of these 2D spaces is occupied by the shape
* to which fe belongs (on its left) and the other one is either occupied
* by another shape or empty or occupied by the same shape.
* We use this ray csating operation to determine which shape
* lies on fe's right.
* The result is the shape id stored in oShapeId
*/
int ComputeRayCastingVisibility(FEdge *fe, Grid* iGrid, real epsilon, set<ViewShape*>& oOccluders,
Polygon3r** oaPolygon, unsigned timestamp);
// FIXME
void FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp);
void FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp,
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
bool cull, GridDensityProviderFactory& factory);
void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
bool cull, GridDensityProviderFactory& factory);
/*! Compute the visibility for the FEdge fe.
* The occluders are added to fe occluders list.
* fe
* The FEdge
* iGrid
* The grid used to compute the ray casting visibility
* epsilon
* The epsilon used for computation
* oShapeId
* fe is the border (in 2D) between 2 2D spaces.
* if fe is a silhouette, One of these 2D spaces is occupied by the shape to which fe belongs (on its left)
* and the other one is either occupied by another shape or empty or occupied by the same shape.
* We use this ray csating operation to determine which shape lies on fe's right.
* The result is the shape id stored in oShapeId
*/
int ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
Polygon3r **oaPolygon, unsigned timestamp);
// FIXME
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
};
#endif // VIEWMAPBUILDER_H
#endif // __FREESTYLE_VIEW_MAP_BUILDER_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,116 +1,129 @@
//
// Filename : ViewMapIO.h
// Author(s) : Emmanuel Turquin
// Purpose : Functions to manage I/O for the view map
// Date of creation : 09/01/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_VIEW_MAP_IO_H__
#define __FREESTYLE_VIEW_MAP_IO_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/ViewMapIO.h
* \ingroup freestyle
* \brief Functions to manage I/O for the view map
* \author Emmanuel Turquin
* \date 09/01/2003
*/
#ifndef VIEWMAPIO_H
# define VIEWMAPIO_H
#include <fstream>
#include <string>
# include "ViewMap.h"
# include <fstream>
# include <string>
# include "../system/FreestyleConfig.h"
# include "../system/ProgressBar.h"
#include "ViewMap.h"
#include "../system/FreestyleConfig.h"
#include "../system/ProgressBar.h"
namespace ViewMapIO {
static const unsigned ZERO = UINT_MAX;
static const unsigned ZERO = UINT_MAX;
LIB_VIEW_MAP_EXPORT
int load(istream& in, ViewMap* vm, ProgressBar* pb = NULL);
LIB_VIEW_MAP_EXPORT
int load(istream& in, ViewMap *vm, ProgressBar *pb = NULL);
LIB_VIEW_MAP_EXPORT
int save(ostream& out, ViewMap* vm, ProgressBar* pb = NULL);
LIB_VIEW_MAP_EXPORT
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;
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 setFlags(const unsigned char flags);
LIB_VIEW_MAP_EXPORT
void addFlags(const unsigned char flags);
LIB_VIEW_MAP_EXPORT
void addFlags(const unsigned char flags);
LIB_VIEW_MAP_EXPORT
void rmFlags(const unsigned char flags);
LIB_VIEW_MAP_EXPORT
void rmFlags(const unsigned char flags);
LIB_VIEW_MAP_EXPORT
unsigned char getFlags();
LIB_VIEW_MAP_EXPORT
unsigned char getFlags();
LIB_VIEW_MAP_EXPORT
void setModelsPath(const string& path);
LIB_VIEW_MAP_EXPORT
void setModelsPath(const string& path);
LIB_VIEW_MAP_EXPORT
string getModelsPath();
LIB_VIEW_MAP_EXPORT
string getModelsPath();
}; // End of namepace Options
}; // End of namepace Options
# ifdef IRIX
#ifdef IRIX
namespace Internal {
namespace Internal {
template <unsigned S>
ostream& write(ostream& out, const char* str) {
out.put(str[S - 1]);
return write<S - 1>(out, str);
}
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<1>(ostream& out, const char *str)
{
return out.put(str[0]);
}
template<>
ostream& write<0>(ostream& out, const char*) {
return out;
}
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 <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<1>(istream& in, char *str)
{
return in.get(str[0]);
}
template<>
istream& read<0>(istream& in, char*) {
return in;
}
template<>
istream& read<0>(istream& in, char*)
{
return in;
}
} // End of namespace Internal
} // End of namespace Internal
# endif // IRIX
#endif // IRIX
} // 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 *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/ViewMapTesselator.cpp
* \ingroup freestyle
* \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
* \author Stephane Grabli
* \date 26/03/2002
*/
#include "ViewMapTesselator.h"
NodeGroup* ViewMapTesselator::Tesselate(ViewMap *iViewMap)
NodeGroup *ViewMapTesselator::Tesselate(ViewMap *iViewMap)
{
if(0 == iViewMap->ViewEdges().size())
return NULL;
if (0 == iViewMap->ViewEdges().size())
return NULL;
const vector<ViewEdge*>& viewedges = iViewMap->ViewEdges();
return Tesselate(viewedges.begin(), viewedges.end());
const vector<ViewEdge*>& viewedges = iViewMap->ViewEdges();
return Tesselate(viewedges.begin(), viewedges.end());
}
NodeGroup* ViewMapTesselator::Tesselate(WShape *)
NodeGroup *ViewMapTesselator::Tesselate(WShape *)
{
return NULL;
return NULL;
}

View File

@@ -1,44 +1,50 @@
//
// Filename : ViewMapTesselator.h
// Author(s) : Stephane Grabli
// Purpose : Class to build a Node Tree designed to be displayed
// from a Silhouette View Map structure.
// Date of creation : 26/03/2002
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_VIEW_MAP_TESSELATOR_H__
#define __FREESTYLE_VIEW_MAP_TESSELATOR_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/view_map/ViewMapTesselator.h
* \ingroup freestyle
* \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
* \author Stephane Grabli
* \date 26/03/2002
*/
#ifndef VIEWMAPTESSELATOR_H
# define VIEWMAPTESSELATOR_H
#include "Silhouette.h"
#include "ViewMap.h"
# include "Silhouette.h"
# include "ViewMap.h"
# include "../scene_graph/NodeShape.h"
# include "../winged_edge/WEdge.h"
# include "../scene_graph/NodeGroup.h"
# include "../scene_graph/LineRep.h"
# include "../scene_graph/OrientedLineRep.h"
# include "../scene_graph/VertexRep.h"
#include "../scene_graph/LineRep.h"
#include "../scene_graph/NodeShape.h"
#include "../scene_graph/NodeGroup.h"
#include "../scene_graph/OrientedLineRep.h"
#include "../scene_graph/VertexRep.h"
#include "../winged_edge/WEdge.h"
class NodeShape;
class NodeGroup;
@@ -48,68 +54,83 @@ class WShape;
class LIB_VIEW_MAP_EXPORT ViewMapTesselator
{
public:
inline ViewMapTesselator()
{
_nature = Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE;
_FrsMaterial.setDiffuse(0, 0, 0, 1);
_overloadFrsMaterial = false;
}
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
* a NodeShape, itself contained under a NodeGroup from a ViewMap
*/
NodeGroup* Tesselate(ViewMap* iViewMap) ;
/*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a ViewMap */
NodeGroup *Tesselate(ViewMap *iViewMap);
/*! Builds a set of lines rep contained under a
* a NodeShape, itself contained under a NodeGroup from a
* set of view edges
*/
template<class ViewEdgesIterator>
NodeGroup* Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end) ;
/*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a set of
* view edges
*/
template<class ViewEdgesIterator>
NodeGroup *Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end);
/*! Builds a set of lines rep contained among a
* a NodeShape, from a WShape
*/
NodeGroup* Tesselate(WShape* iWShape);
/*! Builds a set of lines rep contained among a NodeShape, from a WShape */
NodeGroup *Tesselate(WShape *iWShape);
inline void setNature(Nature::EdgeNature iNature)
{
_nature = iNature;
}
inline void setNature(Nature::EdgeNature iNature) {_nature = iNature;}
inline void setFrsMaterial(const FrsMaterial& iMaterial) {_FrsMaterial=iMaterial;_overloadFrsMaterial=true;}
inline Nature::EdgeNature nature() {return _nature;}
inline const FrsMaterial& frs_material() const {return _FrsMaterial;}
inline void setFrsMaterial(const FrsMaterial& iMaterial)
{
_FrsMaterial = iMaterial;
_overloadFrsMaterial = true;
}
inline Nature::EdgeNature nature()
{
return _nature;
}
inline const FrsMaterial& frs_material() const
{
return _FrsMaterial;
}
protected:
virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
private:
Nature::EdgeNature _nature;
FrsMaterial _FrsMaterial;
bool _overloadFrsMaterial;
Nature::EdgeNature _nature;
FrsMaterial _FrsMaterial;
bool _overloadFrsMaterial;
};
/*! Class to tesselate the 2D projected silhouette */
class ViewMapTesselator2D : public ViewMapTesselator
{
public:
inline ViewMapTesselator2D() : ViewMapTesselator() {}
virtual ~ViewMapTesselator2D() {}
inline ViewMapTesselator2D() : ViewMapTesselator() {}
virtual ~ViewMapTesselator2D() {}
protected:
virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
{
iLine->AddVertex(v->point2D());
}
virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
{
iLine->AddVertex(v->point2D());
}
};
/*! Class to tesselate the 3D silhouette */
class ViewMapTesselator3D : public ViewMapTesselator
{
public:
inline ViewMapTesselator3D() : ViewMapTesselator() {}
virtual ~ViewMapTesselator3D() {}
inline ViewMapTesselator3D() : ViewMapTesselator() {}
virtual ~ViewMapTesselator3D() {}
protected:
virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
{
iLine->AddVertex(v->point3D());
}
virtual void AddVertexToLine(LineRep *iLine, SVertex *v)
{
iLine->AddVertex(v->point3D());
}
};
//
@@ -118,79 +139,73 @@ protected:
///////////////////////////////////////////////
template<class ViewEdgesIterator>
NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
NodeGroup *ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
{
NodeGroup *group = new NodeGroup;
NodeShape *tshape = new NodeShape;
group->AddChild(tshape);
//tshape->frs_material().setDiffuse(0.f, 0.f, 0.f, 1.f);
tshape->setFrsMaterial(_FrsMaterial);
NodeGroup *group = new NodeGroup;
NodeShape *tshape = new NodeShape;
group->AddChild(tshape);
//tshape->frs_material().setDiffuse(0.0f, 0.0f, 0.0f, 1.0f);
tshape->setFrsMaterial(_FrsMaterial);
LineRep* line;
LineRep *line;
FEdge *firstEdge;
FEdge *nextFEdge, *currentEdge;
FEdge *firstEdge;
FEdge *nextFEdge, *currentEdge;
int id = 0;
//for (vector<ViewEdge*>::const_iterator c = viewedges.begin(), cend = viewedges.end(); c != cend; c++)
for (ViewEdgesIterator c = begin, cend = end; c != cend; c++) {
#if 0
if ((*c)->qi() > 0) {
continue;
}
if (!((*c)->nature() & (_nature))) {
continue;
}
#endif
firstEdge = (*c)->fedgeA();
int id=0;
// for(vector<ViewEdge*>::const_iterator c=viewedges.begin(),cend=viewedges.end();
// c!=cend;
// c++)
for(ViewEdgesIterator c=begin, cend=end;
c!=cend;
c++)
{
// if((*c)->qi() > 0){
// continue;
// }
// if(!((*c)->nature() & (_nature)))
// continue;
//
firstEdge = (*c)->fedgeA();
#if 0
if (firstEdge->invisibility() > 0)
continue;
#endif
// if(firstEdge->invisibility() > 0)
// continue;
line = new OrientedLineRep();
if (_overloadFrsMaterial)
line->setFrsMaterial(_FrsMaterial);
line = new OrientedLineRep();
if(_overloadFrsMaterial)
line->setFrsMaterial(_FrsMaterial);
// there might be chains containing a single element
if (0 == (firstEdge)->nextEdge()) {
line->setStyle(LineRep::LINES);
//line->AddVertex((*c)->vertexA()->point3D());
//line->AddVertex((*c)->vertexB()->point3D());
AddVertexToLine(line, firstEdge->vertexA());
AddVertexToLine(line, firstEdge->vertexB());
}
else {
line->setStyle(LineRep::LINE_STRIP);
// there might be chains containing a single element
if(0 == (firstEdge)->nextEdge())
{
line->setStyle(LineRep::LINES);
// line->AddVertex((*c)->vertexA()->point3D());
// line->AddVertex((*c)->vertexB()->point3D());
AddVertexToLine(line, firstEdge->vertexA());
AddVertexToLine(line, firstEdge->vertexB());
}
else
{
line->setStyle(LineRep::LINE_STRIP);
//firstEdge = (*c);
nextFEdge = firstEdge;
currentEdge = firstEdge;
do {
//line->AddVertex(nextFEdge->vertexA()->point3D());
AddVertexToLine(line, nextFEdge->vertexA());
currentEdge = nextFEdge;
nextFEdge = nextFEdge->nextEdge();
} while ((nextFEdge != NULL) && (nextFEdge != firstEdge));
// Add the last vertex
//line->AddVertex(currentEdge->vertexB()->point3D());
AddVertexToLine(line, currentEdge->vertexB());
}
//firstEdge = (*c);
nextFEdge = firstEdge;
currentEdge = firstEdge;
do
{
//line->AddVertex(nextFEdge->vertexA()->point3D());
AddVertexToLine(line, nextFEdge->vertexA());
currentEdge = nextFEdge;
nextFEdge = nextFEdge->nextEdge();
}while((nextFEdge != NULL) && (nextFEdge != firstEdge));
// Add the last vertex
//line->AddVertex(currentEdge->vertexB()->point3D());
AddVertexToLine(line, currentEdge->vertexB());
line->setId((*c)->getId().getFirst());
line->ComputeBBox();
tshape->AddRep(line);
id++;
}
}
line->setId((*c)->getId().getFirst());
line->ComputeBBox();
tshape->AddRep(line);
id++;
}
return group;
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
* Copyright (C) 1999 Stéphane Popinet
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* This Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is:
* GTS - Library for the manipulation of triangulated surfaces
* Copyright (C) 1999 Stephane Popinet
* and:
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
* Copyright (C) 2000-2003 Bruno Levy
* Contact: Bruno Levy levy@loria.fr
* ISA Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
* 54506 VANDOEUVRE LES NANCY CEDEX
* FRANCE
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __CURVATURE_H__
#define __CURVATURE_H__
#ifndef __FREESTYLE_CURVATURE_H__
#define __FREESTYLE_CURVATURE_H__
/** \file blender/freestyle/intern/winged_edge/Curvature.h
* \ingroup freestyle
* \brief GTS - Library for the manipulation of triangulated surfaces
* \author Stephane Popinet
* \date 1999
* \brief OGF/Graphite: Geometry and Graphics Programming Library + Utilities
* \author Bruno Levy
* \date 2000-2003
*/
#include "../geometry/Geom.h"
#include "../system/FreestyleConfig.h"
#include "../system/Precision.h"
# include "../system/FreestyleConfig.h"
# include "../system/Precision.h"
# include "../geometry/Geom.h"
using namespace Geometry;
class WVertex;
@@ -31,126 +61,83 @@ class WVertex;
class LIB_WINGED_EDGE_EXPORT CurvatureInfo
{
public:
CurvatureInfo()
{
K1 = 0.0;
K2 = 0.0;
e1 = Vec3r(0.0, 0.0, 0.0);
e2 = Vec3r(0.0, 0.0, 0.0);
Kr = 0.0;
dKr = 0.0;
er = Vec3r(0.0, 0.0, 0.0);
}
CurvatureInfo()
{
K1 = 0.0;
K2 = 0.0;
e1 = Vec3r(0.0,0.0,0.0);
e2 = Vec3r(0.0,0.0,0.0);
Kr = 0.0;
dKr = 0.0;
er = Vec3r(0.0,0.0,0.0);
}
CurvatureInfo(const CurvatureInfo& iBrother)
{
K1 = iBrother.K1;
K2 = iBrother.K2;
e1 = iBrother.e1;
e2 = iBrother.e2;
Kr = iBrother.Kr;
dKr = iBrother.dKr;
er = iBrother.er;
}
CurvatureInfo(const CurvatureInfo& iBrother){
K1 = iBrother.K1;
K2 = iBrother.K2;
e1 = iBrother.e1;
e2 = iBrother.e2;
Kr = iBrother.Kr;
dKr = iBrother.dKr;
er = iBrother.er;
}
CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t)
{
K1 = ca.K1 + t * (cb.K1 - ca.K1);
K2 = ca.K2 + t * (cb.K2 - ca.K2);
e1 = ca.e1 + t * (cb.e1 - ca.e1);
e2 = ca.e2 + t * (cb.e2 - ca.e2);
Kr = ca.Kr + t * (cb.Kr - ca.Kr);
dKr = ca.dKr + t * (cb.dKr - ca.dKr);
er = ca.er + t * (cb.er - ca.er);
}
CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t) {
K1 = ca.K1 + t * (cb.K1 - ca.K1);
K2 = ca.K2 + t * (cb.K2 - ca.K2);
e1 = ca.e1 + t * (cb.e1 - ca.e1);
e2 = ca.e2 + t * (cb.e2 - ca.e2);
Kr = ca.Kr + t * (cb.Kr - ca.Kr);
dKr = ca.dKr + t * (cb.dKr - ca.dKr);
er = ca.er + t * (cb.er - ca.er);
}
real K1; // maximum curvature
real K2; // minimum curvature
Vec3r e1; // maximum curvature direction
Vec3r e2; // minimum curvature direction
real Kr; // radial curvature
real dKr; // radial curvature
Vec3r er; // radial curvature direction
real K1; // maximum curvature
real K2; // minimum curvature
Vec3r e1; // maximum curvature direction
Vec3r e2; // minimum curvature direction
real Kr; // radial curvature
real dKr; // radial curvature
Vec3r er; // radial curvature direction
};
class Face_Curvature_Info{
class Face_Curvature_Info
{
public:
Face_Curvature_Info() {}
~Face_Curvature_Info(){
for(vector<CurvatureInfo*>::iterator ci=vec_curvature_info.begin(), ciend=vec_curvature_info.end();
ci!=ciend;
++ci){
delete (*ci);
}
vec_curvature_info.clear();
}
vector<CurvatureInfo *> vec_curvature_info;
Face_Curvature_Info() {}
~Face_Curvature_Info()
{
for (vector<CurvatureInfo*>::iterator ci = vec_curvature_info.begin(), ciend = vec_curvature_info.end();
ci != ciend;
++ci)
{
delete (*ci);
}
vec_curvature_info.clear();
}
vector<CurvatureInfo *> vec_curvature_info;
};
bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal (WVertex * v,
Vec3r &n);
bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &n);
bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature (WVertex * v,
real * Kg);
bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature(WVertex *v, real *Kg);
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures (real Kh,
real Kg,
real * K1,
real * K2);
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2);
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions (WVertex * v,
Vec3r Kh,
real Kg,
Vec3r &e1,
Vec3r &e2);
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2);
/*
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
* Copyright (C) 2000-2003 Bruno Levy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* If you modify this software, you should include a notice giving the
* name of the person performing the modification, the date of modification,
* and the reason for such modification.
*
* Contact: Bruno Levy
*
* levy@loria.fr
*
* ISA Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
* 54506 VANDOEUVRE LES NANCY CEDEX
* FRANCE
*
* Note that the GNU General Public License does not permit incorporating
* the Software into proprietary programs.
*/
namespace OGF {
namespace OGF {
class NormalCycle ;
class NormalCycle ;
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor(
WVertex* start, double radius, NormalCycle& nc
) ;
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( WVertex *start, double radius, NormalCycle& nc);
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(
WVertex* start, NormalCycle& nc
) ;
}
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc);
} // OGF namespace
#endif /* __CURVATURE_H__ */
#endif /* __FREESTYLE_CURVATURE_H__ */

View File

@@ -1,79 +1,79 @@
//
// Filename : Nature.h
// Author(s) : Emmanuel Turquin
// Purpose : Different natures for both vertices and edges
// Date of creation : 01/07/2003
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NATURE_H
# define NATURE_H
/*! \file Nature.h
* Definitions of Natures of the ViewMap's elements
/*
* ***** 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 *****
*/
/*! Namespace gathering the different possible
* natures of 0D and 1D elements of the ViewMap
#ifndef __FREESTYLE_NATURE_H__
#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 {
typedef unsigned short VertexNature;
/* XXX Why not using enums??? */
/*! true for any 0D element */
static const VertexNature POINT = 0; // 0
/*! true for SVertex */
static const VertexNature S_VERTEX = (1 << 0); // 1
/*! true for ViewVertex */
static const VertexNature VIEW_VERTEX = (1 << 1); // 2
/*! true for NonTVertex */
static const VertexNature NON_T_VERTEX = (1 << 2); // 4
/*! true for TVertex */
static const VertexNature T_VERTEX = (1 << 3); // 8
/*! true for CUSP */
static const VertexNature CUSP = (1 << 4); // 16
typedef unsigned short VertexNature;
/*! true for any 0D element */
static const VertexNature POINT = 0; // 0
/*! true for SVertex */
static const VertexNature S_VERTEX = (1 << 0); // 1
/*! true for ViewVertex */
static const VertexNature VIEW_VERTEX = (1 << 1); // 2
/*! true for NonTVertex */
static const VertexNature NON_T_VERTEX = (1 << 2); // 4
/*! true for TVertex */
static const VertexNature T_VERTEX = (1 << 3); // 8
/*! true for CUSP */
static const VertexNature CUSP = (1 << 4); // 16
typedef unsigned short EdgeNature;
/*! true for non feature edges (always false for 1D elements of the ViewMap) */
static const EdgeNature NO_FEATURE = 0; // 0
/*! true for silhouettes */
static const EdgeNature SILHOUETTE = (1 << 0); // 1
/*! true for borders */
static const EdgeNature BORDER = (1 << 1); // 2
/*! true for creases */
static const EdgeNature CREASE = (1 << 2); // 4
/*! true for ridges */
static const EdgeNature RIDGE = (1 << 3); // 8
/*! true for valleys */
static const EdgeNature VALLEY = (1 << 4); // 16
/*! true for suggestive contours */
static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32
/*! true for material boundaries */
static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64
/*! true for user-defined edge marks */
static const EdgeNature EDGE_MARK = (1 << 7); // 128
typedef unsigned short EdgeNature;
/*! true for non feature edges (always false for 1D elements of the ViewMap) */
static const EdgeNature NO_FEATURE = 0; // 0
/*! true for silhouettes */
static const EdgeNature SILHOUETTE = (1 << 0); // 1
/*! true for borders */
static const EdgeNature BORDER = (1 << 1); // 2
/*! true for creases */
static const EdgeNature CREASE = (1 << 2); // 4
/*! true for ridges */
static const EdgeNature RIDGE = (1 << 3); // 8
/*! true for valleys */
static const EdgeNature VALLEY = (1 << 4); // 16
/*! true for suggestive contours */
static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32
/*! true for material boundaries */
static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64
/*! true for user-defined edge marks */
static const EdgeNature EDGE_MARK = (1 << 7); // 128
} // end of namespace Nature
#endif // NATURE_H
#endif // __FREESTYLE_NATURE_H__

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 *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/winged_edge/WFillGrid.cpp
* \ingroup freestyle
* \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
* \author Emmanuel Turquin
* \author Stephane Grabli
* \date 03/05/2003
*/
#include "WEdge.h"
#include "WFillGrid.h"
void WFillGrid::fillGrid() {
if (!_winged_edge || !_grid)
return;
void WFillGrid::fillGrid()
{
if (!_winged_edge || !_grid)
return;
vector<WShape*> wshapes = _winged_edge->getWShapes();
vector<WVertex*> fvertices;
vector<Vec3r> vectors;
vector<WFace*> faces;
vector<WShape *> wshapes = _winged_edge->getWShapes();
vector<WVertex *> fvertices;
vector<Vec3r> vectors;
vector<WFace *> faces;
for (vector<WShape*>::const_iterator it = wshapes.begin();
it != wshapes.end();
it++) {
faces = (*it)->GetFaceList();
for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) {
faces = (*it)->GetFaceList();
for (vector<WFace*>::const_iterator f = faces.begin();
f != faces.end();
f++) {
(*f)->RetrieveVertexList(fvertices);
for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) {
(*f)->RetrieveVertexList(fvertices);
for (vector<WVertex*>::const_iterator wv = fvertices.begin();
wv != fvertices.end();
wv++)
vectors.push_back(Vec3r((*wv)->GetVertex()));
for (vector<WVertex*>::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv)
vectors.push_back(Vec3r((*wv)->GetVertex()));
// occluder will be deleted by the grid
Polygon3r *occluder =
new Polygon3r(vectors, (*f)->GetNormal());
occluder->setId(_polygon_id++);
occluder->userdata = (void*)(*f);
_grid->insertOccluder(occluder);
vectors.clear();
fvertices.clear();
}
faces.clear();
}
// occluder will be deleted by the grid
Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal());
occluder->setId(_polygon_id++);
occluder->userdata = (void *)(*f);
_grid->insertOccluder(occluder);
vectors.clear();
fvertices.clear();
}
faces.clear();
}
}

View File

@@ -1,80 +1,88 @@
//
// Filename : WFillGrid.h
// Author(s) : Stephane Grabli
// Emmanuel Turquin
// Purpose : Class to fill in a grid from a SceneGraph
// (uses only the WingedEdge structures)
// Date of creation : 03/05/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_W_FILL_GRID_H__
#define __FREESTYLE_W_FILL_GRID_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/winged_edge/WFillGrid.h
* \ingroup freestyle
* \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
* \author Emmanuel Turquin
* \author Stephane Grabli
* \date 03/05/2003
*/
#ifndef W_FILL_GRID_H
# define W_FILL_GRID_H
#include "WEdge.h"
# include "../geometry/Grid.h"
# include "../geometry/Polygon.h"
# include "WEdge.h"
#include "../geometry/Grid.h"
#include "../geometry/Polygon.h"
class LIB_WINGED_EDGE_EXPORT WFillGrid
{
public:
inline WFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
{
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
}
inline WFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) {
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
}
virtual ~WFillGrid() {}
virtual ~WFillGrid() {}
void fillGrid();
void fillGrid();
/*! Accessors */
WingedEdge *getWingedEdge()
{
return _winged_edge;
}
/*! Accessors */
WingedEdge* getWingedEdge() {
return _winged_edge;
}
Grid *getGrid()
{
return _grid;
}
Grid* getGrid() {
return _grid;
}
/*! Modifiers */
void setWingedEdge(WingedEdge *winged_edge)
{
if (winged_edge)
_winged_edge = winged_edge;
}
/*! Modifiers */
void setWingedEdge(WingedEdge* winged_edge) {
if (winged_edge)
_winged_edge = winged_edge;
}
void setGrid(Grid* grid) {
if (grid)
_grid = grid;
}
void setGrid(Grid *grid)
{
if (grid)
_grid = grid;
}
private:
Grid* _grid;
WingedEdge* _winged_edge;
unsigned _polygon_id;
Grid *_grid;
WingedEdge *_winged_edge;
unsigned _polygon_id;
};
#endif // WS_FILL_GRID_H
#endif // __FREESTYLE_W_FILL_GRID_H__

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 *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/winged_edge/WSFillGrid.cpp
* \ingroup freestyle
* \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
* \author Stephane Grabli
* \date 03/05/2003
*/
#include "WEdge.h"
#include "WSFillGrid.h"
void WSFillGrid::fillGrid() {
if (!_winged_edge || !_grid)
return;
void WSFillGrid::fillGrid()
{
if (!_winged_edge || !_grid)
return;
vector<WShape*> wshapes = _winged_edge->getWShapes();
vector<WVertex*> fvertices;
vector<Vec3r> vectors;
vector<WFace*> faces;
vector<WShape *> wshapes = _winged_edge->getWShapes();
vector<WVertex *> fvertices;
vector<Vec3r> vectors;
vector<WFace *> faces;
for (vector<WShape*>::const_iterator it = wshapes.begin();
it != wshapes.end();
it++) {
faces = (*it)->GetFaceList();
for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) {
faces = (*it)->GetFaceList();
for (vector<WFace*>::const_iterator f = faces.begin();
f != faces.end();
f++) {
(*f)->RetrieveVertexList(fvertices);
for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) {
(*f)->RetrieveVertexList(fvertices);
for (vector<WVertex*>::const_iterator wv = fvertices.begin();
wv != fvertices.end();
wv++)
vectors.push_back(Vec3r((*wv)->GetVertex()));
for (vector<WVertex*>::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv)
vectors.push_back(Vec3r((*wv)->GetVertex()));
// occluder will be deleted by the grid
Polygon3r *occluder =
new Polygon3r(vectors, (*f)->GetNormal());
occluder->setId(_polygon_id++);
occluder->userdata = (void*)(*f);
_grid->insertOccluder(occluder);
vectors.clear();
fvertices.clear();
}
faces.clear();
}
// occluder will be deleted by the grid
Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal());
occluder->setId(_polygon_id++);
occluder->userdata = (void *)(*f);
_grid->insertOccluder(occluder);
vectors.clear();
fvertices.clear();
}
faces.clear();
}
}

View File

@@ -1,79 +1,87 @@
//
// Filename : WSFillGrid.h
// Author(s) : Stephane Grabli
// Purpose : Class to fill in a grid from a SceneGraph
// (uses only the WingedEdge structures)
// Date of creation : 03/05/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_WS_FILL_GRID_H__
#define __FREESTYLE_WS_FILL_GRID_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/winged_edge/WSFillGrid.h
* \ingroup freestyle
* \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
* \author Stephane Grabli
* \date 03/05/2003
*/
#ifndef WS_FILL_GRID_H
# define WS_FILL_GRID_H
#include "WEdge.h"
# include "../geometry/Grid.h"
# include "../geometry/Polygon.h"
# include "WEdge.h"
#include "../geometry/Grid.h"
#include "../geometry/Polygon.h"
class LIB_WINGED_EDGE_EXPORT WSFillGrid
{
public:
inline WSFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
{
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
}
inline WSFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) {
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
}
virtual ~WSFillGrid() {}
virtual ~WSFillGrid() {}
void fillGrid();
void fillGrid();
/*! Accessors */
WingedEdge *getWingedEdge()
{
return _winged_edge;
}
/*! Accessors */
WingedEdge* getWingedEdge() {
return _winged_edge;
}
Grid *getGrid()
{
return _grid;
}
Grid* getGrid() {
return _grid;
}
/*! Modifiers */
void setWingedEdge(WingedEdge *winged_edge)
{
if (winged_edge)
_winged_edge = winged_edge;
}
/*! Modifiers */
void setWingedEdge(WingedEdge* winged_edge) {
if (winged_edge)
_winged_edge = winged_edge;
}
void setGrid(Grid* grid) {
if (grid)
_grid = grid;
}
void setGrid(Grid *grid)
{
if (grid)
_grid = grid;
}
private:
Grid* _grid;
WingedEdge* _winged_edge;
unsigned _polygon_id;
Grid *_grid;
WingedEdge *_winged_edge;
unsigned _polygon_id;
};
#endif // WS_FILL_GRID_H
#endif // __FREESTYLE_WS_FILL_GRID_H__

View File

@@ -1,296 +1,298 @@
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/freestyle/intern/winged_edge/WXEdge.cpp
* \ingroup freestyle
* \brief Classes to define an Extended Winged Edge data structure.
* \author Stephane Grabli
* \date 26/10/2003
*/
#include "WXEdge.h"
/**********************************/
/* */
/* */
/* WXFace */
/* */
/* */
/**********************************/
/**********************************
* *
* *
* WXFace *
* *
* *
**********************************/
unsigned int WXFaceLayer::Get0VertexIndex() const {
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
for(i=0; i<nEdges; ++i){
if(_DotP[i] == 0){
return i;
}
}
return -1;
unsigned int WXFaceLayer::Get0VertexIndex() const
{
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
for (i = 0; i < nEdges; ++i) {
if (_DotP[i] == 0) {
return i;
}
}
return -1;
}
unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
for(i=0; i<nEdges; ++i){
if((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)){
return i;
}
}
return -1;
unsigned int WXFaceLayer::GetSmoothEdgeIndex() const
{
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
for (i = 0; i < nEdges; ++i) {
if ((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)) {
return i;
}
}
return -1;
}
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
for(i=0; i<nEdges; ++i){
if(_DotP[i]*_DotP[(i+1)%nEdges] < 0){
// we got one
oCuspEdges.push_back(i);
}
}
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges)
{
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
for (i = 0; i < nEdges; ++i) {
if (_DotP[i] * _DotP[(i + 1) % nEdges] < 0) {
// we got one
oCuspEdges.push_back(i);
}
}
}
WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
// if the smooth edge has already been
// built: exit
if(0 != _pSmoothEdge)
return _pSmoothEdge;
real ta, tb;
WOEdge *woea(0), *woeb(0);
bool ok = false;
vector<int> cuspEdgesIndices;
int indexStart, indexEnd;
unsigned nedges = _pWXFace->numberOfEdges();
if(_nNullDotP == nedges){
_pSmoothEdge = 0;
return _pSmoothEdge;
}
if((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)){
// that means that we have a smooth edge that starts from
// an edge and ends at an edge
//-----------------------------
// We retrieve the 2 edges for which we have
// opposite signs for each extremity
RetrieveCuspEdgesIndices(cuspEdgesIndices);
if(cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges
return 0;
WXSmoothEdge *WXFaceLayer::BuildSmoothEdge()
{
// if the smooth edge has already been built: exit
if (_pSmoothEdge)
return _pSmoothEdge;
real ta, tb;
WOEdge *woea(0), *woeb(0);
bool ok = false;
vector<int> cuspEdgesIndices;
int indexStart, indexEnd;
unsigned nedges = _pWXFace->numberOfEdges();
if (_nNullDotP == nedges) {
_pSmoothEdge = NULL;
return _pSmoothEdge;
}
if ((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)) {
// that means that we have a smooth edge that starts from an edge and ends at an edge
//-----------------------------
// We retrieve the 2 edges for which we have opposite signs for each extremity
RetrieveCuspEdgesIndices(cuspEdgesIndices);
if (cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges
return 0;
// let us determine which cusp edge corresponds to the starting:
// We can do that because we defined that
// a silhouette edge had the back facing part on its right.
// So if the WOEdge woea is such that woea[0].dotp > 0 and
// woea[1].dotp < 0, it is the starting edge.
//-------------------------------------------
// let us determine which cusp edge corresponds to the starting:
// We can do that because we defined that a silhouette edge had the back facing part on its right.
// So if the WOEdge woea is such that woea[0].dotp > 0 and woea[1].dotp < 0, it is the starting edge.
//-------------------------------------------
if(_DotP[cuspEdgesIndices[0]] > 0){
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
indexStart = cuspEdgesIndices[0];
indexEnd = cuspEdgesIndices[1];
}else{
woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
indexStart = cuspEdgesIndices[1];
indexEnd = cuspEdgesIndices[0];
}
if (_DotP[cuspEdgesIndices[0]] > 0) {
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
indexStart = cuspEdgesIndices[0];
indexEnd = cuspEdgesIndices[1];
}
else {
woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
indexStart = cuspEdgesIndices[1];
indexEnd = cuspEdgesIndices[0];
}
// Compute the interpolation:
ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]);
tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]);
ok = true;
}else if(_nNullDotP == 1){
// that means that we have exactly one of the
// 2 extremities of our silhouette edge is
// a vertex of the mesh
if((_nPosDotP == 2) || (_nPosDotP == 0)){
_pSmoothEdge = 0;
return _pSmoothEdge;
}
RetrieveCuspEdgesIndices(cuspEdgesIndices);
// We should have only one EdgeCusp:
if(cuspEdgesIndices.size() != 1){
cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl;
_pSmoothEdge = 0;
return 0;
}
unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
unsigned nedges = _pWXFace->numberOfEdges();
if(_DotP[cuspEdgesIndices[0]] > 0){
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
woeb = _pWXFace->GetOEdge(index0);
indexStart = cuspEdgesIndices[0];
ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]);
tb = 0.0;
}else{
woea = _pWXFace->GetOEdge(index0);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
indexEnd = cuspEdgesIndices[0];
ta = 0.0;
tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]);
}
ok = true;
}else if(_nNullDotP == 2){
// that means that the silhouette edge
// is an edge of the mesh
int index = GetSmoothEdgeIndex();
if(!_pWXFace->front()) {// is it in the right order ?
// the order of the WOEdge index is wrong
woea = _pWXFace->GetOEdge((index+1)%nedges);
woeb = _pWXFace->GetOEdge((index-1)%nedges);
ta = 0;
tb = 1;
ok = true;
}else{
// here it's not good, our edge is a single point -> skip that face
ok = false;
// the order of the WOEdge index is good
// woea = _pWXFace->GetOEdge((index-1)%nedges);
// woeb = _pWXFace->GetOEdge((index+1)%nedges);
// ta = 1;
// tb = 0;
}
}
if(ok){
_pSmoothEdge = new WXSmoothEdge;
_pSmoothEdge->setWOeA(woea);
_pSmoothEdge->setWOeB(woeb);
_pSmoothEdge->setTa(ta);
_pSmoothEdge->setTb(tb);
if(_Nature & Nature::SILHOUETTE){
if(_nNullDotP != 2){
if(_DotP[_ClosestPointIndex] + 0.01 > 0)
_pSmoothEdge->setFront(true);
else
_pSmoothEdge->setFront(false);
}
}
}
// Compute the interpolation:
ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
ok = true;
}
else if (_nNullDotP == 1) {
// that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex of the mesh
if ((_nPosDotP == 2) || (_nPosDotP == 0)) {
_pSmoothEdge = NULL;
return _pSmoothEdge;
}
RetrieveCuspEdgesIndices(cuspEdgesIndices);
// We should have only one EdgeCusp:
if (cuspEdgesIndices.size() != 1) {
cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl;
_pSmoothEdge = NULL;
return NULL;
}
unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
unsigned nedges = _pWXFace->numberOfEdges();
if (_DotP[cuspEdgesIndices[0]] > 0) {
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
woeb = _pWXFace->GetOEdge(index0);
indexStart = cuspEdgesIndices[0];
ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
tb = 0.0;
}
else {
woea = _pWXFace->GetOEdge(index0);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
indexEnd = cuspEdgesIndices[0];
ta = 0.0;
tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
}
ok = true;
}
else if (_nNullDotP == 2) {
// that means that the silhouette edge is an edge of the mesh
int index = GetSmoothEdgeIndex();
if (!_pWXFace->front()) { // is it in the right order ?
// the order of the WOEdge index is wrong
woea = _pWXFace->GetOEdge((index + 1) % nedges);
woeb = _pWXFace->GetOEdge((index - 1) % nedges);
ta = 0;
tb = 1;
ok = true;
}
else {
// here it's not good, our edge is a single point -> skip that face
ok = false;
#if 0
// the order of the WOEdge index is good
woea = _pWXFace->GetOEdge((index - 1) % nedges);
woeb = _pWXFace->GetOEdge((index + 1) % nedges);
ta = 1;
tb = 0;
#endif
}
}
if (ok) {
_pSmoothEdge = new WXSmoothEdge;
_pSmoothEdge->setWOeA(woea);
_pSmoothEdge->setWOeB(woeb);
_pSmoothEdge->setTa(ta);
_pSmoothEdge->setTb(tb);
if (_Nature & Nature::SILHOUETTE) {
if (_nNullDotP != 2) {
if (_DotP[_ClosestPointIndex] + 0.01 > 0)
_pSmoothEdge->setFront(true);
else
_pSmoothEdge->setFront(false);
}
}
}
// check bording edges to see if they have different dotp values
// in bording faces.
// for(int i=0; i<numberOfEdges(); i++)
// {
// WSFace * bface = (WSFace*)GetBordingFace(i);
// if(bface != 0)
// {
// if((front())^(bface->front())) // fA->front XOR fB->front (true if one is 0 and the other is 1)
// {
// // that means that the edge i of the face is
// // a silhouette edge
// // TESTER D'ABORD SI LE EXACTSILHOUETTEEDGE N'A PAS
// // ETE CONSTRUIT SUR L'AUTRE FACE.(1 suffit)
// if(0 != ((WSExactFace*)bface)->exactSilhouetteEdge())
// {
// // that means that this silhouette edge has already been built
// return ((WSExactFace*)bface)->exactSilhouetteEdge();
// }
// // Else we must build it
// WOEdge *woea, *woeb;
// real ta, tb;
// if(!front()) // is it in the right order ?
// {
// // the order of the WOEdge index is wrong
// woea = _OEdgeList[(i+1)%numberOfEdges()];
// if(0 == i)
// woeb = _OEdgeList[numberOfEdges()-1];
// else
// woeb = _OEdgeList[(i-1)];
// ta = 0;
// tb = 1;
// }
// else
// {
// // the order of the WOEdge index is good
// if(0 == i)
// woea = _OEdgeList[numberOfEdges()-1];
// else
// woea = _OEdgeList[(i-1)];
// woeb = _OEdgeList[(i+1)%numberOfEdges()];
// ta = 1;
// tb = 0;
// }
//
// _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
// _pSmoothEdge->setWOeA(woea);
// _pSmoothEdge->setWOeA(woeb);
// _pSmoothEdge->setTa(ta);
// _pSmoothEdge->setTb(tb);
//
// return _pSmoothEdge;
// }
// }
//}
return _pSmoothEdge;
#if 0
// check bording edges to see if they have different dotp values in bording faces.
for (int i = 0; i < numberOfEdges(); i++) {
WSFace *bface = (WSFace *)GetBordingFace(i);
if (bface) {
if ((front()) ^ (bface->front())) { // fA->front XOR fB->front (true if one is 0 and the other is 1)
// that means that the edge i of the face is a silhouette edge
// CHECK FIRST WHETHER THE EXACTSILHOUETTEEDGE HAS NOT YET BEEN BUILT ON THE OTHER FACE (1 is enough).
if (((WSExactFace *)bface)->exactSilhouetteEdge()) {
// that means that this silhouette edge has already been built
return ((WSExactFace *)bface)->exactSilhouetteEdge();
}
// Else we must build it
WOEdge *woea, *woeb;
real ta, tb;
if (!front()) { // is it in the right order ?
// the order of the WOEdge index is wrong
woea = _OEdgeList[(i + 1) % numberOfEdges()];
if (0 == i)
woeb = _OEdgeList[numberOfEdges() - 1];
else
woeb = _OEdgeList[(i - 1)];
ta = 0;
tb = 1;
}
else {
// the order of the WOEdge index is good
if (0 == i)
woea = _OEdgeList[numberOfEdges() - 1];
else
woea = _OEdgeList[(i - 1)];
woeb = _OEdgeList[(i + 1) % numberOfEdges()];
ta = 1;
tb = 0;
}
_pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
_pSmoothEdge->setWOeA(woea);
_pSmoothEdge->setWOeA(woeb);
_pSmoothEdge->setTa(ta);
_pSmoothEdge->setTb(tb);
return _pSmoothEdge;
}
}
}
#endif
return _pSmoothEdge;
}
void WXFace::ComputeCenter()
{
vector<WVertex*> iVertexList;
RetrieveVertexList(iVertexList);
Vec3r center;
for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
wv!=wvend;
wv++)
{
center += (*wv)->GetVertex();
}
center /= (real)iVertexList.size();
setCenter(center);
vector<WVertex *> iVertexList;
RetrieveVertexList(iVertexList);
Vec3r center;
for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
center += (*wv)->GetVertex();
}
center /= (real)iVertexList.size();
setCenter(center);
}
/**********************************/
/* */
/* */
/* WXShape */
/* */
/* */
/**********************************/
/**********************************
* *
* *
* WXShape *
* *
* *
**********************************/
WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
{
WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
if(0 == face)
return 0;
WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
if (!face)
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);
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;
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);
#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;
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
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/freestyle/intern/winged_edge/WSBuilder.cpp
* \ingroup freestyle
* \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info
* (silhouette etc...)) structure from a polygonal model
* \author Stephane Grabli
* \date 28/05/2003
*/
#include "WXEdgeBuilder.h"
#include "WXEdge.h"
#include "WXEdgeBuilder.h"
void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
{
if (_pRenderMonitor && _pRenderMonitor->testBreak())
return;
WXShape *shape = new WXShape;
buildWShape(*shape, ifs);
shape->setId(ifs.getId().getFirst());
shape->setName(ifs.getName());
//ifs.setId(shape->GetId());
if (_pRenderMonitor && _pRenderMonitor->testBreak())
return;
WXShape *shape = new WXShape;
buildWShape(*shape, ifs);
shape->setId(ifs.getId().getFirst());
shape->setName(ifs.getName());
//ifs.setId(shape->GetId());
}
void WXEdgeBuilder::buildWVertices(WShape& shape,
const real *vertices,
unsigned vsize) {
WXVertex *vertex;
for (unsigned i = 0; i < vsize; i += 3) {
vertex = new WXVertex(Vec3r(vertices[i],
vertices[i + 1],
vertices[i + 2]));
vertex->setId(i / 3);
shape.AddVertex(vertex);
}
void WXEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize)
{
WXVertex *vertex;
for (unsigned int i = 0; i < vsize; i += 3) {
vertex = new WXVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
vertex->setId(i / 3);
shape.AddVertex(vertex);
}
}

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 *****
*/
//
// Filename : WSBuilder.h
// Author(s) : Stephane Grabli
// Purpose : Class inherited from WingedEdgeBuilder and
// designed to build a WX (WingedEdge + extended info(silhouette etc...))
// structure from a polygonal model
// Date of creation : 28/05/03
//
///////////////////////////////////////////////////////////////////////////////
#ifndef __FREESTYLE_WX_EDGE_BUILDER_H__
#define __FREESTYLE_WX_EDGE_BUILDER_H__
/** \file blender/freestyle/intern/winged_edge/WSBuilder.h
* \ingroup freestyle
* \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info
* (silhouette etc...)) structure from a polygonal model
* \author Stephane Grabli
* \date 28/05/2003
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#include "WingedEdgeBuilder.h"
# include "WingedEdgeBuilder.h"
# include "../scene_graph/IndexedFaceSet.h"
#include "../scene_graph/IndexedFaceSet.h"
class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder
{
public:
WXEdgeBuilder() : WingedEdgeBuilder() {}
virtual ~WXEdgeBuilder() {}
VISIT_DECL(IndexedFaceSet)
virtual ~WXEdgeBuilder() {}
VISIT_DECL(IndexedFaceSet)
protected:
virtual void buildWVertices(WShape& shape,
const real *vertices,
unsigned vsize);
virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
};
#endif // WXEDGEBUILDER_H
#endif // __FREESTYLE_WX_EDGE_BUILDER_H__

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 *****
*/
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
* \ingroup freestyle
* \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes
* of a scene graph
* \author Stephane Grabli
* \date 28/05/2003
*/
#include <set>
#include "WingedEdgeBuilder.h"
#include "../geometry/GeomUtils.h"
#include "../scene_graph/NodeShape.h"
#include "WingedEdgeBuilder.h"
#include <set>
using namespace std;
void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) {
if (_pRenderMonitor && _pRenderMonitor->testBreak())
return;
WShape *shape = new WShape;
buildWShape(*shape, ifs);
shape->setId(ifs.getId().getFirst());
//ifs.setId(shape->GetId());
void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
{
if (_pRenderMonitor && _pRenderMonitor->testBreak())
return;
WShape *shape = new WShape;
buildWShape(*shape, ifs);
shape->setId(ifs.getId().getFirst());
//ifs.setId(shape->GetId());
}
void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) {
//Sets the current material to iShapeode->material:
_current_frs_material = &(ns.frs_material());
void WingedEdgeBuilder::visitNodeShape(NodeShape& ns)
{
//Sets the current material to iShapeode->material:
_current_frs_material = &(ns.frs_material());
}
void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) {
if(!_current_matrix) {
_current_matrix = new Matrix44r(tn.matrix());
return;
}
void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn)
{
if (!_current_matrix) {
_current_matrix = new Matrix44r(tn.matrix());
return;
}
_matrices_stack.push_back(_current_matrix);
Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix());
_current_matrix = new_matrix;
_matrices_stack.push_back(_current_matrix);
Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix());
_current_matrix = new_matrix;
}
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) {
if(_current_matrix)
delete _current_matrix;
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&)
{
if (_current_matrix)
delete _current_matrix;
if(_matrices_stack.empty()) {
_current_matrix = NULL;
return;
}
if (_matrices_stack.empty()) {
_current_matrix = NULL;
return;
}
_current_matrix = _matrices_stack.back();
_matrices_stack.pop_back();
_current_matrix = _matrices_stack.back();
_matrices_stack.pop_back();
}
void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
unsigned vsize = ifs.vsize();
unsigned nsize = ifs.nsize();
//soc unused - unsigned tsize = ifs.tsize();
void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs)
{
unsigned int vsize = ifs.vsize();
unsigned int nsize = ifs.nsize();
//soc unused - unsigned tsize = ifs.tsize();
const real* vertices = ifs.vertices();
const real* normals = ifs.normals();
const real* texCoords = ifs.texCoords();
const real *vertices = ifs.vertices();
const real *normals = ifs.normals();
const real *texCoords = ifs.texCoords();
real* new_vertices;
real* new_normals;
real *new_vertices;
real *new_normals;
new_vertices = new real[vsize];
new_normals = new real[nsize];
// transform coordinates from local to world system
if(_current_matrix) {
transformVertices(vertices, vsize, *_current_matrix, new_vertices);
transformNormals(normals, nsize, *_current_matrix, new_normals);
}
else {
memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices));
memcpy(new_normals, normals, nsize * sizeof(*new_normals));
}
// transform coordinates from local to world system
if (_current_matrix) {
transformVertices(vertices, vsize, *_current_matrix, new_vertices);
transformNormals(normals, nsize, *_current_matrix, new_normals);
}
else {
memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices));
memcpy(new_normals, normals, nsize * sizeof(*new_normals));
}
const IndexedFaceSet::TRIANGLES_STYLE* faceStyle = ifs.trianglesStyle();
const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle();
vector<FrsMaterial> frs_materials;
if(ifs.msize()){
const FrsMaterial*const* mats = ifs.frs_materials();
for(unsigned i=0; i<ifs.msize(); ++i)
if (ifs.msize()) {
const FrsMaterial *const *mats = ifs.frs_materials();
for (unsigned i = 0; i < ifs.msize(); ++i)
frs_materials.push_back(*(mats[i]));
shape.setFrsMaterials(frs_materials);
}
// const FrsMaterial * mat = (ifs.frs_material());
// if (mat)
// shape.setFrsMaterial(*mat);
// else if(_current_frs_material)
// shape.setFrsMaterial(*_current_frs_material);
#if 0
const FrsMaterial *mat = (ifs.frs_material());
if (mat)
shape.setFrsMaterial(*mat);
else if (_current_frs_material)
shape.setFrsMaterial(*_current_frs_material);
#endif
const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();
const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();
// sets the current WShape to shape
_current_wshape = &shape;
// sets the current WShape to shape
_current_wshape = &shape;
// create a WVertex for each vertex
buildWVertices(shape, new_vertices, vsize);
// create a WVertex for each vertex
buildWVertices(shape, new_vertices, vsize);
const unsigned int *vindices = ifs.vindices();
const unsigned int *nindices = ifs.nindices();
const unsigned int *tindices = NULL;
if (ifs.tsize()) {
tindices = ifs.tindices();
}
const unsigned* vindices = ifs.vindices();
const unsigned* nindices = ifs.nindices();
const unsigned* tindices = 0;
if(ifs.tsize()){
tindices = ifs.tindices();
}
const unsigned *mindices = 0;
if(ifs.msize())
const unsigned int *mindices = NULL;
if (ifs.msize())
mindices = ifs.mindices();
const unsigned* numVertexPerFace = ifs.numVertexPerFaces();
const unsigned numfaces = ifs.numFaces();
const unsigned int *numVertexPerFace = ifs.numVertexPerFaces();
const unsigned int numfaces = ifs.numFaces();
for (unsigned index = 0; index < numfaces; index++) {
switch(faceStyle[index]) {
case IndexedFaceSet::TRIANGLE_STRIP:
buildTriangleStrip(new_vertices,
new_normals,
frs_materials,
texCoords,
faceEdgeMarks,
vindices,
nindices,
mindices,
tindices,
numVertexPerFace[index]);
break;
case IndexedFaceSet::TRIANGLE_FAN:
buildTriangleFan(new_vertices,
new_normals,
frs_materials,
texCoords,
faceEdgeMarks,
vindices,
nindices,
mindices,
tindices,
numVertexPerFace[index]);
break;
case IndexedFaceSet::TRIANGLES:
buildTriangles(new_vertices,
new_normals,
frs_materials,
texCoords,
faceEdgeMarks,
vindices,
nindices,
mindices,
tindices,
numVertexPerFace[index]);
break;
}
vindices += numVertexPerFace[index];
nindices += numVertexPerFace[index];
if(mindices)
for (unsigned int index = 0; index < numfaces; index++) {
switch (faceStyle[index]) {
case IndexedFaceSet::TRIANGLE_STRIP:
buildTriangleStrip(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
nindices, mindices, tindices, numVertexPerFace[index]);
break;
case IndexedFaceSet::TRIANGLE_FAN:
buildTriangleFan(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
nindices, mindices, tindices, numVertexPerFace[index]);
break;
case IndexedFaceSet::TRIANGLES:
buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
nindices, mindices, tindices, numVertexPerFace[index]);
break;
}
vindices += numVertexPerFace[index];
nindices += numVertexPerFace[index];
if (mindices)
mindices += numVertexPerFace[index];
if(tindices)
tindices += numVertexPerFace[index];
faceEdgeMarks++;
}
if (tindices)
tindices += numVertexPerFace[index];
faceEdgeMarks++;
}
delete[] new_vertices;
delete[] new_normals;
delete[] new_vertices;
delete[] new_normals;
// compute bbox
shape.ComputeBBox();
// compute mean edge size:
shape.ComputeMeanEdgeSize();
// compute bbox
shape.ComputeBBox();
// compute mean edge size:
shape.ComputeMeanEdgeSize();
// Parse the built winged-edge shape to update post-flags
set<Vec3r> normalsSet;
vector<WVertex*>& wvertices = shape.getVertexList();
for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end();
wv!=wvend;
++wv){
if((*wv)->isBoundary())
continue;
if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
continue;
normalsSet.clear();
WVertex::face_iterator fit = (*wv)->faces_begin();
WVertex::face_iterator fitend = (*wv)->faces_end();
while(fit!=fitend){
WFace *face = *fit;
normalsSet.insert(face->GetVertexNormal(*wv));
if(normalsSet.size()!=1){
break;
}
++fit;
}
if(normalsSet.size()!=1){
(*wv)->setSmooth(false);
}
}
// Adds the new WShape to the WingedEdge structure
_winged_edge->addWShape(&shape);
// Parse the built winged-edge shape to update post-flags
set<Vec3r> normalsSet;
vector<WVertex *>& wvertices = shape.getVertexList();
for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
if ((*wv)->isBoundary())
continue;
if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
continue;
normalsSet.clear();
WVertex::face_iterator fit = (*wv)->faces_begin();
WVertex::face_iterator fitend = (*wv)->faces_end();
for (; fit != fitend; ++fit) {
WFace *face = *fit;
normalsSet.insert(face->GetVertexNormal(*wv));
if (normalsSet.size() != 1) {
break;
}
}
if (normalsSet.size() !=1 ) {
(*wv)->setSmooth(false);
}
}
// Adds the new WShape to the WingedEdge structure
_winged_edge->addWShape(&shape);
}
void WingedEdgeBuilder::buildWVertices(WShape& shape,
const real *vertices,
unsigned vsize) {
WVertex *vertex;
for (unsigned i = 0; i < vsize; i += 3) {
vertex = new WVertex(Vec3r(vertices[i],
vertices[i + 1],
vertices[i + 2]));
vertex->setId(i / 3);
shape.AddVertex(vertex);
}
void WingedEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize)
{
WVertex *vertex;
for (unsigned int i = 0; i < vsize; i += 3) {
vertex = new WVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
vertex->setId(i / 3);
shape.AddVertex(vertex);
}
}
void WingedEdgeBuilder::buildTriangleStrip( const real *vertices,
const real *normals,
vector<FrsMaterial>& iMaterials,
const real *texCoords,
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices) {
unsigned nDoneVertices = 2; // number of vertices already treated
unsigned nTriangle = 0; // number of the triangle currently being treated
//int nVertex = 0; // vertex number
void WingedEdgeBuilder::buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const unsigned *tindices, const unsigned nvertices)
{
unsigned nDoneVertices = 2; // number of vertices already treated
unsigned nTriangle = 0; // number of the triangle currently being treated
//int nVertex = 0; // vertex number
WShape* currentShape = _current_wshape; // the current shape being built
vector<WVertex *> triangleVertices;
vector<Vec3r> triangleNormals;
vector<Vec2r> triangleTexCoords;
vector<bool> triangleFaceEdgeMarks;
WShape *currentShape = _current_wshape; // the current shape being built
vector<WVertex *> triangleVertices;
vector<Vec3r> triangleNormals;
vector<Vec2r> triangleTexCoords;
vector<bool> triangleFaceEdgeMarks;
while(nDoneVertices < nvertices)
{
//clear the vertices list:
triangleVertices.clear();
//Then rebuild it:
if(0 == nTriangle%2) // if nTriangle is even
{
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+1]/3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]);
while (nDoneVertices < nvertices) {
//clear the vertices list:
triangleVertices.clear();
//Then rebuild it:
if (0 == nTriangle % 2) { // if nTriangle is even
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]],normals[nindices[nTriangle+1]+1],normals[nindices[nTriangle+1]+2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]], normals[nindices[nTriangle+2]+1], normals[nindices[nTriangle+2]+2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
normals[nindices[nTriangle] + 2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
normals[nindices[nTriangle + 1] + 2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
normals[nindices[nTriangle + 2] + 2]));
if(texCoords){
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]],texCoords[tindices[nTriangle+1]+1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]], texCoords[tindices[nTriangle+2]+1]));
}
}
else // if nTriangle is odd
{
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+1]/3]);
if (texCoords) {
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
texCoords[tindices[nTriangle + 1] + 1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
texCoords[tindices[nTriangle + 2] + 1]));
}
}
else { // if nTriangle is odd
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]],normals[nindices[nTriangle+2]+1],normals[nindices[nTriangle+2]+2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]], normals[nindices[nTriangle+1]+1], normals[nindices[nTriangle+1]+2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
normals[nindices[nTriangle] + 2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
normals[nindices[nTriangle + 2] + 2]));
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
normals[nindices[nTriangle + 1] + 2]));
if(texCoords){
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]],texCoords[tindices[nTriangle+2]+1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]], texCoords[tindices[nTriangle+1]+1]));
}
}
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::FACE_MARK) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
if(mindices)
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[nTriangle/3]);
else
if (texCoords) {
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
texCoords[tindices[nTriangle + 2] + 1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
texCoords[tindices[nTriangle + 1] + 1]));
}
}
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
if (mindices) {
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
mindices[nTriangle / 3]);
}
else {
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
nDoneVertices++; // with a strip, each triangle is one vertex more
nTriangle++;
}
}
nDoneVertices++; // with a strip, each triangle is one vertex more
nTriangle++;
}
}
void WingedEdgeBuilder::buildTriangleFan( const real *vertices,
const real *normals,
vector<FrsMaterial>& iMaterials,
const real *texCoords,
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices) {
// Nothing to be done
void WingedEdgeBuilder::buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const unsigned *tindices, const unsigned nvertices)
{
// Nothing to be done
}
void WingedEdgeBuilder::buildTriangles(const real *vertices,
const real *normals,
vector<FrsMaterial>& iMaterials,
const real *texCoords,
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices) {
WShape * currentShape = _current_wshape; // the current shape begin built
vector<WVertex *> triangleVertices;
vector<Vec3r> triangleNormals;
vector<Vec2r> triangleTexCoords;
vector<bool> triangleFaceEdgeMarks;
void WingedEdgeBuilder::buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const unsigned *tindices, const unsigned nvertices)
{
WShape *currentShape = _current_wshape; // the current shape begin built
vector<WVertex *> triangleVertices;
vector<Vec3r> triangleNormals;
vector<Vec2r> triangleTexCoords;
vector<bool> triangleFaceEdgeMarks;
// Each triplet of vertices is considered as an independent triangle
for(unsigned i = 0; i < nvertices / 3; i++)
{
triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i]/3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+1]/3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+2]/3]);
// Each triplet of vertices is considered as an independent triangle
for (unsigned int i = 0; i < nvertices / 3; i++) {
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]);
triangleNormals.push_back(Vec3r(normals[nindices[3*i]],normals[nindices[3*i]+1], normals[nindices[3*i]+2]));
triangleNormals.push_back(Vec3r(normals[nindices[3*i+1]],normals[nindices[3*i+1]+1],normals[nindices[3*i+1]+2]));
triangleNormals.push_back(Vec3r(normals[nindices[3*i+2]], normals[nindices[3*i+2]+1], normals[nindices[3*i+2]+2]));
triangleNormals.push_back(Vec3r(normals[nindices[3 * i]], normals[nindices[3 * i] + 1],
normals[nindices[3 * i] + 2]));
triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 1]], normals[nindices[3 * i + 1] + 1],
normals[nindices[3 * i + 1] + 2]));
triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 2]], normals[nindices[3 * i + 2] + 1],
normals[nindices[3 * i + 2] + 2]));
if(texCoords){
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i]],texCoords[tindices[3*i]+1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+1]],texCoords[tindices[3*i+1]+1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+2]], texCoords[tindices[3*i+2]+1]));
}
if (texCoords) {
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1]));
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 2]], texCoords[tindices[3 * i + 2] + 1]));
}
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
}
if(mindices)
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
}
if (mindices)
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
mindices[0]);
else
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
}
void WingedEdgeBuilder::transformVertices(const real *vertices,
unsigned vsize,
const Matrix44r& transform,
real *res) {
const real *v = vertices;
real *pv = res;
void WingedEdgeBuilder::transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res)
{
const real *v = vertices;
real *pv = res;
for (unsigned i = 0; i < vsize / 3; i++) {
HVec3r hv_tmp(v[0], v[1], v[2]);
HVec3r hv(transform * hv_tmp);
for (unsigned j = 0; j < 3; j++)
pv[j] = hv[j] / hv[3];
v += 3;
pv += 3;
}
for (unsigned int i = 0; i < vsize / 3; i++) {
HVec3r hv_tmp(v[0], v[1], v[2]);
HVec3r hv(transform * hv_tmp);
for (unsigned int j = 0; j < 3; j++)
pv[j] = hv[j] / hv[3];
v += 3;
pv += 3;
}
}
void WingedEdgeBuilder::transformNormals(const real *normals,
unsigned nsize,
const Matrix44r& transform,
real* res) {
const real *n = normals;
real *pn = res;
void WingedEdgeBuilder::transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res)
{
const real *n = normals;
real *pn = res;
for (unsigned i = 0; i < nsize / 3; i++) {
Vec3r hn(n[0], n[1], n[2]);
hn = GeomUtils::rotateVector(transform, hn);
for (unsigned j = 0; j < 3; j++)
pn[j] = hn[j];
n += 3;
pn += 3;
}
for (unsigned int i = 0; i < nsize / 3; i++) {
Vec3r hn(n[0], n[1], n[2]);
hn = GeomUtils::rotateVector(transform, hn);
for (unsigned int j = 0; j < 3; j++)
pn[j] = hn[j];
n += 3;
pn += 3;
}
}

View File

@@ -1,171 +1,157 @@
//
// Filename : WingedEdgeBuilder.h
// Author(s) : Stephane Grabli
// Purpose : Class to render a WingedEdge data structure
// from a polyhedral data structure organized in
// nodes of a scene graph
// Date of creation : 28/05/03
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_WINGED_EDGE_BUILDER_H__
#define __FREESTYLE_WINGED_EDGE_BUILDER_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
/** \file blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
* \ingroup freestyle
* \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes
* of a scene graph
* \author Stephane Grabli
* \date 28/05/2003
*/
#ifndef WINGED_EDGE_BUILDER_H
# define WINGED_EDGE_BUILDER_H
#include "WEdge.h"
# include "../system/FreestyleConfig.h"
# include "../system/RenderMonitor.h"
# include "../scene_graph/SceneVisitor.h"
# include "WEdge.h"
# include "../scene_graph/IndexedFaceSet.h"
# include "../scene_graph/NodeTransform.h"
#include "../scene_graph/IndexedFaceSet.h"
#include "../scene_graph/NodeTransform.h"
#include "../scene_graph/SceneVisitor.h"
#include "../system/FreestyleConfig.h"
#include "../system/RenderMonitor.h"
class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
{
public:
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() {
_current_wshape = NULL;
_current_frs_material = NULL;
_current_matrix = NULL;
_winged_edge = new WingedEdge; // Not deleted by the destructor
_pRenderMonitor = NULL;
}
virtual ~WingedEdgeBuilder()
{
for (vector<Matrix44r*>::iterator it = _matrices_stack.begin(); it != _matrices_stack.end(); ++it)
delete *it;
_matrices_stack.clear();
}
virtual ~WingedEdgeBuilder() {
for (vector<Matrix44r*>::iterator it = _matrices_stack.begin();
it != _matrices_stack.end();
it++)
delete *it;
_matrices_stack.clear();
}
VISIT_DECL(IndexedFaceSet)
VISIT_DECL(NodeShape)
VISIT_DECL(NodeTransform)
VISIT_DECL(IndexedFaceSet)
VISIT_DECL(NodeShape)
VISIT_DECL(NodeTransform)
virtual void visitNodeTransformAfter(NodeTransform&);
virtual void visitNodeTransformAfter(NodeTransform&);
//
// Accessors
//
/////////////////////////////////////////////////////////////////////////////
//
// Accessors
//
/////////////////////////////////////////////////////////////////////////////
inline WingedEdge *getWingedEdge()
{
return _winged_edge;
}
inline WingedEdge* getWingedEdge() {
return _winged_edge;
}
inline WShape *getCurrentWShape()
{
return _current_wshape;
}
inline WShape* getCurrentWShape() {
return _current_wshape;
}
inline FrsMaterial *getCurrentFrsMaterial()
{
return _current_frs_material;
}
inline FrsMaterial* getCurrentFrsMaterial() {
return _current_frs_material;
}
inline Matrix44r *getCurrentMatrix()
{
return _current_matrix;
}
inline Matrix44r* getCurrentMatrix() {
return _current_matrix;
}
//
// Modifiers
//
/////////////////////////////////////////////////////////////////////////////
//
// Modifiers
//
/////////////////////////////////////////////////////////////////////////////
inline void setCurrentWShape(WShape *wshape)
{
_current_wshape = wshape;
}
inline void setCurrentWShape(WShape* wshape) {
_current_wshape = wshape;
}
inline void setCurrentFrsMaterial(FrsMaterial *mat)
{
_current_frs_material = mat;
}
inline void setCurrentFrsMaterial(FrsMaterial* mat) {
_current_frs_material = mat;
}
#if 0
inline void setCurrentMatrix(Matrix44r *matrix)
{
_current_matrix = matrix;
}
#endif
// inline void setCurrentMatrix(Matrix44r* matrix) {
// _current_matrix = matrix;
// }
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {
_pRenderMonitor = iRenderMonitor;
}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {
_pRenderMonitor = iRenderMonitor;
}
protected:
virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs);
virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
protected:
RenderMonitor *_pRenderMonitor;
virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs);
virtual void buildWVertices(WShape& shape,
const real *vertices,
unsigned vsize);
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);
RenderMonitor *_pRenderMonitor;
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);
private:
void buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const unsigned *tindices, const unsigned nvertices);
void buildTriangleStrip(const real *vertices,
const real *normals,
vector<FrsMaterial>& iMaterials,
const real *texCoords,
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices);
void transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res);
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 transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res);
void buildTriangles(const real *vertices,
const real *normals,
vector<FrsMaterial>& iMaterials,
const real *texCoords,
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices);
void transformVertices(const real *vertices,
unsigned vsize,
const Matrix44r& transform,
real *res);
void transformNormals(const real *normals,
unsigned nsize,
const Matrix44r& transform,
real *res);
WShape* _current_wshape;
FrsMaterial* _current_frs_material;
WingedEdge* _winged_edge;
Matrix44r* _current_matrix;
vector<Matrix44r*> _matrices_stack;
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__