Yet another big style clean-up patch by Bastien Montagne, thanks a lot!

Now the code style is acceptable for the merge now, according to Bastien.
Thanks again Bastien for having this done! :)
This commit is contained in:
2013-01-02 01:55:30 +00:00
parent 520ab93465
commit 699da2fb0d
58 changed files with 19076 additions and 17097 deletions

View File

@@ -1,42 +1,48 @@
//
// Filename : ArbitraryGridDensityProvider.cpp
// 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)
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)
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, unsigned numCells)
: GridDensityProvider(source), numCells(numCells)
{
real proscenium[4];
@@ -70,7 +76,7 @@ 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;
float safetyZone = 0.1f;
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
}
@@ -91,12 +97,15 @@ ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigne
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,46 +1,52 @@
//
// 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);
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();
@@ -51,17 +57,19 @@ private:
void initialize (const real proscenium[4]);
};
class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory {
class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory
{
public:
ArbitraryGridDensityProviderFactory(unsigned numCells);
~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,42 +1,48 @@
//
// 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)
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)
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, real sizeFactor)
: GridDensityProvider(source)
{
real proscenium[4];
@@ -82,7 +88,7 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
// Make sure the grid exceeds the proscenium by a small amount
float safetyZone = 0.1;
float safetyZone = 0.1f;
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
}
@@ -103,12 +109,15 @@ AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(rea
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);
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:
private:
void initialize (const real proscenium[4], real sizeFactor);
};
class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory {
class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory
{
public:
AverageAreaGridDensityProviderFactory(real sizeFactor);
~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
@@ -46,7 +51,8 @@ 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,12 +75,11 @@ 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;
@@ -87,26 +94,29 @@ 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();
@@ -124,11 +134,10 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
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) {
// This is an uninitialized cell
real x, y, width, height;
x = _cellOrigin[0] + _cellSize * i;
@@ -145,7 +154,8 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
}
}
void BoxGrid::distributePolygons (OccluderSource& source) {
void BoxGrid::distributePolygons(OccluderSource& source)
{
unsigned long nFaces = 0;
unsigned long nKeptFaces = 0;
@@ -157,7 +167,8 @@ void BoxGrid::distributePolygons (OccluderSource& source) {
_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,7 +181,8 @@ 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) {
@@ -179,32 +191,37 @@ void BoxGrid::reorganizeCells () {
}
}
void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) {
void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
{
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
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() {}
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,70 +1,79 @@
//
// 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>
// 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 {
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);
@@ -84,28 +93,21 @@ 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);
explicit Iterator(BoxGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
~Iterator();
void initBeforeTarget();
void initAfterTarget();
@@ -116,6 +118,7 @@ public:
WFace *getWFace() const;
Polygon3r *getCameraSpacePolygon();
void reportDepth(Vec3r origin, Vec3r u, real t);
private:
bool testOccluder(bool wantOccludee);
void markCurrentOccludeeCandidate(real depth);
@@ -128,7 +131,8 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate;
};
class Transform : public GridHelpers::Transform {
class Transform : public GridHelpers::Transform
{
public:
explicit Transform();
explicit Transform(Transform& other);
@@ -139,16 +143,17 @@ private:
// Prevent implicit copies and assignments.
BoxGrid(const BoxGrid& other);
BoxGrid& operator=(const BoxGrid& other);
public:
explicit BoxGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
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();
@@ -176,23 +181,25 @@ private:
bool _enableQI;
};
inline void BoxGrid::Iterator::initBeforeTarget () {
inline void BoxGrid::Iterator::initBeforeTarget()
{
_current = _cell->faces.begin();
while (_current != _cell->faces.end() && !testOccluder(false)) {
++_current;
}
}
inline void BoxGrid::Iterator::initAfterTarget () {
inline void BoxGrid::Iterator::initAfterTarget()
{
if (_foundOccludee) {
#if boxgridlogging == 1
#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
@@ -201,26 +208,25 @@ inline void BoxGrid::Iterator::initAfterTarget () {
}
}
inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
inline bool BoxGrid::Iterator::testOccluder(bool wantOccludee)
{
// End-of-list is not even a valid iterator position
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.
// 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 BOX_GRID_LOGGING
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
#endif
_current = _cell->faces.end();
@@ -232,14 +238,15 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
// Specific continue or stop conditions when searching for each type
if (wantOccludee) {
if ((*_current)->deepest < _target[2]) {
#if boxgridlogging == 1
#if BOX_GRID_LOGGING
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
#endif
return false;
}
} else {
}
else {
if ((*_current)->shallowest > _target[2]) {
#if boxgridlogging == 1
#if BOX_GRID_LOGGING
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
#endif
return true;
@@ -252,41 +259,43 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
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 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 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) {
markCurrentOccludeeCandidate(depth);
}
} else {
#if boxgridlogging == 1
}
else {
#if BOX_GRID_LOGGING
std::cout << std::endl;
#endif
}
}
inline void BoxGrid::Iterator::nextOccluder () {
inline void BoxGrid::Iterator::nextOccluder()
{
if (_current != _cell->faces.end()) {
do {
++_current;
@@ -294,7 +303,8 @@ inline void BoxGrid::Iterator::nextOccluder () {
}
}
inline void BoxGrid::Iterator::nextOccludee () {
inline void BoxGrid::Iterator::nextOccludee()
{
if (_current != _cell->faces.end()) {
do {
++_current;
@@ -302,16 +312,19 @@ inline void BoxGrid::Iterator::nextOccludee () {
}
}
inline bool BoxGrid::Iterator::validBeforeTarget () {
inline bool BoxGrid::Iterator::validBeforeTarget()
{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
}
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,11 +332,13 @@ 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);
}
@@ -339,7 +354,8 @@ inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p
deepest = max[2];
}
inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
{
if (GridHelpers::insideProscenium (boundary, poly)) {
if (occluder == NULL) {
// Disposal of occluder will be handled in BoxGrid::distributePolygons(),
@@ -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,8 +378,8 @@ 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 ) {
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,46 +1,51 @@
//
// 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()) {
@@ -48,18 +53,20 @@ CulledOccluderSource::CulledOccluderSource (const GridHelpers::Transform& t, Win
}
}
CulledOccluderSource::~CulledOccluderSource() {
}
CulledOccluderSource::~CulledOccluderSource() {}
bool CulledOccluderSource::testCurrent() {
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() {
bool CulledOccluderSource::next()
{
while (OccluderSource::next()) {
if (testCurrent()) {
++rejected;
@@ -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,23 +122,20 @@ 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;
@@ -138,8 +145,7 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// 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,15 +157,13 @@ 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.
// 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())) {
@@ -169,7 +173,8 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
// 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) {
@@ -202,12 +207,14 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
Vec3r point = bestOccluderTarget->center2d();
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]) {
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,18 +232,14 @@ 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.
// 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++) {
@@ -259,19 +262,20 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
}
// 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) {
void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge *fe)
{
if (gridSpaceOccluderProsceniumInitialized) {
GridHelpers::expandProscenium(gridSpaceOccluderProscenium, transform(fe->center3d()));
} else {
}
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);
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);
@@ -60,4 +66,4 @@ private:
bool gridSpaceOccluderProsceniumInitialized;
};
#endif // CULLEDOCCLUDERSOURCE_H
#endif // __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__

View File

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

View File

@@ -1,57 +1,61 @@
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef FEDGEXDETECTOR_H
# define FEDGEXDETECTOR_H
/** \file blender/freestyle/intern/view_map/FEdgeXDetector.h
* \ingroup freestyle
* \brief Detects/flags/builds extended features edges on the WXEdge structure
* \author Stephane Grabli
* \date 26/10/2003
*/
#include <vector>
# include "../system/FreestyleConfig.h"
#include "../geometry/Geom.h"
# include "../winged_edge/WXEdge.h"
# include "../winged_edge/Curvature.h"
#include "../system/FreestyleConfig.h"
#include "../system/ProgressBar.h"
#include "../system/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 = 0;
_pRenderMonitor = 0;
FEdgeXDetector()
{
_pProgressBar = NULL;
_pRenderMonitor = NULL;
_computeViewIndependant = true;
_bbox_diagonal = 1.0;
_meanEdgeSize = 0;
@@ -65,6 +69,7 @@ public:
_kr_derivative_epsilon = 0.0;
_creaseAngle = 0.7; // angle of 134.43 degrees
}
virtual ~FEdgeXDetector() {}
/*! Process shapes from a WingedEdge containing a list of WShapes */
@@ -83,13 +88,15 @@ public:
// 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.
* 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) {
// XXX angle should be in radian...
inline void setCreaseAngle(real angle)
{
if (angle < 0.0)
angle = 0.0;
else if (angle > 180.0)
@@ -118,7 +125,8 @@ public:
* \param dkr
* The minimal derivative of the radial curvature
*/
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr) {
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr)
{
if (dkr != _kr_derivative_epsilon) {
_kr_derivative_epsilon = dkr;
_changes = true;
@@ -137,40 +145,70 @@ public:
virtual void buildSmoothEdges(WXShape *iShape);
/*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;}
inline void enableOrthographicProjection(bool b) {_orthographicProjection = b;}
inline void enableRidgesAndValleysFlag(bool b) {_computeRidgesAndValleys = b;}
inline void enableSuggestiveContours(bool b) {_computeSuggestiveContours = b;}
inline void enableMaterialBoundaries(bool b) {_computeMaterialBoundaries = b;}
inline void enableFaceSmoothness(bool b) {
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) {
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) {
inline void setSphereRadius(real r)
{
if (r != _sphereRadius) {
_sphereRadius = r;
_changes=true;
}
}
inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;}
inline void setProgressBar(ProgressBar *iProgressBar)
{
_pProgressBar = iProgressBar;
}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
{
_pRenderMonitor = iRenderMonitor;
}
protected:
Vec3r _Viewpoint;
real _bbox_diagonal; // diagonal of the current processed shape bbox
//oldtmp values
@@ -200,4 +238,4 @@ protected:
RenderMonitor *_pRenderMonitor;
};
#endif // FEDGEDXETECTOR_H
#endif // __FREESTYLE_FEDGE_X_DETECTOR_H__

View File

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

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 "../system/Precision.h"
# include "Interface0D.h"
# include "../geometry/Geom.h"
# include "../system/Exception.h"
# include "../scene_graph/FrsMaterial.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"
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,36 +74,40 @@ 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.
*/
/*! 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 );
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
@@ -120,12 +130,12 @@ UnaryFunction0D() { py_uf0D = 0;}
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
#endif // SWIG
//
// Functions definitions
//
///////////////////////////////////////////////////////////
class ViewShape;
namespace Functions0D {
// GetXF0D
@@ -134,11 +144,14 @@ namespace Functions0D {
{
public:
/*! Returns the string "GetXF0D" */
string getName() const {
string getName() const
{
return "GetXF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter) {
int operator()(Interface0DIterator& iter)
{
result = iter->getX();
return 0;
}
@@ -150,11 +163,14 @@ namespace Functions0D {
{
public:
/*! Returns the string "GetYF0D" */
string getName() const {
string getName() const
{
return "GetYF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter) {
int operator()(Interface0DIterator& iter)
{
result = iter->getY();
return 0;
}
@@ -166,11 +182,14 @@ namespace Functions0D {
{
public:
/*! Returns the string "GetZF0D" */
string getName() const {
string getName() const
{
return "GetZF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter) {
int operator()(Interface0DIterator& iter)
{
result = iter->getZ();
return 0;
}
@@ -182,11 +201,14 @@ namespace Functions0D {
{
public:
/*! Returns the string "GetProjectedXF0D" */
string getName() const {
string getName() const
{
return "GetProjectedXF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter) {
int operator()(Interface0DIterator& iter)
{
result = iter->getProjectedX();
return 0;
}
@@ -198,11 +220,14 @@ namespace Functions0D {
{
public:
/*! Returns the string "GetProjectedYF0D" */
string getName() const {
string getName() const
{
return "GetProjectedYF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter) {
int operator()(Interface0DIterator& iter)
{
result = iter->getProjectedY();
return 0;
}
@@ -214,11 +239,14 @@ namespace Functions0D {
{
public:
/*! Returns the string "GetProjectedZF0D" */
string getName() const {
string getName() const
{
return "GetProjectedZF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter) {
int operator()(Interface0DIterator& iter)
{
result = iter->getProjectedZ();
return 0;
}
@@ -230,11 +258,14 @@ namespace Functions0D {
{
public:
/*! Returns the string "GetCurvilinearAbscissaF0D" */
string getName() const {
string getName() const
{
return "GetCurvilinearAbscissaF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter) {
int operator()(Interface0DIterator& iter)
{
result = iter.t();
return 0;
}
@@ -246,94 +277,101 @@ namespace Functions0D {
{
public:
/*! Returns the string "GetCurvilinearAbscissaF0D" */
string getName() const {
string getName() const
{
return "GetParameterF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter) {
int operator()(Interface0DIterator& iter)
{
result = iter.u();
return 0;
}
};
// VertexOrientation2DF0D
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element
* to which the Interface0DIterator& belongs to and
/*! 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 {
string getName() const
{
return "VertexOrientation2DF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// VertexOrientation3DF0D
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element
* to which the Interface0DIterator& belongs to and
/*! 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 {
string getName() const
{
return "VertexOrientation3DF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// Curvature2DAngleF0D
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element
* to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
/*! 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 {
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.
/*! 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 {
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
/*! 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 {
string getName() const
{
return "Normal2DF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
@@ -341,22 +379,21 @@ namespace Functions0D {
// 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.
* 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 {
string getName() const
{
return "MaterialF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
@@ -364,20 +401,20 @@ namespace Functions0D {
// 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.
* 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 {
string getName() const
{
return "ShapeIdF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
@@ -385,86 +422,85 @@ namespace Functions0D {
// 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.
* 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 {
string getName() const
{
return "QuantitativeInvisibilityF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// CurveNatureF0D
/*! Returns the Nature::EdgeNature of the 1D element the
* Interface0DIterator& belongs to.
*/
/*! 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 {
string getName() const
{
return "CurveNatureF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// GetShapeF0D
/*! Returns the ViewShape*
* containing the Interface0D
*/
/*! Returns the ViewShape* containing the Interface0D */
class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*>
{
public:
/*! Returns the string "GetShapeF0D" */
string getName() const {
string getName() const
{
return "GetShapeF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// GetOccludersF0D
/*! Returns a vector containing the ViewShape*
* occluding the Interface0D
*/
/*! 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 {
string getName() const
{
return "GetOccludersF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
// GetOccludeeF0D
/*! Returns the ViewShape*
* "occluded" by the Interface0D
*/
/*! Returns the ViewShape* "occluded" by the Interface0D */
class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
{
public:
/*! Returns the string "GetOccludeeF0D" */
string getName() const {
string getName() const
{
return "GetOccludeeF0D";
}
/*! the () operator. */
int operator()(Interface0DIterator& iter);
};
/////////////////////////// Internal ////////////////////////////
// getFEdge
@@ -473,15 +509,11 @@ namespace Functions0D {
// getFEdges
LIB_VIEW_MAP_EXPORT
void getFEdges(Interface0DIterator& it,
FEdge*& fe1,
FEdge*& fe2);
void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
// getViewEdges
LIB_VIEW_MAP_EXPORT
void getViewEdges(Interface0DIterator& it,
ViewEdge *&ve1,
ViewEdge *&ve2);
void getViewEdges(Interface0DIterator& it, ViewEdge *&ve1, ViewEdge *&ve2);
// getShapeF0D
LIB_VIEW_MAP_EXPORT
@@ -497,4 +529,4 @@ namespace Functions0D {
} // end of namespace Functions0D
#endif // FUNCTIONS0D_H
#endif // __FREESTYLE_FUNCTIONS_0D_H__

View File

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

View File

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

View File

@@ -1,74 +1,85 @@
//
// 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);
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) {
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()) {
const Vec3r& initialPoint = source.getGridSpacePolygon().getVertices()[0];
@@ -79,15 +90,19 @@ public:
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])) {
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 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 ~GridDensityProviderFactory () {}
};
#endif // GRIDDENSITYPROVIDER_H
#endif // __FREESTYLE_GRID_DENSITY_PROVIDER_H__

View File

@@ -1,32 +1,36 @@
//
// 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"
@@ -37,24 +41,30 @@ HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real si
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()) {
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()) {
return (auto_ptr<GridDensityProvider>) p23;
} else {
}
else {
return (auto_ptr<GridDensityProvider>) avg;
}
}
@@ -67,8 +77,8 @@ auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensit
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef HEURISTICGRIDDENSITYPROVIDERFACTORY_H
#define HEURISTICGRIDDENSITYPROVIDERFACTORY_H
/** \file blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
* \author Alexander Beels
* \date 2011-2-8
*/
//#include <memory> // provided by GridDensityProvider.h
#include "AverageAreaGridDensityProvider.h"
//#include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
#include "Pow23GridDensityProvider.h"
#include "AverageAreaGridDensityProvider.h"
class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory {
class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory
{
public:
HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
~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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef INTERFACE0D_H
# define INTERFACE0D_H
/** \file blender/freestyle/intern/view_map/Interface0D.h
* \ingroup freestyle
* \brief Interface to 0D elts
* \author Emmanuel Turquin
* \date 01/07/2003
*/
#include <iostream>
#include <Python.h>
#include <string>
# include <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
/*! Returns the string "Interface0D". */
virtual string getExactTypeName() const {
virtual string getExactTypeName() const
{
return "Interface0D";
}
// Data access methods
/*! Returns the 3D x coordinate of the point. */
virtual real getX() const {
virtual real getX() const
{
PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
return 0;
}
/*! Returns the 3D y coordinate of the point. */
virtual real getY() const {
virtual real getY() const
{
PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
return 0;
}
/*! Returns the 3D z coordinate of the point. */
virtual real getZ() const {
virtual real getZ() const
{
PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
return 0;
}
/*! Returns the 3D point. */
virtual Geometry::Vec3f getPoint3D() const {
virtual Geometry::Vec3f getPoint3D() const
{
PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
return 0;
}
/*! Returns the 2D x coordinate of the point. */
virtual real getProjectedX() const {
virtual real getProjectedX() const
{
PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
return 0;
}
/*! Returns the 2D y coordinate of the point. */
virtual real getProjectedY() const {
virtual real getProjectedY() const
{
PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
return 0;
}
/*! Returns the 2D z coordinate of the point. */
virtual real getProjectedZ() const {
virtual real getProjectedZ() const
{
PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
return 0;
}
/*! Returns the 2D point. */
virtual Geometry::Vec2f getPoint2D() const {
virtual Geometry::Vec2f getPoint2D() const
{
PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
return 0;
}
/*! Returns the FEdge that lies between this Interface0D and the
* Interface0D given as argument. */
virtual FEdge* getFEdge(Interface0D&) {
/*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */
virtual FEdge* getFEdge(Interface0D&)
{
PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
return 0;
}
/*! Returns the Id of the point. */
virtual Id getId() const {
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 {
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(){
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(){
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(){
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(){
virtual TVertex *castToTVertex()
{
PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
return 0;
}
};
@@ -170,16 +192,17 @@ public:
class Interface0DIteratorNested : public Iterator
{
public:
virtual ~Interface0DIteratorNested() {}
virtual string getExactTypeName() const {
virtual string getExactTypeName() const
{
return "Interface0DIteratorNested";
}
virtual Interface0D& operator*() = 0;
virtual Interface0D* operator->() {
virtual Interface0D* operator->()
{
return &(operator*());
}
@@ -193,12 +216,14 @@ public:
virtual bool operator==(const Interface0DIteratorNested& it) const = 0;
virtual bool operator!=(const Interface0DIteratorNested& it) const {
virtual bool operator!=(const Interface0DIteratorNested& it) const
{
return !(*this == it);
}
/*! Returns the curvilinear abscissa */
virtual float t() const = 0;
/*! Returns the point parameter 0<u<1 */
virtual float u() const = 0;
@@ -212,39 +237,39 @@ 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) {
Interface0DIterator(Interface0DIteratorNested* it = NULL)
{
_iterator = it;
}
/*! Copy constructor */
Interface0DIterator(const Interface0DIterator& it) {
Interface0DIterator(const Interface0DIterator& it)
{
_iterator = it._iterator->copy();
}
/*! Destructor */
virtual ~Interface0DIterator() {
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.
* \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) {
Interface0DIterator& operator=(const Interface0DIterator& it)
{
if(_iterator)
delete _iterator;
_iterator = it._iterator->copy();
@@ -252,7 +277,8 @@ public:
}
/*! Returns the string "Interface0DIterator". */
virtual string getExactTypeName() const {
virtual string getExactTypeName() const
{
if (!_iterator)
return "Interface0DIterator";
return _iterator->getExactTypeName() + "Proxy";
@@ -261,100 +287,104 @@ public:
// FIXME test it != 0 (exceptions ?)
/*! Returns a reference to the pointed Interface0D.
* In the scripting language, you must call
* "getObject()" instead using this operator.
* In the scripting language, you must call "getObject()" instead using this operator.
*/
Interface0D& operator*() {
Interface0D& operator*()
{
return _iterator->operator*();
}
/*! Returns a pointer to the pointed Interface0D.
* Can't be called in the scripting language.
*/
Interface0D* operator->() {
Interface0D *operator->()
{
return &(operator*());
}
/*! Increments. In the scripting language, call
* "increment()".
*/
Interface0DIterator& operator++() {
/*! Increments. In the scripting language, call "increment()". */
Interface0DIterator& operator++()
{
_iterator->increment();
return *this;
}
/*! Increments. In the scripting language, call
* "increment()".
*/
Interface0DIterator operator++(int) {
/*! 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--() {
/*! Decrements. In the scripting language, call "decrement()". */
Interface0DIterator& operator--()
{
_iterator->decrement();
return *this;
}
/*! Decrements. In the scripting language, call
* "decrement()".
*/
Interface0DIterator operator--(int) {
/*! Decrements. In the scripting language, call "decrement()". */
Interface0DIterator operator--(int)
{
Interface0DIterator ret(*this);
_iterator->decrement();
return ret;
}
/*! Increments. */
virtual int increment() {
virtual int increment()
{
return _iterator->increment();
}
/*! Decrements. */
virtual int decrement() {
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.
/*! 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 {
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 {
/*! 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 {
bool operator==(const Interface0DIterator& it) const
{
return _iterator->operator==(*(it._iterator));
}
/*! operator != . */
bool operator!=(const Interface0DIterator& it) const {
bool operator!=(const Interface0DIterator& it) const
{
return !(*this == it);
}
/*! Returns the curvilinear abscissa. */
inline float t() const {
inline float t() const
{
return _iterator->t();
}
/*! Returns the point parameter in the curve 0<=u<=1. */
inline float u() const {
inline float u() const
{
return _iterator->u();
}
protected:
protected:
Interface0DIteratorNested *_iterator;
};
#endif // INTERFACE0D_H
#endif // __FREESTYLE_INTERFACE_0D_H__

View File

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

View File

@@ -1,44 +1,51 @@
//
// 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);
@@ -49,7 +56,8 @@ void OccluderSource::buildCachedPolygon() {
cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
}
void OccluderSource::begin() {
void OccluderSource::begin()
{
vector<WShape*>& wshapes = wingedEdge.getWShapes();
currentShape = wshapes.begin();
shapesEnd = wshapes.end();
@@ -74,7 +82,8 @@ bool OccluderSource::next() {
if (currentShape == shapesEnd) {
valid = false;
return false;
} else {
}
else {
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
currentFace = wFaces.begin();
facesEnd = wFaces.end();
@@ -86,25 +95,30 @@ 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];
@@ -113,10 +127,12 @@ void OccluderSource::getOccluderProscenium(real proscenium[4]) {
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()) {
@@ -128,5 +144,3 @@ real OccluderSource::averageOccluderArea() {
area /= numFaces;
return area;
}

View File

@@ -1,40 +1,46 @@
//
// 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);
@@ -67,4 +73,4 @@ protected:
void buildCachedPolygon();
};
#endif // OCCLUDERSOURCE_H
#endif // __FREESTYLE_OCCLUDER_SOURCE_H__

View File

@@ -1,32 +1,36 @@
//
// 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"
@@ -36,7 +40,8 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const
initialize (proscenium);
}
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numFaces)
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform, unsigned numFaces)
: GridDensityProvider(source), numFaces(numFaces)
{
real proscenium[4];
@@ -91,12 +96,15 @@ Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFac
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,46 +1,52 @@
//
// 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);
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();
@@ -51,17 +57,19 @@ private:
void initialize(const real proscenium[4]);
};
class Pow23GridDensityProviderFactory : public GridDensityProviderFactory {
class Pow23GridDensityProviderFactory : public GridDensityProviderFactory
{
public:
Pow23GridDensityProviderFactory(unsigned numFaces);
~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,23 +1,36 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// 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"
@@ -30,26 +43,31 @@
/* */
/**********************************/
Nature::VertexNature SVertex::getNature() const {
Nature::VertexNature SVertex::getNature() const
{
Nature::VertexNature nature = Nature::S_VERTEX;
if (_pViewVertex)
nature |= _pViewVertex->getNature();
return nature;
}
SVertex * SVertex::castToSVertex(){
SVertex *SVertex::castToSVertex()
{
return this;
}
ViewVertex * SVertex::castToViewVertex(){
ViewVertex *SVertex::castToViewVertex()
{
return _pViewVertex;
}
NonTVertex * SVertex::castToNonTVertex(){
NonTVertex *SVertex::castToNonTVertex()
{
return dynamic_cast<NonTVertex*>(_pViewVertex);
}
TVertex * SVertex::castToTVertex(){
TVertex *SVertex::castToTVertex()
{
return dynamic_cast<TVertex*>(_pViewVertex);
}
@@ -58,9 +76,22 @@ float SVertex::shape_importance() const
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
{
@@ -128,62 +159,49 @@ real SVertex::z_discontinuity() const
FEdge *SVertex::fedge()
{
if (getNature() & Nature::T_VERTEX)
return 0;
return NULL;
return _FEdges[0];
}
FEdge *SVertex::getFEdge(Interface0D& inter)
{
FEdge * result = 0;
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)))
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))
{
if ((result == 0) && (getNature() & Nature::T_VERTEX)) {
SVertex *brother;
ViewVertex *vvertex = viewvertex();
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
if(tvertex)
{
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)))
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))
{
if ((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) {
SVertex *brother;
ViewVertex *vvertex = iVertexB->viewvertex();
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
if(tvertex)
{
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)))
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);
}
}
@@ -202,8 +220,18 @@ FEdge* SVertex::getFEdge(Interface0D& inter)
/**********************************/
int FEdge::viewedge_nature() const {return _ViewEdge->getNature();}
//float FEdge::viewedge_length() const {return _ViewEdge->viewedge_length();}
int FEdge::viewedge_nature() const
{
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();
@@ -222,21 +250,36 @@ int FEdge::invisibility() const
return _ViewEdge->qi();
}
occluder_container::const_iterator FEdge::occluders_begin() const {return _ViewEdge->occluders_begin();}
occluder_container::const_iterator FEdge::occluders_end() const {return _ViewEdge->occluders_end();}
bool FEdge::occluders_empty() const {return _ViewEdge->occluders_empty();}
int FEdge::occluders_size() const {return _ViewEdge->occluders_size();}
occluder_container::const_iterator FEdge::occluders_begin() const
{
return _ViewEdge->occluders_begin();
}
occluder_container::const_iterator FEdge::occluders_end() const
{
return _ViewEdge->occluders_end();
}
bool FEdge::occluders_empty() const
{
return _ViewEdge->occluders_empty();
}
int FEdge::occluders_size() const
{
return _ViewEdge->occluders_size();
}
const bool FEdge::occludee_empty() const
{
return _ViewEdge->occludee_empty();
}
Id FEdge::shape_id() const
{
return _VertexA->shape()->getId();
}
const SShape *FEdge::shape() const
{
return _VertexA->shape();
@@ -244,8 +287,7 @@ const SShape* FEdge::shape() const
real FEdge::z_discontinuity() const
{
if(!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER))
{
if (!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) {
return 0;
}
@@ -253,89 +295,85 @@ real FEdge::z_discontinuity() const
Vec3r bbox_size_vec(box.getMax() - box.getMin());
real bboxsize = bbox_size_vec.norm();
if(occludee_empty())
{
if (occludee_empty()) {
//return FLT_MAX;
return 1.0;
//return bboxsize;
}
// real result;
// z_discontinuity_functor<SVertex> _functor;
// Evaluate<SVertex,z_discontinuity_functor<SVertex> >(&_functor, iCombination, result )
#if 0
real result;
z_discontinuity_functor<SVertex> _functor;
Evaluate<SVertex, z_discontinuity_functor<SVertex> >(&_functor, iCombination, result);
#endif
Vec3r middle((_VertexB->point3d() - _VertexA->point3d()));
middle /= 2;
Vec3r disc_vec(middle - _occludeeIntersection);
real res = disc_vec.norm() / bboxsize;
return res;
return 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;
//}
return result;
}
float FEdge::local_depth_variance(int iCombination ) const
{
float result;
local_depth_variance_functor<SVertex> functor;
Evaluate(&functor, iCombination, result);
return result;
}
real FEdge::local_average_density( float sigma, int iCombination) const
{
float result;
density_functor<SVertex> functor(sigma);
Evaluate(&functor, iCombination, result);
return result;
}
Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */)
{
Vec3r Na = _VertexA->normal(oException);
if (oException != Exception::NO_EXCEPTION)
return Na;
Vec3r Nb = _VertexB->normal(oException);
if (oException != Exception::NO_EXCEPTION)
return Nb;
return (Na + Nb) / 2.0;
}
Vec3r FEdge::curvature2d_as_vector(int iCombination) const
{
Vec3r result;
curvature2d_as_vector_functor<SVertex> _functor;
Evaluate<Vec3r, curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result);
return result;
}
real FEdge::curvature2d_as_angle(int iCombination) const
{
real result;
curvature2d_as_angle_functor<SVertex> _functor;
Evaluate<real, curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result);
return result;
}
#endif
/**********************************/
/* */
@@ -345,15 +383,20 @@ real FEdge::z_discontinuity() const
/* */
/**********************************/
//Material FEdge::material() const
//{
// return _VertexA->shape()->material();
//}
const FrsMaterial& FEdgeSharp::aFrsMaterial() const {
#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 {
const FrsMaterial& FEdgeSharp::bFrsMaterial() const
{
return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
}
@@ -365,6 +408,7 @@ const FrsMaterial& FEdgeSharp::bFrsMaterial() const {
/* */
/**********************************/
const FrsMaterial& FEdgeSmooth::frs_material() const {
const FrsMaterial& FEdgeSmooth::frs_material() const
{
return _VertexA->shape()->frs_material(_FrsMaterialIndex);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,62 +1,88 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// 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},
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, 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, 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
{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},
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, 0, 0, 1}
};
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0,0,0,1}};
{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];
@@ -64,24 +90,21 @@ void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const
_translation[2] = iModelViewMatrix[3][2];
for (i = 0; i < 4; i++) {
for(j=0; j<4; j++)
{
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++)
{
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++)
{
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];
@@ -102,50 +125,56 @@ void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
_zfar = iZFar;
}
void SilhouetteGeomEngine::retrieveViewport(int viewport[4]){
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;
#if 0
real min = HUGE;
real max = -HUGE;
#endif
vector<SVertex*>::iterator sv, svend;
const real depth = _zfar - _znear;
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
for(sv=ioVertices.begin(), svend=ioVertices.end();
sv!=svend;
sv++)
{
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;
#if 0
cerr << (*sv)->point2d().z() << " ";
real d = (*sv)->point2d()[2];
if (d > max)
max =d;
if (d < min)
min =d;
#endif
}
// 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]<<" ";
// }
#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)
{
Vec3r newPoint;
// real min=HUGE;
// real max=-HUGE;
#if 0
real min = HUGE;
real max = -HUGE;
vector<SVertex*>::iterator sv, svend;
#endif
const real depth = _zfar - _znear;
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
ioVertex->setPoint2D(newPoint);
@@ -156,8 +185,7 @@ real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
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;
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,42 +1,47 @@
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef SILHOUETTEGEOMENGINE_H
# define SILHOUETTEGEOMENGINE_H
/** \file blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
* \ingroup freestyle
* \brief Class to perform all geometric operations dedicated to silhouette. That, for example, implies that
* this geom engine has as member data the viewpoint, transformations, projections...
* \author Stephane Grabli
* \date 03/09/2002
*/
#include <vector>
# include "../system/FreestyleConfig.h"
#include "../geometry/Geom.h"
#include "../system/FreestyleConfig.h"
using namespace Geometry;
class SVertex;
@@ -45,38 +50,47 @@ class FEdge;
class LIB_VIEW_MAP_EXPORT SilhouetteGeomEngine
{
private:
static Vec3r _Viewpoint; // The viewpoint under which the silhouette has to be computed
// The viewpoint under which the silhouette has to be computed
static Vec3r _Viewpoint;
static real _translation[3];
static real _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
// 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 _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 SilhouetteGeomEngine *_pInstance;
public:
public:
/*! retrieves an instance on the singleton */
static SilhouetteGeomEngine *getInstance()
{
if(0 == _pInstance)
{
if(0 == _pInstance) {
_pInstance = new SilhouetteGeomEngine;
}
return _pInstance;
}
/*! Sets the current viewpoint */
static inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;}
static inline void setViewpoint(const Vec3r& ivp)
{
_Viewpoint = ivp;
}
/*! Sets the current transformation
* iModelViewMatrix
@@ -88,10 +102,10 @@ public:
* iFocal
* The focal length
*/
static void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocal) ;
static void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
const int iViewport[4], real iFocal);
/*! Sets the current znear and zfar
*/
/*! Sets the current znear and zfar */
static void setFrustum(real iZNear, real iZFar);
/* accessors */
@@ -100,8 +114,7 @@ public:
/*! 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.
* The vertices to project. It is modified during the operation.
*/
static void ProjectSilhouette(std::vector<SVertex*>& ioVertices);
static void ProjectSilhouette(SVertex *ioVertex);
@@ -120,4 +133,4 @@ public:
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
@@ -46,7 +51,8 @@ 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);
}
@@ -67,12 +76,11 @@ void SphericalGrid::Cell::indexPolygons() {
//////////////////
SphericalGrid::Iterator::Iterator(SphericalGrid& grid, Vec3r& center, real epsilon)
: _target(SphericalGrid::Transform::sphericalProjection(center)),
_foundOccludee(false)
: _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;
@@ -87,9 +95,9 @@ 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();
@@ -128,7 +136,6 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
getCellCoordinates(point, i, j);
if (_cells[i * _cellsY + j] == NULL) {
// This is an uninitialized cell
real x, y, width, height;
x = _cellOrigin[0] + _cellSize * i;
@@ -145,7 +152,8 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
}
}
void SphericalGrid::distributePolygons (OccluderSource& source) {
void SphericalGrid::distributePolygons(OccluderSource& source)
{
unsigned long nFaces = 0;
unsigned long nKeptFaces = 0;
@@ -157,10 +165,10 @@ void SphericalGrid::distributePolygons (OccluderSource& source) {
_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,7 +178,8 @@ 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) {
@@ -179,37 +188,43 @@ void SphericalGrid::reorganizeCells () {
}
}
void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) {
void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
{
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
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,70 +1,78 @@
//
// 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.
// 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);
@@ -84,28 +92,22 @@ 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);
explicit Iterator(SphericalGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
~Iterator();
void initBeforeTarget();
void initAfterTarget();
@@ -128,7 +130,8 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate;
};
class Transform : public GridHelpers::Transform {
class Transform : public GridHelpers::Transform
{
public:
explicit Transform();
explicit Transform(Transform& other);
@@ -140,16 +143,17 @@ private:
// Prevent implicit copies and assignments.
SphericalGrid(const SphericalGrid& other);
SphericalGrid& operator=(const SphericalGrid& other);
public:
explicit SphericalGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
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();
@@ -176,23 +180,25 @@ private:
bool _enableQI;
};
inline void SphericalGrid::Iterator::initBeforeTarget () {
inline void SphericalGrid::Iterator::initBeforeTarget()
{
_current = _cell->faces.begin();
while (_current != _cell->faces.end() && !testOccluder(false)) {
++_current;
}
}
inline void SphericalGrid::Iterator::initAfterTarget () {
inline void SphericalGrid::Iterator::initAfterTarget()
{
if (_foundOccludee) {
#if sphericalgridlogging == 1
#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
@@ -201,26 +207,25 @@ inline void SphericalGrid::Iterator::initAfterTarget () {
}
}
inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
inline bool SphericalGrid::Iterator::testOccluder(bool wantOccludee)
{
// End-of-list is not even a valid iterator position
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.
// 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 SPHERICAL_GRID_LOGGING
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
#endif
_current = _cell->faces.end();
@@ -232,14 +237,15 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
// Specific continue or stop conditions when searching for each type
if (wantOccludee) {
if ((*_current)->deepest < _target[2]) {
#if sphericalgridlogging == 1
#if SPHERICAL_GRID_LOGGING
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
#endif
return false;
}
} else {
}
else {
if ((*_current)->shallowest > _target[2]) {
#if sphericalgridlogging == 1
#if SPHERICAL_GRID_LOGGING
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
#endif
return true;
@@ -252,44 +258,43 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
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 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 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) {
markCurrentOccludeeCandidate(depth);
}
} else {
#if sphericalgridlogging == 1
}
else {
#if SPHERICAL_GRID_LOGGING
std::cout << std::endl;
#endif
}
}
inline void SphericalGrid::Iterator::nextOccluder () {
inline void SphericalGrid::Iterator::nextOccluder()
{
if (_current != _cell->faces.end()) {
do {
++_current;
@@ -297,7 +302,8 @@ inline void SphericalGrid::Iterator::nextOccluder () {
}
}
inline void SphericalGrid::Iterator::nextOccludee () {
inline void SphericalGrid::Iterator::nextOccludee()
{
if (_current != _cell->faces.end()) {
do {
++_current;
@@ -305,16 +311,19 @@ inline void SphericalGrid::Iterator::nextOccludee () {
}
}
inline bool SphericalGrid::Iterator::validBeforeTarget () {
inline bool SphericalGrid::Iterator::validBeforeTarget()
{
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
}
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,7 +352,7 @@ 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) {
deepest = t;
@@ -351,7 +360,8 @@ inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygo
}
}
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
{
if (GridHelpers::insideProscenium (boundary, poly)) {
if (occluder == NULL) {
// Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
@@ -362,7 +372,8 @@ inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3
}
}
inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) {
inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
{
Polygon3r& poly(source.getGridSpacePolygon());
occluder = NULL;
@@ -373,8 +384,8 @@ 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 ) {
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,57 +1,78 @@
//
// 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){
using namespace Geometry;
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)));
for (unsigned int i = 0; i < _nbOrientations; ++i) {
_directions.push_back(Vec2d(cos((float)i * M_PI / (float)_nbOrientations),
sin((float)i * M_PI / (float)_nbOrientations)));
}
Build();
}
void SteerableViewMap::Build(){
void SteerableViewMap::Build()
{
_imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
memset((_imagesPyramids), 0, (_nbOrientations + 1) * sizeof(ImagePyramid *));
}
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother)
{
_nbOrientations = iBrother._nbOrientations;
unsigned i;
unsigned int i;
_bound = iBrother._bound;
_directions = iBrother._directions;
_mapping = iBrother._mapping;
@@ -60,12 +81,14 @@ SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){
_imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
}
SteerableViewMap::~SteerableViewMap(){
SteerableViewMap::~SteerableViewMap()
{
Clear();
}
void SteerableViewMap::Clear(){
unsigned i;
void SteerableViewMap::Clear()
{
unsigned int i;
if (_imagesPyramids) {
for (i = 0; i <= _nbOrientations; ++i) {
if (_imagesPyramids[i])
@@ -75,31 +98,32 @@ void SteerableViewMap::Clear(){
_imagesPyramids = 0;
}
if (!_mapping.empty()) {
for(map<unsigned int, double*>::iterator m=_mapping.begin(), mend=_mapping.end();
m!=mend;
++m){
for (map<unsigned int, double*>::iterator m = _mapping.begin(), mend = _mapping.end(); m != mend; ++m) {
delete[] (*m).second;
}
_mapping.clear();
}
}
void SteerableViewMap::Reset(){
void SteerableViewMap::Reset()
{
Clear();
Build();
}
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i){
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i)
{
double dotp = fabs(dir * _directions[i]);
if (dotp < _bound)
return 0;
if(dotp>1)
dotp = 1;
return 0.0;
if (dotp > 1.0)
dotp = 1.0;
return cos((float)_nbOrientations / 2.0 * acos(dotp));
}
double * SteerableViewMap::AddFEdge(FEdge *iFEdge){
double *SteerableViewMap::AddFEdge(FEdge *iFEdge)
{
unsigned i;
unsigned id = iFEdge->getId().getFirst();
map<unsigned int, double* >::iterator o = _mapping.find(id);
@@ -108,12 +132,12 @@ double * SteerableViewMap::AddFEdge(FEdge *iFEdge){
}
double *res = new double[_nbOrientations];
for (i = 0; i < _nbOrientations; ++i) {
res[i] = 0;
res[i] = 0.0;
}
Vec3r o2d3 = iFEdge->orientation2d();
Vec2r o2d2(o2d3.x(), o2d3.y());
real norm = o2d2.norm();
if(norm < 1e-6){
if (norm < 1.0e-6) {
return res;
}
o2d2 /= norm;
@@ -125,17 +149,18 @@ double * SteerableViewMap::AddFEdge(FEdge *iFEdge){
return res;
}
unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){
unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient)
{
Vec2f dir(orient);
//soc unsigned res = 0;
real norm = dir.norm();
if(norm < 1e-6){
if (norm < 1.0e-6) {
return _nbOrientations + 1;
}
dir /= norm;
double maxw = 0.f;
double maxw = 0.0f;
unsigned winner = _nbOrientations + 1;
for(unsigned i=0; i<_nbOrientations; ++i){
for (unsigned int i = 0; i < _nbOrientations; ++i) {
double w = ComputeWeight(dir, i);
if (w > maxw) {
maxw = w;
@@ -145,12 +170,12 @@ unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){
return winner;
}
unsigned SteerableViewMap::getSVMNumber(unsigned id){
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;
double maxw = 0.0;
unsigned winner = _nbOrientations + 1;
for (unsigned i = 0; i < _nbOrientations; ++i) {
double w = wvalues[i];
@@ -164,8 +189,9 @@ unsigned SteerableViewMap::getSVMNumber(unsigned id){
return _nbOrientations + 1;
}
void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma){
for(unsigned i=0; i<=_nbOrientations; ++i){
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;
@@ -177,7 +203,8 @@ void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy
}
}
float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y){
float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y)
{
ImagePyramid *pyramid = _imagesPyramids[iOrientation];
if (pyramid == 0) {
cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
@@ -185,29 +212,33 @@ float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLe
}
if ((x < 0) || (x >= pyramid->width()) || (y < 0) || (y >= pyramid->height()))
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.
//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){
float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y)
{
return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y);
}
unsigned int SteerableViewMap::getNumberOfPyramidLevels() const{
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){
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;
cerr << "SteerableViewMap warning: orientation " << i
<< " of steerable View Map whas not been computed yet" << endl;
continue;
}
int ow = _imagesPyramids[i]->width(0);
@@ -218,7 +249,7 @@ void SteerableViewMap::saveSteerableViewMap() const {
stringstream filename;
for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc
float coeff = 1;//1/255.f; //100*255;//*pow(2,j);
float coeff = 1.0f; // 1 / 255.0f; // 100 * 255; // * pow(2, j);
//soc QImage qtmp(ow, oh, QImage::Format_RGB32);
ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
int rowbytes = ow * 4;
@@ -242,26 +273,26 @@ void SteerableViewMap::saveSteerableViewMap() const {
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");
// }
//
#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,13 +48,16 @@ using namespace std;
class FEdge;
class ImagePyramid;
class GrayImage;
/*! This class checks for every FEdge in which steerable
* it belongs and stores the mapping allowing to retrieve
* this information from the FEdge Id
/*! This class checks for every FEdge in which steerable it belongs and stores the mapping allowing to retrieve
* this information from the FEdge Id.
*/
class LIB_VIEW_MAP_EXPORT SteerableViewMap{
class LIB_VIEW_MAP_EXPORT SteerableViewMap
{
protected:
map<unsigned int, double* > _mapping; // for each vector the list of nbOrientations weigths corresponding to its contributions to the nbOrientations directional maps
// 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
@@ -63,45 +74,40 @@ public:
virtual void Reset();
/*! Adds a FEdge to steerable VM.
* Returns the nbOrientations weigths corresponding to
* the FEdge contributions to the nbOrientations directional maps.
* Returns the nbOrientations weigths corresponding to the FEdge contributions to the nbOrientations
* directional maps.
*/
double *AddFEdge(FEdge *iFEdge);
/*! Compute the weight of direction dir for orientation iNOrientation */
double ComputeWeight(const Vec2d& dir, unsigned iNOrientation);
/*! Returns the number of the SVM to which a direction belongs
* to.
/*! 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.
/*! 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.
* 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.
/*! 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.
* 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.
* 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);
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.
@@ -116,17 +122,13 @@ public:
* \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.
* 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.
* 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.
/*! 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)
*/
@@ -136,7 +138,8 @@ public:
unsigned int getNumberOfPyramidLevels() const;
/*! Returns the number of orientations */
unsigned int getNumberOfOrientations() const{
unsigned int getNumberOfOrientations() const
{
return _nbOrientations;
}
@@ -146,8 +149,6 @@ public:
protected:
void Clear();
void Build();
};
#endif // STEERABLEVIEWMAP_H
#endif // __FREESTYLE_STEERABLE_VIEW_MAP_H__

View File

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

View File

@@ -1,72 +1,86 @@
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef VIEWEDGEXBUILDER_H
# define VIEWEDGEXBUILDER_H
/** \file blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
* \ingroup freestyle
* \brief Class to build view edges and the underlying chains of feature edges...
* \author Stephane Grabli
* \date 27/10/2003
*/
#include <map>
#include <utility>
#include <vector>
// 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
#if 0 // soc
#if defined(__GNUC__) && (__GNUC__ >= 3)
//hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
# include <hash_map.h>
#else
# include <hash_map>
#endif
#endif
#include "Interface1D.h"
#include "../geometry/Geom.h"
#include "../system/FreestyleConfig.h"
# include "../geometry/Geom.h"
# include "Interface1D.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 {
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{
struct epsilonEquals
{
bool operator()(const Vec3r& v1, const Vec3r& v2) const
{
real norm = (v1 - v2).norm();
return (norm<1e-06);
return (norm < 1.0e-06);
}
};
@@ -75,45 +89,79 @@ struct epsilonEquals{
typedef map<Vec3r , SVertex*> SVertexMap;
class WXFaceLayer;
/*! class to describe an oriented smooth edge */
class OWXFaceLayer{
class OWXFaceLayer
{
public:
WXFaceLayer *fl;
bool order;
OWXFaceLayer() {fl=0;order=true;}
OWXFaceLayer(WXFaceLayer *ifl, bool iOrder=true){fl = ifl;order=iOrder;}
OWXFaceLayer& operator=(const OWXFaceLayer& iBrother){
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){
bool operator==(const OWXFaceLayer& b)
{
return ((fl == b.fl) && (order == b.order));
}
bool operator!=(const OWXFaceLayer& b){
bool operator!=(const OWXFaceLayer& b)
{
return !(*this == b);
}
};
class WXEdge;
/*! class to describe an oriented sharp edge */
class OWXEdge{
class OWXEdge
{
public:
WXEdge *e;
bool order;
OWXEdge() {e=0;order=true;}
OWXEdge(WXEdge *ie, bool iOrder=true){e = ie;order=iOrder;}
OWXEdge& operator=(const OWXEdge& iBrother){
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){
bool operator==(const OWXEdge& b)
{
return ((e == b.e) && (order == b.order));
}
bool operator!=(const OWXEdge& b){
bool operator!=(const OWXEdge& b)
{
return !(*this == b);
}
};
@@ -126,24 +174,28 @@ 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:
public:
inline ViewEdgeXBuilder()
{_currentViewId = 1;_currentFId=0;_currentSVertexId=0;}
{
_currentViewId = 1;
_currentFId = 0;
_currentSVertexId = 0;
}
virtual ~ViewEdgeXBuilder() {}
/*! Builds a view shape from a WXShape in which the feature edges
* are flagged
/*! 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.
* 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
@@ -155,29 +207,48 @@ public:
* 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,
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
*/
/*! 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; }
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 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 */
@@ -214,5 +285,4 @@ protected:
ViewShape *_pCurrentVShape;
};
#endif
#endif // __FREESTYLE_VIEW_EDGE_X_BUILDER_H__

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,43 @@
//
// Filename : ViewMapAdvancedIterators.h
// Author(s) : Stephane Grabli
// Purpose : Iterators used to iterate over the various elements of the ViewMap
// These iterators can't be exported to python.
// Date of creation : 01/07/2003
//
///////////////////////////////////////////////////////////////////////////////
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
#define __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef VIEWMAPADVANCEDITERATORS_H
# define VIEWMAPADVANCEDITERATORS_H
/** \file blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
* \ingroup freestyle
* \brief Iterators used to iterate over the various elements of the ViewMap.
* These iterators can't be exported to python.
* \author Stephane Grabli
* \date 01/07/2003
*/
#include "ViewMap.h"
#include "../system/Iterator.h" //soc
/**********************************/
@@ -52,14 +58,17 @@
namespace ViewVertexInternal {
class edge_const_traits : public Const_traits< ::ViewVertex::directedViewEdge> {
class edge_const_traits : public Const_traits< ::ViewVertex::directedViewEdge>
{
public:
typedef vector< ::ViewVertex::directedViewEdge> edges_container;
typedef edges_container::const_iterator edges_container_iterator;
typedef vector< ::ViewVertex::directedViewEdge*> edge_pointers_container;
typedef edge_pointers_container::const_iterator edge_pointers_container_iterator;
};
class edge_nonconst_traits : public Nonconst_traits< ::ViewVertex::directedViewEdge> {
class edge_nonconst_traits : public Nonconst_traits< ::ViewVertex::directedViewEdge>
{
public:
typedef vector< ::ViewVertex::directedViewEdge> edges_container;
typedef edges_container::iterator edges_container_iterator;
@@ -80,12 +89,14 @@ template<class Traits>
typedef typename Traits::edge_pointers_container_iterator edge_pointers_container_iterator;
typedef edge_iterator_base<edge_nonconst_traits> iterator;
typedef edge_iterator_base<edge_const_traits> const_iterator;
public:
friend class ViewVertex;
friend class TVertex;
friend class NonTVertex;
friend class ViewEdge;
friend class edge_iterator;
protected:
Nature::VertexNature _Nature; // the nature of the underlying vertex
// T vertex attributes
@@ -93,11 +104,13 @@ template<class Traits>
edge_pointers_container_iterator _tend;
edge_pointers_container_iterator _tvertex_iter;
// mutable value_type _tvertex_iter;
// value_type _feA;
// value_type _feB;
// value_type _beA;
// value_type _beB;
#if 0
mutable value_type _tvertex_iter;
value_type _feA;
value_type _feB;
value_type _beA;
value_type _beB;
#endif
// Non TVertex attributes
edges_container_iterator _begin;
@@ -108,72 +121,74 @@ template<class Traits>
public:
inline edge_iterator_base() : parent_class() {}
inline edge_iterator_base(Nature::VertexNature iNature)
: parent_class()
{_Nature = iNature;}
edge_iterator_base(const edge_iterator_base<edge_nonconst_traits>& iBrother)
: parent_class(iBrother)
inline edge_iterator_base(Nature::VertexNature iNature) : parent_class()
{
_Nature = iNature;
}
edge_iterator_base(const edge_iterator_base<edge_nonconst_traits>& iBrother) : parent_class(iBrother)
{
_Nature = iBrother._Nature;
if(_Nature & Nature::T_VERTEX)
{
// _feA = iBrother._feA;
// _feB = iBrother._feB;
// _beA = iBrother._beA;
// _beB = iBrother._beB;
// _tvertex_iter = iBrother._tvertex_iter;
if (_Nature & Nature::T_VERTEX) {
#if 0
_feA = iBrother._feA;
_feB = iBrother._feB;
_beA = iBrother._beA;
_beB = iBrother._beB;
_tvertex_iter = iBrother._tvertex_iter;
#endif
_tbegin = iBrother._tbegin;
_tend = iBrother._tend;
_tvertex_iter = iBrother._tvertex_iter;
}
else
{
else {
_begin = iBrother._begin;
_end = iBrother._end;
_nontvertex_iter = iBrother._nontvertex_iter;
}
}
edge_iterator_base(const edge_iterator_base<edge_const_traits>& iBrother)
: parent_class(iBrother)
edge_iterator_base(const edge_iterator_base<edge_const_traits>& iBrother) : parent_class(iBrother)
{
_Nature = iBrother._Nature;
if(_Nature & Nature::T_VERTEX)
{
// _feA = iBrother._feA;
// _feB = iBrother._feB;
// _beA = iBrother._beA;
// _beB = iBrother._beB;
// _tvertex_iter = iBrother._tvertex_iter;
if (_Nature & Nature::T_VERTEX) {
#if 0
_feA = iBrother._feA;
_feB = iBrother._feB;
_beA = iBrother._beA;
_beB = iBrother._beB;
_tvertex_iter = iBrother._tvertex_iter;
#endif
_tbegin = iBrother._tbegin;
_tend = iBrother._tend;
_tvertex_iter = iBrother._tvertex_iter;
}
else
{
else {
_begin = iBrother._begin;
_end = iBrother._end;
_nontvertex_iter = iBrother._nontvertex_iter;
}
}
virtual ~edge_iterator_base() {}
//protected://FIXME
public:
// inline edge_iterator_base(value_type ifeA,
// value_type ifeB,
// value_type ibeA,
// value_type ibeB,
// value_type iter)
// : parent_class()
// {
// _Nature = Nature::T_VERTEX;
// _feA = ifeA;
// _feB = ifeB;
// _beA = ibeA;
// _beB = ibeB;
// _tvertex_iter = iter;
// }
inline edge_iterator_base(edge_pointers_container_iterator begin,
edge_pointers_container_iterator end,
#if 0
inline edge_iterator_base(value_type ifeA, value_type ifeB, value_type ibeA, value_type ibeB, value_type iter)
: parent_class()
{
_Nature = Nature::T_VERTEX;
_feA = ifeA;
_feB = ifeB;
_beA = ibeA;
_beB = ibeB;
_tvertex_iter = iter;
}
#endif
inline edge_iterator_base(edge_pointers_container_iterator begin, edge_pointers_container_iterator end,
edge_pointers_container_iterator iter)
: parent_class()
{
@@ -182,8 +197,8 @@ template<class Traits>
_tend = end;
_tvertex_iter = iter;
}
inline edge_iterator_base(edges_container_iterator begin,
edges_container_iterator end,
inline edge_iterator_base(edges_container_iterator begin, edges_container_iterator end,
edges_container_iterator iter)
: parent_class()
{
@@ -194,8 +209,6 @@ template<class Traits>
}
public:
virtual bool begin() const
{
if (_Nature & Nature::T_VERTEX)
@@ -204,6 +217,7 @@ template<class Traits>
else
return (_nontvertex_iter == _begin);
}
virtual bool end() const
{
if (_Nature & Nature::T_VERTEX)
@@ -214,15 +228,19 @@ template<class Traits>
}
// operators
virtual Self& operator++() // operator corresponding to ++i
// operator corresponding to ++i
virtual Self& operator++()
{
increment();
return *this;
}
// operator corresponding to i++, i.e. which returns the value *and then* increments it.
// That's why we store the value in a temp.
virtual Self operator++(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente.
Self tmp = *this; // C'est pour cela qu'on stocke la valeur
increment(); // dans un temporaire.
{
Self tmp = *this;
increment();
return tmp;
}
@@ -236,7 +254,9 @@ template<class Traits>
}
virtual bool operator==(const Self& b) const
{return !(*this != b);}
{
return !(*this != b);
}
// dereferencing
virtual reference operator*() const
@@ -247,87 +267,82 @@ template<class Traits>
else
return (*_nontvertex_iter);
}
virtual pointer operator->() const { return &(operator*());}
virtual pointer operator->() const
{
return &(operator*());
}
protected:
inline void increment()
{
if(_Nature & Nature::T_VERTEX)
{
if (_Nature & Nature::T_VERTEX) {
value_type tmp = (**_tvertex_iter);
++_tvertex_iter;
value_type tmp2 = (**_tvertex_iter);
if (tmp2.first == tmp.first)
++_tvertex_iter;
// // Hack to deal with cusp. the result of a cusp
// // is a TVertex having two identical viewedges.
// // In order to iterate properly, we chose to
// // to skip these last ones.
// if(_feB.first == _beA.first)
// {
// if(_feA.first == _beB.first)
// {
// _tvertex_iter.first = 0;
// return;
// }
//
// if(_tvertex_iter.first == _feA.first)
// _tvertex_iter.first = _beB.first;
// else if(_tvertex_iter.first == _beB.first)
// _tvertex_iter.first = 0;
// else
// _tvertex_iter.first = _feA.first;
// return;
// }
// if(_feA.first == _beB.first)
// {
// if(_feB.first == _beA.first)
// {
// _tvertex_iter.first = 0;
// return;
// }
//
// if(_tvertex_iter.first == _feB.first)
// _tvertex_iter.first = _beA.first;
// else if(_tvertex_iter.first == _beA.first)
// _tvertex_iter.first = 0;
// else
// _tvertex_iter.first = _feB.first;
// return;
// }
// // End of hack
//
// if(_tvertex_iter.first == _feA.first){
// // we return bea or beb
//
//
// // choose one of them
//
// _tvertex_iter.first = _feB.first;
// return;
// }
// if(_tvertex_iter.first == _feB.first)
// {
// _tvertex_iter.first = _beA.first;
// return;
// }
// if(_tvertex_iter.first == _beA.first)
// {
// _tvertex_iter.first = _beB.first;
// return;
// }
// if(_tvertex_iter.first == _beB.first)
// {
// _tvertex_iter.first = 0;
// return;
// }
#if 0
// Hack to deal with cusp. the result of a cusp is a TVertex having two identical viewedges.
// In order to iterate properly, we chose to to skip these last ones.
if (_feB.first == _beA.first) {
if (_feA.first == _beB.first) {
_tvertex_iter.first = 0;
return;
}
if (_tvertex_iter.first == _feA.first)
_tvertex_iter.first = _beB.first;
else if (_tvertex_iter.first == _beB.first)
_tvertex_iter.first = 0;
else
_tvertex_iter.first = _feA.first;
return;
}
if (_feA.first == _beB.first) {
if (_feB.first == _beA.first) {
_tvertex_iter.first = 0;
return;
}
if (_tvertex_iter.first == _feB.first)
_tvertex_iter.first = _beA.first;
else if (_tvertex_iter.first == _beA.first)
_tvertex_iter.first = 0;
else
_tvertex_iter.first = _feB.first;
return;
}
// End of hack
if (_tvertex_iter.first == _feA.first) {
// we return bea or beb
// choose one of them
_tvertex_iter.first = _feB.first;
return;
}
if (_tvertex_iter.first == _feB.first) {
_tvertex_iter.first = _beA.first;
return;
}
if (_tvertex_iter.first == _beA.first) {
_tvertex_iter.first = _beB.first;
return;
}
if (_tvertex_iter.first == _beB.first) {
_tvertex_iter.first = 0;
return;
}
#endif
}
else {
++_nontvertex_iter;
}
}
};
}
} // ViewVertexInternal namespace
/**********************************/
/* */
/* */
@@ -350,6 +365,7 @@ namespace ViewEdgeInternal {
typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference;
typedef edge_iterator_base<Traits> Self;
public:
mutable value_type _ViewEdge;
//friend class edge_iterator_base<Nonconst_traits<ViewEdge*> >;
@@ -360,20 +376,20 @@ namespace ViewEdgeInternal {
public:
friend class ViewEdge;
inline edge_iterator_base()
: parent_class()
{_orientation=true;_first=0;}
inline edge_iterator_base() : parent_class()
{
_orientation = true;
_first = 0;
}
inline edge_iterator_base(const edge_iterator_base<Nonconst_traits< ::ViewEdge*> >& iBrother)
: parent_class()
inline edge_iterator_base(const edge_iterator_base<Nonconst_traits< ::ViewEdge*> >& iBrother) : parent_class()
{
_ViewEdge = iBrother._ViewEdge;
_first = iBrother._first;
_orientation = iBrother._orientation;
}
inline edge_iterator_base(const edge_iterator_base<Const_traits< ::ViewEdge*> >& iBrother)
: parent_class()
inline edge_iterator_base(const edge_iterator_base<Const_traits< ::ViewEdge*> >& iBrother) : parent_class()
{
_ViewEdge = iBrother._ViewEdge;
_first = iBrother._first;
@@ -382,54 +398,76 @@ namespace ViewEdgeInternal {
//protected://FIXME
public:
inline edge_iterator_base(value_type iEdge, bool orientation = true)
: parent_class()
inline edge_iterator_base(value_type iEdge, bool orientation = true) : parent_class()
{
_ViewEdge = iEdge;
_first = iEdge;
_orientation = orientation;
}
public:
virtual Self *clone() const
{
return new edge_iterator_base(*this);
}
virtual ~edge_iterator_base() {}
public:
virtual bool orientation()
{
return _orientation;
}
virtual bool orientation() {return _orientation;}
virtual void set_edge(value_type iVE) {_ViewEdge=iVE;}
virtual void set_orientation(bool iOrientation) {_orientation = iOrientation;}
virtual void change_orientation() {_orientation = !_orientation;}
virtual void set_edge(value_type iVE)
{
_ViewEdge = iVE;
}
virtual void set_orientation(bool iOrientation)
{
_orientation = iOrientation;
}
virtual void change_orientation()
{
_orientation = !_orientation;
}
// operators
inline Self& operator++() // operator corresponding to ++i
// operator corresponding to ++i
inline Self& operator++()
{
//++_ViewEdge->getTimeStamp();
increment();
return *this;
}
inline Self operator++(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente.
// operator corresponding to i++, i.e. which returns the value *and then* increments it.
// That's why we store the value in a temp.
inline Self operator++(int)
{
//++_ViewEdge->getTimeStamp();
Self tmp = *this; // C'est pour cela qu'on stocke la valeur
increment(); // dans un temporaire.
Self tmp = *this;
increment();
return tmp;
}
inline Self& operator--() // operator corresponding to ++i
// operator corresponding to --i
inline Self& operator--()
{
//++_ViewEdge->getTimeStamp();
decrement();
return *this;
}
inline Self operator--(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente.
// operator corresponding to i--, i.e. which returns the value *and then* increments it.
// That's why we store the value in a temp.
inline Self operator--(int)
{
//++_ViewEdge->getTimeStamp();
Self tmp = *this; // C'est pour cela qu'on stocke la valeur
decrement(); // dans un temporaire.
Self tmp = *this;
decrement();
return tmp;
}
@@ -438,18 +476,33 @@ namespace ViewEdgeInternal {
{
return (_ViewEdge != b._ViewEdge);
}
virtual bool operator==(const Self& b) const
{
return !(*this != b);
}
// dereferencing
virtual reference operator*() const {return (_ViewEdge);}
virtual pointer operator->() const { return &(operator*());}
virtual reference operator*() const
{
return (_ViewEdge);
}
virtual pointer operator->() const
{
return &(operator*());
}
public:
virtual bool begin() const {return _ViewEdge==_first ? true : false;}
virtual bool end() const {return _ViewEdge==0 ? true : false;}
virtual bool begin() const
{
return (_ViewEdge == _first) ? true : false;
}
virtual bool end() const
{
return (_ViewEdge == 0) ? true : false;
}
protected:
virtual void increment() {}
@@ -465,6 +518,7 @@ namespace ViewEdgeInternal {
typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference;
typedef fedge_iterator_base<Traits> Self;
public:
typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class;
mutable value_type _FEdge;
@@ -474,27 +528,26 @@ namespace ViewEdgeInternal {
public:
friend class ::ViewEdge;
friend class fedge_iterator;
inline fedge_iterator_base()
: parent_class()
{}
inline fedge_iterator_base(const fedge_iterator_base<Nonconst_traits<FEdge*> >& iBrother)
: parent_class()
inline fedge_iterator_base() : parent_class() {}
inline fedge_iterator_base(const fedge_iterator_base<Nonconst_traits<FEdge*> >& iBrother) : parent_class()
{
_FEdge = iBrother._FEdge;
_first = iBrother._first;
_FEdgeB = iBrother._FEdgeB;
}
inline fedge_iterator_base(const fedge_iterator_base<Const_traits<FEdge*> >& iBrother)
: parent_class()
inline fedge_iterator_base(const fedge_iterator_base<Const_traits<FEdge*> >& iBrother) : parent_class()
{
_FEdge = iBrother._FEdge;
_first = iBrother._first;
_FEdgeB = iBrother._FEdgeB;
}
//protected://FIXME
public:
inline fedge_iterator_base(value_type iEdge, value_type iFEdgeB)
: parent_class()
inline fedge_iterator_base(value_type iEdge, value_type iFEdgeB) : parent_class()
{
_FEdge = iEdge;
_first = iEdge;
@@ -503,27 +556,37 @@ namespace ViewEdgeInternal {
public:
virtual ~fedge_iterator_base() {}
// operators
inline Self& operator++() // operator corresponding to ++i
// operator corresponding to ++i.
inline Self& operator++()
{
increment();
return *this;
}
inline Self operator++(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente.
Self tmp = *this; // C'est pour cela qu'on stocke la valeur
increment(); // dans un temporaire.
// operator corresponding to i++, i.e. which returns the value *and then* increments it.
// That's why we store the value in a temp.
inline Self operator++(int)
{
Self tmp = *this;
increment();
return tmp;
}
inline Self& operator--() // operator corresponding to ++i
// operator corresponding to --i
inline Self& operator--()
{
decrement();
return *this;
}
inline Self operator--(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente.
Self tmp = *this; // C'est pour cela qu'on stocke la valeur
decrement(); // dans un temporaire.
// operator corresponding to i--, i.e. which returns the value *and then* increments it.
// That's why we store the value in a temp.
inline Self operator--(int)
{
Self tmp = *this;
decrement();
return tmp;
}
@@ -532,19 +595,34 @@ namespace ViewEdgeInternal {
{
return (_FEdge != b._FEdge);
}
virtual bool operator==(const Self& b) const
{
return !(*this != b);
}
// dereferencing
virtual reference operator*() const {return (_FEdge);}
virtual pointer operator->() const { return &(operator*());}
virtual reference operator*() const
{
return (_FEdge);
}
virtual pointer operator->() const
{
return &(operator*());
}
public:
virtual bool begin() const {return _FEdge==_first ? true : false;}
virtual bool end() const {return _FEdge==0 ? true : false;}
virtual bool begin() const
{
return (_FEdge == _first) ? true : false;
}
virtual bool end() const
{
return (_FEdge == 0) ? true : false;
}
protected:
virtual void increment()
{
@@ -553,8 +631,7 @@ namespace ViewEdgeInternal {
virtual void decrement()
{
if(0 == _FEdge)
{
if (0 == _FEdge) {
_FEdge = _FEdgeB;
return;
}
@@ -571,27 +648,29 @@ namespace ViewEdgeInternal {
typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference;
typedef vertex_iterator_base<Traits> Self;
protected:
typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class;
public:
mutable value_type _SVertex;
FEdge *_NextFEdge;
FEdge *_PreviousFEdge;
public:
friend class ViewEdge;
friend class vertex_iterator;
inline vertex_iterator_base()
: parent_class()
{}
inline vertex_iterator_base(const vertex_iterator_base<Const_traits<SVertex*> >& iBrother)
: parent_class()
inline vertex_iterator_base() : parent_class() {}
inline vertex_iterator_base(const vertex_iterator_base<Const_traits<SVertex*> >& iBrother) : parent_class()
{
_SVertex = iBrother._SVertex;
_NextFEdge = iBrother._NextFEdge;
_PreviousFEdge = iBrother._PreviousFEdge;
}
inline vertex_iterator_base(const vertex_iterator_base<Nonconst_traits<SVertex*> >& iBrother)
: parent_class()
inline vertex_iterator_base(const vertex_iterator_base<Nonconst_traits<SVertex*> >& iBrother) : parent_class()
{
_SVertex = iBrother._SVertex;
_NextFEdge = iBrother._NextFEdge;
@@ -600,9 +679,7 @@ namespace ViewEdgeInternal {
//protected://FIXME
public:
inline vertex_iterator_base(value_type iVertex, FEdge *iPreviousFEdge, FEdge *iNextFEdge)
: parent_class()
inline vertex_iterator_base(value_type iVertex, FEdge *iPreviousFEdge, FEdge *iNextFEdge) : parent_class()
{
_SVertex = iVertex;
_NextFEdge = iNextFEdge;
@@ -612,30 +689,46 @@ namespace ViewEdgeInternal {
public:
virtual ~vertex_iterator_base() {}
virtual bool begin() const {return _PreviousFEdge==0? true : false;}
virtual bool end() const {return _SVertex==0 ? true : false;}
virtual bool begin() const
{
return (_PreviousFEdge == 0) ? true : false;
}
virtual bool end() const
{
return (_SVertex == 0) ? true : false;
}
// operators
inline Self& operator++() // operator corresponding to ++i
// operator corresponding to ++i
inline Self& operator++()
{
increment();
return *this;
}
inline Self operator++(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente.
Self tmp = *this; // C'est pour cela qu'on stocke la valeur
increment(); // dans un temporaire.
// operator corresponding to i++, i.e. which returns the value *and then* increments it.
// That's why we store the value in a temp.
inline Self operator++(int)
{
Self tmp = *this;
increment();
return tmp;
}
inline Self& operator--() // operator corresponding to ++i
// operator corresponding to --i
inline Self& operator--()
{
decrement();
return *this;
}
inline Self operator--(int) // opérateur correspondant à i++
{ // c.a.d qui renvoie la valeur *puis* incrémente.
Self tmp = *this; // C'est pour cela qu'on stocke la valeur
decrement(); // dans un temporaire.
// operator corresponding to --i, i.e. which returns the value *and then* increments it.
// That's why we store the value in a temp.
inline Self operator--(int)
{
Self tmp = *this;
decrement();
return tmp;
}
@@ -644,39 +737,45 @@ namespace ViewEdgeInternal {
{
return (_SVertex != b._SVertex);
}
virtual bool operator==(const Self& b) const
{
return !(*this != b);
}
// dereferencing
virtual reference operator*() const {return (_SVertex);}
virtual pointer operator->() const { return &(operator*());}
virtual reference operator*() const
{
return (_SVertex);
}
virtual pointer operator->() const
{
return &(operator*());
}
protected:
virtual void increment()
{
if(0 == _NextFEdge)
{
_SVertex = 0;
if (!_NextFEdge) {
_SVertex = NULL;
return;
}
_SVertex = _NextFEdge->vertexB();
_PreviousFEdge = _NextFEdge;
_NextFEdge = _NextFEdge->nextEdge();
}
virtual void decrement()
{
// if(0 == _SVertex)
// {
// _SVertex = _PreviousFEdge->vertexB();
// return;
// }
if(0 == _PreviousFEdge)
{
_SVertex = 0;
#if 0
if (!_SVertex) {
_SVertex = _PreviousFEdge->vertexB();
return;
}
#endif
if (!_PreviousFEdge) {
_SVertex = NULL;
return;
}
_SVertex = _PreviousFEdge->vertexA();
@@ -685,7 +784,6 @@ namespace ViewEdgeInternal {
}
};
} // end of namespace ViewEdgeInternal
#endif // VIEWMAPADVANCEDITERATORS_H
#endif // __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +1,69 @@
//
// Filename : ViewMapBuilder.h
// 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 "Silhouette.h"
#include <vector>
# include "../system/FreestyleConfig.h"
#include "GridDensityProvider.h"
#include "Silhouette.h"
#include "SilhouetteGeomEngine.h"
#include "ViewEdgeXBuilder.h"
#include "ViewMap.h"
#include "../geometry/Geom.h"
# include "../scene_graph/NodeGroup.h"
# include "../winged_edge/WXEdge.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 "../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 "../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;
@@ -67,17 +75,14 @@ private:
bool _EnableQI;
double _epsilon;
// tmp values:
int _currentId;
int _currentFId;
int _currentSVertexId;
public:
typedef enum {
sweep_line
sweep_line,
} intersection_algo;
typedef enum {
@@ -87,14 +92,14 @@ public:
ray_casting_culled_adaptive_traditional,
ray_casting_adaptive_traditional,
ray_casting_culled_adaptive_cumulative,
ray_casting_adaptive_cumulative
ray_casting_adaptive_cumulative,
} visibility_algo;
inline ViewMapBuilder()
{
_pProgressBar = 0;
_pRenderMonitor = 0;
_Grid = 0;
_pProgressBar = NULL;
_pRenderMonitor = NULL;
_Grid = NULL;
_currentId = 1;
_currentFId = 0;
_currentSVertexId = 0;
@@ -106,7 +111,7 @@ public:
{
if (_pViewEdgeBuilder) {
delete _pViewEdgeBuilder;
_pViewEdgeBuilder = 0;
_pViewEdgeBuilder = NULL;
}
}
@@ -119,15 +124,18 @@ public:
/*! Compute Cusps */
void computeCusps(ViewMap *ioViewMap);
/*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of
* each cusp SVertex
/*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of each cusp SVertex
* We use a hysteresis approach to avoid noise.
*/
void DetectCusps(ViewEdge *ioEdge);
/*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp) {_viewpoint = ivp; SilhouetteGeomEngine::setViewpoint(ivp);}
inline void setViewpoint(const Vec3r& ivp)
{
_viewpoint = ivp;
SilhouetteGeomEngine::setViewpoint(ivp);
}
/*! Sets the current transformation
* iModelViewMatrix
@@ -137,86 +145,91 @@ public:
* 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) {
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) {
inline void setFrustum(real iZnear, real iZfar)
{
SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
}
/*! Builds the scene view map
* returns the list the view map
/*! 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);
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.
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).
* 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);
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);
visibility_algo iAlgo = ray_casting, real epsilon = 1.0e-6);
void setGrid(Grid *iGrid) {_Grid = iGrid;}
void setGrid(Grid *iGrid)
{
_Grid = iGrid;
}
/*! accessors */
/*! Modifiers */
inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;}
inline void setEnableQI(bool iBool) {_EnableQI = iBool;}
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.
/*! 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.
* 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 ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we,
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory);
void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we,
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory);
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.
@@ -228,12 +241,9 @@ void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we,
* 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.
* 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,
@@ -242,7 +252,6 @@ void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we,
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
};
#endif // VIEWMAPBUILDER_H
#endif // __FREESTYLE_VIEW_MAP_BUILDER_H__

View File

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

View File

@@ -1,38 +1,45 @@
//
// 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 "ViewMap.h"
#include <fstream>
#include <string>
#include "ViewMap.h"
#include "../system/FreestyleConfig.h"
#include "../system/ProgressBar.h"
@@ -76,34 +83,40 @@ namespace ViewMapIO {
namespace Internal {
template <unsigned S>
ostream& write(ostream& out, const char* str) {
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) {
ostream& write<1>(ostream& out, const char *str)
{
return out.put(str[0]);
}
template<>
ostream& write<0>(ostream& out, const char*) {
ostream& write<0>(ostream& out, const char*)
{
return out;
}
template <unsigned S>
istream& read(istream& in, char* str) {
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) {
istream& read<1>(istream& in, char *str)
{
return in.get(str[0]);
}
template<>
istream& read<0>(istream& in, char*) {
istream& read<0>(istream& in, char*)
{
return in;
}
@@ -113,4 +126,4 @@ namespace ViewMapIO {
} // End of namespace ViewMapIO
#endif // VIEWMAPIO_H
#endif // __FREESTYLE_VIEW_MAP_IO_H__

View File

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

View File

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

View File

@@ -1,45 +1,51 @@
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef VIEWMAPTESSELATOR_H
# define VIEWMAPTESSELATOR_H
/** \file blender/freestyle/intern/view_map/ViewMapTesselator.h
* \ingroup freestyle
* \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
* \author Stephane Grabli
* \date 26/03/2002
*/
#include "Silhouette.h"
#include "ViewMap.h"
# include "../scene_graph/NodeShape.h"
# include "../winged_edge/WEdge.h"
# include "../scene_graph/NodeGroup.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;
class SShape;
@@ -48,32 +54,47 @@ 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() {}
/*! Builds a set of lines rep contained under a
* a NodeShape, itself contained under a NodeGroup from a ViewMap
*/
/*! 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
/*! 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
*/
/*! 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;
@@ -123,56 +144,51 @@ NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesItera
NodeGroup *group = new NodeGroup;
NodeShape *tshape = new NodeShape;
group->AddChild(tshape);
//tshape->frs_material().setDiffuse(0.f, 0.f, 0.f, 1.f);
//tshape->frs_material().setDiffuse(0.0f, 0.0f, 0.0f, 1.0f);
tshape->setFrsMaterial(_FrsMaterial);
LineRep *line;
FEdge *firstEdge;
FEdge *nextFEdge, *currentEdge;
int id = 0;
// for(vector<ViewEdge*>::const_iterator c=viewedges.begin(),cend=viewedges.end();
// c!=cend;
// c++)
for(ViewEdgesIterator c=begin, cend=end;
c!=cend;
c++)
{
// if((*c)->qi() > 0){
// continue;
// }
// if(!((*c)->nature() & (_nature)))
// continue;
//
//for (vector<ViewEdge*>::const_iterator c = viewedges.begin(), cend = viewedges.end(); c != cend; c++)
for (ViewEdgesIterator c = begin, cend = end; c != cend; c++) {
#if 0
if ((*c)->qi() > 0) {
continue;
}
if (!((*c)->nature() & (_nature))) {
continue;
}
#endif
firstEdge = (*c)->fedgeA();
// if(firstEdge->invisibility() > 0)
// continue;
#if 0
if (firstEdge->invisibility() > 0)
continue;
#endif
line = new OrientedLineRep();
if (_overloadFrsMaterial)
line->setFrsMaterial(_FrsMaterial);
// there might be chains containing a single element
if(0 == (firstEdge)->nextEdge())
{
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
{
else {
line->setStyle(LineRep::LINE_STRIP);
//firstEdge = (*c);
nextFEdge = firstEdge;
currentEdge = firstEdge;
do
{
do {
//line->AddVertex(nextFEdge->vertexA()->point3D());
AddVertexToLine(line, nextFEdge->vertexA());
currentEdge = nextFEdge;
@@ -181,7 +197,6 @@ NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesItera
// Add the last vertex
//line->AddVertex(currentEdge->vertexB()->point3D());
AddVertexToLine(line, currentEdge->vertexB());
}
line->setId((*c)->getId().getFirst());
@@ -193,4 +208,4 @@ NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesItera
return group;
}
#endif // VIEWMAPTESSELATOR_H
#endif // __FREESTYLE_VIEW_MAP_TESSELATOR_H__

View File

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

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 "../geometry/Geom.h"
using namespace Geometry;
class WVertex;
@@ -31,7 +61,6 @@ class WVertex;
class LIB_WINGED_EDGE_EXPORT CurvatureInfo
{
public:
CurvatureInfo()
{
K1 = 0.0;
@@ -43,7 +72,8 @@ public:
er = Vec3r(0.0, 0.0, 0.0);
}
CurvatureInfo(const CurvatureInfo& iBrother){
CurvatureInfo(const CurvatureInfo& iBrother)
{
K1 = iBrother.K1;
K2 = iBrother.K2;
e1 = iBrother.e1;
@@ -53,7 +83,8 @@ public:
er = iBrother.er;
}
CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t) {
CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t)
{
K1 = ca.K1 + t * (cb.K1 - ca.K1);
K2 = ca.K2 + t * (cb.K2 - ca.K2);
e1 = ca.e1 + t * (cb.e1 - ca.e1);
@@ -72,85 +103,41 @@ public:
Vec3r er; // radial curvature direction
};
class Face_Curvature_Info{
class Face_Curvature_Info
{
public:
Face_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){
++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 {
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,46 +1,46 @@
//
// 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??? */
typedef unsigned short VertexNature;
/*! true for any 0D element */
static const VertexNature POINT = 0; // 0
/*! true for SVertex */
@@ -76,4 +76,4 @@ namespace Nature {
} // end of namespace Nature
#endif // NATURE_H
#endif // __FREESTYLE_NATURE_H__

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,46 +1,51 @@
//
// 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"
class LIB_WINGED_EDGE_EXPORT WFillGrid
{
public:
inline WFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) {
inline WFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
{
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
@@ -51,30 +56,33 @@ public:
void fillGrid();
/*! Accessors */
WingedEdge* getWingedEdge() {
WingedEdge *getWingedEdge()
{
return _winged_edge;
}
Grid* getGrid() {
Grid *getGrid()
{
return _grid;
}
/*! Modifiers */
void setWingedEdge(WingedEdge* winged_edge) {
void setWingedEdge(WingedEdge *winged_edge)
{
if (winged_edge)
_winged_edge = winged_edge;
}
void setGrid(Grid* grid) {
void setGrid(Grid *grid)
{
if (grid)
_grid = grid;
}
private:
Grid *_grid;
WingedEdge *_winged_edge;
unsigned _polygon_id;
};
#endif // WS_FILL_GRID_H
#endif // __FREESTYLE_W_FILL_GRID_H__

View File

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

View File

@@ -1,45 +1,50 @@
//
// 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"
class LIB_WINGED_EDGE_EXPORT WSFillGrid
{
public:
inline WSFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) {
inline WSFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
{
_winged_edge = winged_edge;
_grid = grid;
_polygon_id = 0;
@@ -50,30 +55,33 @@ public:
void fillGrid();
/*! Accessors */
WingedEdge* getWingedEdge() {
WingedEdge *getWingedEdge()
{
return _winged_edge;
}
Grid* getGrid() {
Grid *getGrid()
{
return _grid;
}
/*! Modifiers */
void setWingedEdge(WingedEdge* winged_edge) {
void setWingedEdge(WingedEdge *winged_edge)
{
if (winged_edge)
_winged_edge = winged_edge;
}
void setGrid(Grid* grid) {
void setGrid(Grid *grid)
{
if (grid)
_grid = grid;
}
private:
Grid *_grid;
WingedEdge *_winged_edge;
unsigned _polygon_id;
};
#endif // WS_FILL_GRID_H
#endif // __FREESTYLE_WS_FILL_GRID_H__

View File

@@ -1,34 +1,49 @@
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// 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 {
unsigned int WXFaceLayer::Get0VertexIndex() const
{
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
for (i = 0; i < nEdges; ++i) {
@@ -38,7 +53,8 @@ unsigned int WXFaceLayer::Get0VertexIndex() const {
}
return -1;
}
unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{
unsigned int WXFaceLayer::GetSmoothEdgeIndex() const
{
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
for (i = 0; i < nEdges; ++i) {
@@ -49,7 +65,8 @@ unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{
return -1;
}
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges)
{
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
for (i = 0; i < nEdges; ++i) {
@@ -60,10 +77,10 @@ void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){
}
}
WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
// if the smooth edge has already been
// built: exit
if(0 != _pSmoothEdge)
WXSmoothEdge *WXFaceLayer::BuildSmoothEdge()
{
// if the smooth edge has already been built: exit
if (_pSmoothEdge)
return _pSmoothEdge;
real ta, tb;
WOEdge *woea(0), *woeb(0);
@@ -72,24 +89,20 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
int indexStart, indexEnd;
unsigned nedges = _pWXFace->numberOfEdges();
if (_nNullDotP == nedges) {
_pSmoothEdge = 0;
_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
// 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
// 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.
// 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) {
@@ -97,7 +110,8 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
indexStart = cuspEdgesIndices[0];
indexEnd = cuspEdgesIndices[1];
}else{
}
else {
woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
indexStart = cuspEdgesIndices[1];
@@ -108,20 +122,19 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
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
}
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;
_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 = 0;
return 0;
_pSmoothEdge = NULL;
return NULL;
}
unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
unsigned nedges = _pWXFace->numberOfEdges();
@@ -131,7 +144,8 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
indexStart = cuspEdgesIndices[0];
ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
tb = 0.0;
}else{
}
else {
woea = _pWXFace->GetOEdge(index0);
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
indexEnd = cuspEdgesIndices[0];
@@ -139,9 +153,9 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
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
}
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
@@ -150,14 +164,17 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
ta = 0;
tb = 1;
ok = true;
}else{
}
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;
woea = _pWXFace->GetOEdge((index - 1) % nedges);
woeb = _pWXFace->GetOEdge((index + 1) % nedges);
ta = 1;
tb = 0;
#endif
}
}
if (ok) {
@@ -176,60 +193,53 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
}
}
// 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;
// }
// }
//}
#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;
}
@@ -239,36 +249,29 @@ void WXFace::ComputeCenter()
vector<WVertex *> iVertexList;
RetrieveVertexList(iVertexList);
Vec3r center;
for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
wv!=wvend;
wv++)
{
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 *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
if(0 == face)
return 0;
if (!face)
return NULL;
Vec3r center;
for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
wv!=wvend;
wv++)
{
for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
center += (*wv)->GetVertex();
}
center /= (real)iVertexList.size();
@@ -277,20 +280,19 @@ WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeM
return face;
}
WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
{
WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
// Vec3r center;
// for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
// wv!=wvend;
// wv++)
// {
// center += (*wv)->GetVertex();
// }
// center /= (real)iVertexList.size();
// ((WSFace*)face)->setCenter(center);
#if 0
Vec3r center;
for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
center += (*wv)->GetVertex();
}
center /= (real)iVertexList.size();
((WSFace *)face)->setCenter(center);
#endif
return face;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +1,40 @@
//
// 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)
{
@@ -32,14 +47,11 @@ void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
//ifs.setId(shape->GetId());
}
void WXEdgeBuilder::buildWVertices(WShape& shape,
const real *vertices,
unsigned vsize) {
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]));
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,38 +1,43 @@
#ifndef WXEDGEBUILDER_H
# define WXEDGEBUILDER_H
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// 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__
//
// 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/WSBuilder.h
* \ingroup freestyle
* \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info
* (silhouette etc...)) structure from a polygonal model
* \author Stephane Grabli
* \date 28/05/2003
*/
#include "WingedEdgeBuilder.h"
#include "../scene_graph/IndexedFaceSet.h"
class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder
@@ -43,9 +48,7 @@ public:
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,31 +1,50 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
//
// 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) {
void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
{
if (_pRenderMonitor && _pRenderMonitor->testBreak())
return;
WShape *shape = new WShape;
@@ -34,12 +53,14 @@ void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) {
//ifs.setId(shape->GetId());
}
void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) {
void WingedEdgeBuilder::visitNodeShape(NodeShape& ns)
{
//Sets the current material to iShapeode->material:
_current_frs_material = &(ns.frs_material());
}
void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) {
void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn)
{
if (!_current_matrix) {
_current_matrix = new Matrix44r(tn.matrix());
return;
@@ -50,7 +71,8 @@ void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) {
_current_matrix = new_matrix;
}
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) {
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&)
{
if (_current_matrix)
delete _current_matrix;
@@ -63,9 +85,10 @@ void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) {
_matrices_stack.pop_back();
}
void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
unsigned vsize = ifs.vsize();
unsigned nsize = ifs.nsize();
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();
@@ -98,12 +121,13 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
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();
// sets the current WShape to shape
@@ -112,56 +136,32 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
// create a WVertex for each vertex
buildWVertices(shape, new_vertices, vsize);
const unsigned* vindices = ifs.vindices();
const unsigned* nindices = ifs.nindices();
const unsigned* tindices = 0;
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 *mindices = 0;
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++) {
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]);
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]);
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]);
buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
nindices, mindices, tindices, numVertexPerFace[index]);
break;
}
vindices += numVertexPerFace[index];
@@ -184,9 +184,7 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
// 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){
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.)
@@ -194,13 +192,12 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
normalsSet.clear();
WVertex::face_iterator fit = (*wv)->faces_begin();
WVertex::face_iterator fitend = (*wv)->faces_end();
while(fit!=fitend){
for (; fit != fitend; ++fit) {
WFace *face = *fit;
normalsSet.insert(face->GetVertexNormal(*wv));
if (normalsSet.size() != 1) {
break;
}
++fit;
}
if (normalsSet.size() !=1 ) {
(*wv)->setSmooth(false);
@@ -210,29 +207,21 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
_winged_edge->addWShape(&shape);
}
void WingedEdgeBuilder::buildWVertices(WShape& shape,
const real *vertices,
unsigned vsize) {
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]));
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) {
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
@@ -243,79 +232,79 @@ void WingedEdgeBuilder::buildTriangleStrip( const real *vertices,
vector<Vec2r> triangleTexCoords;
vector<bool> triangleFaceEdgeMarks;
while(nDoneVertices < nvertices)
{
while (nDoneVertices < nvertices) {
//clear the vertices list:
triangleVertices.clear();
//Then rebuild it:
if(0 == nTriangle%2) // if nTriangle is even
{
if (0 == nTriangle % 2) { // if nTriangle is even
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 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]));
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
{
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]));
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 (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++;
}
}
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) {
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) {
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;
@@ -323,15 +312,17 @@ void WingedEdgeBuilder::buildTriangles(const real *vertices,
vector<bool> triangleFaceEdgeMarks;
// Each triplet of vertices is considered as an independent triangle
for(unsigned i = 0; i < nvertices / 3; i++)
{
for (unsigned int i = 0; i < nvertices / 3; i++) {
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 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]));
@@ -345,40 +336,36 @@ void WingedEdgeBuilder::buildTriangles(const real *vertices,
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
}
if (mindices)
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]);
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) {
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++) {
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 j = 0; j < 3; j++)
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) {
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++) {
for (unsigned int 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++)
for (unsigned int j = 0; j < 3; j++)
pn[j] = hn[j];
n += 3;
pn += 3;

View File

@@ -1,49 +1,55 @@
//
// 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 "../scene_graph/IndexedFaceSet.h"
#include "../scene_graph/NodeTransform.h"
#include "../scene_graph/SceneVisitor.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"
class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
{
public:
inline WingedEdgeBuilder() : SceneVisitor() {
inline WingedEdgeBuilder() : SceneVisitor()
{
_current_wshape = NULL;
_current_frs_material = NULL;
_current_matrix = NULL;
@@ -51,10 +57,9 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
_pRenderMonitor = NULL;
}
virtual ~WingedEdgeBuilder() {
for (vector<Matrix44r*>::iterator it = _matrices_stack.begin();
it != _matrices_stack.end();
it++)
virtual ~WingedEdgeBuilder()
{
for (vector<Matrix44r*>::iterator it = _matrices_stack.begin(); it != _matrices_stack.end(); ++it)
delete *it;
_matrices_stack.clear();
}
@@ -70,19 +75,23 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
//
/////////////////////////////////////////////////////////////////////////////
inline WingedEdge* getWingedEdge() {
inline WingedEdge *getWingedEdge()
{
return _winged_edge;
}
inline WShape* getCurrentWShape() {
inline WShape *getCurrentWShape()
{
return _current_wshape;
}
inline FrsMaterial* getCurrentFrsMaterial() {
inline FrsMaterial *getCurrentFrsMaterial()
{
return _current_frs_material;
}
inline Matrix44r* getCurrentMatrix() {
inline Matrix44r *getCurrentMatrix()
{
return _current_matrix;
}
@@ -91,75 +100,52 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
//
/////////////////////////////////////////////////////////////////////////////
inline void setCurrentWShape(WShape* wshape) {
inline void setCurrentWShape(WShape *wshape)
{
_current_wshape = wshape;
}
inline void setCurrentFrsMaterial(FrsMaterial* mat) {
inline void setCurrentFrsMaterial(FrsMaterial *mat)
{
_current_frs_material = mat;
}
// inline void setCurrentMatrix(Matrix44r* matrix) {
// _current_matrix = matrix;
// }
#if 0
inline void setCurrentMatrix(Matrix44r *matrix)
{
_current_matrix = matrix;
}
#endif
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {
_pRenderMonitor = iRenderMonitor;
}
protected:
virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs);
virtual void buildWVertices(WShape& shape,
const real *vertices,
unsigned vsize);
virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
RenderMonitor *_pRenderMonitor;
private:
void buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const unsigned *tindices, const unsigned nvertices);
void buildTriangleStrip(const real *vertices,
const real *normals,
vector<FrsMaterial>& iMaterials,
const real *texCoords,
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices);
void buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const unsigned *tindices, const unsigned nvertices);
void buildTriangleFan(const real *vertices,
const real *normals,
vector<FrsMaterial>& iMaterials,
const real *texCoords,
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices,
const unsigned *nindices,
const unsigned *mindices,
const unsigned *tindices,
const unsigned nvertices);
void buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
const unsigned *tindices, const unsigned nvertices);
void 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 transformVertices(const real *vertices,
unsigned vsize,
const Matrix44r& transform,
real *res);
void transformNormals(const real *normals,
unsigned nsize,
const Matrix44r& transform,
real *res);
void transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res);
WShape *_current_wshape;
FrsMaterial *_current_frs_material;
@@ -168,4 +154,4 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
vector<Matrix44r *> _matrices_stack;
};
#endif // WINGED_EDGE_BUILDER_H
#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__