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:
@@ -1,43 +1,49 @@
|
||||
//
|
||||
// Filename : ArbitraryGridDensityProvider.cpp
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-2-5
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-2-5
|
||||
*/
|
||||
|
||||
#include "ArbitraryGridDensityProvider.h"
|
||||
|
||||
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells)
|
||||
: GridDensityProvider(source), numCells(numCells)
|
||||
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4],
|
||||
unsigned numCells)
|
||||
: GridDensityProvider(source), numCells(numCells)
|
||||
{
|
||||
initialize (proscenium);
|
||||
}
|
||||
|
||||
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numCells)
|
||||
: GridDensityProvider(source), numCells(numCells)
|
||||
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform, unsigned numCells)
|
||||
: GridDensityProvider(source), numCells(numCells)
|
||||
{
|
||||
real proscenium[4];
|
||||
calculateQuickProscenium(transform, bbox, proscenium);
|
||||
@@ -46,7 +52,7 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& sourc
|
||||
}
|
||||
|
||||
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells)
|
||||
: GridDensityProvider(source), numCells(numCells)
|
||||
: GridDensityProvider(source), numCells(numCells)
|
||||
{
|
||||
real proscenium[4];
|
||||
calculateOptimalProscenium(source, proscenium);
|
||||
@@ -54,9 +60,9 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& sourc
|
||||
initialize (proscenium);
|
||||
}
|
||||
|
||||
ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider () {}
|
||||
ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider() {}
|
||||
|
||||
void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
|
||||
void ArbitraryGridDensityProvider::initialize(const real proscenium[4])
|
||||
{
|
||||
float prosceniumWidth = (proscenium[1] - proscenium[0]);
|
||||
float prosceniumHeight = (proscenium[3] - proscenium[2]);
|
||||
@@ -70,11 +76,11 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
|
||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||
|
||||
// Make sure the grid exceeds the proscenium by a small amount
|
||||
float safetyZone = 0.1;
|
||||
if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
|
||||
float safetyZone = 0.1f;
|
||||
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
|
||||
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
|
||||
}
|
||||
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
|
||||
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
|
||||
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
|
||||
}
|
||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||
@@ -85,18 +91,21 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
|
||||
}
|
||||
|
||||
ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigned numCells)
|
||||
: numCells(numCells)
|
||||
: numCells(numCells)
|
||||
{
|
||||
}
|
||||
|
||||
ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory () {}
|
||||
ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory() {}
|
||||
|
||||
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source,
|
||||
const real proscenium[4])
|
||||
{
|
||||
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, proscenium, numCells));
|
||||
}
|
||||
|
||||
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
|
||||
auto_ptr<GridDensityProvider>
|
||||
ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform)
|
||||
{
|
||||
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
|
||||
}
|
||||
@@ -105,4 +114,3 @@ auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensit
|
||||
{
|
||||
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,48 +1,54 @@
|
||||
//
|
||||
// Filename : ArbitraryGridDensityProvider.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-2-5
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
|
||||
#define __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARBITRARYGRIDDENSITYPROVIDER_H
|
||||
#define ARBITRARYGRIDDENSITYPROVIDER_H
|
||||
/** \file blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-2-5
|
||||
*/
|
||||
|
||||
#include "GridDensityProvider.h"
|
||||
|
||||
class ArbitraryGridDensityProvider : public GridDensityProvider {
|
||||
class ArbitraryGridDensityProvider : public GridDensityProvider
|
||||
{
|
||||
// Disallow copying and assignment
|
||||
ArbitraryGridDensityProvider (const ArbitraryGridDensityProvider& other);
|
||||
ArbitraryGridDensityProvider& operator= (const ArbitraryGridDensityProvider& other);
|
||||
ArbitraryGridDensityProvider(const ArbitraryGridDensityProvider& other);
|
||||
ArbitraryGridDensityProvider& operator=(const ArbitraryGridDensityProvider& other);
|
||||
|
||||
public:
|
||||
ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells);
|
||||
ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numCells);
|
||||
ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform, unsigned numCells);
|
||||
ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells);
|
||||
virtual ~ArbitraryGridDensityProvider ();
|
||||
virtual ~ArbitraryGridDensityProvider();
|
||||
|
||||
protected:
|
||||
unsigned numCells;
|
||||
@@ -51,17 +57,19 @@ private:
|
||||
void initialize (const real proscenium[4]);
|
||||
};
|
||||
|
||||
class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory {
|
||||
class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory
|
||||
{
|
||||
public:
|
||||
ArbitraryGridDensityProviderFactory(unsigned numCells);
|
||||
~ArbitraryGridDensityProviderFactory ();
|
||||
~ArbitraryGridDensityProviderFactory();
|
||||
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
||||
|
||||
protected:
|
||||
unsigned numCells;
|
||||
};
|
||||
|
||||
#endif // ARBITRARYGRIDDENSITYPROVIDER_H
|
||||
|
||||
#endif // __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
|
||||
|
||||
@@ -1,69 +1,75 @@
|
||||
//
|
||||
// Filename : AverageAreaGridDensityProvider.cpp
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-2-9
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-2-9
|
||||
*/
|
||||
|
||||
#include "AverageAreaGridDensityProvider.h"
|
||||
|
||||
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor)
|
||||
: GridDensityProvider(source)
|
||||
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4],
|
||||
real sizeFactor)
|
||||
: GridDensityProvider(source)
|
||||
{
|
||||
initialize (proscenium, sizeFactor);
|
||||
}
|
||||
|
||||
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, real sizeFactor)
|
||||
: GridDensityProvider(source)
|
||||
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform, real sizeFactor)
|
||||
: GridDensityProvider(source)
|
||||
{
|
||||
real proscenium[4];
|
||||
calculateQuickProscenium(transform, bbox, proscenium);
|
||||
|
||||
initialize (proscenium, sizeFactor);
|
||||
initialize(proscenium, sizeFactor);
|
||||
}
|
||||
|
||||
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor)
|
||||
: GridDensityProvider(source)
|
||||
: GridDensityProvider(source)
|
||||
{
|
||||
real proscenium[4];
|
||||
calculateOptimalProscenium(source, proscenium);
|
||||
|
||||
initialize (proscenium, sizeFactor);
|
||||
initialize(proscenium, sizeFactor);
|
||||
}
|
||||
|
||||
AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider () {}
|
||||
AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider() {}
|
||||
|
||||
void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real sizeFactor)
|
||||
void AverageAreaGridDensityProvider::initialize(const real proscenium[4], real sizeFactor)
|
||||
{
|
||||
float prosceniumWidth = (proscenium[1] - proscenium[0]);
|
||||
float prosceniumHeight = (proscenium[3] - proscenium[2]);
|
||||
|
||||
real cellArea = 0.0;
|
||||
unsigned numFaces = 0;
|
||||
for ( source.begin(); source.isValid(); source.next() ) {
|
||||
for (source.begin(); source.isValid(); source.next()) {
|
||||
Polygon3r& poly(source.getGridSpacePolygon());
|
||||
Vec3r min, max;
|
||||
poly.getBBox(min, max);
|
||||
@@ -82,11 +88,11 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
|
||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||
|
||||
// Make sure the grid exceeds the proscenium by a small amount
|
||||
float safetyZone = 0.1;
|
||||
if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
|
||||
float safetyZone = 0.1f;
|
||||
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
|
||||
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
|
||||
}
|
||||
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
|
||||
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
|
||||
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
|
||||
}
|
||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||
@@ -97,18 +103,21 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
|
||||
}
|
||||
|
||||
AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(real sizeFactor)
|
||||
: sizeFactor(sizeFactor)
|
||||
: sizeFactor(sizeFactor)
|
||||
{
|
||||
}
|
||||
|
||||
AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory () {}
|
||||
AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory() {}
|
||||
|
||||
auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||
auto_ptr<GridDensityProvider>
|
||||
AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||
{
|
||||
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
|
||||
}
|
||||
|
||||
auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
|
||||
auto_ptr<GridDensityProvider>
|
||||
AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform)
|
||||
{
|
||||
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
|
||||
}
|
||||
@@ -117,4 +126,3 @@ auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDens
|
||||
{
|
||||
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,67 +1,72 @@
|
||||
//
|
||||
// Filename : AverageAreaGridDensityProvider.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-2-9
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
|
||||
#define __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef AVERAGEAREAGRIDDENSITYPROVIDER_H
|
||||
#define AVERAGEAREAGRIDDENSITYPROVIDER_H
|
||||
/** \file blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-2-9
|
||||
*/
|
||||
|
||||
#include "GridDensityProvider.h"
|
||||
|
||||
class AverageAreaGridDensityProvider : public GridDensityProvider {
|
||||
class AverageAreaGridDensityProvider : public GridDensityProvider
|
||||
{
|
||||
// Disallow copying and assignment
|
||||
AverageAreaGridDensityProvider (const AverageAreaGridDensityProvider& other);
|
||||
AverageAreaGridDensityProvider& operator= (const AverageAreaGridDensityProvider& other);
|
||||
AverageAreaGridDensityProvider(const AverageAreaGridDensityProvider& other);
|
||||
AverageAreaGridDensityProvider& operator=(const AverageAreaGridDensityProvider& other);
|
||||
|
||||
public:
|
||||
AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor);
|
||||
AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, real sizeFactor);
|
||||
AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform, real sizeFactor);
|
||||
AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor);
|
||||
virtual ~AverageAreaGridDensityProvider ();
|
||||
|
||||
protected:
|
||||
virtual ~AverageAreaGridDensityProvider();
|
||||
|
||||
private:
|
||||
void initialize (const real proscenium[4], real sizeFactor);
|
||||
};
|
||||
|
||||
class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory {
|
||||
class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory
|
||||
{
|
||||
public:
|
||||
AverageAreaGridDensityProviderFactory(real sizeFactor);
|
||||
~AverageAreaGridDensityProviderFactory ();
|
||||
~AverageAreaGridDensityProviderFactory();
|
||||
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
||||
|
||||
protected:
|
||||
real sizeFactor;
|
||||
};
|
||||
|
||||
#endif // AVERAGEAREAGRIDDENSITYPROVIDER_H
|
||||
|
||||
#endif // __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
|
||||
|
||||
@@ -1,37 +1,42 @@
|
||||
//
|
||||
// Filename : BoxGrid.cpp
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-1-29
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/BoxGrid.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-1-29
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "BoxGrid.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Helper Classes
|
||||
@@ -42,11 +47,12 @@ using namespace std;
|
||||
// Cell
|
||||
/////////
|
||||
|
||||
BoxGrid::Cell::Cell () {}
|
||||
BoxGrid::Cell::Cell() {}
|
||||
|
||||
BoxGrid::Cell::~Cell () {}
|
||||
BoxGrid::Cell::~Cell() {}
|
||||
|
||||
void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
|
||||
void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
|
||||
{
|
||||
const real epsilon = 1.0e-06;
|
||||
boundary[0] = x - epsilon;
|
||||
boundary[1] = x + sizeX + epsilon;
|
||||
@@ -54,11 +60,13 @@ void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
|
||||
boundary[3] = y + sizeY + epsilon;
|
||||
}
|
||||
|
||||
bool BoxGrid::Cell::compareOccludersByShallowestPoint (const BoxGrid::OccluderData* a, const BoxGrid::OccluderData* b) {
|
||||
bool BoxGrid::Cell::compareOccludersByShallowestPoint(const BoxGrid::OccluderData *a, const BoxGrid::OccluderData *b)
|
||||
{
|
||||
return a->shallowest < b->shallowest;
|
||||
}
|
||||
|
||||
void BoxGrid::Cell::indexPolygons() {
|
||||
void BoxGrid::Cell::indexPolygons()
|
||||
{
|
||||
// Sort occluders by their shallowest points.
|
||||
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
|
||||
}
|
||||
@@ -67,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;
|
||||
@@ -82,31 +89,34 @@ BoxGrid::Iterator::Iterator (BoxGrid& grid, Vec3r& center, real epsilon)
|
||||
_current = _cell->faces.begin();
|
||||
}
|
||||
|
||||
BoxGrid::Iterator::~Iterator () {}
|
||||
BoxGrid::Iterator::~Iterator() {}
|
||||
|
||||
// BoxGrid
|
||||
/////////////////
|
||||
|
||||
BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI)
|
||||
: _viewpoint(viewpoint),
|
||||
_enableQI(enableQI)
|
||||
BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
|
||||
bool enableQI)
|
||||
: _viewpoint(viewpoint), _enableQI(enableQI)
|
||||
{
|
||||
cout << "Generate Cell structure" << endl;
|
||||
// Generate Cell structure
|
||||
cout << "Generate Cell structure" << endl;
|
||||
assignCells(source, density, viewMap);
|
||||
cout << "Distribute occluders" << endl;
|
||||
|
||||
// Fill Cells
|
||||
cout << "Distribute occluders" << endl;
|
||||
distributePolygons(source);
|
||||
cout << "Reorganize cells" << endl;
|
||||
|
||||
// Reorganize Cells
|
||||
cout << "Reorganize cells" << endl;
|
||||
reorganizeCells();
|
||||
|
||||
cout << "Ready to use BoxGrid" << endl;
|
||||
}
|
||||
|
||||
BoxGrid::~BoxGrid () {
|
||||
}
|
||||
BoxGrid::~BoxGrid() {}
|
||||
|
||||
void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap) {
|
||||
void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap)
|
||||
{
|
||||
_cellSize = density.cellSize();
|
||||
_cellsX = density.cellsX();
|
||||
_cellsY = density.cellsY();
|
||||
@@ -115,20 +125,19 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
|
||||
|
||||
// Now allocate the cell table and fill it with default (empty) cells
|
||||
_cells.resize(_cellsX * _cellsY);
|
||||
for ( cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
|
||||
for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
|
||||
(*i) = NULL;
|
||||
}
|
||||
|
||||
// Identify cells that will be used, and set the dimensions for each
|
||||
ViewMap::fedges_container& fedges = viewMap->FEdges();
|
||||
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f ) {
|
||||
if ( (*f)->isInImage() ) {
|
||||
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
|
||||
if ((*f)->isInImage()) {
|
||||
Vec3r point = transform((*f)->center3d());
|
||||
unsigned i, j;
|
||||
unsigned int i, j;
|
||||
getCellCoordinates(point, i, j);
|
||||
if ( _cells[i * _cellsY + j] == NULL ) {
|
||||
if (_cells[i * _cellsY + j] == NULL) {
|
||||
// This is an uninitialized cell
|
||||
|
||||
real x, y, width, height;
|
||||
|
||||
x = _cellOrigin[0] + _cellSize * i;
|
||||
@@ -145,19 +154,21 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
|
||||
}
|
||||
}
|
||||
|
||||
void BoxGrid::distributePolygons (OccluderSource& source) {
|
||||
void BoxGrid::distributePolygons(OccluderSource& source)
|
||||
{
|
||||
unsigned long nFaces = 0;
|
||||
unsigned long nKeptFaces = 0;
|
||||
|
||||
for ( source.begin(); source.isValid(); source.next() ) {
|
||||
OccluderData* occluder = NULL;
|
||||
for (source.begin(); source.isValid(); source.next()) {
|
||||
OccluderData *occluder = NULL;
|
||||
|
||||
try {
|
||||
if ( insertOccluder(source, occluder) ) {
|
||||
if (insertOccluder(source, occluder)) {
|
||||
_faces.push_back(occluder);
|
||||
++nKeptFaces;
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
catch (...) {
|
||||
// If an exception was thrown, _faces.push_back() cannot have succeeded.
|
||||
// occluder is not owned by anyone, and must be deleted.
|
||||
// If the exception was thrown before or during new OccluderData(), then
|
||||
@@ -170,41 +181,47 @@ void BoxGrid::distributePolygons (OccluderSource& source) {
|
||||
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
|
||||
}
|
||||
|
||||
void BoxGrid::reorganizeCells () {
|
||||
void BoxGrid::reorganizeCells()
|
||||
{
|
||||
// Sort the occluders by shallowest point
|
||||
for ( vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
|
||||
if ( *i != NULL ) {
|
||||
for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
|
||||
if (*i != NULL) {
|
||||
(*i)->indexPolygons();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) {
|
||||
void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
|
||||
{
|
||||
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
|
||||
y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
|
||||
}
|
||||
|
||||
BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point) {
|
||||
unsigned x, y;
|
||||
BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point)
|
||||
{
|
||||
unsigned int x, y;
|
||||
getCellCoordinates(point, x, y);
|
||||
return _cells[x * _cellsY + y];
|
||||
}
|
||||
|
||||
bool BoxGrid::orthographicProjection () const {
|
||||
bool BoxGrid::orthographicProjection() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const Vec3r& BoxGrid::viewpoint() const {
|
||||
const Vec3r& BoxGrid::viewpoint() const
|
||||
{
|
||||
return _viewpoint;
|
||||
}
|
||||
|
||||
bool BoxGrid::enableQI() const {
|
||||
bool BoxGrid::enableQI() const
|
||||
{
|
||||
return _enableQI;
|
||||
}
|
||||
|
||||
BoxGrid::Transform::Transform () : GridHelpers::Transform() {}
|
||||
BoxGrid::Transform::Transform() : GridHelpers::Transform() {}
|
||||
|
||||
Vec3r BoxGrid::Transform::operator() (const Vec3r& point) const {
|
||||
Vec3r BoxGrid::Transform::operator()(const Vec3r& point) const
|
||||
{
|
||||
return Vec3r(point[0], point[1], -point[2]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,78 +1,87 @@
|
||||
//
|
||||
// Filename : BoxGrid.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-1-29
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_BOX_GRID_H__
|
||||
#define __FREESTYLE_BOX_GRID_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/BoxGrid.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-1-29
|
||||
*/
|
||||
|
||||
#ifndef BOXGRID_H
|
||||
#define BOXGRID_H
|
||||
|
||||
#define boxgridlogging 0
|
||||
#define BOX_GRID_LOGGING FALSE
|
||||
|
||||
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector>
|
||||
// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
|
||||
// so it should be a safe fall-back.
|
||||
//#include <vector>
|
||||
//#include <deque>
|
||||
|
||||
#include "GridDensityProvider.h"
|
||||
#include "OccluderSource.h"
|
||||
#include "ViewMap.h"
|
||||
#include "../winged_edge/WEdge.h"
|
||||
#include "../geometry/Polygon.h"
|
||||
#include "../system/PointerSequence.h"
|
||||
|
||||
#include "../geometry/BBox.h"
|
||||
#include "../geometry/GridHelpers.h"
|
||||
#include "OccluderSource.h"
|
||||
#include "GridDensityProvider.h"
|
||||
#include "../geometry/Polygon.h"
|
||||
|
||||
#include "../system/PointerSequence.h"
|
||||
|
||||
#include "../winged_edge/WEdge.h"
|
||||
|
||||
class BoxGrid
|
||||
{
|
||||
public:
|
||||
// Helper classes
|
||||
struct OccluderData {
|
||||
explicit OccluderData (OccluderSource& source, Polygon3r& p);
|
||||
struct OccluderData
|
||||
{
|
||||
explicit OccluderData(OccluderSource& source, Polygon3r& p);
|
||||
Polygon3r poly;
|
||||
Polygon3r cameraSpacePolygon;
|
||||
real shallowest, deepest;
|
||||
// N.B. We could, of course, store face in poly's userdata
|
||||
// member, like the old ViewMapBuilder code does. However,
|
||||
// code comments make it clear that userdata is deprecated,
|
||||
// so we avoid the temptation to save 4 or 8 bytes.
|
||||
// N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
|
||||
// However, code comments make it clear that userdata is deprecated, so we avoid the temptation
|
||||
// to save 4 or 8 bytes.
|
||||
WFace* face;
|
||||
};
|
||||
|
||||
private:
|
||||
struct Cell {
|
||||
struct Cell
|
||||
{
|
||||
// Can't store Cell in a vector without copy and assign
|
||||
//Cell(const Cell& other);
|
||||
//Cell& operator= (const Cell& other);
|
||||
// Cell(const Cell& other);
|
||||
// Cell& operator=(const Cell& other);
|
||||
|
||||
explicit Cell ();
|
||||
~Cell ();
|
||||
explicit Cell();
|
||||
~Cell();
|
||||
|
||||
static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b);
|
||||
static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
|
||||
|
||||
void setDimensions(real x, real y, real sizeX, real sizeY);
|
||||
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
|
||||
@@ -84,43 +93,37 @@ private:
|
||||
};
|
||||
|
||||
public:
|
||||
/*****
|
||||
|
||||
Iterator needs to allow the user to avoid full 3D comparison in
|
||||
two cases:
|
||||
|
||||
(1) Where (*current)->deepest < target[2], where the occluder is
|
||||
unambiguously in front of the target point.
|
||||
|
||||
(2) Where (*current)->shallowest > target[2], where the occluder
|
||||
is unambiguously in back of the target point.
|
||||
|
||||
In addition, when used by OptimizedFindOccludee, Iterator should
|
||||
stop iterating as soon as it has an occludee candidate and
|
||||
(*current)->shallowest > candidate[2], because at that point forward
|
||||
no new occluder could possibly be a better occludee.
|
||||
|
||||
*****/
|
||||
|
||||
class Iterator {
|
||||
/* Iterator needs to allow the user to avoid full 3D comparison in two cases:
|
||||
*
|
||||
* (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
|
||||
*
|
||||
* (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
|
||||
*
|
||||
* In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an
|
||||
* occludee candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder
|
||||
* could possibly be a better occludee.
|
||||
*/
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
// epsilon is not used in this class, but other grids with the same interface may need an epsilon
|
||||
explicit Iterator (BoxGrid& grid, Vec3r& center, real epsilon=1e-06);
|
||||
~Iterator ();
|
||||
void initBeforeTarget ();
|
||||
void initAfterTarget ();
|
||||
void nextOccluder ();
|
||||
void nextOccludee ();
|
||||
explicit Iterator(BoxGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
|
||||
~Iterator();
|
||||
void initBeforeTarget();
|
||||
void initAfterTarget();
|
||||
void nextOccluder();
|
||||
void nextOccludee();
|
||||
bool validBeforeTarget();
|
||||
bool validAfterTarget();
|
||||
WFace* getWFace() const;
|
||||
Polygon3r* getCameraSpacePolygon();
|
||||
WFace *getWFace() const;
|
||||
Polygon3r *getCameraSpacePolygon();
|
||||
void reportDepth(Vec3r origin, Vec3r u, real t);
|
||||
|
||||
private:
|
||||
bool testOccluder(bool wantOccludee);
|
||||
void markCurrentOccludeeCandidate(real depth);
|
||||
|
||||
Cell* _cell;
|
||||
Cell *_cell;
|
||||
Vec3r _target;
|
||||
bool _foundOccludee;
|
||||
real _occludeeDepth;
|
||||
@@ -128,32 +131,34 @@ public:
|
||||
vector<OccluderData*>::iterator _current, _occludeeCandidate;
|
||||
};
|
||||
|
||||
class Transform : public GridHelpers::Transform {
|
||||
class Transform : public GridHelpers::Transform
|
||||
{
|
||||
public:
|
||||
explicit Transform ();
|
||||
explicit Transform (Transform& other);
|
||||
Vec3r operator() (const Vec3r& point) const;
|
||||
explicit Transform();
|
||||
explicit Transform(Transform& other);
|
||||
Vec3r operator()(const Vec3r& point) const;
|
||||
};
|
||||
|
||||
private:
|
||||
// Prevent implicit copies and assignments.
|
||||
BoxGrid(const BoxGrid& other);
|
||||
BoxGrid& operator= (const BoxGrid& other);
|
||||
BoxGrid& operator=(const BoxGrid& other);
|
||||
|
||||
public:
|
||||
explicit BoxGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
|
||||
explicit BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
|
||||
bool enableQI);
|
||||
virtual ~BoxGrid();
|
||||
|
||||
// Generate Cell structure
|
||||
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
|
||||
// Fill Cells
|
||||
void distributePolygons(OccluderSource& source);
|
||||
// Insert one polygon into each matching cell,
|
||||
// return true if any cell consumes the polygon
|
||||
// Insert one polygon into each matching cell, return true if any cell consumes the polygon
|
||||
bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
|
||||
// Sort occluders in each cell
|
||||
void reorganizeCells();
|
||||
|
||||
Cell* findCell(const Vec3r& point);
|
||||
Cell *findCell(const Vec3r& point);
|
||||
|
||||
// Accessors:
|
||||
bool orthographicProjection() const;
|
||||
@@ -176,51 +181,52 @@ private:
|
||||
bool _enableQI;
|
||||
};
|
||||
|
||||
inline void BoxGrid::Iterator::initBeforeTarget () {
|
||||
inline void BoxGrid::Iterator::initBeforeTarget()
|
||||
{
|
||||
_current = _cell->faces.begin();
|
||||
while ( _current != _cell->faces.end() && ! testOccluder(false) ) {
|
||||
while (_current != _cell->faces.end() && !testOccluder(false)) {
|
||||
++_current;
|
||||
}
|
||||
}
|
||||
|
||||
inline void BoxGrid::Iterator::initAfterTarget () {
|
||||
if ( _foundOccludee ) {
|
||||
#if boxgridlogging == 1
|
||||
inline void BoxGrid::Iterator::initAfterTarget()
|
||||
{
|
||||
if (_foundOccludee) {
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
|
||||
#endif
|
||||
_current = _occludeeCandidate;
|
||||
return;
|
||||
}
|
||||
|
||||
#if boxgridlogging == 1
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << "\tStarting occludee search from current position" << std::endl;
|
||||
#endif
|
||||
|
||||
while ( _current != _cell->faces.end() && ! testOccluder(true) ) {
|
||||
while (_current != _cell->faces.end() && !testOccluder(true)) {
|
||||
++_current;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
|
||||
inline bool BoxGrid::Iterator::testOccluder(bool wantOccludee)
|
||||
{
|
||||
// End-of-list is not even a valid iterator position
|
||||
if ( _current == _cell->faces.end() ) {
|
||||
// Returning true seems strange, but it will break us out of whatever loop
|
||||
// is calling testOccluder, and _current=_cell->face.end() will make
|
||||
// the calling routine give up.
|
||||
if (_current == _cell->faces.end()) {
|
||||
// Returning true seems strange, but it will break us out of whatever loop is calling testOccluder,
|
||||
// and _current = _cell->face.end() will make the calling routine give up.
|
||||
return true;
|
||||
}
|
||||
#if boxgridlogging == 1
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
|
||||
for ( unsigned i = 1; i < (*_current)->poly.getVertices().size(); ++i ) {
|
||||
for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
|
||||
std::cout << ", " << (*_current)->poly.getVertices()[i];
|
||||
}
|
||||
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
// If we have an occluder candidate and we are unambiguously after it, abort
|
||||
if ( _foundOccludee && (*_current)->shallowest > _occludeeDepth ) {
|
||||
#if boxgridlogging == 1
|
||||
if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
|
||||
#endif
|
||||
_current = _cell->faces.end();
|
||||
@@ -230,16 +236,17 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
|
||||
}
|
||||
|
||||
// Specific continue or stop conditions when searching for each type
|
||||
if ( wantOccludee ) {
|
||||
if ( (*_current)->deepest < _target[2] ) {
|
||||
#if boxgridlogging == 1
|
||||
if (wantOccludee) {
|
||||
if ((*_current)->deepest < _target[2]) {
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ( (*_current)->shallowest > _target[2] ) {
|
||||
#if boxgridlogging == 1
|
||||
}
|
||||
else {
|
||||
if ((*_current)->shallowest > _target[2]) {
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
@@ -251,67 +258,73 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
|
||||
// Check to see if target is in the 2D bounding box
|
||||
Vec3r bbMin, bbMax;
|
||||
(*_current)->poly.getBBox(bbMin, bbMax);
|
||||
if ( _target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1] ) {
|
||||
#if boxgridlogging == 1
|
||||
if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// We've done all the corner cutting we can.
|
||||
// Let the caller work out whether or not
|
||||
// the geometry is correct.
|
||||
// Let the caller work out whether or not the geometry is correct.
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void BoxGrid::Iterator::reportDepth (Vec3r origin, Vec3r u, real t) {
|
||||
inline void BoxGrid::Iterator::reportDepth(Vec3r origin, Vec3r u, real t)
|
||||
{
|
||||
// The reported depth is the length of a ray in camera space
|
||||
// We need to convert it into a Z-value in grid space
|
||||
real depth = -(origin + (u * t))[2];
|
||||
#if boxgridlogging == 1
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
|
||||
#endif
|
||||
if ( depth > _target[2] ) {
|
||||
#if boxgridlogging == 1
|
||||
if (depth > _target[2]) {
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << " is deeper than target" << std::endl;
|
||||
#endif
|
||||
// If the current occluder is the best occludee so far, save it.
|
||||
if ( ! _foundOccludee || _occludeeDepth > depth ) {
|
||||
if (! _foundOccludee || _occludeeDepth > depth) {
|
||||
markCurrentOccludeeCandidate(depth);
|
||||
}
|
||||
} else {
|
||||
#if boxgridlogging == 1
|
||||
}
|
||||
else {
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
inline void BoxGrid::Iterator::nextOccluder () {
|
||||
if ( _current != _cell->faces.end() ) {
|
||||
inline void BoxGrid::Iterator::nextOccluder()
|
||||
{
|
||||
if (_current != _cell->faces.end()) {
|
||||
do {
|
||||
++_current;
|
||||
} while ( _current != _cell->faces.end() && ! testOccluder(false) );
|
||||
} while (_current != _cell->faces.end() && ! testOccluder(false));
|
||||
}
|
||||
}
|
||||
|
||||
inline void BoxGrid::Iterator::nextOccludee () {
|
||||
if ( _current != _cell->faces.end() ) {
|
||||
inline void BoxGrid::Iterator::nextOccludee()
|
||||
{
|
||||
if (_current != _cell->faces.end()) {
|
||||
do {
|
||||
++_current;
|
||||
} while ( _current != _cell->faces.end() && ! testOccluder(true) );
|
||||
} while (_current != _cell->faces.end() && ! testOccluder(true));
|
||||
}
|
||||
}
|
||||
|
||||
inline bool BoxGrid::Iterator::validBeforeTarget () {
|
||||
inline bool BoxGrid::Iterator::validBeforeTarget()
|
||||
{
|
||||
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
|
||||
}
|
||||
|
||||
inline bool BoxGrid::Iterator::validAfterTarget () {
|
||||
inline bool BoxGrid::Iterator::validAfterTarget()
|
||||
{
|
||||
return _current != _cell->faces.end();
|
||||
}
|
||||
|
||||
inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
|
||||
#if boxgridlogging == 1
|
||||
inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth)
|
||||
{
|
||||
#if BOX_GRID_LOGGING
|
||||
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
|
||||
#endif
|
||||
_occludeeCandidate = _current;
|
||||
@@ -319,16 +332,18 @@ inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
|
||||
_foundOccludee = true;
|
||||
}
|
||||
|
||||
inline WFace* BoxGrid::Iterator::getWFace() const {
|
||||
inline WFace* BoxGrid::Iterator::getWFace() const
|
||||
{
|
||||
return (*_current)->face;
|
||||
}
|
||||
|
||||
inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon() {
|
||||
inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon()
|
||||
{
|
||||
return &((*_current)->cameraSpacePolygon);
|
||||
}
|
||||
|
||||
inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
|
||||
: poly(p),
|
||||
inline BoxGrid::OccluderData::OccluderData(OccluderSource& source, Polygon3r& p)
|
||||
: poly(p),
|
||||
cameraSpacePolygon(source.getCameraSpacePolygon()),
|
||||
face(source.getWFace())
|
||||
{
|
||||
@@ -339,9 +354,10 @@ inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p
|
||||
deepest = max[2];
|
||||
}
|
||||
|
||||
inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
|
||||
if ( GridHelpers::insideProscenium (boundary, poly) ) {
|
||||
if ( occluder == NULL) {
|
||||
inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
|
||||
{
|
||||
if (GridHelpers::insideProscenium (boundary, poly)) {
|
||||
if (occluder == NULL) {
|
||||
// Disposal of occluder will be handled in BoxGrid::distributePolygons(),
|
||||
// or automatically by BoxGrid::_faces;
|
||||
occluder = new OccluderData(source, poly);
|
||||
@@ -350,7 +366,8 @@ inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& pol
|
||||
}
|
||||
}
|
||||
|
||||
inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) {
|
||||
inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
|
||||
{
|
||||
Polygon3r& poly(source.getGridSpacePolygon());
|
||||
occluder = NULL;
|
||||
|
||||
@@ -361,9 +378,9 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
|
||||
getCellCoordinates(bbMin, startX, startY);
|
||||
getCellCoordinates(bbMax, endX, endY);
|
||||
|
||||
for ( unsigned i = startX; i <= endX; ++i ) {
|
||||
for ( unsigned j = startY; j <= endY; ++j ) {
|
||||
if ( _cells[i * _cellsY + j] != NULL ) {
|
||||
for (unsigned int i = startX; i <= endX; ++i) {
|
||||
for (unsigned int j = startY; j <= endY; ++j) {
|
||||
if (_cells[i * _cellsY + j] != NULL) {
|
||||
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
|
||||
}
|
||||
}
|
||||
@@ -372,5 +389,4 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
|
||||
return occluder != NULL;
|
||||
}
|
||||
|
||||
#endif // BOXGRID_H
|
||||
|
||||
#endif // __FREESTYLE_BOX_GRID_H__
|
||||
|
||||
@@ -1,67 +1,74 @@
|
||||
//
|
||||
// Filename : CulledOccluderSource.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2010-12-21
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/CulledOccluderSource.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2010-12-21
|
||||
*/
|
||||
|
||||
#include "CulledOccluderSource.h"
|
||||
#include "../geometry/GridHelpers.h"
|
||||
|
||||
#include "FRS_freestyle.h"
|
||||
|
||||
CulledOccluderSource::CulledOccluderSource (const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap, bool extensiveFEdgeSearch)
|
||||
: OccluderSource(t, we),
|
||||
rejected(0),
|
||||
gridSpaceOccluderProsceniumInitialized(false)
|
||||
#include "../geometry/GridHelpers.h"
|
||||
|
||||
CulledOccluderSource::CulledOccluderSource(const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap,
|
||||
bool extensiveFEdgeSearch)
|
||||
: OccluderSource(t, we), rejected(0), gridSpaceOccluderProsceniumInitialized(false)
|
||||
{
|
||||
cullViewEdges(viewMap, extensiveFEdgeSearch);
|
||||
|
||||
// If we have not found any visible FEdges during our cull, then there is nothing
|
||||
// to iterate over. Short-circuit everything.
|
||||
// If we have not found any visible FEdges during our cull, then there is nothing to iterate over.
|
||||
// Short-circuit everything.
|
||||
valid = gridSpaceOccluderProsceniumInitialized;
|
||||
|
||||
if ( valid && ! testCurrent() ) {
|
||||
if (valid && ! testCurrent()) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
CulledOccluderSource::~CulledOccluderSource() {
|
||||
}
|
||||
CulledOccluderSource::~CulledOccluderSource() {}
|
||||
|
||||
bool CulledOccluderSource::testCurrent() {
|
||||
if ( valid ) {
|
||||
bool CulledOccluderSource::testCurrent()
|
||||
{
|
||||
if (valid) {
|
||||
// The test for gridSpaceOccluderProsceniumInitialized should not be necessary
|
||||
return gridSpaceOccluderProsceniumInitialized && GridHelpers::insideProscenium (gridSpaceOccluderProscenium, cachedPolygon);
|
||||
return gridSpaceOccluderProsceniumInitialized &&
|
||||
GridHelpers::insideProscenium(gridSpaceOccluderProscenium, cachedPolygon);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CulledOccluderSource::next() {
|
||||
while ( OccluderSource::next() ) {
|
||||
if ( testCurrent() ) {
|
||||
bool CulledOccluderSource::next()
|
||||
{
|
||||
while (OccluderSource::next()) {
|
||||
if (testCurrent()) {
|
||||
++rejected;
|
||||
return true;
|
||||
}
|
||||
@@ -70,17 +77,20 @@ bool CulledOccluderSource::next() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CulledOccluderSource::getOccluderProscenium(real proscenium[4]) {
|
||||
for ( unsigned i = 0; i < 4; ++i ) {
|
||||
void CulledOccluderSource::getOccluderProscenium(real proscenium[4])
|
||||
{
|
||||
for (unsigned int i = 0; i < 4; ++i) {
|
||||
proscenium[i] = gridSpaceOccluderProscenium[i];
|
||||
}
|
||||
}
|
||||
|
||||
static inline real distance2D(const Vec3r & point, const real origin[2]) {
|
||||
static inline real distance2D(const Vec3r & point, const real origin[2])
|
||||
{
|
||||
return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
|
||||
}
|
||||
|
||||
static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
|
||||
static inline bool crossesProscenium(real proscenium[4], FEdge *fe)
|
||||
{
|
||||
Vec2r min(proscenium[0], proscenium[2]);
|
||||
Vec2r max(proscenium[1], proscenium[3]);
|
||||
Vec2r A(fe->vertexA()->getProjectedX(), fe->vertexA()->getProjectedY());
|
||||
@@ -89,20 +99,20 @@ static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
|
||||
return GeomUtils::intersect2dSeg2dArea (min, max, A, B);
|
||||
}
|
||||
|
||||
static inline bool insideProscenium(real proscenium[4], const Vec3r& point) {
|
||||
return ! ( point[0] < proscenium[0] || point[0] > proscenium[1] || point[1] < proscenium[2] || point[1] > proscenium[3] );
|
||||
static inline bool insideProscenium(real proscenium[4], const Vec3r& point)
|
||||
{
|
||||
return !(point[0] < proscenium[0] || point[0] > proscenium[1] ||
|
||||
point[1] < proscenium[2] || point[1] > proscenium[3]);
|
||||
}
|
||||
|
||||
void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch) {
|
||||
void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch)
|
||||
{
|
||||
// Cull view edges by marking them as non-displayable.
|
||||
// This avoids the complications of trying to delete
|
||||
// edges from the ViewMap.
|
||||
// This avoids the complications of trying to delete edges from the ViewMap.
|
||||
|
||||
// Non-displayable view edges will be skipped over during
|
||||
// visibility calculation.
|
||||
// Non-displayable view edges will be skipped over during visibility calculation.
|
||||
|
||||
// View edges will be culled according to their position
|
||||
// w.r.t. the viewport proscenium (viewport + 5% border,
|
||||
// View edges will be culled according to their position w.r.t. the viewport proscenium (viewport + 5% border,
|
||||
// or some such).
|
||||
|
||||
// Get proscenium boundary for culling
|
||||
@@ -112,34 +122,30 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
||||
prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
|
||||
prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
|
||||
cout << "Proscenium culling:" << endl;
|
||||
cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2] << ", " << viewProscenium[3] << "]"<< endl;
|
||||
cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2]
|
||||
<< ", " << viewProscenium[3] << "]"<< endl;
|
||||
cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]"<< endl;
|
||||
|
||||
// A separate occluder proscenium will also be maintained,
|
||||
// starting out the same as the viewport proscenium, and
|
||||
// expanding as necessary so that it encompasses the center
|
||||
// point of at least one feature edge in each retained view
|
||||
// edge.
|
||||
// The occluder proscenium will be used later to cull occluding
|
||||
// triangles before they are inserted into the Grid.
|
||||
// The occluder proscenium starts out the same size as the view
|
||||
// proscenium
|
||||
// A separate occluder proscenium will also be maintained, starting out the same as the viewport proscenium, and
|
||||
// expanding as necessary so that it encompasses the center point of at least one feature edge in each
|
||||
// retained view edge.
|
||||
// The occluder proscenium will be used later to cull occluding triangles before they are inserted into the Grid.
|
||||
// The occluder proscenium starts out the same size as the view proscenium
|
||||
GridHelpers::getDefaultViewProscenium(occluderProscenium);
|
||||
|
||||
// N.B. Freestyle is inconsistent in its use of ViewMap::viewedges_container
|
||||
// and vector<ViewEdge*>::iterator. Probably all occurences of vector<ViewEdge*>::iterator
|
||||
// should be replaced ViewMap::viewedges_container throughout the code.
|
||||
// XXX Freestyle is inconsistent in its use of ViewMap::viewedges_container and vector<ViewEdge*>::iterator.
|
||||
// Probably all occurences of vector<ViewEdge*>::iterator should be replaced ViewMap::viewedges_container
|
||||
// throughout the code.
|
||||
// For each view edge
|
||||
ViewMap::viewedges_container::iterator ve, veend;
|
||||
|
||||
for(ve=viewMap.ViewEdges().begin(), veend=viewMap.ViewEdges().end(); ve!=veend; ve++) {
|
||||
for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
|
||||
// Overview:
|
||||
// Search for a visible feature edge
|
||||
// If none: mark view edge as non-displayable
|
||||
// Otherwise:
|
||||
// Find a feature edge with center point inside occluder proscenium.
|
||||
// If none exists, find the feature edge with center point
|
||||
// closest to viewport origin.
|
||||
// If none exists, find the feature edge with center point closest to viewport origin.
|
||||
// Expand occluder proscenium to enclose center point.
|
||||
|
||||
// For each feature edge, while bestOccluderTarget not found and view edge not visibile
|
||||
@@ -151,28 +157,27 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
||||
// All ViewEdges start culled
|
||||
(*ve)->setIsInImage(false);
|
||||
|
||||
// For simple visibility calculation: mark a feature edge
|
||||
// that is known to have a center point inside the occluder proscenium.
|
||||
// Cull all other feature edges.
|
||||
// For simple visibility calculation: mark a feature edge that is known to have a center point inside
|
||||
// the occluder proscenium. Cull all other feature edges.
|
||||
do {
|
||||
// All FEdges start culled
|
||||
fe->setIsInImage(false);
|
||||
|
||||
// Look for the visible edge that can most easily be included
|
||||
// in the occluder proscenium.
|
||||
if ( ! bestOccluderTargetFound ) {
|
||||
// Look for the visible edge that can most easily be included in the occluder proscenium.
|
||||
if (!bestOccluderTargetFound) {
|
||||
// If center point is inside occluder proscenium,
|
||||
if ( insideProscenium(occluderProscenium, fe->center2d()) ) {
|
||||
if (insideProscenium(occluderProscenium, fe->center2d())) {
|
||||
// Use this feature edge for visibility deterimination
|
||||
fe->setIsInImage(true);
|
||||
expandGridSpaceOccluderProscenium(fe);
|
||||
// Mark bestOccluderTarget as found
|
||||
bestOccluderTargetFound = true;
|
||||
bestOccluderTarget = fe;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
real d = distance2D(fe->center2d(), prosceniumOrigin);
|
||||
// If center point is closer to viewport origin than current target
|
||||
if ( bestOccluderTarget == NULL || d < bestOccluderDistance ) {
|
||||
if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
|
||||
// Then store as bestOccluderTarget
|
||||
bestOccluderDistance = d;
|
||||
bestOccluderTarget = fe;
|
||||
@@ -181,33 +186,35 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
||||
}
|
||||
|
||||
// If feature edge crosses the view proscenium
|
||||
if ( ! (*ve)->isInImage() && crossesProscenium(viewProscenium, fe) ) {
|
||||
if (!(*ve)->isInImage() && crossesProscenium(viewProscenium, fe)) {
|
||||
// Then the view edge will be included in the image
|
||||
(*ve)->setIsInImage(true);
|
||||
}
|
||||
fe = fe->nextEdge();
|
||||
} while ( fe != NULL && fe != festart && ! ( bestOccluderTargetFound && (*ve)->isInImage() ) );
|
||||
} while (fe != NULL && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));
|
||||
|
||||
// Either we have run out of FEdges, or we already have the one edge we need to determine visibility
|
||||
// Cull all remaining edges.
|
||||
while ( fe != NULL && fe != festart ) {
|
||||
while (fe != NULL && fe != festart) {
|
||||
fe->setIsInImage(false);
|
||||
fe = fe->nextEdge();
|
||||
}
|
||||
|
||||
// If bestOccluderTarget was not found inside the occluder proscenium,
|
||||
// we need to expand the occluder proscenium to include it.
|
||||
if ( (*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound ) {
|
||||
if ((*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound) {
|
||||
// Expand occluder proscenium to enclose bestOccluderTarget
|
||||
Vec3r point = bestOccluderTarget->center2d();
|
||||
if ( point[0] < occluderProscenium[0] ) {
|
||||
if (point[0] < occluderProscenium[0]) {
|
||||
occluderProscenium[0] = point[0];
|
||||
} else if ( point[0] > occluderProscenium[1] ) {
|
||||
}
|
||||
else if (point[0] > occluderProscenium[1]) {
|
||||
occluderProscenium[1] = point[0];
|
||||
}
|
||||
if ( point[1] < occluderProscenium[2] ) {
|
||||
if (point[1] < occluderProscenium[2]) {
|
||||
occluderProscenium[2] = point[1];
|
||||
} else if ( point[1] > occluderProscenium[3] ) {
|
||||
}
|
||||
else if (point[1] > occluderProscenium[3]) {
|
||||
occluderProscenium[3] = point[1];
|
||||
}
|
||||
// Use bestOccluderTarget for visibility determination
|
||||
@@ -225,22 +232,18 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
||||
|
||||
// For "Normal" or "Fast" style visibility computation only:
|
||||
|
||||
// For more detailed visibility calculation, make a second pass through
|
||||
// the view map, marking all feature edges with center points inside
|
||||
// the final occluder proscenium. All of these feature edges can be
|
||||
// considered during visibility calculation.
|
||||
// For more detailed visibility calculation, make a second pass through the view map, marking all feature edges
|
||||
// with center points inside the final occluder proscenium. All of these feature edges can be considered during
|
||||
// visibility calculation.
|
||||
|
||||
// So far we have only found one FEdge per ViewEdge. The "Normal" and
|
||||
// "Fast" styles of visibility computation want to consider many
|
||||
// FEdges for each ViewEdge.
|
||||
// Here we re-scan the view map to find any usable FEdges that we
|
||||
// skipped on the first pass, or that have become usable because the
|
||||
// occluder proscenium has been expanded since the edge was visited
|
||||
// on the first pass.
|
||||
if ( extensiveFEdgeSearch ) {
|
||||
// So far we have only found one FEdge per ViewEdge. The "Normal" and "Fast" styles of visibility computation
|
||||
// want to consider many FEdges for each ViewEdge.
|
||||
// Here we re-scan the view map to find any usable FEdges that we skipped on the first pass, or that have become
|
||||
// usable because the occluder proscenium has been expanded since the edge was visited on the first pass.
|
||||
if (extensiveFEdgeSearch) {
|
||||
// For each view edge,
|
||||
for(ve=viewMap.ViewEdges().begin(), veend=viewMap.ViewEdges().end(); ve!=veend; ve++) {
|
||||
if ( ! (*ve)->isInImage() ) {
|
||||
for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
|
||||
if (!(*ve)->isInImage()) {
|
||||
continue;
|
||||
}
|
||||
// For each feature edge,
|
||||
@@ -248,30 +251,31 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
||||
FEdge *fe = festart;
|
||||
do {
|
||||
// If not (already) visible and center point inside occluder proscenium,
|
||||
if ( ! fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d()) ) {
|
||||
if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
|
||||
// Use the feature edge for visibility determination
|
||||
fe->setIsInImage(true);
|
||||
expandGridSpaceOccluderProscenium(fe);
|
||||
}
|
||||
fe = fe->nextEdge();
|
||||
} while ( fe != NULL && fe != festart );
|
||||
} while (fe != NULL && fe != festart);
|
||||
}
|
||||
}
|
||||
|
||||
// Up until now, all calculations have been done in camera space.
|
||||
// However, the occluder source's iteration and the grid that consumes the occluders
|
||||
// both work in gridspace, so we need a version of the occluder proscenium in gridspace.
|
||||
// However, the occluder source's iteration and the grid that consumes the occluders both work in gridspace,
|
||||
// so we need a version of the occluder proscenium in gridspace.
|
||||
// Set the gridspace occlude proscenium
|
||||
}
|
||||
|
||||
void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge* fe) {
|
||||
if ( gridSpaceOccluderProsceniumInitialized ) {
|
||||
GridHelpers::expandProscenium (gridSpaceOccluderProscenium, transform(fe->center3d()));
|
||||
} else {
|
||||
void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge *fe)
|
||||
{
|
||||
if (gridSpaceOccluderProsceniumInitialized) {
|
||||
GridHelpers::expandProscenium(gridSpaceOccluderProscenium, transform(fe->center3d()));
|
||||
}
|
||||
else {
|
||||
const Vec3r& point = transform(fe->center3d());
|
||||
gridSpaceOccluderProscenium[0] = gridSpaceOccluderProscenium[1] = point[0];
|
||||
gridSpaceOccluderProscenium[2] = gridSpaceOccluderProscenium[3] = point[1];
|
||||
gridSpaceOccluderProsceniumInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +1,52 @@
|
||||
//
|
||||
// Filename : CulledOccluderSource.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2010-12-21
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
|
||||
#define __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef CULLEDOCCLUDERSOURCE_H
|
||||
#define CULLEDOCCLUDERSOURCE_H
|
||||
/** \file blender/freestyle/intern/view_map/CulledOccluderSource.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2010-12-21
|
||||
*/
|
||||
|
||||
#include "OccluderSource.h"
|
||||
#include "ViewMap.h"
|
||||
|
||||
class CulledOccluderSource : public OccluderSource {
|
||||
class CulledOccluderSource : public OccluderSource
|
||||
{
|
||||
// Disallow copying and assignment
|
||||
CulledOccluderSource (const CulledOccluderSource& other);
|
||||
CulledOccluderSource& operator= (const CulledOccluderSource& other);
|
||||
CulledOccluderSource(const CulledOccluderSource& other);
|
||||
CulledOccluderSource& operator=(const CulledOccluderSource& other);
|
||||
|
||||
public:
|
||||
CulledOccluderSource (const GridHelpers::Transform& transform, WingedEdge& we, ViewMap& viewMap, bool extensiveFEdgeSearch = true);
|
||||
CulledOccluderSource(const GridHelpers::Transform& transform, WingedEdge& we, ViewMap& viewMap,
|
||||
bool extensiveFEdgeSearch = true);
|
||||
virtual ~CulledOccluderSource();
|
||||
|
||||
void cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch);
|
||||
@@ -51,7 +57,7 @@ public:
|
||||
|
||||
private:
|
||||
bool testCurrent();
|
||||
void expandGridSpaceOccluderProscenium(FEdge* fe);
|
||||
void expandGridSpaceOccluderProscenium(FEdge *fe);
|
||||
|
||||
real occluderProscenium[4];
|
||||
real gridSpaceOccluderProscenium[4];
|
||||
@@ -60,4 +66,4 @@ private:
|
||||
bool gridSpaceOccluderProsceniumInitialized;
|
||||
};
|
||||
|
||||
#endif // CULLEDOCCLUDERSOURCE_H
|
||||
#endif // __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
|
||||
|
||||
@@ -1,37 +1,53 @@
|
||||
/*
|
||||
* ***** 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();
|
||||
WXShape * wxs;
|
||||
WXShape *wxs;
|
||||
|
||||
if(_pProgressBar != NULL) {
|
||||
if (_pProgressBar != NULL) {
|
||||
_pProgressBar->reset();
|
||||
_pProgressBar->setLabelText("Detecting feature lines");
|
||||
_pProgressBar->setTotalSteps(wshapes.size() * 3);
|
||||
@@ -39,39 +55,37 @@ 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);
|
||||
wxs->bbox(Min, Max);
|
||||
_bbox_diagonal = (Max-Min).norm();
|
||||
if(_changes){
|
||||
_bbox_diagonal = (Max - Min).norm();
|
||||
if (_changes) {
|
||||
vector<WFace*>& wfaces = wxs->GetFaceList();
|
||||
for(vector<WFace*>::iterator wf=wfaces.begin(), wfend=wfaces.end();
|
||||
wf!=wfend;
|
||||
++wf){
|
||||
WXFace* wxf = dynamic_cast<WXFace*>(*wf);
|
||||
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);
|
||||
if (progressBarDisplay)
|
||||
_pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
|
||||
processBorderShape(wxs);
|
||||
if(_computeMaterialBoundaries)
|
||||
if (_computeMaterialBoundaries)
|
||||
processMaterialBoundaryShape(wxs);
|
||||
processCreaseShape(wxs);
|
||||
if(_computeRidgesAndValleys)
|
||||
if (_computeRidgesAndValleys)
|
||||
processRidgesAndValleysShape(wxs);
|
||||
if(_computeSuggestiveContours)
|
||||
if (_computeSuggestiveContours)
|
||||
processSuggestiveContourShape(wxs);
|
||||
processSilhouetteShape(wxs);
|
||||
processEdgeMarksShape(wxs);
|
||||
@@ -82,7 +96,7 @@ void FEdgeXDetector::processShapes(WingedEdge& we) {
|
||||
buildSmoothEdges(wxs);
|
||||
|
||||
// Post processing for suggestive contours
|
||||
if(_computeSuggestiveContours)
|
||||
if (_computeSuggestiveContours)
|
||||
postProcessSuggestiveContourShape(wxs);
|
||||
if (progressBarDisplay)
|
||||
_pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
|
||||
@@ -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;
|
||||
@@ -109,21 +124,17 @@ void FEdgeXDetector::preProcessShape(WXShape* iWShape) {
|
||||
_meanEdgeSize = iWShape->getMeanEdgeSize();
|
||||
|
||||
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
||||
vector<WFace*>::iterator f,fend;
|
||||
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 ) {
|
||||
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);
|
||||
WXVertex *wxv = dynamic_cast<WXVertex*>(*wv);
|
||||
computeCurvatures(wxv);
|
||||
}
|
||||
_meanK1 /= (real)(_nPoints);
|
||||
@@ -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
|
||||
|
||||
@@ -164,42 +179,44 @@ void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
|
||||
Vec3r e1, n, v;
|
||||
// one vertex curvature info :
|
||||
CurvatureInfo *C;
|
||||
float radius = _sphereRadius*_meanEdgeSize;
|
||||
float radius = _sphereRadius * _meanEdgeSize;
|
||||
|
||||
// view independant stuff
|
||||
if(_computeViewIndependant){
|
||||
if (_computeViewIndependant) {
|
||||
C = new CurvatureInfo();
|
||||
vertex->setCurvatures(C);
|
||||
OGF::NormalCycle ncycle ;
|
||||
ncycle.begin() ;
|
||||
if(radius > 0) {
|
||||
OGF::compute_curvature_tensor(vertex, radius, ncycle) ;
|
||||
} else {
|
||||
OGF::compute_curvature_tensor_one_ring(vertex, ncycle) ;
|
||||
OGF::NormalCycle ncycle;
|
||||
ncycle.begin();
|
||||
if (radius > 0) {
|
||||
OGF::compute_curvature_tensor(vertex, radius, ncycle);
|
||||
}
|
||||
ncycle.end() ;
|
||||
else {
|
||||
OGF::compute_curvature_tensor_one_ring(vertex, ncycle);
|
||||
}
|
||||
ncycle.end();
|
||||
C->K1 = ncycle.kmin();
|
||||
C->K2 = ncycle.kmax();
|
||||
C->e1 = ncycle.Kmax(); //ncycle.kmin() * ncycle.Kmax();
|
||||
C->e2 = ncycle.Kmin(); //ncycle.kmax() * ncycle.Kmin() ;
|
||||
C->e2 = ncycle.Kmin(); //ncycle.kmax() * ncycle.Kmin();
|
||||
|
||||
real absK1 = fabs(C->K1);
|
||||
_meanK1 += absK1;
|
||||
if(absK1 > _maxK1)
|
||||
if (absK1 > _maxK1)
|
||||
_maxK1 = absK1;
|
||||
if(absK1 < _minK1)
|
||||
if (absK1 < _minK1)
|
||||
_minK1 = absK1;
|
||||
}
|
||||
// view dependant
|
||||
C = vertex->curvatures();
|
||||
if(C == 0)
|
||||
if (C == 0)
|
||||
return;
|
||||
|
||||
// compute radial curvature :
|
||||
n = C->e1 ^ C->e2;
|
||||
if (_orthographicProjection) {
|
||||
v = Vec3r(0.0, 0.0, _Viewpoint.z() - vertex->GetVertex().z());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
v = Vec3r(_Viewpoint - vertex->GetVertex());
|
||||
}
|
||||
C->er = v - (v * n) * n;
|
||||
@@ -212,9 +229,9 @@ void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
|
||||
C->Kr = C->K1 * cos2theta + C->K2 * sin2theta;
|
||||
real absKr = fabs(C->Kr);
|
||||
_meanKr += absKr;
|
||||
if(absKr > _maxKr)
|
||||
if (absKr > _maxKr)
|
||||
_maxKr = absKr;
|
||||
if(absKr < _minKr)
|
||||
if (absKr < _minKr)
|
||||
_minKr = absKr;
|
||||
|
||||
++_nPoints;
|
||||
@@ -222,52 +239,42 @@ 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)
|
||||
{
|
||||
vector<WFace*>::iterator f, fend;
|
||||
for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
|
||||
ProcessSilhouetteFace((WXFace*)(*f));
|
||||
}
|
||||
|
||||
// Make a pass on the edges to detect
|
||||
// the silhouette edges that are not smooth
|
||||
// --------------------
|
||||
// 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;
|
||||
int numVertices = iFace->numberOfVertices();
|
||||
WXFaceLayer * faceLayer = new WXFaceLayer(iFace, Nature::SILHOUETTE, true);
|
||||
for(int i=0; i<numVertices; i++){
|
||||
WXFaceLayer *faceLayer = new WXFaceLayer(iFace, Nature::SILHOUETTE, true);
|
||||
for (int i = 0; i < numVertices; i++) {
|
||||
point = iFace->GetVertex(i)->GetVertex();
|
||||
normal = iFace->GetVertexNormal(i);
|
||||
normal.normalize();
|
||||
Vec3r V;
|
||||
if (_orthographicProjection) {
|
||||
V = Vec3r(0.0, 0.0, _Viewpoint.z() - point.z());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
V = Vec3r(_Viewpoint - point);
|
||||
}
|
||||
V.normalize();
|
||||
@@ -276,11 +283,12 @@ 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();
|
||||
}
|
||||
if(dist < minDist) {
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
closestPointId = i;
|
||||
}
|
||||
@@ -293,54 +301,47 @@ void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
|
||||
|
||||
void FEdgeXDetector::ProcessSilhouetteEdge(WXEdge *iEdge)
|
||||
{
|
||||
if(iEdge->nature() & Nature::BORDER)
|
||||
if (iEdge->nature() & Nature::BORDER)
|
||||
return;
|
||||
// SILHOUETTE ?
|
||||
//-------------
|
||||
WXFace * fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
|
||||
WXFace * fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
|
||||
WXFace *fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
|
||||
WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
|
||||
|
||||
if((fA->front())^(fB->front())){ // fA->visible XOR fB->visible (true if one is 0 and the other is 1)
|
||||
// The only edges we want to set as silhouette edges in this
|
||||
// way are the ones with 2 different normals for 1 vertex
|
||||
if ((fA->front()) ^ (fB->front())) { // fA->visible XOR fB->visible (true if one is 0 and the other is 1)
|
||||
// The only edges we want to set as silhouette edges in this way are the ones with 2 different normals for 1 vertex
|
||||
// for these two faces
|
||||
//--------------------
|
||||
// In reality we only test the normals for 1 of the 2 vertices.
|
||||
if(fA->GetVertexNormal(iEdge->GetaVertex()) == fB->GetVertexNormal(iEdge->GetaVertex()))
|
||||
if (fA->GetVertexNormal(iEdge->GetaVertex()) == fB->GetVertexNormal(iEdge->GetaVertex()))
|
||||
return;
|
||||
iEdge->AddNature(Nature::SILHOUETTE);
|
||||
if(fB->front())
|
||||
if (fB->front())
|
||||
iEdge->setOrder(1);
|
||||
else
|
||||
iEdge->setOrder(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// BORDER
|
||||
/////////
|
||||
void FEdgeXDetector::processBorderShape(WXShape* iWShape) {
|
||||
|
||||
if(!_computeViewIndependant)
|
||||
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){
|
||||
ProcessBorderEdge((WXEdge*)(*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){
|
||||
if (iEdge->GetaFace() == 0) {
|
||||
// it is a border edge
|
||||
iEdge->AddNature(Nature::BORDER);
|
||||
}
|
||||
@@ -349,19 +350,16 @@ void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge)
|
||||
|
||||
// CREASE
|
||||
/////////
|
||||
void FEdgeXDetector::processCreaseShape(WXShape* iWShape) {
|
||||
if(!_computeViewIndependant)
|
||||
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){
|
||||
ProcessCreaseEdge((WXEdge*)(*we));
|
||||
for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
|
||||
ProcessCreaseEdge((WXEdge *)(*we));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,34 +367,30 @@ void FEdgeXDetector::ProcessCreaseEdge(WXEdge *iEdge)
|
||||
{
|
||||
// CREASE ?
|
||||
//---------
|
||||
if(iEdge->nature() & Nature::BORDER)
|
||||
if (iEdge->nature() & Nature::BORDER)
|
||||
return;
|
||||
WXFace * fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
|
||||
WXFace * fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
|
||||
WXFace *fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
|
||||
WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
|
||||
|
||||
WVertex * aVertex = iEdge->GetaVertex();
|
||||
if((fA->GetVertexNormal(aVertex) * fB->GetVertexNormal(aVertex)) <= _creaseAngle)
|
||||
WVertex *aVertex = iEdge->GetaVertex();
|
||||
if ((fA->GetVertexNormal(aVertex) * fB->GetVertexNormal(aVertex)) <= _creaseAngle)
|
||||
iEdge->AddNature(Nature::CREASE);
|
||||
}
|
||||
|
||||
// RIDGES AND VALLEYS
|
||||
/////////////////////
|
||||
|
||||
void FEdgeXDetector::processRidgesAndValleysShape(WXShape* iWShape) {
|
||||
// Don't forget to add the built layer to the face at the end
|
||||
// of the ProcessFace:
|
||||
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,24 +398,25 @@ void FEdgeXDetector::processRidgesAndValleysShape(WXShape* iWShape) {
|
||||
|
||||
// RIDGES
|
||||
/////////
|
||||
|
||||
void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
|
||||
{
|
||||
WXFaceLayer * flayer = new WXFaceLayer(iFace, Nature::RIDGE|Nature::VALLEY, false);
|
||||
WXFaceLayer *flayer = new WXFaceLayer(iFace, Nature::RIDGE|Nature::VALLEY, false);
|
||||
iFace->AddSmoothLayer(flayer);
|
||||
|
||||
unsigned int numVertices = iFace->numberOfVertices();
|
||||
for(unsigned int i=0; i<numVertices; ++i){
|
||||
for (unsigned int i = 0; i < numVertices; ++i) {
|
||||
WVertex *wv = iFace->GetVertex(i);
|
||||
WXVertex * wxv = dynamic_cast<WXVertex*>(wv);
|
||||
WXVertex *wxv = dynamic_cast<WXVertex*>(wv);
|
||||
flayer->PushDotP(wxv->curvatures()->K1);
|
||||
}
|
||||
|
||||
real threshold = 0;
|
||||
//real threshold = _maxK1 - (_maxK1-_meanK1)/20.0;
|
||||
//real threshold = _maxK1 - (_maxK1 - _meanK1) / 20.0;
|
||||
|
||||
if(flayer->nPosDotP()!=numVertices){
|
||||
if((fabs(flayer->dotP(0)) < threshold) && (fabs(flayer->dotP(1)) < threshold) && (fabs(flayer->dotP(2)) < threshold)){
|
||||
if (flayer->nPosDotP() != numVertices) {
|
||||
if ((fabs(flayer->dotP(0)) < threshold) && (fabs(flayer->dotP(1)) < threshold) &&
|
||||
(fabs(flayer->dotP(2)) < threshold))
|
||||
{
|
||||
flayer->ReplaceDotP(0, 0);
|
||||
flayer->ReplaceDotP(1, 0);
|
||||
flayer->ReplaceDotP(2, 0);
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -557,45 +547,43 @@ void FEdgeXDetector::ProcessSuggestiveContourFace(WXFace *iFace)
|
||||
iFace->AddSmoothLayer(faceLayer);
|
||||
|
||||
unsigned int numVertices = iFace->numberOfVertices();
|
||||
for(unsigned int i=0; i<numVertices; ++i){
|
||||
for (unsigned int i = 0; i < numVertices; ++i) {
|
||||
WVertex *wv = iFace->GetVertex(i);
|
||||
WXVertex * wxv = dynamic_cast<WXVertex*>(wv);
|
||||
WXVertex *wxv = dynamic_cast<WXVertex*>(wv);
|
||||
faceLayer->PushDotP(wxv->curvatures()->Kr);
|
||||
}
|
||||
|
||||
// FIXME: find a more clever way to compute the threshold
|
||||
// real threshold = _meanKr;
|
||||
// if(faceLayer->nPosDotP()!=numVertices){
|
||||
// if((fabs(faceLayer->dotP(0)) < threshold) && (fabs(faceLayer->dotP(1)) < threshold) && (fabs(faceLayer->dotP(2)) < threshold)){
|
||||
// faceLayer->ReplaceDotP(0, 0);
|
||||
// faceLayer->ReplaceDotP(1, 0);
|
||||
// faceLayer->ReplaceDotP(2, 0);
|
||||
// }
|
||||
// }
|
||||
#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;
|
||||
iFace->retrieveSmoothEdgesLayers(Nature::SUGGESTIVE_CONTOUR, sc_layers);
|
||||
if(sc_layers.empty())
|
||||
if (sc_layers.empty())
|
||||
return;
|
||||
|
||||
WXFaceLayer *sc_layer;
|
||||
@@ -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,23 +613,20 @@ 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();
|
||||
opposite_vertex_b = (WXVertex*)opposite_edge->GetbVertex();
|
||||
opposite_vertex_a = (WXVertex *)opposite_edge->GetaVertex();
|
||||
opposite_vertex_b = (WXVertex *)opposite_edge->GetbVertex();
|
||||
normal_vec = wxf->GetVertexNormal(v); // FIXME: what about e1 ^ e2 ?
|
||||
radial_normal_vec = er_vec ^ normal_vec;
|
||||
|
||||
// Test wether the radial plan intersects with the edge at the opposite of v.
|
||||
res = GeomUtils::intersectRayPlane(opposite_vertex_a->GetVertex(), opposite_edge->GetVec(),
|
||||
radial_normal_vec, -(v_vec * radial_normal_vec),
|
||||
t,
|
||||
1.e-06);
|
||||
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) {
|
||||
|
||||
if(!_computeViewIndependant)
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -706,26 +692,25 @@ void FEdgeXDetector::ProcessMaterialBoundaryEdge(WXEdge *iEdge)
|
||||
// check whether the edge is a material boundary?
|
||||
WFace *aFace = iEdge->GetaFace();
|
||||
WFace *bFace = iEdge->GetbFace();
|
||||
if(aFace && bFace && aFace->frs_materialIndex() != bFace->frs_materialIndex()){
|
||||
if (aFace && bFace && aFace->frs_materialIndex() != bFace->frs_materialIndex()) {
|
||||
iEdge->AddNature(Nature::MATERIAL_BOUNDARY);
|
||||
}
|
||||
}
|
||||
|
||||
// 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){
|
||||
for (vector<WXFaceLayer*>::iterator wxfl = faceLayers.begin(), wxflend = faceLayers.end();
|
||||
wxfl != wxflend;
|
||||
++wxfl)
|
||||
{
|
||||
if ((*wxfl)->BuildSmoothEdge())
|
||||
hasSmoothEdges = true;
|
||||
}
|
||||
@@ -754,11 +738,9 @@ 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);
|
||||
WXVertex *wxv = dynamic_cast<WXVertex*>(*wv);
|
||||
computeCurvatures(wxv);
|
||||
}
|
||||
_meanK1 /= (real)(_nPoints);
|
||||
|
||||
@@ -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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/FEdgeXDetector.h
|
||||
* \ingroup freestyle
|
||||
* \brief Detects/flags/builds extended features edges on the WXEdge structure
|
||||
* \author Stephane Grabli
|
||||
* \date 26/10/2003
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifndef FEDGEXDETECTOR_H
|
||||
# define FEDGEXDETECTOR_H
|
||||
#include "../geometry/Geom.h"
|
||||
|
||||
# include <vector>
|
||||
# include "../system/FreestyleConfig.h"
|
||||
# include "../geometry/Geom.h"
|
||||
# include "../winged_edge/WXEdge.h"
|
||||
# include "../winged_edge/Curvature.h"
|
||||
# include "../system/ProgressBar.h"
|
||||
# include "../system/RenderMonitor.h"
|
||||
#include "../system/FreestyleConfig.h"
|
||||
#include "../system/ProgressBar.h"
|
||||
#include "../system/RenderMonitor.h"
|
||||
|
||||
#include "../winged_edge/Curvature.h"
|
||||
#include "../winged_edge/WXEdge.h"
|
||||
|
||||
using namespace Geometry;
|
||||
|
||||
/*! This class takes as input a WXEdge structure and fills it
|
||||
*/
|
||||
|
||||
/*! This class takes as input a WXEdge structure and fills it */
|
||||
class LIB_VIEW_MAP_EXPORT FEdgeXDetector
|
||||
{
|
||||
public:
|
||||
|
||||
FEdgeXDetector() {
|
||||
_pProgressBar = 0;
|
||||
_pRenderMonitor = 0;
|
||||
FEdgeXDetector()
|
||||
{
|
||||
_pProgressBar = NULL;
|
||||
_pRenderMonitor = NULL;
|
||||
_computeViewIndependant = true;
|
||||
_bbox_diagonal = 1.0;
|
||||
_meanEdgeSize = 0;
|
||||
@@ -65,112 +69,146 @@ 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 */
|
||||
virtual void processShapes(WingedEdge&);
|
||||
|
||||
// GENERAL STUFF
|
||||
virtual void preProcessShape(WXShape* iShape);
|
||||
virtual void preProcessFace(WXFace* iFace);
|
||||
virtual void preProcessShape(WXShape *iShape);
|
||||
virtual void preProcessFace(WXFace *iFace);
|
||||
virtual void computeCurvatures(WXVertex *iVertex);
|
||||
|
||||
// SILHOUETTE
|
||||
virtual void processSilhouetteShape(WXShape* iShape);
|
||||
virtual void processSilhouetteShape(WXShape *iShape);
|
||||
virtual void ProcessSilhouetteFace(WXFace *iFace);
|
||||
virtual void ProcessSilhouetteEdge(WXEdge *iEdge);
|
||||
|
||||
// CREASE
|
||||
virtual void processCreaseShape(WXShape* iShape);
|
||||
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)
|
||||
angle = 180.0;
|
||||
angle = cos(M_PI * (180.0 - angle) / 180.0);
|
||||
if (angle != _creaseAngle){
|
||||
if (angle != _creaseAngle) {
|
||||
_creaseAngle = angle;
|
||||
_changes = true;
|
||||
}
|
||||
}
|
||||
|
||||
// BORDER
|
||||
virtual void processBorderShape(WXShape* iShape);
|
||||
virtual void processBorderShape(WXShape *iShape);
|
||||
virtual void ProcessBorderEdge(WXEdge *iEdge);
|
||||
|
||||
// RIDGES AND VALLEYS
|
||||
virtual void processRidgesAndValleysShape(WXShape* iShape);
|
||||
virtual void processRidgesAndValleysShape(WXShape *iShape);
|
||||
virtual void ProcessRidgeFace(WXFace *iFace);
|
||||
|
||||
// SUGGESTIVE CONTOURS
|
||||
virtual void processSuggestiveContourShape(WXShape* iShape);
|
||||
virtual void processSuggestiveContourShape(WXShape *iShape);
|
||||
virtual void ProcessSuggestiveContourFace(WXFace *iFace);
|
||||
virtual void postProcessSuggestiveContourShape(WXShape* iShape);
|
||||
virtual void postProcessSuggestiveContourShape(WXShape *iShape);
|
||||
virtual void postProcessSuggestiveContourFace(WXFace *iFace);
|
||||
/*! Sets the minimal derivative of the radial curvature for suggestive contours
|
||||
* \param dkr
|
||||
* The minimal derivative of the radial curvature
|
||||
*/
|
||||
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr) {
|
||||
if (dkr != _kr_derivative_epsilon){
|
||||
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr)
|
||||
{
|
||||
if (dkr != _kr_derivative_epsilon) {
|
||||
_kr_derivative_epsilon = dkr;
|
||||
_changes = true;
|
||||
}
|
||||
}
|
||||
|
||||
// MATERIAL BOUNDARY
|
||||
virtual void processMaterialBoundaryShape(WXShape* iWShape);
|
||||
virtual void processMaterialBoundaryShape(WXShape *iWShape);
|
||||
virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge);
|
||||
|
||||
// EDGE MARKS
|
||||
virtual void processEdgeMarksShape(WXShape* iShape);
|
||||
virtual void processEdgeMarksShape(WXShape *iShape);
|
||||
virtual void ProcessEdgeMarks(WXEdge *iEdge);
|
||||
|
||||
// EVERYBODY
|
||||
virtual void buildSmoothEdges(WXShape* iShape);
|
||||
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) {
|
||||
if(r!=_sphereRadius){
|
||||
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__
|
||||
|
||||
@@ -1,39 +1,53 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/Functions0D.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Functions taking 0D input
|
||||
* \author Stephane Grabli
|
||||
* \author Emmanuel Turquin
|
||||
* \date 01/07/2003
|
||||
*/
|
||||
|
||||
# include "Functions0D.h"
|
||||
# include "ViewMap.h"
|
||||
#include "Functions0D.h"
|
||||
#include "ViewMap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Functions0D {
|
||||
|
||||
// Internal function
|
||||
FEdge* getFEdge(Interface0D& it1, Interface0D& it2){
|
||||
// Internal function
|
||||
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,242 +55,235 @@ namespace Functions0D {
|
||||
if (!it.isBegin() && !next.isEnd()) {
|
||||
count = 3;
|
||||
}
|
||||
if(count < 3)
|
||||
{
|
||||
if (count < 3) {
|
||||
// if we only have 2 vertices
|
||||
FEdge * fe = 0;
|
||||
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;
|
||||
bool begin = false, last = false;
|
||||
Interface0DIterator previous = it;
|
||||
if(!previous.isBegin())
|
||||
if (!previous.isBegin())
|
||||
--previous;
|
||||
else
|
||||
begin=true;
|
||||
begin = true;
|
||||
Interface0DIterator next = it;
|
||||
++next;
|
||||
if(next.isEnd())
|
||||
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)
|
||||
{
|
||||
FEdge * fe1, *fe2;
|
||||
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;
|
||||
if (ve2 == ve1)
|
||||
ve2 = NULL;
|
||||
}
|
||||
else
|
||||
ve2 = 0;
|
||||
else {
|
||||
ve2 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ViewShape* getShapeF0D(Interface0DIterator& it)
|
||||
{
|
||||
ViewShape *getShapeF0D(Interface0DIterator& it)
|
||||
{
|
||||
ViewEdge *ve1, *ve2;
|
||||
getViewEdges(it, ve1, ve2);
|
||||
return ve1->viewShape();
|
||||
}
|
||||
}
|
||||
|
||||
void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders){
|
||||
ViewEdge * ve1, *ve2;
|
||||
void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders)
|
||||
{
|
||||
ViewEdge *ve1, *ve2;
|
||||
getViewEdges(it, ve1, ve2);
|
||||
occluder_container::const_iterator oit = ve1->occluders_begin();
|
||||
occluder_container::const_iterator oitend = ve1->occluders_end();
|
||||
|
||||
for(;oit!=oitend; ++oit)
|
||||
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)
|
||||
for (; oit != oitend; ++oit)
|
||||
oOccluders.insert((*oit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ViewShape * getOccludeeF0D(Interface0DIterator& it){
|
||||
ViewEdge * ve1, *ve2;
|
||||
ViewShape *getOccludeeF0D(Interface0DIterator& it)
|
||||
{
|
||||
ViewEdge *ve1, *ve2;
|
||||
getViewEdges(it, ve1, ve2);
|
||||
ViewShape *aShape = ve1->aShape();
|
||||
return aShape;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
int VertexOrientation2DF0D::operator()(Interface0DIterator& iter) {
|
||||
Vec2f A,C;
|
||||
//
|
||||
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());
|
||||
}
|
||||
Interface0DIterator next = iter;
|
||||
++next ;
|
||||
if(next.isEnd())
|
||||
++next;
|
||||
if (next.isEnd())
|
||||
C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
|
||||
else
|
||||
C = Vec2f(next->getProjectedX(), next->getProjectedY());
|
||||
|
||||
Vec2f AB(B-A);
|
||||
if(AB.norm() != 0)
|
||||
Vec2f AB(B - A);
|
||||
if (AB.norm() != 0)
|
||||
AB.normalize();
|
||||
Vec2f BC(C-B);
|
||||
if(BC.norm() != 0)
|
||||
Vec2f BC(C - B);
|
||||
if (BC.norm() != 0)
|
||||
BC.normalize();
|
||||
result = AB + BC;
|
||||
if(result.norm() != 0)
|
||||
if (result.norm() != 0)
|
||||
result.normalize();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int VertexOrientation3DF0D::operator()(Interface0DIterator& iter) {
|
||||
Vec3r A,C;
|
||||
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());
|
||||
}
|
||||
Interface0DIterator next = iter;
|
||||
++next ;
|
||||
if(next.isEnd())
|
||||
if (next.isEnd())
|
||||
C = Vec3r(iter->getX(), iter->getY(), iter->getZ());
|
||||
else
|
||||
C = Vec3r(next->getX(), next->getY(), next->getZ());
|
||||
|
||||
Vec3r AB(B-A);
|
||||
if(AB.norm() != 0)
|
||||
Vec3r AB(B - A);
|
||||
if (AB.norm() != 0)
|
||||
AB.normalize();
|
||||
Vec3r BC(C-B);
|
||||
if(BC.norm() != 0)
|
||||
Vec3r BC(C - B);
|
||||
if (BC.norm() != 0)
|
||||
BC.normalize();
|
||||
result = AB + BC;
|
||||
if(result.norm() != 0)
|
||||
if (result.norm() != 0)
|
||||
result.normalize();
|
||||
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;
|
||||
}
|
||||
if(count < 3) {
|
||||
if (count < 3) {
|
||||
// if we only have 2 vertices
|
||||
result = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Interface0DIterator v = iter;
|
||||
if(iter.isBegin())
|
||||
if (iter.isBegin())
|
||||
++v;
|
||||
Interface0DIterator next=v;
|
||||
Interface0DIterator next = v;
|
||||
++next;
|
||||
if(next.isEnd())
|
||||
{
|
||||
if (next.isEnd()) {
|
||||
next = v;
|
||||
--v;
|
||||
}
|
||||
Interface0DIterator prev=v;
|
||||
Interface0DIterator prev = v;
|
||||
--prev;
|
||||
|
||||
Vec2r A(prev->getProjectedX(), prev->getProjectedY());
|
||||
Vec2r B(v->getProjectedX(), v->getProjectedY());
|
||||
Vec2r C(next->getProjectedX(), next->getProjectedY());
|
||||
Vec2r AB(B-A);
|
||||
Vec2r BC(C-B);
|
||||
Vec2r AB(B - A);
|
||||
Vec2r BC(C - B);
|
||||
Vec2r N1(-AB[1], AB[0]);
|
||||
if(N1.norm() != 0)
|
||||
if (N1.norm() != 0)
|
||||
N1.normalize();
|
||||
Vec2r N2(-BC[1], BC[0]);
|
||||
if(N2.norm() != 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;
|
||||
}
|
||||
double cosin = N1*N2;
|
||||
if(cosin > 1)
|
||||
double cosin = N1 * N2;
|
||||
if (cosin > 1)
|
||||
cosin = 1;
|
||||
if(cosin < -1)
|
||||
if (cosin < -1)
|
||||
cosin = -1;
|
||||
result = acos(cosin);
|
||||
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);
|
||||
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;
|
||||
@@ -284,74 +291,81 @@ namespace Functions0D {
|
||||
n.normalize();
|
||||
result = n;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int MaterialF0D::operator()(Interface0DIterator& iter) {
|
||||
int MaterialF0D::operator()(Interface0DIterator& iter)
|
||||
{
|
||||
FEdge *fe1, *fe2;
|
||||
getFEdges(iter,fe1,fe2);
|
||||
if(fe1 == 0)
|
||||
getFEdges(iter, fe1, fe2);
|
||||
if (fe1 == NULL)
|
||||
return -1;
|
||||
if(fe1->isSmooth())
|
||||
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) {
|
||||
ViewShape * vshape = getShapeF0D(iter);
|
||||
int ShapeIdF0D::operator()(Interface0DIterator& iter)
|
||||
{
|
||||
ViewShape *vshape = getShapeF0D(iter);
|
||||
result = vshape->getId();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter) {
|
||||
ViewEdge * ve1, *ve2;
|
||||
getViewEdges(iter,ve1,ve2);
|
||||
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)
|
||||
if (qi2 != qi1)
|
||||
cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
|
||||
}
|
||||
result = qi1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int CurveNatureF0D::operator()(Interface0DIterator& iter) {
|
||||
int CurveNatureF0D::operator()(Interface0DIterator& iter)
|
||||
{
|
||||
Nature::EdgeNature nat = 0;
|
||||
ViewEdge * ve1, *ve2;
|
||||
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);
|
||||
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){
|
||||
//vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end());
|
||||
for (set<ViewShape*>::iterator it = occluders.begin(), itend = occluders.end(); it != itend; ++it) {
|
||||
result.push_back((*it));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int GetShapeF0D::operator()(Interface0DIterator& iter) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace Functions0D
|
||||
|
||||
@@ -1,64 +1,70 @@
|
||||
//
|
||||
// Filename : Functions0D.h
|
||||
// Author(s) : Stephane Grabli, Emmanuel Turquin
|
||||
// Purpose : Functions taking 0D input
|
||||
// Date of creation : 01/07/2003
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_FUNCTIONS_0D_H__
|
||||
#define __FREESTYLE_FUNCTIONS_0D_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/Functions0D.h
|
||||
* \ingroup freestyle
|
||||
* \brief Functions taking 0D input
|
||||
* \author Stephane Grabli
|
||||
* \author Emmanuel Turquin
|
||||
* \date 01/07/2003
|
||||
*/
|
||||
|
||||
#ifndef FUNCTIONS0D_H
|
||||
# define FUNCTIONS0D_H
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "Interface0D.h"
|
||||
|
||||
#include "../geometry/Geom.h"
|
||||
|
||||
#include "../python/Director.h"
|
||||
|
||||
#include "../scene_graph/FrsMaterial.h"
|
||||
|
||||
#include "../system/Exception.h"
|
||||
#include "../system/Precision.h"
|
||||
|
||||
# include "../system/Precision.h"
|
||||
# include "Interface0D.h"
|
||||
# include "../geometry/Geom.h"
|
||||
# include "../system/Exception.h"
|
||||
# include "../scene_graph/FrsMaterial.h"
|
||||
# include <set>
|
||||
# include <vector>
|
||||
class FEdge;
|
||||
class ViewEdge;
|
||||
class SShape;
|
||||
|
||||
using namespace Geometry;
|
||||
|
||||
#include "../python/Director.h"
|
||||
|
||||
//
|
||||
// UnaryFunction0D (base class for functions in 0D)
|
||||
//
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
/*! Base class for Unary Functions (functors) working
|
||||
* on Interface0DIterator.
|
||||
* A unary function will be used by calling
|
||||
* its operator() on an Interface0DIterator.
|
||||
* \attention In the scripting language, there exists
|
||||
* several prototypes depending on the returned value type.
|
||||
* For example, you would inherit from a UnaryFunction0DDouble
|
||||
* if you wish to define a function that returns a double.
|
||||
/*! Base class for Unary Functions (functors) working on Interface0DIterator.
|
||||
* A unary function will be used by calling its operator() on an Interface0DIterator.
|
||||
* \attention In the scripting language, there exists several prototypes depending on the returned value type.
|
||||
* For example, you would inherit from a UnaryFunction0DDouble if you wish to define a function that returns a double.
|
||||
* The different existing prototypes are:
|
||||
* - UnaryFunction0DVoid
|
||||
* - UnaryFunction0DUnsigned
|
||||
@@ -68,39 +74,43 @@ 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;}
|
||||
UnaryFunction0D()
|
||||
{
|
||||
py_uf0D = NULL;
|
||||
}
|
||||
|
||||
/*! Destructor; */
|
||||
virtual ~UnaryFunction0D() {}
|
||||
|
||||
/*! Returns the string "UnaryFunction0D" */
|
||||
virtual string getName() const {
|
||||
virtual string getName() const
|
||||
{
|
||||
return "UnaryFunction0D";
|
||||
}
|
||||
|
||||
/*! The operator ().
|
||||
* \param iter
|
||||
* An Interface0DIterator pointing onto
|
||||
* the point at which we wish to evaluate
|
||||
* the function.
|
||||
* 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 );
|
||||
virtual int operator()(Interface0DIterator& iter)
|
||||
{
|
||||
return Director_BPy_UnaryFunction0D___call__(this, py_uf0D, iter);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
# ifdef SWIG
|
||||
#ifdef SWIG
|
||||
%feature("director") UnaryFunction0D<void>;
|
||||
%feature("director") UnaryFunction0D<unsigned>;
|
||||
%feature("director") UnaryFunction0D<float>;
|
||||
@@ -118,383 +128,405 @@ UnaryFunction0D() { py_uf0D = 0;}
|
||||
%template(UnaryFunction0DId) UnaryFunction0D<Id>;
|
||||
%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
|
||||
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
|
||||
# endif // SWIG
|
||||
|
||||
#endif // SWIG
|
||||
|
||||
//
|
||||
// Functions definitions
|
||||
//
|
||||
///////////////////////////////////////////////////////////
|
||||
class ViewShape;
|
||||
|
||||
namespace Functions0D {
|
||||
|
||||
// GetXF0D
|
||||
/*! Returns the X 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
|
||||
// GetXF0D
|
||||
/*! Returns the X 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetXF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetXF0D"*/
|
||||
string getName() const {
|
||||
return "GetXF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter) {
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter)
|
||||
{
|
||||
result = iter->getX();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GetYF0D
|
||||
/*! Returns the Y 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real>
|
||||
// GetYF0D
|
||||
/*! Returns the Y 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetYF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetYF0D"*/
|
||||
string getName() const {
|
||||
return "GetYF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter) {
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter)
|
||||
{
|
||||
result = iter->getY();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GetZF0D
|
||||
/*! Returns the Z 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real>
|
||||
// GetZF0D
|
||||
/*! Returns the Z 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetZF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetZF0D"*/
|
||||
string getName() const {
|
||||
return "GetZF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter) {
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter)
|
||||
{
|
||||
result = iter->getZ();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GetProjectedXF0D
|
||||
/*! Returns the X 3D projected coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real>
|
||||
// GetProjectedXF0D
|
||||
/*! Returns the X 3D projected coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetProjectedXF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetProjectedXF0D"*/
|
||||
string getName() const {
|
||||
return "GetProjectedXF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter) {
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter)
|
||||
{
|
||||
result = iter->getProjectedX();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GetProjectedYF0D
|
||||
/*! Returns the Y projected 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real>
|
||||
// GetProjectedYF0D
|
||||
/*! Returns the Y projected 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetProjectedYF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetProjectedYF0D"*/
|
||||
string getName() const {
|
||||
return "GetProjectedYF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter) {
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter)
|
||||
{
|
||||
result = iter->getProjectedY();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GetProjectedZF0D
|
||||
/*! Returns the Z projected 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real>
|
||||
// GetProjectedZF0D
|
||||
/*! Returns the Z projected 3D coordinate of an Interface0D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetProjectedZF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetProjectedZF0D"*/
|
||||
string getName() const {
|
||||
return "GetProjectedZF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter) {
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter)
|
||||
{
|
||||
result = iter->getProjectedZ();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GetCurvilinearAbscissaF0D
|
||||
/*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
|
||||
class LIB_VIEW_MAP_EXPORT GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
|
||||
// GetCurvilinearAbscissaF0D
|
||||
/*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
|
||||
class LIB_VIEW_MAP_EXPORT GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetCurvilinearAbscissaF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetCurvilinearAbscissaF0D"*/
|
||||
string getName() const {
|
||||
return "GetCurvilinearAbscissaF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter) {
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter)
|
||||
{
|
||||
result = iter.t();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GetParameterF0D
|
||||
/*! Returns the parameter of an Interface0D in the context of its 1D element. */
|
||||
class LIB_VIEW_MAP_EXPORT GetParameterF0D : public UnaryFunction0D<float>
|
||||
// GetParameterF0D
|
||||
/*! Returns the parameter of an Interface0D in the context of its 1D element. */
|
||||
class LIB_VIEW_MAP_EXPORT GetParameterF0D : public UnaryFunction0D<float>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetCurvilinearAbscissaF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetCurvilinearAbscissaF0D"*/
|
||||
string getName() const {
|
||||
return "GetParameterF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter) {
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter)
|
||||
{
|
||||
result = iter.u();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// VertexOrientation2DF0D
|
||||
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element
|
||||
* to which the Interface0DIterator& belongs to and
|
||||
// VertexOrientation2DF0D
|
||||
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
|
||||
* evaluated at the Interface0D pointed by this Interface0DIterator&.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
|
||||
class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "VertexOrientation2DF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "VertexOrientation2DF0D"*/
|
||||
string getName() const {
|
||||
return "VertexOrientation2DF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// VertexOrientation3DF0D
|
||||
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element
|
||||
* to which the Interface0DIterator& belongs to and
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// VertexOrientation3DF0D
|
||||
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
|
||||
* evaluated at the Interface0D pointed by this Interface0DIterator&.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
|
||||
class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "VertexOrientation3DF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "VertexOrientation3DF0D"*/
|
||||
string getName() const {
|
||||
return "VertexOrientation3DF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// Curvature2DAngleF0D
|
||||
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element
|
||||
* to which the Interface0DIterator& belongs to and
|
||||
* evaluated at the Interface0D pointed by this Interface0DIterator&.
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// Curvature2DAngleF0D
|
||||
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element to which the Interface0DIterator&
|
||||
* belongs to and evaluated at the Interface0D pointed by this Interface0DIterator&.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real>
|
||||
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "Curvature2DAngleF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "Curvature2DAngleF0D"*/
|
||||
string getName() const {
|
||||
return "Curvature2DAngleF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// ZDiscontinuity
|
||||
/*! Returns a real giving the distance between
|
||||
* and Interface0D and the shape that lies behind (occludee).
|
||||
* This distance is evaluated in the camera space and normalized
|
||||
* between 0 and 1. Therefore, if no oject is occluded by the
|
||||
* shape to which the Interface0D belongs to, 1 is returned.
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// ZDiscontinuity
|
||||
/*! Returns a real giving the distance between and Interface0D and the shape that lies behind (occludee).
|
||||
* This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no oject is occluded
|
||||
* by the shape to which the Interface0D belongs to, 1 is returned.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
|
||||
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "ZDiscontinuityF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "ZDiscontinuityF0D"*/
|
||||
string getName() const {
|
||||
return "ZDiscontinuityF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// Normal2DF0D
|
||||
/*! Returns a Vec2f giving the normalized 2D normal to the 1D element
|
||||
* to which the Interface0DIterator& belongs to and
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// Normal2DF0D
|
||||
/*! Returns a Vec2f giving the normalized 2D normal to the 1D element to which the Interface0DIterator& belongs to and
|
||||
* evaluated at the Interface0D pointed by this Interface0DIterator&.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f>
|
||||
class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "Normal2DF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "Normal2DF0D"*/
|
||||
string getName() const {
|
||||
return "Normal2DF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// MaterialF0D
|
||||
/*! Returns the material of the object evaluated at the Interface0D.
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// MaterialF0D
|
||||
/*! Returns the material of the object evaluated at the Interface0D.
|
||||
* This evaluation can be ambiguous (in the case of a TVertex for example.
|
||||
* This functor tries to remove this ambiguity using the context
|
||||
* offered by the 1D element to which the Interface0DIterator& belongs
|
||||
* to and by arbitrary chosing the material of the face
|
||||
* that lies on its left when following the 1D element if there
|
||||
* are two different materials on each side of the point.
|
||||
* However, there still can be problematic cases, and the user willing
|
||||
* to deal with this cases in a specific way should implement
|
||||
* its own getMaterial functor.
|
||||
* 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>
|
||||
class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "MaterialF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "MaterialF0D"*/
|
||||
string getName() const {
|
||||
return "MaterialF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// ShapeIdF0D
|
||||
/*! Returns the Id of the Shape the Interface0D belongs to.
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// ShapeIdF0D
|
||||
/*! Returns the Id of the Shape the Interface0D belongs to.
|
||||
* This evaluation can be ambiguous (in the case of a TVertex for example).
|
||||
* This functor tries to remove this ambiguity using the context
|
||||
* offered by the 1D element to which the Interface0DIterator& belongs
|
||||
* to.
|
||||
* However, there still can be problematic cases, and the user willing
|
||||
* to deal with this cases in a specific way should implement
|
||||
* its own getShapeIdF0D functor.
|
||||
* 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>
|
||||
class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "ShapeIdF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "ShapeIdF0D"*/
|
||||
string getName() const {
|
||||
return "ShapeIdF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// QiF0D
|
||||
/*! Returns the quantitative invisibility of this Interface0D.
|
||||
* This evaluation can be ambiguous (in the case of a TVertex for example).
|
||||
* This functor tries to remove this ambiguity using the context
|
||||
* offered by the 1D element to which the Interface0DIterator& belongs
|
||||
* to.
|
||||
* However, there still can be problematic cases, and the user willing
|
||||
* to deal with this cases in a specific way should implement
|
||||
* its own getQIF0D functor.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// QiF0D
|
||||
/*! Returns the quantitative invisibility of this Interface0D.
|
||||
* This evaluation can be ambiguous (in the case of a TVertex for example).
|
||||
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
|
||||
* Interface0DIterator& belongs to.
|
||||
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
|
||||
* should implement its own getQIF0D functor.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "QuantitativeInvisibilityF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "QuantitativeInvisibilityF0D"*/
|
||||
string getName() const {
|
||||
return "QuantitativeInvisibilityF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// CurveNatureF0D
|
||||
/*! Returns the Nature::EdgeNature of the 1D element the
|
||||
* Interface0DIterator& belongs to.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// CurveNatureF0D
|
||||
/*! Returns the Nature::EdgeNature of the 1D element the Interface0DIterator& belongs to. */
|
||||
class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "QuantitativeInvisibilityF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "QuantitativeInvisibilityF0D"*/
|
||||
string getName() const {
|
||||
return "CurveNatureF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// GetShapeF0D
|
||||
/*! Returns the ViewShape*
|
||||
* containing the Interface0D
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*>
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// GetShapeF0D
|
||||
/*! Returns the ViewShape* containing the Interface0D */
|
||||
class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetShapeF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetShapeF0D"*/
|
||||
string getName() const {
|
||||
return "GetShapeF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// GetOccludersF0D
|
||||
/*! Returns a vector containing the ViewShape*
|
||||
* occluding the Interface0D
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// GetOccludersF0D
|
||||
/*! Returns a vector containing the ViewShape* occluding the Interface0D */
|
||||
class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetOccludersF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetOccludersF0D"*/
|
||||
string getName() const {
|
||||
return "GetOccludersF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// GetOccludeeF0D
|
||||
/*! Returns the ViewShape*
|
||||
* "occluded" by the Interface0D
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
|
||||
// GetOccludeeF0D
|
||||
/*! Returns the ViewShape* "occluded" by the Interface0D */
|
||||
class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetOccludeeF0D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "GetOccludeeF0D"*/
|
||||
string getName() const {
|
||||
return "GetOccludeeF0D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface0DIterator& iter);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////// Internal ////////////////////////////
|
||||
|
||||
/////////////////////////// Internal ////////////////////////////
|
||||
// getFEdge
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
FEdge *getFEdge(Interface0D& it1, Interface0D& it2);
|
||||
|
||||
// getFEdge
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
FEdge* getFEdge(Interface0D& it1, Interface0D& it2);
|
||||
// getFEdges
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
|
||||
|
||||
// getFEdges
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getFEdges(Interface0DIterator& it,
|
||||
FEdge*& fe1,
|
||||
FEdge*& fe2);
|
||||
// getViewEdges
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getViewEdges(Interface0DIterator& it, ViewEdge *&ve1, ViewEdge *&ve2);
|
||||
|
||||
// getViewEdges
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getViewEdges(Interface0DIterator& it,
|
||||
ViewEdge *&ve1,
|
||||
ViewEdge *&ve2);
|
||||
// getShapeF0D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
ViewShape *getShapeF0D(Interface0DIterator& it);
|
||||
|
||||
// getShapeF0D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
ViewShape* getShapeF0D(Interface0DIterator& it);
|
||||
// getOccludersF0D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
|
||||
|
||||
// getOccludersF0D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
|
||||
|
||||
// getOccludeeF0D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
ViewShape* getOccludeeF0D(Interface0DIterator& it);
|
||||
// getOccludeeF0D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
ViewShape *getOccludeeF0D(Interface0DIterator& it);
|
||||
|
||||
} // end of namespace Functions0D
|
||||
|
||||
#endif // FUNCTIONS0D_H
|
||||
#endif // __FREESTYLE_FUNCTIONS_0D_H__
|
||||
|
||||
@@ -1,82 +1,108 @@
|
||||
/*
|
||||
* ***** 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) {
|
||||
FEdge * fe = dynamic_cast<FEdge*>(&inter);
|
||||
if(fe){
|
||||
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) {
|
||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
int QuantitativeInvisibilityF1D::operator()(Interface1D& inter)
|
||||
{
|
||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve) {
|
||||
result = ve->qi();
|
||||
return 0;
|
||||
@@ -88,144 +114,158 @@ namespace Functions1D {
|
||||
}
|
||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int CurveNatureF1D::operator()(Interface1D& inter) {
|
||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve)
|
||||
int CurveNatureF1D::operator()(Interface1D& inter)
|
||||
{
|
||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve) {
|
||||
result = ve->getNature();
|
||||
else{
|
||||
// we return a nature that contains every
|
||||
// natures of the viewedges spanned by the chain.
|
||||
}
|
||||
else {
|
||||
// we return a nature that contains every natures of the viewedges spanned by the chain.
|
||||
Nature::EdgeNature nat = Nature::NO_FEATURE;
|
||||
Interface0DIterator it = inter.verticesBegin();
|
||||
while(!it.isEnd()){
|
||||
while (!it.isEnd()) {
|
||||
nat |= _func(it);
|
||||
++it;
|
||||
}
|
||||
result = nat;
|
||||
}
|
||||
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)
|
||||
if (ve)
|
||||
ve->setChainingTimeStamp(timestamp->getTimeStamp());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int IncrementChainingTimeStampF1D::operator()(Interface1D& inter) {
|
||||
int IncrementChainingTimeStampF1D::operator()(Interface1D& inter)
|
||||
{
|
||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if(ve)
|
||||
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){
|
||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve) {
|
||||
shapesVector.push_back(ve->viewShape());
|
||||
}else{
|
||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
||||
for(;it!=itend;++it)
|
||||
}
|
||||
else {
|
||||
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||
for (; it != itend; ++it)
|
||||
shapesSet.insert(Functions0D::getShapeF0D(it));
|
||||
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
|
||||
}
|
||||
result = shapesVector;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int GetOccludersF1D::operator()(Interface1D& inter) {
|
||||
int GetOccludersF1D::operator()(Interface1D& inter)
|
||||
{
|
||||
vector<ViewShape*> shapesVector;
|
||||
set<ViewShape*> shapesSet;
|
||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve){
|
||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve) {
|
||||
result = ve->occluders();
|
||||
}else{
|
||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
||||
for(;it!=itend;++it){
|
||||
}
|
||||
else {
|
||||
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||
for (; it != itend; ++it) {
|
||||
Functions0D::getOccludersF0D(it, shapesSet);
|
||||
}
|
||||
shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
|
||||
result = shapesVector;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int GetOccludeeF1D::operator()(Interface1D& inter) {
|
||||
int GetOccludeeF1D::operator()(Interface1D& inter)
|
||||
{
|
||||
vector<ViewShape*> shapesVector;
|
||||
set<ViewShape*> shapesSet;
|
||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve){
|
||||
ViewShape * aShape = ve->aShape();
|
||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve) {
|
||||
ViewShape *aShape = ve->aShape();
|
||||
shapesVector.push_back(aShape);
|
||||
}else{
|
||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
||||
for(;it!=itend;++it){
|
||||
}
|
||||
else {
|
||||
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||
for (; it != itend; ++it) {
|
||||
shapesSet.insert(Functions0D::getOccludeeF0D(it));
|
||||
}
|
||||
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
|
||||
}
|
||||
result = shapesVector;
|
||||
return 0;
|
||||
}
|
||||
// Internal
|
||||
////////////
|
||||
}
|
||||
|
||||
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes){
|
||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve){
|
||||
ViewShape * aShape = ve->aShape();
|
||||
if(aShape == 0){
|
||||
// Internal
|
||||
////////////
|
||||
|
||||
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
|
||||
{
|
||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve) {
|
||||
ViewShape *aShape = ve->aShape();
|
||||
if (aShape == 0) {
|
||||
oShapes.insert(0);
|
||||
return;
|
||||
}
|
||||
oShapes.insert(aShape);
|
||||
}
|
||||
else{
|
||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
||||
for(;it!=itend;++it)
|
||||
else {
|
||||
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||
for (; it != itend; ++it)
|
||||
oShapes.insert(Functions0D::getOccludeeF0D(it));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes){
|
||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve){
|
||||
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes)
|
||||
{
|
||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve) {
|
||||
vector<ViewShape*>& occluders = ve->occluders();
|
||||
oShapes.insert<vector<ViewShape*>::iterator>(occluders.begin(), occluders.end());
|
||||
}
|
||||
else{
|
||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
||||
for(;it!=itend;++it){
|
||||
else {
|
||||
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||
for (; it != itend; ++it) {
|
||||
set<ViewShape*> shapes;
|
||||
Functions0D::getOccludersF0D(it, shapes);
|
||||
for(set<ViewShape*>::iterator s=shapes.begin(), send=shapes.end();
|
||||
s!=send;
|
||||
++s)
|
||||
for (set<ViewShape*>::iterator s = shapes.begin(), send = shapes.end(); s != send; ++s)
|
||||
oShapes.insert(*s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes){
|
||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve){
|
||||
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
|
||||
{
|
||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||
if (ve) {
|
||||
oShapes.insert(ve->viewShape());
|
||||
}else{
|
||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
||||
for(;it!=itend;++it)
|
||||
}
|
||||
else {
|
||||
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||
for (; it != itend; ++it)
|
||||
oShapes.insert(Functions0D::getShapeF0D(it));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace Functions1D
|
||||
|
||||
@@ -1,41 +1,48 @@
|
||||
//
|
||||
// Filename : Functions1D.h
|
||||
// Author(s) : Stephane Grabli, Emmanuel Turquin
|
||||
// Purpose : Functions taking 1D input
|
||||
// Date of creation : 01/07/2003
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_FUNCTIONS_1D_H__
|
||||
#define __FREESTYLE_FUNCTIONS_1D_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/Functions1D.h
|
||||
* \ingroup freestyle
|
||||
* \brief Functions taking 1D input
|
||||
* \author Stephane Grabli
|
||||
* \author Emmanuel Turquin
|
||||
* \date 01/07/2003
|
||||
*/
|
||||
|
||||
#ifndef FUNCTIONS1D_HPP
|
||||
# define FUNCTIONS1D_HPP
|
||||
#include "Functions0D.h"
|
||||
#include "Interface1D.h"
|
||||
#include "ViewMap.h"
|
||||
|
||||
# include "ViewMap.h"
|
||||
# include "Functions0D.h"
|
||||
# include "Interface1D.h"
|
||||
# include "../system/Precision.h"
|
||||
# include "../system/TimeStamp.h"
|
||||
# include "../system/FreestyleConfig.h"
|
||||
#include "../system/FreestyleConfig.h"
|
||||
#include "../system/Precision.h"
|
||||
#include "../system/TimeStamp.h"
|
||||
|
||||
#include "../python/Director.h"
|
||||
|
||||
@@ -44,14 +51,10 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
/*! Base class for Unary Functions (functors) working
|
||||
* on Interface1D.
|
||||
* A unary function will be used by calling
|
||||
* its operator() on an Interface1D.
|
||||
* \attention In the scripting language, there exists
|
||||
* several prototypes depending on the returned value type.
|
||||
* For example, you would inherit from a UnaryFunction1DDouble
|
||||
* if you wish to define a function that returns a double.
|
||||
/*! Base class for Unary Functions (functors) working on Interface1D.
|
||||
* A unary function will be used by calling its operator() on an Interface1D.
|
||||
* \attention In the scripting language, there exists several prototypes depending on the returned value type.
|
||||
* For example, you would inherit from a UnaryFunction1DDouble if you wish to define a function that returns a double.
|
||||
* The different existing prototypes are:
|
||||
* - UnaryFunction1DVoid
|
||||
* - UnaryFunction1DUnsigned
|
||||
@@ -65,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) {
|
||||
return Director_BPy_UnaryFunction1D___call__( this, py_uf1D, 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,25 +130,41 @@ 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) {
|
||||
return Director_BPy_UnaryFunction1D___call__( this, py_uf1D, inter );
|
||||
int operator()(Interface1D& inter)
|
||||
{
|
||||
return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
|
||||
}
|
||||
|
||||
void setIntegrationType(IntegrationType integration) { _integration = integration; }
|
||||
IntegrationType getIntegrationType() const { return _integration; }
|
||||
void setIntegrationType(IntegrationType integration)
|
||||
{
|
||||
_integration = integration;
|
||||
}
|
||||
|
||||
protected:
|
||||
IntegrationType getIntegrationType() const
|
||||
{
|
||||
return _integration;
|
||||
}
|
||||
|
||||
protected:
|
||||
IntegrationType _integration;
|
||||
};
|
||||
|
||||
@@ -150,406 +176,452 @@ public:
|
||||
|
||||
namespace Functions1D {
|
||||
|
||||
// GetXF1D
|
||||
/*! Returns the X 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetXF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
// GetXF1D
|
||||
/*! Returns the X 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetXF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
Functions0D::GetXF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
GetXF1D(IntegrationType iType) : UnaryFunction1D<real>(iType) {}
|
||||
|
||||
/*! Returns the string "GetXF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "GetXF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter) ;
|
||||
};
|
||||
|
||||
// GetYF1D
|
||||
/*! Returns the Y 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetYF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
Functions0D::GetYF0D _func;
|
||||
public:
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetYF1D
|
||||
/*! Returns the Y 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetYF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
Functions0D::GetYF0D _func;
|
||||
|
||||
public:
|
||||
/*! Builds the functor.
|
||||
* \param iType
|
||||
* The integration method used to compute
|
||||
* a single value from a set of values.
|
||||
* 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 {
|
||||
GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||
|
||||
/*! Returns the string "GetYF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "GetYF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter) ;
|
||||
};
|
||||
|
||||
// GetZF1D
|
||||
/*! Returns the Z 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetZF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetZF1D
|
||||
/*! Returns the Z 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetZF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
Functions0D::GetZF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||
|
||||
/*! Returns the string "GetZF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "GetZF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter) ;
|
||||
};
|
||||
|
||||
// GetProjectedXF1D
|
||||
/*! Returns the projected X 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedXF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetProjectedXF1D
|
||||
/*! Returns the projected X 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedXF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
Functions0D::GetProjectedXF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||
|
||||
/*! Returns the string "GetProjectedXF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "GetProjectedXF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetProjectedYF1D
|
||||
/*! Returns the projected Y 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedYF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetProjectedYF1D
|
||||
/*! Returns the projected Y 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedYF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
Functions0D::GetProjectedYF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||
|
||||
/*! Returns the string "GetProjectedYF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "GetProjectedYF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetProjectedZF1D
|
||||
/*! Returns the projected Z 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedZF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetProjectedZF1D
|
||||
/*! Returns the projected Z 3D coordinate of an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetProjectedZF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
Functions0D::GetProjectedZF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||
|
||||
/*! Returns the string "GetProjectedZF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "GetProjectedZF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// Orientation2DF1D
|
||||
/*! Returns the 2D orientation as a Vec2f*/
|
||||
class LIB_VIEW_MAP_EXPORT Orientation2DF1D : public UnaryFunction1D<Vec2f>
|
||||
{
|
||||
private:
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// Orientation2DF1D
|
||||
/*! Returns the 2D orientation as a Vec2f*/
|
||||
class LIB_VIEW_MAP_EXPORT Orientation2DF1D : public UnaryFunction1D<Vec2f>
|
||||
{
|
||||
private:
|
||||
Functions0D::VertexOrientation2DF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
Orientation2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {}
|
||||
|
||||
/*! Returns the string "Orientation2DF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "Orientation2DF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// Orientation3DF1D
|
||||
/*! Returns the 3D orientation as a Vec3f. */
|
||||
class LIB_VIEW_MAP_EXPORT Orientation3DF1D : public UnaryFunction1D<Vec3f>
|
||||
{
|
||||
private:
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// Orientation3DF1D
|
||||
/*! Returns the 3D orientation as a Vec3f. */
|
||||
class LIB_VIEW_MAP_EXPORT Orientation3DF1D : public UnaryFunction1D<Vec3f>
|
||||
{
|
||||
private:
|
||||
Functions0D::VertexOrientation3DF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
Orientation3DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec3f>(iType) {}
|
||||
|
||||
/*! Returns the string "Orientation3DF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "Orientation3DF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// ZDiscontinuityF1D
|
||||
/*! Returns a real giving the distance between
|
||||
* and Interface1D and the shape that lies behind (occludee).
|
||||
* This distance is evaluated in the camera space and normalized
|
||||
* between 0 and 1. Therefore, if no oject is occluded by the
|
||||
* shape to which the Interface1D belongs to, 1 is returned.
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// ZDiscontinuityF1D
|
||||
/*! Returns a real giving the distance between and Interface1D and the shape that lies behind (occludee).
|
||||
* This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no oject is occluded
|
||||
* by the shape to which the Interface1D belongs to, 1 is returned.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
private:
|
||||
Functions0D::ZDiscontinuityF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||
|
||||
/*! Returns the string "ZDiscontinuityF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "ZDiscontinuityF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// QuantitativeInvisibilityF1D
|
||||
/*! Returns the Quantitative Invisibility of an Interface1D element.
|
||||
* If the Interface1D is a ViewEdge, then there is no ambiguity
|
||||
* concerning the result. But, if the Interface1D results of a chaining
|
||||
* (chain, stroke), then it might be made of several 1D elements
|
||||
* of different Quantitative Invisibilities.
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// QuantitativeInvisibilityF1D
|
||||
/*! Returns the Quantitative Invisibility of an Interface1D element.
|
||||
* If the Interface1D is a ViewEdge, then there is no ambiguity concerning the result. But, if the Interface1D
|
||||
* results of a chaining (chain, stroke), then it might be made of several 1D elements of different
|
||||
* Quantitative Invisibilities.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned>
|
||||
{
|
||||
private:
|
||||
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned>
|
||||
{
|
||||
private:
|
||||
Functions0D::QuantitativeInvisibilityF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
|
||||
/*! Returns the string "QuantitativeInvisibilityF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "QuantitativeInvisibilityF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// CurveNatureF1D
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// CurveNatureF1D
|
||||
/*! Returns the nature of the Interface1D (silhouette, ridge, crease...).
|
||||
* Except if the Interface1D is a ViewEdge, this result might be ambiguous.
|
||||
* Indeed, the Interface1D might result from the gathering of several 1D elements,
|
||||
* each one being of a different nature. An integration method, such as
|
||||
* the MEAN, might give, in this case, irrelevant results.
|
||||
* Indeed, the Interface1D might result from the gathering of several 1D elements, each one being of a different
|
||||
* nature. An integration method, such as the MEAN, might give, in this case, irrelevant results.
|
||||
*/
|
||||
class LIB_VIEW_MAP_EXPORT CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature>
|
||||
{
|
||||
private:
|
||||
class LIB_VIEW_MAP_EXPORT CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature>
|
||||
{
|
||||
private:
|
||||
Functions0D::CurveNatureF0D _func;
|
||||
public:
|
||||
|
||||
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 {
|
||||
|
||||
/*! Returns the string "CurveNatureF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "CurveNatureF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// TimeStampF1D
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// TimeStampF1D
|
||||
/*! Returns the time stamp of the Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT TimeStampF1D : public UnaryFunction1D_void
|
||||
class LIB_VIEW_MAP_EXPORT TimeStampF1D : public UnaryFunction1D_void
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "TimeStampF1D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "TimeStampF1D"*/
|
||||
string getName() const {
|
||||
return "TimeStampF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// IncrementChainingTimeStampF1D
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// IncrementChainingTimeStampF1D
|
||||
/*! Increments the chaining time stamp of the Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT IncrementChainingTimeStampF1D : public UnaryFunction1D_void
|
||||
class LIB_VIEW_MAP_EXPORT IncrementChainingTimeStampF1D : public UnaryFunction1D_void
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "IncrementChainingTimeStampF1D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "IncrementChainingTimeStampF1D"*/
|
||||
string getName() const {
|
||||
return "IncrementChainingTimeStampF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// ChainingTimeStampF1D
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// ChainingTimeStampF1D
|
||||
/*! Sets the chaining time stamp of the Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT ChainingTimeStampF1D : public UnaryFunction1D_void
|
||||
class LIB_VIEW_MAP_EXPORT ChainingTimeStampF1D : public UnaryFunction1D_void
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "ChainingTimeStampF1D" */
|
||||
string getName() const
|
||||
{
|
||||
public:
|
||||
/*! Returns the string "ChainingTimeStampF1D"*/
|
||||
string getName() const {
|
||||
return "ChainingTimeStampF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Curvature2DAngleF1D
|
||||
// Curvature2DAngleF1D
|
||||
/*! Returns the 2D curvature as an angle for an Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
public:
|
||||
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF1D : public UnaryFunction1D<real>
|
||||
{
|
||||
public:
|
||||
/*! Builds the functor.
|
||||
* \param iType
|
||||
* The integration method used to compute
|
||||
* a single value from a set of values.
|
||||
* 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 {
|
||||
|
||||
/*! Returns the string "Curvature2DAngleF1D" */
|
||||
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;
|
||||
};
|
||||
|
||||
// Normal2DF1D
|
||||
/*! Returns the 2D normal for an interface 1D. */
|
||||
class LIB_VIEW_MAP_EXPORT Normal2DF1D : public UnaryFunction1D<Vec2f>
|
||||
{
|
||||
public:
|
||||
private:
|
||||
Functions0D::Curvature2DAngleF0D _fun;
|
||||
};
|
||||
|
||||
// Normal2DF1D
|
||||
/*! Returns the 2D normal for an interface 1D. */
|
||||
class LIB_VIEW_MAP_EXPORT Normal2DF1D : public UnaryFunction1D<Vec2f>
|
||||
{
|
||||
public:
|
||||
/*! Builds the functor.
|
||||
* \param iType
|
||||
* The integration method used to compute
|
||||
* a single value from a set of values.
|
||||
* 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 {
|
||||
|
||||
/*! Returns the string "Normal2DF1D" */
|
||||
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;
|
||||
};
|
||||
|
||||
// GetShapeF1D
|
||||
/*! Returns list of shapes covered by this Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
|
||||
{
|
||||
public:
|
||||
/*! Builds the functor.
|
||||
*/
|
||||
private:
|
||||
Functions0D::Normal2DF0D _fun;
|
||||
};
|
||||
|
||||
// GetShapeF1D
|
||||
/*! Returns list of shapes covered by this Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
|
||||
{
|
||||
public:
|
||||
/*! Builds the functor. */
|
||||
GetShapeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
|
||||
/*! Returns the string "GetShapeF1D"*/
|
||||
string getName() const {
|
||||
|
||||
/*! Returns the string "GetShapeF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "GetShapeF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetOccludersF1D
|
||||
/*! Returns list of occluding shapes covered by this Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape*> >
|
||||
{
|
||||
public:
|
||||
/*! Builds the functor.
|
||||
*/
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetOccludersF1D
|
||||
/*! Returns list of occluding shapes covered by this Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape*> >
|
||||
{
|
||||
public:
|
||||
/*! Builds the functor. */
|
||||
GetOccludersF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
|
||||
/*! Returns the string "GetOccludersF1D"*/
|
||||
string getName() const {
|
||||
|
||||
/*! Returns the string "GetOccludersF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "GetOccludersF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetOccludeeF1D
|
||||
/*! Returns list of occluded shapes covered by this Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
|
||||
{
|
||||
public:
|
||||
/*! Builds the functor.
|
||||
*/
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
|
||||
// GetOccludeeF1D
|
||||
/*! Returns list of occluded shapes covered by this Interface1D. */
|
||||
class LIB_VIEW_MAP_EXPORT GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
|
||||
{
|
||||
public:
|
||||
/*! Builds the functor. */
|
||||
GetOccludeeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
|
||||
/*! Returns the string "GetOccludeeF1D"*/
|
||||
string getName() const {
|
||||
|
||||
/*! Returns the string "GetOccludeeF1D" */
|
||||
string getName() const
|
||||
{
|
||||
return "GetOccludeeF1D";
|
||||
}
|
||||
/*! the () operator.*/
|
||||
|
||||
/*! the () operator. */
|
||||
int operator()(Interface1D& inter);
|
||||
};
|
||||
};
|
||||
|
||||
// internal
|
||||
////////////
|
||||
// internal
|
||||
////////////
|
||||
|
||||
// getOccludeeF1D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
||||
// getOccludeeF1D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
||||
|
||||
// getOccludersF1D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
||||
// getOccludersF1D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
||||
|
||||
// getShapeF1D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
||||
// getShapeF1D
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
||||
|
||||
} // end of namespace Functions1D
|
||||
|
||||
#endif // FUNCTIONS1D_HPP
|
||||
#endif // __FREESTYLE_FUNCTIONS_1D_H__
|
||||
|
||||
@@ -1,93 +1,108 @@
|
||||
//
|
||||
// Filename : GridDensityProvider.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-2-5
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_GRID_DENSITY_PROVIDER_H__
|
||||
#define __FREESTYLE_GRID_DENSITY_PROVIDER_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GRIDDENSITYPROVIDER_H
|
||||
#define GRIDDENSITYPROVIDER_H
|
||||
/** \file blender/freestyle/intern/view_map/GridDensityProvider.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-2-5
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
|
||||
#include "OccluderSource.h"
|
||||
|
||||
#include "../geometry/BBox.h"
|
||||
|
||||
class GridDensityProvider {
|
||||
class GridDensityProvider
|
||||
{
|
||||
// Disallow copying and assignment
|
||||
GridDensityProvider (const GridDensityProvider& other);
|
||||
GridDensityProvider& operator= (const GridDensityProvider& other);
|
||||
GridDensityProvider(const GridDensityProvider& other);
|
||||
GridDensityProvider& operator=(const GridDensityProvider& other);
|
||||
|
||||
public:
|
||||
GridDensityProvider (OccluderSource& source)
|
||||
: source(source) {
|
||||
}
|
||||
GridDensityProvider(OccluderSource& source) : source(source) {}
|
||||
|
||||
virtual ~GridDensityProvider() {};
|
||||
|
||||
float cellSize() {
|
||||
float cellSize()
|
||||
{
|
||||
return _cellSize;
|
||||
}
|
||||
|
||||
unsigned cellsX() {
|
||||
unsigned cellsX()
|
||||
{
|
||||
return _cellsX;
|
||||
}
|
||||
|
||||
unsigned cellsY() {
|
||||
unsigned cellsY()
|
||||
{
|
||||
return _cellsY;
|
||||
}
|
||||
|
||||
float cellOrigin(int index) {
|
||||
if ( index < 2 ) {
|
||||
float cellOrigin(int index)
|
||||
{
|
||||
if (index < 2) {
|
||||
return _cellOrigin[index];
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new out_of_range("GridDensityProvider::cellOrigin can take only indexes of 0 or 1.");
|
||||
}
|
||||
}
|
||||
|
||||
static void calculateOptimalProscenium(OccluderSource& source, real proscenium[4]) {
|
||||
static void calculateOptimalProscenium(OccluderSource& source, real proscenium[4])
|
||||
{
|
||||
source.begin();
|
||||
if ( source.isValid() ) {
|
||||
if (source.isValid()) {
|
||||
const Vec3r& initialPoint = source.getGridSpacePolygon().getVertices()[0];
|
||||
proscenium[0] = proscenium[1] = initialPoint[0];
|
||||
proscenium[2] = proscenium[3] = initialPoint[1];
|
||||
while ( source.isValid() ) {
|
||||
while (source.isValid()) {
|
||||
GridHelpers::expandProscenium (proscenium, source.getGridSpacePolygon());
|
||||
source.next();
|
||||
}
|
||||
}
|
||||
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << ")" << endl;
|
||||
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2]
|
||||
<< ", " << proscenium[3] << ")" << endl;
|
||||
}
|
||||
|
||||
static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox, real proscenium[4]) {
|
||||
static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox,
|
||||
real proscenium[4])
|
||||
{
|
||||
real z;
|
||||
// We want to use the z-coordinate closest to the camera to determine the proscenium face
|
||||
if ( ::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2]) ) {
|
||||
if (::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2])) {
|
||||
z = bbox.getMin()[2];
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
z = bbox.getMax()[2];
|
||||
}
|
||||
// Now calculate the proscenium according to the min and max values of the x and y coordinates
|
||||
@@ -98,7 +113,8 @@ public:
|
||||
proscenium[1] = std::max(minPoint[0], maxPoint[0]);
|
||||
proscenium[2] = std::min(minPoint[1], maxPoint[1]);
|
||||
proscenium[3] = std::max(minPoint[1], maxPoint[1]);
|
||||
cout << "Proscenium : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << endl;
|
||||
cout << "Proscenium : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", "
|
||||
<< proscenium[3] << endl;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -108,24 +124,23 @@ protected:
|
||||
float _cellOrigin[2];
|
||||
};
|
||||
|
||||
class GridDensityProviderFactory {
|
||||
class GridDensityProviderFactory
|
||||
{
|
||||
// Disallow copying and assignment
|
||||
GridDensityProviderFactory (const GridDensityProviderFactory& other);
|
||||
GridDensityProviderFactory& operator= (const GridDensityProviderFactory& other);
|
||||
|
||||
public:
|
||||
GridDensityProviderFactory()
|
||||
{
|
||||
}
|
||||
GridDensityProviderFactory() {}
|
||||
|
||||
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) =0;
|
||||
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) = 0;
|
||||
|
||||
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform) =0;
|
||||
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform) = 0;
|
||||
|
||||
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) =0;
|
||||
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) = 0;
|
||||
|
||||
virtual ~GridDensityProviderFactory () {}
|
||||
};
|
||||
|
||||
#endif // GRIDDENSITYPROVIDER_H
|
||||
|
||||
#endif // __FREESTYLE_GRID_DENSITY_PROVIDER_H__
|
||||
|
||||
@@ -1,60 +1,70 @@
|
||||
//
|
||||
// Filename : HeuristicGridDensityProviderFactory.cpp
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-2-8
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-2-8
|
||||
*/
|
||||
|
||||
#include "HeuristicGridDensityProviderFactory.h"
|
||||
|
||||
HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces)
|
||||
: sizeFactor(sizeFactor), numFaces(numFaces)
|
||||
: sizeFactor(sizeFactor), numFaces(numFaces)
|
||||
{
|
||||
}
|
||||
|
||||
HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory () {}
|
||||
HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory() {}
|
||||
|
||||
auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||
auto_ptr<GridDensityProvider>
|
||||
HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||
{
|
||||
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
|
||||
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
|
||||
if ( avg->cellSize() > p23->cellSize() ) {
|
||||
if (avg->cellSize() > p23->cellSize()) {
|
||||
return (auto_ptr<GridDensityProvider>) p23;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return (auto_ptr<GridDensityProvider>) avg;
|
||||
}
|
||||
}
|
||||
|
||||
auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
|
||||
auto_ptr<GridDensityProvider>
|
||||
HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform)
|
||||
{
|
||||
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
|
||||
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox,
|
||||
transform, sizeFactor));
|
||||
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
|
||||
if ( avg->cellSize() > p23->cellSize() ) {
|
||||
if (avg->cellSize() > p23->cellSize()) {
|
||||
return (auto_ptr<GridDensityProvider>) p23;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return (auto_ptr<GridDensityProvider>) avg;
|
||||
}
|
||||
}
|
||||
@@ -65,10 +75,10 @@ auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensit
|
||||
GridDensityProvider::calculateOptimalProscenium(source, proscenium);
|
||||
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
|
||||
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
|
||||
if ( avg->cellSize() > p23->cellSize() ) {
|
||||
if (avg->cellSize() > p23->cellSize()) {
|
||||
return (auto_ptr<GridDensityProvider>) p23;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return (auto_ptr<GridDensityProvider>) avg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,48 +1,55 @@
|
||||
//
|
||||
// Filename : HeuristicGridDensityProviderFactory.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-2-8
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
|
||||
#define __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-2-8
|
||||
*/
|
||||
|
||||
#ifndef HEURISTICGRIDDENSITYPROVIDERFACTORY_H
|
||||
#define HEURISTICGRIDDENSITYPROVIDERFACTORY_H
|
||||
//#include <memory> // provided by GridDensityProvider.h
|
||||
|
||||
// #include <memory> // provided by GridDensityProvider.h
|
||||
// #include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
|
||||
#include "Pow23GridDensityProvider.h"
|
||||
#include "AverageAreaGridDensityProvider.h"
|
||||
//#include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
|
||||
#include "Pow23GridDensityProvider.h"
|
||||
|
||||
class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory {
|
||||
class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory
|
||||
{
|
||||
public:
|
||||
HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
|
||||
~HeuristicGridDensityProviderFactory ();
|
||||
~HeuristicGridDensityProviderFactory();
|
||||
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
||||
|
||||
protected:
|
||||
@@ -50,5 +57,4 @@ protected:
|
||||
unsigned numFaces;
|
||||
};
|
||||
|
||||
#endif // HEURISTICGRIDDENSITYPROVIDERFACTORY_H
|
||||
|
||||
#endif // __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
|
||||
|
||||
@@ -1,45 +1,53 @@
|
||||
//
|
||||
// Filename : Interface0D.h
|
||||
// Author(s) : Emmanuel Turquin
|
||||
// Purpose : Interface to 0D elts
|
||||
// Date of creation : 01/07/2003
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_INTERFACE_0D_H__
|
||||
#define __FREESTYLE_INTERFACE_0D_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/Interface0D.h
|
||||
* \ingroup freestyle
|
||||
* \brief Interface to 0D elts
|
||||
* \author Emmanuel Turquin
|
||||
* \date 01/07/2003
|
||||
*/
|
||||
|
||||
#ifndef INTERFACE0D_H
|
||||
# define INTERFACE0D_H
|
||||
#include <iostream>
|
||||
#include <Python.h>
|
||||
#include <string>
|
||||
|
||||
# include <Python.h>
|
||||
# include <string>
|
||||
# include <iostream>
|
||||
# include "../system/Id.h"
|
||||
# include "../system/Precision.h"
|
||||
# include "../winged_edge/Nature.h"
|
||||
# include "../geometry/Geom.h"
|
||||
using namespace std;
|
||||
#include "../geometry/Geom.h"
|
||||
|
||||
#include "../system/Id.h"
|
||||
#include "../system/Iterator.h" //soc
|
||||
#include "../system/Precision.h"
|
||||
|
||||
#include "../winged_edge/Nature.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//
|
||||
// Interface0D
|
||||
@@ -51,114 +59,128 @@ class SVertex;
|
||||
class ViewVertex;
|
||||
class NonTVertex;
|
||||
class TVertex;
|
||||
|
||||
/*! Base class for any 0D element. */
|
||||
class Interface0D
|
||||
{
|
||||
public:
|
||||
|
||||
/*! Default constructor */
|
||||
Interface0D() {}
|
||||
virtual ~Interface0D() {}; //soc
|
||||
|
||||
/*! Returns the string "Interface0D".*/
|
||||
virtual string getExactTypeName() const {
|
||||
/*! Returns the string "Interface0D". */
|
||||
virtual string getExactTypeName() const
|
||||
{
|
||||
return "Interface0D";
|
||||
}
|
||||
|
||||
// Data access methods
|
||||
|
||||
/*! Returns the 3D x coordinate of the point. */
|
||||
virtual real getX() const {
|
||||
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:
|
||||
|
||||
Interface0DIteratorNested* _iterator;
|
||||
protected:
|
||||
Interface0DIteratorNested *_iterator;
|
||||
};
|
||||
|
||||
#endif // INTERFACE0D_H
|
||||
#endif // __FREESTYLE_INTERFACE_0D_H__
|
||||
|
||||
@@ -1,90 +1,89 @@
|
||||
//
|
||||
// Filename : Interface1D.h
|
||||
// Author(s) : Emmanuel Turquin
|
||||
// Purpose : Interface to 1D elts
|
||||
// Date of creation : 01/07/2003
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_INTERFACE_1D_H__
|
||||
#define __FREESTYLE_INTERFACE_1D_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/Interface1D.h
|
||||
* \ingroup freestyle
|
||||
* \brief Interface 1D and related tools definitions
|
||||
* \author Emmanuel Turquin
|
||||
* \date 01/07/2003
|
||||
*/
|
||||
|
||||
#ifndef INTERFACE1D_H
|
||||
# define INTERFACE1D_H
|
||||
#include <float.h>
|
||||
#include <iostream>
|
||||
#include <Python.h>
|
||||
#include <string>
|
||||
|
||||
# include <Python.h>
|
||||
# include <string>
|
||||
# include <iostream>
|
||||
# include <float.h>
|
||||
# include "../system/Id.h"
|
||||
# include "../system/Precision.h"
|
||||
# include "../winged_edge/Nature.h"
|
||||
# include "Functions0D.h"
|
||||
#include "Functions0D.h"
|
||||
|
||||
#include "../system/Id.h"
|
||||
#include "../system/Precision.h"
|
||||
|
||||
#include "../winged_edge/Nature.h"
|
||||
|
||||
using namespace std;
|
||||
/*! \file Interface1D.h
|
||||
* Interface1D and related tools definitions
|
||||
*/
|
||||
|
||||
// Integration method
|
||||
/*! The different integration
|
||||
* methods that can be invoked
|
||||
* to integrate into a single value the set of values obtained
|
||||
/*! The different integration methods that can be invoked to integrate into a single value the set of values obtained
|
||||
* from each 0D element of a 1D element.
|
||||
*/
|
||||
typedef enum {
|
||||
MEAN,/*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/
|
||||
MIN,/*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/
|
||||
MAX,/*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/
|
||||
FIRST,/*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/
|
||||
LAST/*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/
|
||||
MEAN, /*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/
|
||||
MIN, /*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/
|
||||
MAX, /*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/
|
||||
FIRST, /*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/
|
||||
LAST /*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/
|
||||
} IntegrationType;
|
||||
|
||||
/*! Returns a single
|
||||
* value from a set of values evaluated at each 0D element
|
||||
* of this 1D element.
|
||||
/*! Returns a single value from a set of values evaluated at each 0D element of this 1D element.
|
||||
* \param fun
|
||||
* The UnaryFunction0D used to compute a value at each Interface0D.
|
||||
* \param it
|
||||
* The Interface0DIterator used to iterate over the 0D elements of
|
||||
* this 1D element. The integration will occur over the 0D elements
|
||||
* starting from the one pointed by it.
|
||||
* The Interface0DIterator used to iterate over the 0D elements of this 1D element. The integration will occur
|
||||
* over the 0D elements starting from the one pointed by it.
|
||||
* \param it_end
|
||||
* The Interface0DIterator pointing the end of the 0D elements of the
|
||||
* 1D element.
|
||||
* The Interface0DIterator pointing the end of the 0D elements of the 1D element.
|
||||
* \param integration_type
|
||||
* The integration method used to compute a single value from
|
||||
* a set of values.
|
||||
* The integration method used to compute a single value from a set of values.
|
||||
* \return the single value obtained for the 1D element.
|
||||
*/
|
||||
template <class T>
|
||||
T integrate(UnaryFunction0D<T>& fun,
|
||||
Interface0DIterator it,
|
||||
Interface0DIterator it_end,
|
||||
IntegrationType integration_type = MEAN) {
|
||||
T 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 {
|
||||
/*! Returns the string "Interface1D". */
|
||||
virtual string getExactTypeName() const
|
||||
{
|
||||
return "Interface1D";
|
||||
}
|
||||
|
||||
// Iterator access
|
||||
|
||||
/*! Returns an iterator over the Interface1D vertices,
|
||||
* pointing to the first vertex.
|
||||
*/
|
||||
virtual Interface0DIterator verticesBegin() {
|
||||
/*! 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 {
|
||||
/*! Returns the Id of the 1D element. */
|
||||
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__
|
||||
|
||||
@@ -1,65 +1,73 @@
|
||||
//
|
||||
// Filename : OccluderSource.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2010-12-21
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/freestyle/intern/view_map/OccluderSource.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2010-12-21
|
||||
*/
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "OccluderSource.h"
|
||||
#include <algorithm>
|
||||
|
||||
OccluderSource::OccluderSource (const GridHelpers::Transform& t, WingedEdge& we) : wingedEdge(we), valid(false), transform(t) {
|
||||
#include "OccluderSource.h"
|
||||
|
||||
OccluderSource::OccluderSource(const GridHelpers::Transform& t, WingedEdge& we)
|
||||
: wingedEdge(we), valid(false), transform(t)
|
||||
{
|
||||
begin();
|
||||
}
|
||||
|
||||
OccluderSource::~OccluderSource() {
|
||||
}
|
||||
OccluderSource::~OccluderSource() {}
|
||||
|
||||
void OccluderSource::buildCachedPolygon() {
|
||||
void OccluderSource::buildCachedPolygon()
|
||||
{
|
||||
vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()));
|
||||
// This doesn't work, because our functor's polymorphism won't survive the copy:
|
||||
// std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform);
|
||||
// so we have to do:
|
||||
for ( vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i ) {
|
||||
for (vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i) {
|
||||
(*i) = transform(*i);
|
||||
}
|
||||
cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
|
||||
}
|
||||
|
||||
void OccluderSource::begin() {
|
||||
void OccluderSource::begin()
|
||||
{
|
||||
vector<WShape*>& wshapes = wingedEdge.getWShapes();
|
||||
currentShape = wshapes.begin();
|
||||
shapesEnd = wshapes.end();
|
||||
valid = false;
|
||||
if ( currentShape != shapesEnd ) {
|
||||
if (currentShape != shapesEnd) {
|
||||
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
|
||||
currentFace = wFaces.begin();
|
||||
facesEnd = wFaces.end();
|
||||
|
||||
if ( currentFace != facesEnd ) {
|
||||
if (currentFace != facesEnd) {
|
||||
buildCachedPolygon();
|
||||
valid = true;
|
||||
}
|
||||
@@ -67,14 +75,15 @@ void OccluderSource::begin() {
|
||||
}
|
||||
|
||||
bool OccluderSource::next() {
|
||||
if ( valid ) {
|
||||
if (valid) {
|
||||
++currentFace;
|
||||
while ( currentFace == facesEnd ) {
|
||||
while (currentFace == facesEnd) {
|
||||
++currentShape;
|
||||
if ( currentShape == shapesEnd ) {
|
||||
if (currentShape == shapesEnd) {
|
||||
valid = false;
|
||||
return false;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
|
||||
currentFace = wFaces.begin();
|
||||
facesEnd = wFaces.end();
|
||||
@@ -86,40 +95,47 @@ bool OccluderSource::next() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OccluderSource::isValid() {
|
||||
bool OccluderSource::isValid()
|
||||
{
|
||||
// Or:
|
||||
// return currentShapes != shapesEnd && currentFace != facesEnd;
|
||||
return valid;
|
||||
}
|
||||
|
||||
WFace* OccluderSource::getWFace() {
|
||||
WFace *OccluderSource::getWFace()
|
||||
{
|
||||
return valid ? *currentFace : NULL;
|
||||
}
|
||||
|
||||
Polygon3r OccluderSource::getCameraSpacePolygon() {
|
||||
Polygon3r OccluderSource::getCameraSpacePolygon()
|
||||
{
|
||||
return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()), (*currentFace)->GetNormal());
|
||||
}
|
||||
|
||||
Polygon3r& OccluderSource::getGridSpacePolygon() {
|
||||
Polygon3r& OccluderSource::getGridSpacePolygon()
|
||||
{
|
||||
return cachedPolygon;
|
||||
}
|
||||
|
||||
void OccluderSource::getOccluderProscenium(real proscenium[4]) {
|
||||
void OccluderSource::getOccluderProscenium(real proscenium[4])
|
||||
{
|
||||
begin();
|
||||
const Vec3r& initialPoint = cachedPolygon.getVertices()[0];
|
||||
proscenium[0] = proscenium[1] = initialPoint[0];
|
||||
proscenium[2] = proscenium[3] = initialPoint[1];
|
||||
while ( isValid() ) {
|
||||
while (isValid()) {
|
||||
GridHelpers::expandProscenium (proscenium, cachedPolygon);
|
||||
next();
|
||||
}
|
||||
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << ")" << endl;
|
||||
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", "
|
||||
<< proscenium[3] << ")" << endl;
|
||||
}
|
||||
|
||||
real OccluderSource::averageOccluderArea() {
|
||||
real OccluderSource::averageOccluderArea()
|
||||
{
|
||||
real area = 0.0;
|
||||
unsigned numFaces = 0;
|
||||
for ( begin(); isValid(); next() ) {
|
||||
for (begin(); isValid(); next()) {
|
||||
Vec3r min, max;
|
||||
cachedPolygon.getBBox(min, max);
|
||||
area += (max[0] - min[0]) * (max[1] - min[1]);
|
||||
@@ -128,5 +144,3 @@ real OccluderSource::averageOccluderArea() {
|
||||
area /= numFaces;
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,53 +1,59 @@
|
||||
//
|
||||
// Filename : OccluderSource.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2010-12-21
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_OCCLUDER_SOURCE_H__
|
||||
#define __FREESTYLE_OCCLUDER_SOURCE_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/OccluderSource.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2010-12-21
|
||||
*/
|
||||
|
||||
#ifndef OCCLUDERSOURCE_H
|
||||
#define OCCLUDERSOURCE_H
|
||||
|
||||
#include "../winged_edge/WEdge.h"
|
||||
#include "../geometry/GridHelpers.h"
|
||||
|
||||
class OccluderSource {
|
||||
#include "../winged_edge/WEdge.h"
|
||||
|
||||
class OccluderSource
|
||||
{
|
||||
// Disallow copying and assignment
|
||||
OccluderSource (const OccluderSource& other);
|
||||
OccluderSource& operator= (const OccluderSource& other);
|
||||
OccluderSource(const OccluderSource& other);
|
||||
OccluderSource& operator=(const OccluderSource& other);
|
||||
|
||||
public:
|
||||
OccluderSource (const GridHelpers::Transform& transform, WingedEdge& we);
|
||||
OccluderSource(const GridHelpers::Transform& transform, WingedEdge& we);
|
||||
virtual ~OccluderSource();
|
||||
|
||||
void begin();
|
||||
virtual bool next();
|
||||
bool isValid();
|
||||
|
||||
WFace* getWFace();
|
||||
WFace *getWFace();
|
||||
Polygon3r getCameraSpacePolygon();
|
||||
Polygon3r& getGridSpacePolygon();
|
||||
|
||||
@@ -67,4 +73,4 @@ protected:
|
||||
void buildCachedPolygon();
|
||||
};
|
||||
|
||||
#endif // OCCLUDERSOURCE_H
|
||||
#endif // __FREESTYLE_OCCLUDER_SOURCE_H__
|
||||
|
||||
@@ -1,43 +1,48 @@
|
||||
//
|
||||
// Filename : Pow23GridDensityProvider.cpp
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-2-8
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-2-8
|
||||
*/
|
||||
|
||||
#include "Pow23GridDensityProvider.h"
|
||||
|
||||
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces)
|
||||
: GridDensityProvider(source), numFaces(numFaces)
|
||||
: GridDensityProvider(source), numFaces(numFaces)
|
||||
{
|
||||
initialize (proscenium);
|
||||
}
|
||||
|
||||
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numFaces)
|
||||
: GridDensityProvider(source), numFaces(numFaces)
|
||||
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform, unsigned numFaces)
|
||||
: GridDensityProvider(source), numFaces(numFaces)
|
||||
{
|
||||
real proscenium[4];
|
||||
calculateQuickProscenium(transform, bbox, proscenium);
|
||||
@@ -46,7 +51,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const
|
||||
}
|
||||
|
||||
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces)
|
||||
: GridDensityProvider(source), numFaces(numFaces)
|
||||
: GridDensityProvider(source), numFaces(numFaces)
|
||||
{
|
||||
real proscenium[4];
|
||||
calculateOptimalProscenium(source, proscenium);
|
||||
@@ -56,7 +61,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsig
|
||||
|
||||
Pow23GridDensityProvider::~Pow23GridDensityProvider () {}
|
||||
|
||||
void Pow23GridDensityProvider::initialize (const real proscenium[4])
|
||||
void Pow23GridDensityProvider::initialize(const real proscenium[4])
|
||||
{
|
||||
float prosceniumWidth = (proscenium[1] - proscenium[0]);
|
||||
float prosceniumHeight = (proscenium[3] - proscenium[2]);
|
||||
@@ -71,10 +76,10 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
|
||||
|
||||
// Make sure the grid exceeds the proscenium by a small amount
|
||||
float safetyZone = 0.1;
|
||||
if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
|
||||
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
|
||||
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
|
||||
}
|
||||
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
|
||||
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
|
||||
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
|
||||
}
|
||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||
@@ -85,18 +90,21 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
|
||||
}
|
||||
|
||||
Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFaces)
|
||||
: numFaces(numFaces)
|
||||
: numFaces(numFaces)
|
||||
{
|
||||
}
|
||||
|
||||
Pow23GridDensityProviderFactory::~Pow23GridDensityProviderFactory () {}
|
||||
|
||||
auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||
auto_ptr<GridDensityProvider>
|
||||
Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||
{
|
||||
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, proscenium, numFaces));
|
||||
}
|
||||
|
||||
auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
|
||||
auto_ptr<GridDensityProvider>
|
||||
Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform)
|
||||
{
|
||||
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
|
||||
}
|
||||
@@ -105,5 +113,3 @@ auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityPro
|
||||
{
|
||||
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,67 +1,75 @@
|
||||
//
|
||||
// Filename : Pow23GridDensityProvider.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2011-2-8
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
|
||||
#define __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef POW23GRIDDENSITYPROVIDER_H
|
||||
#define POW23GRIDDENSITYPROVIDER_H
|
||||
/** \file blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2011-2-8
|
||||
*/
|
||||
|
||||
#include "GridDensityProvider.h"
|
||||
|
||||
class Pow23GridDensityProvider : public GridDensityProvider {
|
||||
class Pow23GridDensityProvider : public GridDensityProvider
|
||||
{
|
||||
// Disallow copying and assignment
|
||||
Pow23GridDensityProvider (const Pow23GridDensityProvider& other);
|
||||
Pow23GridDensityProvider& operator= (const Pow23GridDensityProvider& other);
|
||||
Pow23GridDensityProvider(const Pow23GridDensityProvider& other);
|
||||
Pow23GridDensityProvider& operator=(const Pow23GridDensityProvider& other);
|
||||
|
||||
public:
|
||||
Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces);
|
||||
Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numFaces);
|
||||
Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform,
|
||||
unsigned numFaces);
|
||||
Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces);
|
||||
virtual ~Pow23GridDensityProvider ();
|
||||
virtual ~Pow23GridDensityProvider();
|
||||
|
||||
protected:
|
||||
unsigned numFaces;
|
||||
|
||||
private:
|
||||
void initialize (const real proscenium[4]);
|
||||
void initialize(const real proscenium[4]);
|
||||
};
|
||||
|
||||
class Pow23GridDensityProviderFactory : public GridDensityProviderFactory {
|
||||
class Pow23GridDensityProviderFactory : public GridDensityProviderFactory
|
||||
{
|
||||
public:
|
||||
Pow23GridDensityProviderFactory(unsigned numFaces);
|
||||
~Pow23GridDensityProviderFactory ();
|
||||
~Pow23GridDensityProviderFactory();
|
||||
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||
const GridHelpers::Transform& transform);
|
||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
||||
|
||||
protected:
|
||||
unsigned numFaces;
|
||||
};
|
||||
|
||||
#endif // POW23GRIDDENSITYPROVIDER_H
|
||||
|
||||
#endif // __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
|
||||
|
||||
@@ -1,55 +1,73 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/Silhouette.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Classes to define a silhouette structure
|
||||
* \author Stephane Grabli
|
||||
* \date 25/03/2002
|
||||
*/
|
||||
|
||||
#include "Silhouette.h"
|
||||
#include "ViewMap.h"
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* SVertex */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* SVertex */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
|
||||
Nature::VertexNature SVertex::getNature() const {
|
||||
Nature::VertexNature 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
|
||||
{
|
||||
@@ -104,7 +135,7 @@ const Polygon3r& SVertex::occludee() const
|
||||
return (_FEdges[0])->occludee();
|
||||
}
|
||||
|
||||
const SShape* SVertex::occluded_shape() const
|
||||
const SShape *SVertex::occluded_shape() const
|
||||
{
|
||||
if (getNature() & Nature::T_VERTEX)
|
||||
Exception::raiseException();
|
||||
@@ -125,65 +156,52 @@ real SVertex::z_discontinuity() const
|
||||
return (_FEdges[0])->z_discontinuity();
|
||||
}
|
||||
|
||||
FEdge* SVertex::fedge()
|
||||
FEdge *SVertex::fedge()
|
||||
{
|
||||
if (getNature() & Nature::T_VERTEX)
|
||||
return 0;
|
||||
return NULL;
|
||||
return _FEdges[0];
|
||||
}
|
||||
|
||||
FEdge* SVertex::getFEdge(Interface0D& inter)
|
||||
FEdge *SVertex::getFEdge(Interface0D& inter)
|
||||
{
|
||||
FEdge * result = 0;
|
||||
SVertex* iVertexB = dynamic_cast<SVertex*>(&inter);
|
||||
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)))
|
||||
vector<FEdge*>::const_iterator fe = _FEdges.begin(), feend = _FEdges.end();
|
||||
for (; fe != feend; ++fe) {
|
||||
if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB)) ||
|
||||
(((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB)))
|
||||
result = (*fe);
|
||||
}
|
||||
if((result == 0) && (getNature() & Nature::T_VERTEX))
|
||||
{
|
||||
if ((result == 0) && (getNature() & Nature::T_VERTEX)) {
|
||||
SVertex *brother;
|
||||
ViewVertex *vvertex = viewvertex();
|
||||
TVertex * tvertex = dynamic_cast<TVertex*>(vvertex);
|
||||
if(tvertex)
|
||||
{
|
||||
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
|
||||
if (tvertex) {
|
||||
brother = tvertex->frontSVertex();
|
||||
if(this == brother)
|
||||
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)
|
||||
{
|
||||
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
|
||||
if (tvertex) {
|
||||
brother = tvertex->frontSVertex();
|
||||
if(iVertexB == brother)
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -193,21 +211,31 @@ FEdge* SVertex::getFEdge(Interface0D& inter)
|
||||
}
|
||||
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* FEdge */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* FEdge */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
|
||||
|
||||
int FEdge::viewedge_nature() const {return _ViewEdge->getNature();}
|
||||
//float FEdge::viewedge_length() const {return _ViewEdge->viewedge_length();}
|
||||
const SShape* FEdge::occluded_shape() const
|
||||
int FEdge::viewedge_nature() const
|
||||
{
|
||||
ViewShape * aShape = _ViewEdge->aShape();
|
||||
if(aShape == 0)
|
||||
return _ViewEdge->getNature();
|
||||
}
|
||||
|
||||
#if 0
|
||||
float FEdge::viewedge_length() const
|
||||
{
|
||||
return _ViewEdge->viewedge_length();
|
||||
}
|
||||
#endif
|
||||
|
||||
const SShape *FEdge::occluded_shape() const
|
||||
{
|
||||
ViewShape *aShape = _ViewEdge->aShape();
|
||||
if (aShape == 0)
|
||||
return 0;
|
||||
return aShape->sshape();
|
||||
}
|
||||
@@ -222,30 +250,44 @@ 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
|
||||
|
||||
const SShape *FEdge::shape() const
|
||||
{
|
||||
return _VertexA->shape();
|
||||
}
|
||||
|
||||
real FEdge::z_discontinuity() const
|
||||
{
|
||||
if(!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER))
|
||||
{
|
||||
if (!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -253,118 +295,120 @@ 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 )
|
||||
Vec3r middle((_VertexB->point3d()-_VertexA->point3d()));
|
||||
|
||||
#if 0
|
||||
real result;
|
||||
z_discontinuity_functor<SVertex> _functor;
|
||||
Evaluate<SVertex, z_discontinuity_functor<SVertex> >(&_functor, iCombination, result);
|
||||
#endif
|
||||
Vec3r middle((_VertexB->point3d() - _VertexA->point3d()));
|
||||
middle /= 2;
|
||||
Vec3r disc_vec(middle - _occludeeIntersection);
|
||||
real res = disc_vec.norm() / bboxsize;
|
||||
return res;
|
||||
|
||||
//return fabs((middle.z()-_occludeeIntersection.z()));
|
||||
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;
|
||||
}
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* FEdgeSharp */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
float FEdge::local_depth_variance(int iCombination ) const
|
||||
{
|
||||
float result;
|
||||
|
||||
//Material FEdge::material() const
|
||||
//{
|
||||
// return _VertexA->shape()->material();
|
||||
//}
|
||||
const FrsMaterial& FEdgeSharp::aFrsMaterial() const {
|
||||
local_depth_variance_functor<SVertex> functor;
|
||||
|
||||
Evaluate(&functor, iCombination, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
real FEdge::local_average_density( float sigma, int iCombination) const
|
||||
{
|
||||
float result;
|
||||
|
||||
density_functor<SVertex> functor(sigma);
|
||||
|
||||
Evaluate(&functor, iCombination, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */)
|
||||
{
|
||||
Vec3r Na = _VertexA->normal(oException);
|
||||
if (oException != Exception::NO_EXCEPTION)
|
||||
return Na;
|
||||
Vec3r Nb = _VertexB->normal(oException);
|
||||
if (oException != Exception::NO_EXCEPTION)
|
||||
return Nb;
|
||||
return (Na + Nb) / 2.0;
|
||||
}
|
||||
|
||||
Vec3r FEdge::curvature2d_as_vector(int iCombination) const
|
||||
{
|
||||
Vec3r result;
|
||||
curvature2d_as_vector_functor<SVertex> _functor;
|
||||
Evaluate<Vec3r, curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
real FEdge::curvature2d_as_angle(int iCombination) const
|
||||
{
|
||||
real result;
|
||||
curvature2d_as_angle_functor<SVertex> _functor;
|
||||
Evaluate<real, curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* FEdgeSharp */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
|
||||
#if 0
|
||||
Material FEdge::material() const
|
||||
{
|
||||
return _VertexA->shape()->material();
|
||||
}
|
||||
#endif
|
||||
|
||||
const FrsMaterial& FEdgeSharp::aFrsMaterial() const
|
||||
{
|
||||
return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
|
||||
}
|
||||
|
||||
const FrsMaterial& FEdgeSharp::bFrsMaterial() const {
|
||||
const FrsMaterial& FEdgeSharp::bFrsMaterial() const
|
||||
{
|
||||
return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
|
||||
}
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* FEdgeSmooth */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* FEdgeSmooth */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
|
||||
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
@@ -1,94 +1,117 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to perform all geometric operations dedicated to silhouette. That, for example, implies that
|
||||
* this geom engine has as member data the viewpoint, transformations, projections...
|
||||
* \author Stephane Grabli
|
||||
* \date 03/09/2002
|
||||
*/
|
||||
|
||||
#include "Silhouette.h"
|
||||
#include "SilhouetteGeomEngine.h"
|
||||
|
||||
#include "../geometry/GeomUtils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0,0,0);
|
||||
real SilhouetteGeomEngine::_translation[3] = {0,0,0};
|
||||
real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {{1,0,0,0},
|
||||
{0,1,0,0},
|
||||
{0,0,1,0},
|
||||
{0,0,0,1}};
|
||||
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {{1,0,0,0},
|
||||
{0,1,0,0},
|
||||
{0,0,1,0},
|
||||
{0,0,0,1}};
|
||||
real SilhouetteGeomEngine::_transform[4][4] = {{1,0,0,0},
|
||||
{0,1,0,0},
|
||||
{0,0,1,0},
|
||||
{0,0,0,1}};
|
||||
int SilhouetteGeomEngine::_viewport[4] = {1,1,1,1}; // the viewport
|
||||
Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0, 0, 0);
|
||||
real SilhouetteGeomEngine::_translation[3] = {0, 0, 0};
|
||||
real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{0, 0, 0, 1}
|
||||
};
|
||||
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{0, 0, 0, 1}
|
||||
};
|
||||
real SilhouetteGeomEngine::_transform[4][4] = {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{0, 0, 0, 1}
|
||||
};
|
||||
int SilhouetteGeomEngine::_viewport[4] = {1, 1, 1, 1};
|
||||
real SilhouetteGeomEngine::_Focal = 0.0;
|
||||
|
||||
real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {{1,0,0,0},
|
||||
{0,1,0,0},
|
||||
{0,0,1,0},
|
||||
{0,0,0,1}};
|
||||
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {{1,0,0,0},
|
||||
{0,1,0,0},
|
||||
{0,0,1,0},
|
||||
{0,0,0,1}};
|
||||
real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{0, 0, 0, 1}
|
||||
};
|
||||
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{0, 0, 0, 1}
|
||||
};
|
||||
real SilhouetteGeomEngine::_znear = 0.0;
|
||||
real SilhouetteGeomEngine::_zfar = 100.0;
|
||||
bool SilhouetteGeomEngine::_isOrthographicProjection = false;
|
||||
|
||||
SilhouetteGeomEngine * SilhouetteGeomEngine::_pInstance = 0;
|
||||
SilhouetteGeomEngine *SilhouetteGeomEngine::_pInstance = NULL;
|
||||
|
||||
void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocal)
|
||||
void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
|
||||
const int iViewport[4], real iFocal)
|
||||
{
|
||||
unsigned int i,j;
|
||||
unsigned int i, j;
|
||||
_translation[0] = iModelViewMatrix[3][0];
|
||||
_translation[1] = iModelViewMatrix[3][1];
|
||||
_translation[2] = iModelViewMatrix[3][2];
|
||||
|
||||
for(i=0; i<4; i++){
|
||||
for(j=0; j<4; j++)
|
||||
{
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
_modelViewMatrix[i][j] = iModelViewMatrix[j][i];
|
||||
_glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<4; i++){
|
||||
for(j=0; j<4; j++)
|
||||
{
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
_projectionMatrix[i][j] = iProjectionMatrix[j][i];
|
||||
_glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<4; i++){
|
||||
for(j=0; j<4; j++)
|
||||
{
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
_transform[i][j] = 0;
|
||||
for(unsigned int k=0; k<4; k++)
|
||||
for (unsigned int k = 0; k < 4; k++)
|
||||
_transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<4; i++){
|
||||
for (i = 0; i < 4; i++) {
|
||||
_viewport[i] = iViewport[i];
|
||||
}
|
||||
_Focal = iFocal;
|
||||
@@ -102,62 +125,67 @@ void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
|
||||
_zfar = iZFar;
|
||||
}
|
||||
|
||||
void SilhouetteGeomEngine::retrieveViewport(int viewport[4]){
|
||||
memcpy(viewport, _viewport, 4*sizeof(int));
|
||||
void SilhouetteGeomEngine::retrieveViewport(int viewport[4])
|
||||
{
|
||||
memcpy(viewport, _viewport, 4 * sizeof(int));
|
||||
}
|
||||
//#define HUGE 1e9
|
||||
|
||||
//#define HUGE 1.0e9
|
||||
|
||||
void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices)
|
||||
{
|
||||
Vec3r newPoint;
|
||||
// real min=HUGE;
|
||||
// real max=-HUGE;
|
||||
#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
|
||||
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)
|
||||
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
|
||||
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
|
||||
ioVertex->setPoint2D(newPoint);
|
||||
}
|
||||
|
||||
real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
|
||||
{
|
||||
if( _isOrthographicProjection )
|
||||
if (_isOrthographicProjection)
|
||||
return t;
|
||||
|
||||
// we need to compute for each parameter t the corresponding
|
||||
// parameter T which gives the intersection in 3D.
|
||||
// we need to compute for each parameter t the corresponding parameter T which gives the intersection in 3D.
|
||||
real T;
|
||||
|
||||
// suffix w for world, c for camera, r for retina, i for image
|
||||
@@ -184,44 +212,48 @@ real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
|
||||
real m22 = _projectionMatrix[1][1];
|
||||
real m23 = _projectionMatrix[1][2];
|
||||
|
||||
if (fabs(ABc[0]) > 1e-6) {
|
||||
|
||||
if (fabs(ABc[0]) > 1.0e-6) {
|
||||
alpha = ABc[2] / ABc[0];
|
||||
beta = Ac[2] - alpha * Ac[0];
|
||||
denom = alpha * (Ir[0] + m13) + m11;
|
||||
if (fabs(denom) < 1e-6)
|
||||
if (fabs(denom) < 1.0e-6)
|
||||
goto iter;
|
||||
Ic[0] = -beta * (Ir[0] + m13) / denom;
|
||||
// Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
|
||||
// Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
|
||||
#if 0
|
||||
Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
|
||||
Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
|
||||
#endif
|
||||
T = (Ic[0] - Ac[0]) / ABc[0];
|
||||
|
||||
} else if (fabs(ABc[1]) > 1e-6) {
|
||||
|
||||
}
|
||||
else if (fabs(ABc[1]) > 1.0e-6) {
|
||||
alpha = ABc[2] / ABc[1];
|
||||
beta = Ac[2] - alpha * Ac[1];
|
||||
denom = alpha * (Ir[1] + m23) + m22;
|
||||
if (fabs(denom) < 1e-6)
|
||||
if (fabs(denom) < 1.0e-6)
|
||||
goto iter;
|
||||
Ic[1] = -beta * (Ir[1] + m23) / denom;
|
||||
// Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
|
||||
// Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
|
||||
#if 0
|
||||
Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
|
||||
Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
|
||||
#endif
|
||||
T = (Ic[1] - Ac[1]) / ABc[1];
|
||||
|
||||
} else {
|
||||
|
||||
iter: bool x_coords, less_than;
|
||||
if (fabs(Bi[0] - Ai[0]) > 1e-6) {
|
||||
}
|
||||
else {
|
||||
iter:
|
||||
bool x_coords, less_than;
|
||||
if (fabs(Bi[0] - Ai[0]) > 1.0e-6) {
|
||||
x_coords = true;
|
||||
less_than = Ai[0] < Bi[0];
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
x_coords = false;
|
||||
less_than = Ai[1] < Bi[1];
|
||||
}
|
||||
Vec3r Pc, Pr, Pi;
|
||||
real T_sta = 0.0;
|
||||
real T_end = 1.0;
|
||||
real delta_x, delta_y, dist, dist_threshold = 1e-6;
|
||||
real delta_x, delta_y, dist, dist_threshold = 1.0e-6;
|
||||
int i, max_iters = 100;
|
||||
for (i = 0; i < max_iters; i++) {
|
||||
T = T_sta + 0.5 * (T_end - T_sta);
|
||||
@@ -235,15 +267,30 @@ iter: bool x_coords, less_than;
|
||||
break;
|
||||
if (x_coords) {
|
||||
if (less_than) {
|
||||
if (Pi[0] < Ii[0]) { T_sta = T; } else { T_end = T; }
|
||||
} else {
|
||||
if (Pi[0] > Ii[0]) { T_sta = T; } else { T_end = T; }
|
||||
if (Pi[0] < Ii[0])
|
||||
T_sta = T;
|
||||
else
|
||||
T_end = T;
|
||||
}
|
||||
} else {
|
||||
else {
|
||||
if (Pi[0] > Ii[0])
|
||||
T_sta = T;
|
||||
else
|
||||
T_end = T;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (less_than) {
|
||||
if (Pi[1] < Ii[1]) { T_sta = T; } else { T_end = T; }
|
||||
} else {
|
||||
if (Pi[1] > Ii[1]) { T_sta = T; } else { T_end = T; }
|
||||
if (Pi[1] < Ii[1])
|
||||
T_sta = T;
|
||||
else
|
||||
T_end = T;
|
||||
}
|
||||
else {
|
||||
if (Pi[1] > Ii[1])
|
||||
T_sta = T;
|
||||
else
|
||||
T_end = T;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,15 +305,11 @@ iter: bool x_coords, less_than;
|
||||
}
|
||||
|
||||
Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r& M)
|
||||
|
||||
{
|
||||
|
||||
const real depth = _zfar - _znear;
|
||||
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
|
||||
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
|
||||
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
|
||||
return newPoint;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +1,46 @@
|
||||
//
|
||||
// Filename : SilhouetteGeomEngine.h
|
||||
// Author(s) : Stephane Grabli
|
||||
// Purpose : Class to perform all geometric operations dedicated
|
||||
// to silhouette. That, for example, implies that
|
||||
// this geom engine has as member data the viewpoint,
|
||||
// transformations, projections...
|
||||
// Date of creation : 03/09/2002
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
|
||||
#define __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to perform all geometric operations dedicated to silhouette. That, for example, implies that
|
||||
* this geom engine has as member data the viewpoint, transformations, projections...
|
||||
* \author Stephane Grabli
|
||||
* \date 03/09/2002
|
||||
*/
|
||||
|
||||
#ifndef SILHOUETTEGEOMENGINE_H
|
||||
# define SILHOUETTEGEOMENGINE_H
|
||||
#include <vector>
|
||||
|
||||
# include <vector>
|
||||
# include "../system/FreestyleConfig.h"
|
||||
# include "../geometry/Geom.h"
|
||||
#include "../geometry/Geom.h"
|
||||
|
||||
#include "../system/FreestyleConfig.h"
|
||||
|
||||
using namespace Geometry;
|
||||
|
||||
@@ -45,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
|
||||
|
||||
static bool _isOrthographicProjection;
|
||||
// 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)
|
||||
static SilhouetteGeomEngine *getInstance()
|
||||
{
|
||||
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,11 +102,11 @@ 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
|
||||
*/
|
||||
static void setFrustum(real iZNear, real iZFar) ;
|
||||
/*! Sets the current znear and zfar */
|
||||
static void setFrustum(real iZNear, real iZFar);
|
||||
|
||||
/* accessors */
|
||||
static void retrieveViewport(int viewport[4]);
|
||||
@@ -100,11 +114,10 @@ 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);
|
||||
static void ProjectSilhouette(SVertex *ioVertex);
|
||||
|
||||
/*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain
|
||||
* the parameter giving the corresponding 3D intersection.
|
||||
@@ -120,4 +133,4 @@ public:
|
||||
static Vec3r WorldToImage(const Vec3r& M);
|
||||
};
|
||||
|
||||
#endif // SILHOUETTEGEOMENGINE_H
|
||||
#endif // __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
|
||||
|
||||
@@ -1,37 +1,42 @@
|
||||
//
|
||||
// Filename : SphericalGrid.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2010-12-19
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/SphericalGrid.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2010-12-19
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "SphericalGrid.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Helper Classes
|
||||
@@ -42,11 +47,12 @@ using namespace std;
|
||||
// Cell
|
||||
/////////
|
||||
|
||||
SphericalGrid::Cell::Cell () {}
|
||||
SphericalGrid::Cell::Cell() {}
|
||||
|
||||
SphericalGrid::Cell::~Cell () {}
|
||||
SphericalGrid::Cell::~Cell() {}
|
||||
|
||||
void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
|
||||
void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
|
||||
{
|
||||
const real epsilon = 1.0e-06;
|
||||
boundary[0] = x - epsilon;
|
||||
boundary[1] = x + sizeX + epsilon;
|
||||
@@ -54,11 +60,14 @@ void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
|
||||
boundary[3] = y + sizeY + epsilon;
|
||||
}
|
||||
|
||||
bool SphericalGrid::Cell::compareOccludersByShallowestPoint (const SphericalGrid::OccluderData* a, const SphericalGrid::OccluderData* b) {
|
||||
bool SphericalGrid::Cell::compareOccludersByShallowestPoint(const SphericalGrid::OccluderData *a,
|
||||
const SphericalGrid::OccluderData *b)
|
||||
{
|
||||
return a->shallowest < b->shallowest;
|
||||
}
|
||||
|
||||
void SphericalGrid::Cell::indexPolygons() {
|
||||
void SphericalGrid::Cell::indexPolygons()
|
||||
{
|
||||
// Sort occluders by their shallowest points.
|
||||
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
|
||||
}
|
||||
@@ -66,13 +75,12 @@ void SphericalGrid::Cell::indexPolygons() {
|
||||
// Iterator
|
||||
//////////////////
|
||||
|
||||
SphericalGrid::Iterator::Iterator (SphericalGrid& grid, Vec3r& center, real epsilon)
|
||||
: _target(SphericalGrid::Transform::sphericalProjection(center)),
|
||||
_foundOccludee(false)
|
||||
SphericalGrid::Iterator::Iterator(SphericalGrid& grid, Vec3r& center, real epsilon)
|
||||
: _target(SphericalGrid::Transform::sphericalProjection(center)), _foundOccludee(false)
|
||||
{
|
||||
// Find target cell
|
||||
_cell = grid.findCell(_target);
|
||||
#if sphericalgridlogging == 1
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
cout << "Searching for occluders of edge centered at " << _target << " in cell ["
|
||||
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
|
||||
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
|
||||
@@ -82,14 +90,14 @@ SphericalGrid::Iterator::Iterator (SphericalGrid& grid, Vec3r& center, real epsi
|
||||
_current = _cell->faces.begin();
|
||||
}
|
||||
|
||||
SphericalGrid::Iterator::~Iterator () {}
|
||||
SphericalGrid::Iterator::~Iterator() {}
|
||||
|
||||
// SphericalGrid
|
||||
/////////////////
|
||||
|
||||
SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI)
|
||||
: _viewpoint(viewpoint),
|
||||
_enableQI(enableQI)
|
||||
SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
|
||||
Vec3r& viewpoint, bool enableQI)
|
||||
: _viewpoint(viewpoint), _enableQI(enableQI)
|
||||
{
|
||||
cout << "Generate Cell structure" << endl;
|
||||
// Generate Cell structure
|
||||
@@ -103,10 +111,10 @@ SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& densit
|
||||
cout << "Ready to use SphericalGrid" << endl;
|
||||
}
|
||||
|
||||
SphericalGrid::~SphericalGrid () {
|
||||
}
|
||||
SphericalGrid::~SphericalGrid() {}
|
||||
|
||||
void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap) {
|
||||
void SphericalGrid::assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap)
|
||||
{
|
||||
_cellSize = density.cellSize();
|
||||
_cellsX = density.cellsX();
|
||||
_cellsY = density.cellsY();
|
||||
@@ -115,20 +123,19 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
|
||||
|
||||
// Now allocate the cell table and fill it with default (empty) cells
|
||||
_cells.resize(_cellsX * _cellsY);
|
||||
for ( cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
|
||||
for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
|
||||
(*i) = NULL;
|
||||
}
|
||||
|
||||
// Identify cells that will be used, and set the dimensions for each
|
||||
ViewMap::fedges_container& fedges = viewMap->FEdges();
|
||||
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f ) {
|
||||
if ( (*f)->isInImage() ) {
|
||||
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
|
||||
if ((*f)->isInImage()) {
|
||||
Vec3r point = SphericalGrid::Transform::sphericalProjection((*f)->center3d());
|
||||
unsigned i, j;
|
||||
getCellCoordinates(point, i, j);
|
||||
if ( _cells[i * _cellsY + j] == NULL ) {
|
||||
if (_cells[i * _cellsY + j] == NULL) {
|
||||
// This is an uninitialized cell
|
||||
|
||||
real x, y, width, height;
|
||||
|
||||
x = _cellOrigin[0] + _cellSize * i;
|
||||
@@ -145,22 +152,23 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
|
||||
}
|
||||
}
|
||||
|
||||
void SphericalGrid::distributePolygons (OccluderSource& source) {
|
||||
void SphericalGrid::distributePolygons(OccluderSource& source)
|
||||
{
|
||||
unsigned long nFaces = 0;
|
||||
unsigned long nKeptFaces = 0;
|
||||
|
||||
for ( source.begin(); source.isValid(); source.next() ) {
|
||||
OccluderData* occluder = NULL;
|
||||
for (source.begin(); source.isValid(); source.next()) {
|
||||
OccluderData *occluder = NULL;
|
||||
|
||||
try {
|
||||
if ( insertOccluder(source, occluder) ) {
|
||||
if (insertOccluder(source, occluder)) {
|
||||
_faces.push_back(occluder);
|
||||
++nKeptFaces;
|
||||
}
|
||||
} catch (...) {
|
||||
// If an exception was thrown, _faces.push_back() cannot have succeeded.
|
||||
// occluder is not owned by anyone, and must be deleted.
|
||||
// If the exception was thrown before or during new OccluderData(), then
|
||||
}
|
||||
catch (...) {
|
||||
// If an exception was thrown, _faces.push_back() cannot have succeeded. Occluder is not owned by anyone,
|
||||
// and must be deleted. If the exception was thrown before or during new OccluderData(), then
|
||||
// occluder is NULL, and this delete is harmless.
|
||||
delete occluder;
|
||||
throw;
|
||||
@@ -170,46 +178,53 @@ void SphericalGrid::distributePolygons (OccluderSource& source) {
|
||||
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
|
||||
}
|
||||
|
||||
void SphericalGrid::reorganizeCells () {
|
||||
void SphericalGrid::reorganizeCells()
|
||||
{
|
||||
// Sort the occluders by shallowest point
|
||||
for ( vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
|
||||
if ( *i != NULL ) {
|
||||
for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
|
||||
if (*i != NULL) {
|
||||
(*i)->indexPolygons();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) {
|
||||
void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
|
||||
{
|
||||
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
|
||||
y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
|
||||
}
|
||||
|
||||
SphericalGrid::Cell* SphericalGrid::findCell(const Vec3r& point) {
|
||||
SphericalGrid::Cell *SphericalGrid::findCell(const Vec3r& point)
|
||||
{
|
||||
unsigned x, y;
|
||||
getCellCoordinates(point, x, y);
|
||||
return _cells[x * _cellsY + y];
|
||||
}
|
||||
|
||||
bool SphericalGrid::orthographicProjection () const {
|
||||
bool SphericalGrid::orthographicProjection() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const Vec3r& SphericalGrid::viewpoint() const {
|
||||
const Vec3r& SphericalGrid::viewpoint() const
|
||||
{
|
||||
return _viewpoint;
|
||||
}
|
||||
|
||||
bool SphericalGrid::enableQI() const {
|
||||
bool SphericalGrid::enableQI() const
|
||||
{
|
||||
return _enableQI;
|
||||
}
|
||||
|
||||
SphericalGrid::Transform::Transform () : GridHelpers::Transform() {
|
||||
}
|
||||
SphericalGrid::Transform::Transform () : GridHelpers::Transform() {}
|
||||
|
||||
Vec3r SphericalGrid::Transform::operator() (const Vec3r& point) const {
|
||||
Vec3r SphericalGrid::Transform::operator()(const Vec3r& point) const
|
||||
{
|
||||
return sphericalProjection(point);
|
||||
}
|
||||
|
||||
Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) {
|
||||
Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M)
|
||||
{
|
||||
Vec3r newPoint;
|
||||
|
||||
newPoint[0] = ::atan(M[0] / M[2]);
|
||||
@@ -218,4 +233,3 @@ Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) {
|
||||
|
||||
return newPoint;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,78 +1,86 @@
|
||||
//
|
||||
// Filename : SphericalGrid.h
|
||||
// Author(s) : Alexander Beels
|
||||
// Purpose : Class to define a cell grid surrounding
|
||||
// the projected image of a scene
|
||||
// Date of creation : 2010-12-19
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_SPHERICAL_GRID_H__
|
||||
#define __FREESTYLE_SPHERICAL_GRID_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/SphericalGrid.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||
* \author Alexander Beels
|
||||
* \date 2010-12-19
|
||||
*/
|
||||
|
||||
#ifndef SPHERICALGRID_H
|
||||
#define SPHERICALGRID_H
|
||||
#define SPHERICAL_GRID_LOGGING FALSE
|
||||
|
||||
#define sphericalgridlogging 0
|
||||
|
||||
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector>
|
||||
// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
|
||||
// so it should be a safe fall-back.
|
||||
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector> separately results in
|
||||
// redefinitions of identifiers. ViewMap.h already includes <vector> so it should be a safe fall-back.
|
||||
//#include <vector>
|
||||
//#include <deque>
|
||||
|
||||
#include "GridDensityProvider.h"
|
||||
#include "OccluderSource.h"
|
||||
#include "ViewMap.h"
|
||||
#include "../winged_edge/WEdge.h"
|
||||
|
||||
#include "../geometry/Polygon.h"
|
||||
#include "../system/PointerSequence.h"
|
||||
#include "../geometry/BBox.h"
|
||||
#include "../geometry/GridHelpers.h"
|
||||
#include "OccluderSource.h"
|
||||
#include "GridDensityProvider.h"
|
||||
|
||||
#include "../system/PointerSequence.h"
|
||||
|
||||
#include "../winged_edge/WEdge.h"
|
||||
|
||||
class SphericalGrid
|
||||
{
|
||||
public:
|
||||
// Helper classes
|
||||
struct OccluderData {
|
||||
struct OccluderData
|
||||
{
|
||||
explicit OccluderData (OccluderSource& source, Polygon3r& p);
|
||||
Polygon3r poly;
|
||||
Polygon3r cameraSpacePolygon;
|
||||
real shallowest, deepest;
|
||||
// N.B. We could, of course, store face in poly's userdata
|
||||
// member, like the old ViewMapBuilder code does. However,
|
||||
// code comments make it clear that userdata is deprecated,
|
||||
// so we avoid the temptation to save 4 or 8 bytes.
|
||||
WFace* face;
|
||||
// N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
|
||||
// However, code comments make it clear that userdata is deprecated, so we avoid the temptation to save
|
||||
// 4 or 8 bytes.
|
||||
WFace *face;
|
||||
};
|
||||
|
||||
private:
|
||||
struct Cell {
|
||||
struct Cell
|
||||
{
|
||||
// Can't store Cell in a vector without copy and assign
|
||||
//Cell(const Cell& other);
|
||||
//Cell& operator= (const Cell& other);
|
||||
//Cell& operator=(const Cell& other);
|
||||
|
||||
explicit Cell ();
|
||||
~Cell ();
|
||||
explicit Cell();
|
||||
~Cell();
|
||||
|
||||
static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b);
|
||||
static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
|
||||
|
||||
void setDimensions(real x, real y, real sizeX, real sizeY);
|
||||
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
|
||||
@@ -84,43 +92,37 @@ private:
|
||||
};
|
||||
|
||||
public:
|
||||
/*****
|
||||
/*! Iterator needs to allow the user to avoid full 3D comparison in two cases:
|
||||
*
|
||||
* (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
|
||||
*
|
||||
* (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
|
||||
*
|
||||
* In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an occludee
|
||||
* candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder could
|
||||
* possibly be a better occludee.
|
||||
*/
|
||||
|
||||
Iterator needs to allow the user to avoid full 3D comparison in
|
||||
two cases:
|
||||
|
||||
(1) Where (*current)->deepest < target[2], where the occluder is
|
||||
unambiguously in front of the target point.
|
||||
|
||||
(2) Where (*current)->shallowest > target[2], where the occluder
|
||||
is unambiguously in back of the target point.
|
||||
|
||||
In addition, when used by OptimizedFindOccludee, Iterator should
|
||||
stop iterating as soon as it has an occludee candidate and
|
||||
(*current)->shallowest > candidate[2], because at that point forward
|
||||
no new occluder could possibly be a better occludee.
|
||||
|
||||
*****/
|
||||
|
||||
class Iterator {
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
// epsilon is not used in this class, but other grids with the same interface may need an epsilon
|
||||
explicit Iterator (SphericalGrid& grid, Vec3r& center, real epsilon=1e-06);
|
||||
~Iterator ();
|
||||
void initBeforeTarget ();
|
||||
void initAfterTarget ();
|
||||
void nextOccluder ();
|
||||
void nextOccludee ();
|
||||
explicit Iterator(SphericalGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
|
||||
~Iterator();
|
||||
void initBeforeTarget();
|
||||
void initAfterTarget();
|
||||
void nextOccluder();
|
||||
void nextOccludee();
|
||||
bool validBeforeTarget();
|
||||
bool validAfterTarget();
|
||||
WFace* getWFace() const;
|
||||
Polygon3r* getCameraSpacePolygon();
|
||||
WFace *getWFace() const;
|
||||
Polygon3r *getCameraSpacePolygon();
|
||||
void reportDepth(Vec3r origin, Vec3r u, real t);
|
||||
private:
|
||||
bool testOccluder(bool wantOccludee);
|
||||
void markCurrentOccludeeCandidate(real depth);
|
||||
|
||||
Cell* _cell;
|
||||
Cell *_cell;
|
||||
Vec3r _target;
|
||||
bool _foundOccludee;
|
||||
real _occludeeDepth;
|
||||
@@ -128,33 +130,35 @@ public:
|
||||
vector<OccluderData*>::iterator _current, _occludeeCandidate;
|
||||
};
|
||||
|
||||
class Transform : public GridHelpers::Transform {
|
||||
class Transform : public GridHelpers::Transform
|
||||
{
|
||||
public:
|
||||
explicit Transform ();
|
||||
explicit Transform (Transform& other);
|
||||
Vec3r operator() (const Vec3r& point) const;
|
||||
explicit Transform();
|
||||
explicit Transform(Transform& other);
|
||||
Vec3r operator()(const Vec3r& point) const;
|
||||
static Vec3r sphericalProjection(const Vec3r& M);
|
||||
};
|
||||
|
||||
private:
|
||||
// Prevent implicit copies and assignments.
|
||||
SphericalGrid(const SphericalGrid& other);
|
||||
SphericalGrid& operator= (const SphericalGrid& other);
|
||||
SphericalGrid& operator=(const SphericalGrid& other);
|
||||
|
||||
public:
|
||||
explicit SphericalGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
|
||||
explicit SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
|
||||
Vec3r& viewpoint, bool enableQI);
|
||||
virtual ~SphericalGrid();
|
||||
|
||||
// Generate Cell structure
|
||||
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
|
||||
// Fill Cells
|
||||
void distributePolygons(OccluderSource& source);
|
||||
// Insert one polygon into each matching cell,
|
||||
// return true if any cell consumes the polygon
|
||||
// Insert one polygon into each matching cell, return true if any cell consumes the polygon
|
||||
bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
|
||||
// Sort occluders in each cell
|
||||
void reorganizeCells();
|
||||
|
||||
Cell* findCell(const Vec3r& point);
|
||||
Cell *findCell(const Vec3r& point);
|
||||
|
||||
// Accessors:
|
||||
bool orthographicProjection() const;
|
||||
@@ -176,51 +180,52 @@ private:
|
||||
bool _enableQI;
|
||||
};
|
||||
|
||||
inline void SphericalGrid::Iterator::initBeforeTarget () {
|
||||
inline void SphericalGrid::Iterator::initBeforeTarget()
|
||||
{
|
||||
_current = _cell->faces.begin();
|
||||
while ( _current != _cell->faces.end() && ! testOccluder(false) ) {
|
||||
while (_current != _cell->faces.end() && !testOccluder(false)) {
|
||||
++_current;
|
||||
}
|
||||
}
|
||||
|
||||
inline void SphericalGrid::Iterator::initAfterTarget () {
|
||||
if ( _foundOccludee ) {
|
||||
#if sphericalgridlogging == 1
|
||||
inline void SphericalGrid::Iterator::initAfterTarget()
|
||||
{
|
||||
if (_foundOccludee) {
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
|
||||
#endif
|
||||
_current = _occludeeCandidate;
|
||||
return;
|
||||
}
|
||||
|
||||
#if sphericalgridlogging == 1
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << "\tStarting occludee search from current position" << std::endl;
|
||||
#endif
|
||||
|
||||
while ( _current != _cell->faces.end() && ! testOccluder(true) ) {
|
||||
while (_current != _cell->faces.end() && !testOccluder(true)) {
|
||||
++_current;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
|
||||
inline bool SphericalGrid::Iterator::testOccluder(bool wantOccludee)
|
||||
{
|
||||
// End-of-list is not even a valid iterator position
|
||||
if ( _current == _cell->faces.end() ) {
|
||||
// Returning true seems strange, but it will break us out of whatever loop
|
||||
// is calling testOccluder, and _current=_cell->face.end() will make
|
||||
// the calling routine give up.
|
||||
if (_current == _cell->faces.end()) {
|
||||
// Returning true seems strange, but it will break us out of whatever loop is calling testOccluder, and
|
||||
// _current=_cell->face.end() will make the calling routine give up.
|
||||
return true;
|
||||
}
|
||||
#if sphericalgridlogging == 1
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
|
||||
for ( unsigned i = 1; i < (*_current)->poly.getVertices().size(); ++i ) {
|
||||
for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
|
||||
std::cout << ", " << (*_current)->poly.getVertices()[i];
|
||||
}
|
||||
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
// If we have an occluder candidate and we are unambiguously after it, abort
|
||||
if ( _foundOccludee && (*_current)->shallowest > _occludeeDepth ) {
|
||||
#if sphericalgridlogging == 1
|
||||
if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
|
||||
#endif
|
||||
_current = _cell->faces.end();
|
||||
@@ -230,16 +235,17 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
|
||||
}
|
||||
|
||||
// Specific continue or stop conditions when searching for each type
|
||||
if ( wantOccludee ) {
|
||||
if ( (*_current)->deepest < _target[2] ) {
|
||||
#if sphericalgridlogging == 1
|
||||
if (wantOccludee) {
|
||||
if ((*_current)->deepest < _target[2]) {
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ( (*_current)->shallowest > _target[2] ) {
|
||||
#if sphericalgridlogging == 1
|
||||
}
|
||||
else {
|
||||
if ((*_current)->shallowest > _target[2]) {
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
@@ -251,70 +257,73 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
|
||||
// Check to see if target is in the 2D bounding box
|
||||
Vec3r bbMin, bbMax;
|
||||
(*_current)->poly.getBBox(bbMin, bbMax);
|
||||
if ( _target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1] ) {
|
||||
#if sphericalgridlogging == 1
|
||||
if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// We've done all the corner cutting we can.
|
||||
// Let the caller work out whether or not
|
||||
// the geometry is correct.
|
||||
// We've done all the corner cutting we can. Let the caller work out whether or not the geometry is correct.
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void SphericalGrid::Iterator::reportDepth (Vec3r origin, Vec3r u, real t) {
|
||||
// The reported depth is the length of a ray in camera space
|
||||
// We need to convert it into the distance from viewpoint
|
||||
// If origin is the viewpoint, depth == t
|
||||
// A future optimization could allow the caller to tell us if origin is viewponit or target,
|
||||
// at the cost of changing the OptimizedGrid API.
|
||||
inline void SphericalGrid::Iterator::reportDepth(Vec3r origin, Vec3r u, real t)
|
||||
{
|
||||
// The reported depth is the length of a ray in camera space. We need to convert it into the distance from viewpoint
|
||||
// If origin is the viewpoint, depth == t. A future optimization could allow the caller to tell us if origin is
|
||||
// viewponit or target, at the cost of changing the OptimizedGrid API.
|
||||
real depth = (origin + u * t).norm();
|
||||
#if sphericalgridlogging == 1
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
|
||||
#endif
|
||||
if ( depth > _target[2] ) {
|
||||
#if sphericalgridlogging == 1
|
||||
if (depth > _target[2]) {
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << " is deeper than target" << std::endl;
|
||||
#endif
|
||||
// If the current occluder is the best occludee so far, save it.
|
||||
if ( ! _foundOccludee || _occludeeDepth > depth ) {
|
||||
if (! _foundOccludee || _occludeeDepth > depth) {
|
||||
markCurrentOccludeeCandidate(depth);
|
||||
}
|
||||
} else {
|
||||
#if sphericalgridlogging == 1
|
||||
}
|
||||
else {
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
inline void SphericalGrid::Iterator::nextOccluder () {
|
||||
if ( _current != _cell->faces.end() ) {
|
||||
inline void SphericalGrid::Iterator::nextOccluder()
|
||||
{
|
||||
if (_current != _cell->faces.end()) {
|
||||
do {
|
||||
++_current;
|
||||
} while ( _current != _cell->faces.end() && ! testOccluder(false) );
|
||||
} while (_current != _cell->faces.end() && !testOccluder(false));
|
||||
}
|
||||
}
|
||||
|
||||
inline void SphericalGrid::Iterator::nextOccludee () {
|
||||
if ( _current != _cell->faces.end() ) {
|
||||
inline void SphericalGrid::Iterator::nextOccludee()
|
||||
{
|
||||
if (_current != _cell->faces.end()) {
|
||||
do {
|
||||
++_current;
|
||||
} while ( _current != _cell->faces.end() && ! testOccluder(true) );
|
||||
} while (_current != _cell->faces.end() && !testOccluder(true));
|
||||
}
|
||||
}
|
||||
|
||||
inline bool SphericalGrid::Iterator::validBeforeTarget () {
|
||||
inline bool SphericalGrid::Iterator::validBeforeTarget()
|
||||
{
|
||||
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
|
||||
}
|
||||
|
||||
inline bool SphericalGrid::Iterator::validAfterTarget () {
|
||||
inline bool SphericalGrid::Iterator::validAfterTarget()
|
||||
{
|
||||
return _current != _cell->faces.end();
|
||||
}
|
||||
|
||||
inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
|
||||
#if sphericalgridlogging == 1
|
||||
inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth)
|
||||
{
|
||||
#if SPHERICAL_GRID_LOGGING
|
||||
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
|
||||
#endif
|
||||
_occludeeCandidate = _current;
|
||||
@@ -322,18 +331,18 @@ inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
|
||||
_foundOccludee = true;
|
||||
}
|
||||
|
||||
inline WFace* SphericalGrid::Iterator::getWFace() const {
|
||||
inline WFace *SphericalGrid::Iterator::getWFace() const
|
||||
{
|
||||
return (*_current)->face;
|
||||
}
|
||||
|
||||
inline Polygon3r* SphericalGrid::Iterator::getCameraSpacePolygon() {
|
||||
inline Polygon3r *SphericalGrid::Iterator::getCameraSpacePolygon()
|
||||
{
|
||||
return &((*_current)->cameraSpacePolygon);
|
||||
}
|
||||
|
||||
inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
|
||||
: poly(p),
|
||||
cameraSpacePolygon(source.getCameraSpacePolygon()),
|
||||
face(source.getWFace())
|
||||
: poly(p), cameraSpacePolygon(source.getCameraSpacePolygon()), face(source.getWFace())
|
||||
{
|
||||
const Vec3r viewpoint(0, 0, 0);
|
||||
// Get the point on the camera-space polygon that is closest to the viewpoint
|
||||
@@ -343,17 +352,18 @@ inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygo
|
||||
// Get the point on the camera-space polygon that is furthest from the viewpoint
|
||||
// deepest is the distance from the viewpoint to that point
|
||||
deepest = cameraSpacePolygon.getVertices()[2].norm();
|
||||
for ( unsigned i = 0; i < 2; ++i ) {
|
||||
for (unsigned int i = 0; i < 2; ++i) {
|
||||
real t = cameraSpacePolygon.getVertices()[i].norm();
|
||||
if ( t > deepest ) {
|
||||
if (t > deepest) {
|
||||
deepest = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
|
||||
if ( GridHelpers::insideProscenium (boundary, poly) ) {
|
||||
if ( occluder == NULL) {
|
||||
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
|
||||
{
|
||||
if (GridHelpers::insideProscenium (boundary, poly)) {
|
||||
if (occluder == NULL) {
|
||||
// Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
|
||||
// or automatically by SphericalGrid::_faces;
|
||||
occluder = new OccluderData(source, poly);
|
||||
@@ -362,7 +372,8 @@ inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3
|
||||
}
|
||||
}
|
||||
|
||||
inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) {
|
||||
inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
|
||||
{
|
||||
Polygon3r& poly(source.getGridSpacePolygon());
|
||||
occluder = NULL;
|
||||
|
||||
@@ -373,9 +384,9 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
|
||||
getCellCoordinates(bbMin, startX, startY);
|
||||
getCellCoordinates(bbMax, endX, endY);
|
||||
|
||||
for ( unsigned i = startX; i <= endX; ++i ) {
|
||||
for ( unsigned j = startY; j <= endY; ++j ) {
|
||||
if ( _cells[i * _cellsY + j] != NULL ) {
|
||||
for (unsigned int i = startX; i <= endX; ++i) {
|
||||
for (unsigned int j = startY; j <= endY; ++j) {
|
||||
if (_cells[i * _cellsY + j] != NULL) {
|
||||
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
|
||||
}
|
||||
}
|
||||
@@ -384,5 +395,4 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
|
||||
return occluder != NULL;
|
||||
}
|
||||
|
||||
#endif // SPHERICALGRID_H
|
||||
|
||||
#endif // __FREESTYLE_SPHERICAL_GRID_H__
|
||||
|
||||
@@ -1,143 +1,168 @@
|
||||
//
|
||||
// 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(){
|
||||
_imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM
|
||||
memset((_imagesPyramids),0,(_nbOrientations+1)*sizeof(ImagePyramid*));
|
||||
void SteerableViewMap::Build()
|
||||
{
|
||||
_imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
|
||||
memset((_imagesPyramids), 0, (_nbOrientations + 1) * sizeof(ImagePyramid *));
|
||||
}
|
||||
|
||||
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){
|
||||
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother)
|
||||
{
|
||||
_nbOrientations = iBrother._nbOrientations;
|
||||
unsigned i;
|
||||
unsigned int i;
|
||||
_bound = iBrother._bound;
|
||||
_directions = iBrother._directions;
|
||||
_mapping = iBrother._mapping;
|
||||
_imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM
|
||||
for(i=0;i<_nbOrientations+1;++i)
|
||||
_imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
|
||||
for (i = 0; i < _nbOrientations + 1; ++i)
|
||||
_imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
|
||||
}
|
||||
|
||||
SteerableViewMap::~SteerableViewMap(){
|
||||
SteerableViewMap::~SteerableViewMap()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void SteerableViewMap::Clear(){
|
||||
unsigned i;
|
||||
if(_imagesPyramids){
|
||||
for(i=0; i<=_nbOrientations; ++i){
|
||||
if(_imagesPyramids[i])
|
||||
void SteerableViewMap::Clear()
|
||||
{
|
||||
unsigned int i;
|
||||
if (_imagesPyramids) {
|
||||
for (i = 0; i <= _nbOrientations; ++i) {
|
||||
if (_imagesPyramids[i])
|
||||
delete (_imagesPyramids)[i];
|
||||
}
|
||||
delete [] _imagesPyramids;
|
||||
delete[] _imagesPyramids;
|
||||
_imagesPyramids = 0;
|
||||
}
|
||||
if(!_mapping.empty()){
|
||||
for(map<unsigned int, double*>::iterator m=_mapping.begin(), mend=_mapping.end();
|
||||
m!=mend;
|
||||
++m){
|
||||
delete [] (*m).second;
|
||||
if (!_mapping.empty()) {
|
||||
for (map<unsigned int, double*>::iterator m = _mapping.begin(), mend = _mapping.end(); m != mend; ++m) {
|
||||
delete[] (*m).second;
|
||||
}
|
||||
_mapping.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void SteerableViewMap::Reset(){
|
||||
void SteerableViewMap::Reset()
|
||||
{
|
||||
Clear();
|
||||
Build();
|
||||
}
|
||||
|
||||
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i){
|
||||
double dotp = fabs(dir*_directions[i]);
|
||||
if(dotp < _bound)
|
||||
return 0;
|
||||
if(dotp>1)
|
||||
dotp = 1;
|
||||
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i)
|
||||
{
|
||||
double dotp = fabs(dir * _directions[i]);
|
||||
if (dotp < _bound)
|
||||
return 0.0;
|
||||
if (dotp > 1.0)
|
||||
dotp = 1.0;
|
||||
|
||||
return cos((float)_nbOrientations/2.0*acos(dotp));
|
||||
return cos((float)_nbOrientations / 2.0 * acos(dotp));
|
||||
}
|
||||
|
||||
double * SteerableViewMap::AddFEdge(FEdge *iFEdge){
|
||||
double *SteerableViewMap::AddFEdge(FEdge *iFEdge)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned id = iFEdge->getId().getFirst();
|
||||
map<unsigned int, double* >::iterator o = _mapping.find(id);
|
||||
if(o!=_mapping.end()){
|
||||
if (o != _mapping.end()) {
|
||||
return (*o).second;
|
||||
}
|
||||
double * res = new double[_nbOrientations];
|
||||
for(i=0; i<_nbOrientations; ++i){
|
||||
res[i] = 0;
|
||||
double *res = new double[_nbOrientations];
|
||||
for (i = 0; i < _nbOrientations; ++i) {
|
||||
res[i] = 0.0;
|
||||
}
|
||||
Vec3r o2d3 = iFEdge->orientation2d();
|
||||
Vec2r o2d2(o2d3.x(), o2d3.y());
|
||||
real norm = o2d2.norm();
|
||||
if(norm < 1e-6){
|
||||
if (norm < 1.0e-6) {
|
||||
return res;
|
||||
}
|
||||
o2d2/=norm;
|
||||
o2d2 /= norm;
|
||||
|
||||
for(i=0; i<_nbOrientations; ++i){
|
||||
for (i = 0; i < _nbOrientations; ++i) {
|
||||
res[i] = ComputeWeight(o2d2, i);
|
||||
}
|
||||
_mapping[id] = res;
|
||||
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){
|
||||
return _nbOrientations+1;
|
||||
if (norm < 1.0e-6) {
|
||||
return _nbOrientations + 1;
|
||||
}
|
||||
dir/=norm;
|
||||
double maxw = 0.f;
|
||||
unsigned winner = _nbOrientations+1;
|
||||
for(unsigned i=0; i<_nbOrientations; ++i){
|
||||
dir /= norm;
|
||||
double maxw = 0.0f;
|
||||
unsigned winner = _nbOrientations + 1;
|
||||
for (unsigned int i = 0; i < _nbOrientations; ++i) {
|
||||
double w = ComputeWeight(dir, i);
|
||||
if(w>maxw){
|
||||
if (w > maxw) {
|
||||
maxw = w;
|
||||
winner = i;
|
||||
}
|
||||
@@ -145,31 +170,32 @@ 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;
|
||||
unsigned winner = _nbOrientations+1;
|
||||
for(unsigned i=0; i<_nbOrientations; ++i){
|
||||
if (o != _mapping.end()) {
|
||||
double *wvalues = (*o).second;
|
||||
double maxw = 0.0;
|
||||
unsigned winner = _nbOrientations + 1;
|
||||
for (unsigned i = 0; i < _nbOrientations; ++i) {
|
||||
double w = wvalues[i];
|
||||
if(w>maxw){
|
||||
if (w > maxw) {
|
||||
maxw = w;
|
||||
winner = i;
|
||||
}
|
||||
}
|
||||
return winner;
|
||||
}
|
||||
return _nbOrientations+1;
|
||||
return _nbOrientations + 1;
|
||||
}
|
||||
|
||||
void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma){
|
||||
for(unsigned i=0; i<=_nbOrientations; ++i){
|
||||
ImagePyramid * svm = (_imagesPyramids)[i];
|
||||
if(svm)
|
||||
void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma)
|
||||
{
|
||||
for (unsigned int i = 0; i <= _nbOrientations; ++i) {
|
||||
ImagePyramid *svm = (_imagesPyramids)[i];
|
||||
if (svm)
|
||||
delete svm;
|
||||
if(copy)
|
||||
if (copy)
|
||||
svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma);
|
||||
else
|
||||
svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma);
|
||||
@@ -177,37 +203,42 @@ 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){
|
||||
if (pyramid == 0) {
|
||||
cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
|
||||
return 0;
|
||||
}
|
||||
if((x<0) || (x>=pyramid->width()) || (y<0) || (y>=pyramid->height()))
|
||||
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){
|
||||
return readSteerableViewMapPixel(_nbOrientations,iLevel,x,y);
|
||||
float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y)
|
||||
{
|
||||
return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y);
|
||||
}
|
||||
|
||||
unsigned int SteerableViewMap::getNumberOfPyramidLevels() const{
|
||||
if(_imagesPyramids[0])
|
||||
unsigned int SteerableViewMap::getNumberOfPyramidLevels() const
|
||||
{
|
||||
if (_imagesPyramids[0])
|
||||
return _imagesPyramids[0]->getNumberOfLevels();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SteerableViewMap::saveSteerableViewMap() const {
|
||||
for(unsigned i=0; i<=_nbOrientations; ++i){
|
||||
if(_imagesPyramids[i] == 0){
|
||||
cerr << "SteerableViewMap warning: orientation " << i <<" of steerable View Map whas not been computed yet" << endl;
|
||||
void SteerableViewMap::saveSteerableViewMap() const
|
||||
{
|
||||
for (unsigned int i = 0; i <= _nbOrientations; ++i) {
|
||||
if (_imagesPyramids[i] == 0) {
|
||||
cerr << "SteerableViewMap warning: orientation " << i
|
||||
<< " of steerable View Map whas not been computed yet" << endl;
|
||||
continue;
|
||||
}
|
||||
int ow = _imagesPyramids[i]->width(0);
|
||||
@@ -217,22 +248,22 @@ void SteerableViewMap::saveSteerableViewMap() const {
|
||||
string base("SteerableViewMap");
|
||||
stringstream filename;
|
||||
|
||||
for(int j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ //soc
|
||||
float coeff = 1;//1/255.f; //100*255;//*pow(2,j);
|
||||
for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc
|
||||
float coeff = 1.0f; // 1 / 255.0f; // 100 * 255; // * pow(2, j);
|
||||
//soc QImage qtmp(ow, oh, QImage::Format_RGB32);
|
||||
ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
|
||||
int rowbytes = ow*4;
|
||||
int rowbytes = ow * 4;
|
||||
char *pix;
|
||||
|
||||
for(int y=0;y<oh;++y){ //soc
|
||||
for(int x=0;x<ow;++x){ //soc
|
||||
int c = (int)(coeff*_imagesPyramids[i]->pixel(x,y,j));
|
||||
if(c>255)
|
||||
c=255;
|
||||
//int c = (int)(_imagesPyramids[i]->pixel(x,y,j));
|
||||
for (int y = 0; y < oh; ++y) { //soc
|
||||
for (int x = 0; x < ow; ++x) { //soc
|
||||
int c = (int)(coeff * _imagesPyramids[i]->pixel(x, y, j));
|
||||
if (c > 255)
|
||||
c = 255;
|
||||
//int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
|
||||
|
||||
//soc qtmp.setPixel(x,y,qRgb(c,c,c));
|
||||
pix = (char*)ibuf->rect + y*rowbytes + x*4;
|
||||
//soc qtmp.setPixel(x, y, qRgb(c, c, c));
|
||||
pix = (char*)ibuf->rect + y * rowbytes + x * 4;
|
||||
pix[0] = pix [1] = pix[2] = c;
|
||||
}
|
||||
}
|
||||
@@ -240,28 +271,28 @@ void SteerableViewMap::saveSteerableViewMap() const {
|
||||
//soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
|
||||
filename << base;
|
||||
filename << i << "-" << j << ".png";
|
||||
ibuf->ftype= 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
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,19 +122,15 @@ 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)
|
||||
* Equivalent to : readSteerableViewMapPixel(nbOrientations, x, y)
|
||||
*/
|
||||
float readCompleteViewMapPixel(int iLevel, int x, int y);
|
||||
|
||||
@@ -136,18 +138,17 @@ public:
|
||||
unsigned int getNumberOfPyramidLevels() const;
|
||||
|
||||
/*! Returns the number of orientations */
|
||||
unsigned int getNumberOfOrientations() const{
|
||||
unsigned int getNumberOfOrientations() const
|
||||
{
|
||||
return _nbOrientations;
|
||||
}
|
||||
|
||||
/*! for debug purposes */
|
||||
void saveSteerableViewMap() const ;
|
||||
void saveSteerableViewMap() const;
|
||||
|
||||
protected:
|
||||
void Clear();
|
||||
void Build();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // STEERABLEVIEWMAP_H
|
||||
#endif // __FREESTYLE_STEERABLE_VIEW_MAP_H__
|
||||
|
||||
@@ -1,81 +1,92 @@
|
||||
//
|
||||
// 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){
|
||||
if(0 == oVShape)
|
||||
void ViewEdgeXBuilder::Init(ViewShape *oVShape)
|
||||
{
|
||||
if (0 == oVShape)
|
||||
return;
|
||||
|
||||
// for design conveniance, we store the current SShape.
|
||||
_pCurrentSShape = oVShape->sshape();
|
||||
if(0 == _pCurrentSShape)
|
||||
if (0 == _pCurrentSShape)
|
||||
return;
|
||||
|
||||
_pCurrentVShape = oVShape;
|
||||
|
||||
// Reset previous data
|
||||
//--------------------
|
||||
if(!_SVertexMap.empty())
|
||||
if (!_SVertexMap.empty())
|
||||
_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 ;
|
||||
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 ?
|
||||
if (false == ((wxf))->hasSmoothEdges()) // does it contain at least one smooth edge ?
|
||||
continue;
|
||||
// parse all smooth layers:
|
||||
vector<WXFaceLayer*>& smoothLayers = wxf->getSmoothLayers();
|
||||
for(vector<WXFaceLayer*>::iterator sl = smoothLayers.begin(), slend=smoothLayers.end();
|
||||
sl!=slend;
|
||||
++sl){
|
||||
if(!(*sl)->hasSmoothEdge())
|
||||
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 ?
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -86,22 +97,19 @@ void ViewEdgeXBuilder::BuildViewEdges( WXShape *iWShape, ViewShape *oVShape,
|
||||
//----------------------------------------
|
||||
//iWShape->ResetUserData();
|
||||
|
||||
WXEdge * wxe;
|
||||
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())
|
||||
if (Nature::NO_FEATURE == wxe->nature())
|
||||
continue;
|
||||
|
||||
if(!stopSharpViewEdge(wxe)){
|
||||
bool b=true;
|
||||
if(wxe->order() == -1)
|
||||
if (!stopSharpViewEdge(wxe)) {
|
||||
bool b = true;
|
||||
if (wxe->order() == -1)
|
||||
b = false;
|
||||
BuildSharpViewEdge(OWXEdge(wxe,b));
|
||||
BuildSharpViewEdge(OWXEdge(wxe, b));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -133,51 +141,48 @@ ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
|
||||
// first direction
|
||||
list<OWXFaceLayer> facesChain;
|
||||
unsigned size = 0;
|
||||
while(!stopSmoothViewEdge(currentFace.fl)){
|
||||
while (!stopSmoothViewEdge(currentFace.fl)) {
|
||||
facesChain.push_back(currentFace);
|
||||
++size;
|
||||
currentFace.fl->userdata = (void*)1; // processed
|
||||
currentFace.fl->userdata = (void *)1; // processed
|
||||
// Find the next edge!
|
||||
currentFace = FindNextFaceLayer(currentFace);
|
||||
}
|
||||
OWXFaceLayer end = facesChain.back();
|
||||
// second direction
|
||||
currentFace = FindPreviousFaceLayer(first);
|
||||
while(!stopSmoothViewEdge(currentFace.fl)){
|
||||
while (!stopSmoothViewEdge(currentFace.fl)) {
|
||||
facesChain.push_front(currentFace);
|
||||
++size;
|
||||
currentFace.fl->userdata = (void*)1; // processed
|
||||
currentFace.fl->userdata = (void *)1; // processed
|
||||
// Find the previous edge!
|
||||
currentFace = FindPreviousFaceLayer(currentFace);
|
||||
}
|
||||
first = facesChain.front();
|
||||
|
||||
if(iFaceLayer.fl->nature() & Nature::RIDGE){
|
||||
if(size<4){
|
||||
if (iFaceLayer.fl->nature() & Nature::RIDGE) {
|
||||
if (size < 4) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Start a new chain edges
|
||||
ViewEdge * newVEdge = new ViewEdge;
|
||||
ViewEdge *newVEdge = new ViewEdge;
|
||||
newVEdge->setId(_currentViewId);
|
||||
++_currentViewId;
|
||||
|
||||
_pCurrentVShape->AddEdge(newVEdge);
|
||||
|
||||
|
||||
// build FEdges
|
||||
FEdge * feprevious = 0;
|
||||
FEdge * fefirst = 0;
|
||||
FEdge * fe = 0;
|
||||
for(list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend=facesChain.end();
|
||||
fl!=flend;
|
||||
++fl){
|
||||
FEdge *feprevious = NULL;
|
||||
FEdge *fefirst = NULL;
|
||||
FEdge *fe = NULL;
|
||||
for (list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend = facesChain.end(); fl != flend; ++fl) {
|
||||
fe = BuildSmoothFEdge(feprevious, (*fl));
|
||||
if (feprevious && fe == feprevious)
|
||||
continue;
|
||||
fe->setViewEdge(newVEdge);
|
||||
if(!fefirst)
|
||||
if (!fefirst)
|
||||
fefirst = fe;
|
||||
feprevious = fe;
|
||||
}
|
||||
@@ -188,12 +193,13 @@ ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
|
||||
newVEdge->setFEdgeB(fe);
|
||||
|
||||
// is it a closed loop ?
|
||||
if((first == end) && (size != 1)){
|
||||
if ((first == end) && (size != 1)) {
|
||||
fefirst->setPreviousEdge(fe);
|
||||
fe->setNextEdge(fefirst);
|
||||
newVEdge->setA(0);
|
||||
newVEdge->setB(0);
|
||||
}else{
|
||||
}
|
||||
else {
|
||||
ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
|
||||
ViewVertex *vvb = MakeViewVertex(fe->vertexB());
|
||||
|
||||
@@ -207,12 +213,13 @@ 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;
|
||||
ViewEdge *newVEdge = new ViewEdge;
|
||||
newVEdge->setId(_currentViewId);
|
||||
++_currentViewId;
|
||||
unsigned size=0;
|
||||
unsigned size = 0;
|
||||
|
||||
_pCurrentVShape->AddEdge(newVEdge);
|
||||
|
||||
@@ -224,41 +231,39 @@ ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
|
||||
#if 0 /* TK 02-Sep-2012 Experimental fix for incorrect view edge visibility. */
|
||||
// bidirectional chaining
|
||||
// first direction:
|
||||
while(!stopSharpViewEdge(currentWEdge.e)){
|
||||
while (!stopSharpViewEdge(currentWEdge.e)) {
|
||||
edgesChain.push_back(currentWEdge);
|
||||
++size;
|
||||
currentWEdge.e->userdata = (void*)1; // processed
|
||||
currentWEdge.e->userdata = (void *)1; // processed
|
||||
// Find the next edge!
|
||||
currentWEdge = FindNextWEdge(currentWEdge);
|
||||
}
|
||||
OWXEdge endWEdge = edgesChain.back();
|
||||
// second direction
|
||||
currentWEdge = FindPreviousWEdge(firstWEdge);
|
||||
while(!stopSharpViewEdge(currentWEdge.e)){
|
||||
while (!stopSharpViewEdge(currentWEdge.e)) {
|
||||
edgesChain.push_front(currentWEdge);
|
||||
++size;
|
||||
currentWEdge.e->userdata = (void*)1; // processed
|
||||
currentWEdge.e->userdata = (void *)1; // processed
|
||||
// Find the previous edge!
|
||||
currentWEdge = FindPreviousWEdge(currentWEdge);
|
||||
}
|
||||
#else
|
||||
edgesChain.push_back(currentWEdge);
|
||||
++size;
|
||||
currentWEdge.e->userdata = (void*)1; // processed
|
||||
currentWEdge.e->userdata = (void *)1; // processed
|
||||
OWXEdge endWEdge = edgesChain.back();
|
||||
#endif
|
||||
firstWEdge = edgesChain.front();
|
||||
|
||||
// build FEdges
|
||||
FEdge * feprevious = 0;
|
||||
FEdge * fefirst = 0;
|
||||
FEdge * fe = 0;
|
||||
for(list<OWXEdge>::iterator we = edgesChain.begin(), weend=edgesChain.end();
|
||||
we!=weend;
|
||||
++we){
|
||||
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)
|
||||
if (!fefirst)
|
||||
fefirst = fe;
|
||||
feprevious = fe;
|
||||
}
|
||||
@@ -269,12 +274,13 @@ ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
|
||||
newVEdge->setFEdgeB(fe);
|
||||
|
||||
// is it a closed loop ?
|
||||
if((firstWEdge == endWEdge) && (size!=1)){
|
||||
if ((firstWEdge == endWEdge) && (size != 1)) {
|
||||
fefirst->setPreviousEdge(fe);
|
||||
fe->setNextEdge(fefirst);
|
||||
newVEdge->setA(0);
|
||||
newVEdge->setB(0);
|
||||
}else{
|
||||
}
|
||||
else {
|
||||
ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
|
||||
ViewVertex *vvb = MakeViewVertex(fe->vertexB());
|
||||
|
||||
@@ -288,147 +294,152 @@ ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
|
||||
return newVEdge;
|
||||
}
|
||||
|
||||
OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer){
|
||||
WXFace *nextFace = 0;
|
||||
WOEdge * woeend;
|
||||
OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer)
|
||||
{
|
||||
WXFace *nextFace = NULL;
|
||||
WOEdge *woeend;
|
||||
real tend;
|
||||
if(iFaceLayer.order){
|
||||
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();
|
||||
}
|
||||
// special case of EDGE_VERTEX config:
|
||||
if((tend == 0.0) || (tend == 1.0)){
|
||||
if ((tend == 0.0) || (tend == 1.0)) {
|
||||
WVertex *nextVertex;
|
||||
if(tend == 0.0)
|
||||
if (tend == 0.0)
|
||||
nextVertex = woeend->GetaVertex();
|
||||
else
|
||||
nextVertex = woeend->GetbVertex();
|
||||
if(nextVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
|
||||
return OWXFaceLayer(0,true);
|
||||
if (nextVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
|
||||
return OWXFaceLayer(0, true);
|
||||
bool found = false;
|
||||
WVertex::face_iterator f=nextVertex->faces_begin();
|
||||
WVertex::face_iterator fend=nextVertex->faces_end();
|
||||
while((!found) && (f!=fend)){
|
||||
WVertex::face_iterator f = nextVertex->faces_begin();
|
||||
WVertex::face_iterator fend = nextVertex->faces_end();
|
||||
while ((!found) && (f != fend)) {
|
||||
nextFace = dynamic_cast<WXFace*>(*f);
|
||||
if((0 != nextFace) && (nextFace!=iFaceLayer.fl->getFace())){
|
||||
if ((0 != nextFace) && (nextFace != iFaceLayer.fl->getFace())) {
|
||||
vector<WXFaceLayer*> sameNatureLayers;
|
||||
nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
||||
if(sameNatureLayers.size() == 1) {// don't know
|
||||
// maybe should test whether this face has
|
||||
// also a vertex_edge configuration
|
||||
WXFaceLayer * winner = sameNatureLayers[0];
|
||||
// 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);
|
||||
if(woeend == winner->getSmoothEdge()->woea()->twin())
|
||||
return OWXFaceLayer(winner,true);
|
||||
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
||||
return OWXFaceLayer(NULL, true);
|
||||
if (woeend == winner->getSmoothEdge()->woea()->twin())
|
||||
return OWXFaceLayer(winner, true);
|
||||
else
|
||||
return OWXFaceLayer(winner,false);
|
||||
return OWXFaceLayer(winner, false);
|
||||
}
|
||||
}
|
||||
++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->hasSmoothEdges())
|
||||
return OWXFaceLayer(0,true);
|
||||
if (!nextFace)
|
||||
return OWXFaceLayer(NULL, true);
|
||||
// if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
|
||||
if (!nextFace->hasSmoothEdges())
|
||||
return OWXFaceLayer(NULL,true);
|
||||
vector<WXFaceLayer*> sameNatureLayers;
|
||||
nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
||||
if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face
|
||||
return OWXFaceLayer(0,true);
|
||||
else{
|
||||
WXFaceLayer * winner = sameNatureLayers[0];
|
||||
// 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);
|
||||
if(woeend == winner->getSmoothEdge()->woea()->twin())
|
||||
return OWXFaceLayer(winner,true);
|
||||
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
||||
return OWXFaceLayer(NULL, true);
|
||||
if (woeend == winner->getSmoothEdge()->woea()->twin())
|
||||
return OWXFaceLayer(winner, true);
|
||||
else
|
||||
return OWXFaceLayer(winner,false);
|
||||
return OWXFaceLayer(winner, false);
|
||||
}
|
||||
}
|
||||
return OWXFaceLayer(0,true);
|
||||
return OWXFaceLayer(NULL, true);
|
||||
}
|
||||
|
||||
OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer) {
|
||||
WXFace *previousFace = 0;
|
||||
WOEdge * woebegin;
|
||||
OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer)
|
||||
{
|
||||
WXFace *previousFace = NULL;
|
||||
WOEdge *woebegin;
|
||||
real tend;
|
||||
if(iFaceLayer.order){
|
||||
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();
|
||||
}
|
||||
|
||||
// special case of EDGE_VERTEX config:
|
||||
if((tend == 0.0) || (tend == 1.0)){
|
||||
if ((tend == 0.0) || (tend == 1.0)) {
|
||||
WVertex *previousVertex;
|
||||
if(tend == 0.0)
|
||||
if (tend == 0.0)
|
||||
previousVertex = woebegin->GetaVertex();
|
||||
else
|
||||
previousVertex = woebegin->GetbVertex();
|
||||
if(previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
|
||||
return OWXFaceLayer(0,true);
|
||||
if (previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
|
||||
return OWXFaceLayer(NULL, true);
|
||||
bool found = false;
|
||||
WVertex::face_iterator f=previousVertex->faces_begin();
|
||||
WVertex::face_iterator fend=previousVertex->faces_end();
|
||||
while((!found) && (f!=fend)){
|
||||
WVertex::face_iterator f = previousVertex->faces_begin();
|
||||
WVertex::face_iterator fend = previousVertex->faces_end();
|
||||
for (; (!found) && (f != fend); ++f) {
|
||||
previousFace = dynamic_cast<WXFace*>(*f);
|
||||
if((0 != previousFace) && (previousFace!=iFaceLayer.fl->getFace())){
|
||||
if ((0 != previousFace) && (previousFace!=iFaceLayer.fl->getFace())) {
|
||||
vector<WXFaceLayer*> sameNatureLayers;
|
||||
previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
||||
if(sameNatureLayers.size() == 1) {// don't know
|
||||
// maybe should test whether this face has
|
||||
// also a vertex_edge configuration
|
||||
WXFaceLayer * winner = sameNatureLayers[0];
|
||||
// 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);
|
||||
if(woebegin == winner->getSmoothEdge()->woeb()->twin())
|
||||
return OWXFaceLayer(winner,true);
|
||||
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
||||
return OWXFaceLayer(NULL, true);
|
||||
if (woebegin == winner->getSmoothEdge()->woeb()->twin())
|
||||
return OWXFaceLayer(winner, true);
|
||||
else
|
||||
return OWXFaceLayer(winner,false);
|
||||
return OWXFaceLayer(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
|
||||
if(!previousFace->hasSmoothEdges())
|
||||
return OWXFaceLayer(0,true);
|
||||
if (0 == previousFace)
|
||||
return OWXFaceLayer(NULL, true);
|
||||
// if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
|
||||
if (!previousFace->hasSmoothEdges())
|
||||
return OWXFaceLayer(NULL, true);
|
||||
vector<WXFaceLayer*> sameNatureLayers;
|
||||
previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
||||
if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face
|
||||
return OWXFaceLayer(0,true);
|
||||
else{
|
||||
WXFaceLayer * winner = sameNatureLayers[0];
|
||||
// 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);
|
||||
if(woebegin == winner->getSmoothEdge()->woeb()->twin())
|
||||
return OWXFaceLayer(winner,true);
|
||||
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
||||
return OWXFaceLayer(NULL, true);
|
||||
if (woebegin == winner->getSmoothEdge()->woeb()->twin())
|
||||
return OWXFaceLayer(winner, true);
|
||||
else
|
||||
return OWXFaceLayer(winner,false);
|
||||
return OWXFaceLayer(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();
|
||||
@@ -450,10 +462,10 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
|
||||
|
||||
Vec3r normal;
|
||||
// Make the 2 Svertices
|
||||
if(feprevious == 0){ // that means that we don't have any vertex already built for that face
|
||||
if (feprevious == 0) { // that means that we don't have any vertex already built for that face
|
||||
Vec3r A1(woea->GetaVertex()->GetVertex());
|
||||
Vec3r A2(woea->GetbVertex()->GetVertex());
|
||||
Vec3r A(A1+ta*(A2-A1));
|
||||
Vec3r A(A1 + ta * (A2 - A1));
|
||||
|
||||
va = MakeSVertex(A, false);
|
||||
// Set normal:
|
||||
@@ -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));
|
||||
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
|
||||
@@ -504,11 +515,11 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
|
||||
fe->setFrsMaterialIndex(ifl.fl->getFace()->frs_materialIndex());
|
||||
fe->setFace(ifl.fl->getFace());
|
||||
fe->setFaceMark(ifl.fl->getFace()->GetMark());
|
||||
if(feprevious == 0)
|
||||
if (feprevious == 0)
|
||||
normal.normalize();
|
||||
fe->setNormal(normal);
|
||||
fe->setPreviousEdge(feprevious);
|
||||
if(feprevious)
|
||||
if (feprevious)
|
||||
feprevious->setNextEdge(fe);
|
||||
_pCurrentSShape->AddEdge(fe);
|
||||
va->AddFEdge(fe);
|
||||
@@ -519,10 +530,11 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
|
||||
return fe;
|
||||
}
|
||||
|
||||
bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer){
|
||||
if(0 == iFaceLayer)
|
||||
bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer)
|
||||
{
|
||||
if (0 == iFaceLayer)
|
||||
return true;
|
||||
if(iFaceLayer->userdata == 0)
|
||||
if (iFaceLayer->userdata == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -539,100 +551,100 @@ int ViewEdgeXBuilder::retrieveFaceMarks(WXEdge *iEdge)
|
||||
return result;
|
||||
}
|
||||
|
||||
OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge){
|
||||
if(Nature::NO_FEATURE == iEdge.e->nature())
|
||||
return OWXEdge(0, true);
|
||||
OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge)
|
||||
{
|
||||
if (Nature::NO_FEATURE == iEdge.e->nature())
|
||||
return OWXEdge(NULL, true);
|
||||
|
||||
WVertex *v;
|
||||
if(true == iEdge.order)
|
||||
if (true == iEdge.order)
|
||||
v = iEdge.e->GetbVertex();
|
||||
else
|
||||
v = iEdge.e->GetaVertex();
|
||||
|
||||
if(((WXVertex*)v)->isFeature())
|
||||
return 0;
|
||||
|
||||
if (((WXVertex*)v)->isFeature())
|
||||
return 0; /* XXX eeek? NULL? OWXEdge(NULL, true/false)?*/
|
||||
|
||||
int faceMarks = retrieveFaceMarks(iEdge.e);
|
||||
vector<WEdge*>& vEdges = (v)->GetEdges();
|
||||
for(vector<WEdge*>::iterator ve=vEdges.begin(),veend=vEdges.end();
|
||||
ve!=veend;
|
||||
ve++){
|
||||
for (vector<WEdge*>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
|
||||
WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
|
||||
if(wxe == iEdge.e)
|
||||
if (wxe == iEdge.e)
|
||||
continue; // same edge as the one processed
|
||||
|
||||
if(wxe->nature() != iEdge.e->nature())
|
||||
if (wxe->nature() != iEdge.e->nature())
|
||||
continue;
|
||||
|
||||
// check face mark continuity
|
||||
if(retrieveFaceMarks(wxe) != faceMarks)
|
||||
if (retrieveFaceMarks(wxe) != faceMarks)
|
||||
continue;
|
||||
|
||||
if(wxe->GetaVertex() == v){
|
||||
if (wxe->GetaVertex() == v) {
|
||||
// That means that the face necesarily lies on the edge left.
|
||||
// So the vertex order is OK.
|
||||
return OWXEdge(wxe, true);
|
||||
}else{
|
||||
}
|
||||
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){
|
||||
if(Nature::NO_FEATURE == iEdge.e->nature())
|
||||
return OWXEdge(0, true);
|
||||
OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge)
|
||||
{
|
||||
if (Nature::NO_FEATURE == iEdge.e->nature())
|
||||
return OWXEdge(NULL, true);
|
||||
|
||||
WVertex *v;
|
||||
if(true == iEdge.order)
|
||||
if (true == iEdge.order)
|
||||
v = iEdge.e->GetaVertex();
|
||||
else
|
||||
v = iEdge.e->GetbVertex();
|
||||
|
||||
if(((WXVertex*)v)->isFeature())
|
||||
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)
|
||||
if (wxe == iEdge.e)
|
||||
continue; // same edge as the one processed
|
||||
|
||||
if(wxe->nature() != iEdge.e->nature())
|
||||
if (wxe->nature() != iEdge.e->nature())
|
||||
continue;
|
||||
|
||||
// check face mark continuity
|
||||
if(retrieveFaceMarks(wxe) != faceMarks)
|
||||
if (retrieveFaceMarks(wxe) != faceMarks)
|
||||
continue;
|
||||
|
||||
if(wxe->GetbVertex() == v){
|
||||
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{
|
||||
wxVA = (WXVertex*)iwe.e->GetbVertex();
|
||||
wxVB = (WXVertex*)iwe.e->GetaVertex();
|
||||
if (iwe.order) {
|
||||
wxVA = (WXVertex *)iwe.e->GetaVertex();
|
||||
wxVB = (WXVertex *)iwe.e->GetbVertex();
|
||||
}
|
||||
else {
|
||||
wxVA = (WXVertex *)iwe.e->GetbVertex();
|
||||
wxVB = (WXVertex *)iwe.e->GetaVertex();
|
||||
}
|
||||
// Make the 2 SVertex
|
||||
va = MakeSVertex(wxVA->GetVertex(), true);
|
||||
@@ -642,27 +654,27 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
|
||||
Vec3r normalA, normalB;
|
||||
unsigned matA(0), matB(0);
|
||||
bool faceMarkA = false, faceMarkB = false;
|
||||
if(iwe.order){
|
||||
if (iwe.order) {
|
||||
normalB = (iwe.e->GetbFace()->GetNormal());
|
||||
matB = (iwe.e->GetbFace()->frs_materialIndex());
|
||||
faceMarkB = (iwe.e->GetbFace()->GetMark());
|
||||
if(!(iwe.e->nature() & Nature::BORDER)) {
|
||||
if (!(iwe.e->nature() & Nature::BORDER)) {
|
||||
normalA = (iwe.e->GetaFace()->GetNormal());
|
||||
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());
|
||||
if(!(iwe.e->nature() & Nature::BORDER)) {
|
||||
if (!(iwe.e->nature() & Nature::BORDER)) {
|
||||
normalB = (iwe.e->GetaFace()->GetNormal());
|
||||
matB = (iwe.e->GetaFace()->frs_materialIndex());
|
||||
faceMarkB = (iwe.e->GetaFace()->GetMark());
|
||||
}
|
||||
}
|
||||
// Creates the corresponding feature edge
|
||||
// Creates the corresponding feature edge
|
||||
fe = new FEdgeSharp(va, vb);
|
||||
fe->setNature(iwe.e->nature());
|
||||
fe->setId(_currentFId);
|
||||
@@ -673,7 +685,7 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
|
||||
fe->setNormalA(normalA);
|
||||
fe->setNormalB(normalB);
|
||||
fe->setPreviousEdge(feprevious);
|
||||
if(feprevious)
|
||||
if (feprevious)
|
||||
feprevious->setNextEdge(fe);
|
||||
_pCurrentSShape->AddEdge(fe);
|
||||
va->AddFEdge(fe);
|
||||
@@ -689,15 +701,17 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
|
||||
return fe;
|
||||
}
|
||||
|
||||
bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge){
|
||||
if(0 == iEdge)
|
||||
bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge)
|
||||
{
|
||||
if (0 == iEdge)
|
||||
return true;
|
||||
if(iEdge->userdata == 0)
|
||||
if (iEdge->userdata == 0)
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to build view edges and the underlying chains of feature edges...
|
||||
* \author Stephane Grabli
|
||||
* \date 27/10/2003
|
||||
*/
|
||||
|
||||
#ifndef VIEWEDGEXBUILDER_H
|
||||
# define VIEWEDGEXBUILDER_H
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
# include <map>
|
||||
# include <utility>
|
||||
# include <vector>
|
||||
#if 0 // soc
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 3)
|
||||
//hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
|
||||
# include <hash_map.h>
|
||||
#else
|
||||
# include <hash_map>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// soc
|
||||
// # if defined(__GNUC__) && (__GNUC__ >= 3)
|
||||
// //hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
|
||||
// # include <hash_map.h>
|
||||
// # else
|
||||
// # include <hash_map>
|
||||
// # endif
|
||||
#include "Interface1D.h"
|
||||
|
||||
# include "../system/FreestyleConfig.h"
|
||||
# include "../geometry/Geom.h"
|
||||
# include "Interface1D.h"
|
||||
#include "../geometry/Geom.h"
|
||||
|
||||
#include "../system/FreestyleConfig.h"
|
||||
|
||||
using namespace Geometry;
|
||||
using namespace std;
|
||||
|
||||
class SVertex;
|
||||
|
||||
/*! Defines a hash table used for searching the SVertex */
|
||||
struct SVertexHasher {
|
||||
struct SVertexHasher
|
||||
{
|
||||
#define _MUL 950706376UL
|
||||
#define _MOD 2147483647UL
|
||||
inline size_t operator() (const Vec3r& p) const {
|
||||
size_t res = ((unsigned long) (p[0] * _MUL)) % _MOD;
|
||||
res = ((res + (unsigned long) (p[1]) * _MUL)) % _MOD;
|
||||
return ((res +(unsigned long) (p[2]) * _MUL)) % _MOD;
|
||||
inline size_t operator()(const Vec3r& p) const
|
||||
{
|
||||
size_t res = ((unsigned long)(p[0] * _MUL)) % _MOD;
|
||||
res = ((res + (unsigned long)(p[1]) * _MUL)) % _MOD;
|
||||
return ((res +(unsigned long)(p[2]) * _MUL)) % _MOD;
|
||||
}
|
||||
#undef _MUL
|
||||
#undef _MOD
|
||||
};
|
||||
|
||||
// Key_compare predicate for hash_map. In particular, return false if equal.
|
||||
struct epsilonEquals{
|
||||
bool operator()(const Vec3r& v1, const Vec3r& v2) const{
|
||||
real norm = (v1-v2).norm();
|
||||
return (norm<1e-06);
|
||||
struct epsilonEquals
|
||||
{
|
||||
bool operator()(const Vec3r& v1, const Vec3r& v2) const
|
||||
{
|
||||
real norm = (v1 - v2).norm();
|
||||
return (norm < 1.0e-06);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -75,46 +89,80 @@ struct epsilonEquals{
|
||||
typedef map<Vec3r , SVertex*> SVertexMap;
|
||||
|
||||
class WXFaceLayer;
|
||||
|
||||
/*! class to describe an oriented smooth edge */
|
||||
class OWXFaceLayer{
|
||||
class OWXFaceLayer
|
||||
{
|
||||
public:
|
||||
WXFaceLayer * fl;
|
||||
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){
|
||||
return !(*this==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;
|
||||
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){
|
||||
return !(*this==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:
|
||||
|
||||
inline ViewEdgeXBuilder()
|
||||
{_currentViewId = 1;_currentFId=0;_currentSVertexId=0;}
|
||||
virtual ~ViewEdgeXBuilder(){}
|
||||
{
|
||||
_currentViewId = 1;
|
||||
_currentFId = 0;
|
||||
_currentSVertexId = 0;
|
||||
}
|
||||
|
||||
/*! Builds a view shape from a WXShape in which the feature edges
|
||||
* are flagged
|
||||
virtual ~ViewEdgeXBuilder() {}
|
||||
|
||||
/*! Builds a view shape from a WXShape in which the feature edges are flagged
|
||||
* Builds chains of feature edges (so ViewEdges) from a WXShape
|
||||
* iWShape
|
||||
* The Winged Edge structure in which all silhouette edges
|
||||
* and vertices are flagged.
|
||||
* 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,40 +207,59 @@ 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,
|
||||
std::vector<SVertex*>& ioSVertices) ;
|
||||
virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, std::vector<ViewEdge*>& ioVEdges,
|
||||
std::vector<ViewVertex*>& ioVVertices, std::vector<FEdge*>& ioFEdges,
|
||||
std::vector<SVertex*>& ioSVertices);
|
||||
|
||||
/*! Builds a smooth view edge, starting the face iFace.*/
|
||||
ViewEdge * BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer);
|
||||
|
||||
/*! Makes a sharp viewedge
|
||||
*/
|
||||
ViewEdge * BuildSharpViewEdge(const OWXEdge& iWEdge) ;
|
||||
/*! Builds a smooth view edge, starting the face iFace. */
|
||||
ViewEdge *BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer);
|
||||
|
||||
/*! Makes a sharp viewedge */
|
||||
ViewEdge *BuildSharpViewEdge(const OWXEdge& iWEdge);
|
||||
|
||||
public:
|
||||
/*! accessors */
|
||||
inline int currentViewId() const { return _currentViewId; }
|
||||
inline int currentFId() const { return _currentFId; }
|
||||
inline int currentSVertexId() const { return _currentSVertexId; }
|
||||
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 */
|
||||
virtual void Init(ViewShape *oVShape) ;
|
||||
virtual void Init(ViewShape *oVShape);
|
||||
|
||||
// SMOOTH //
|
||||
/*! checks whether a face has already been processed or not */
|
||||
bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer);
|
||||
OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer& iFaceLayer);
|
||||
OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer);
|
||||
FEdge * BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl);
|
||||
FEdge *BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl);
|
||||
|
||||
// SHARP //
|
||||
/*! checks whether a WEdge has already been processed or not */
|
||||
@@ -196,23 +267,22 @@ protected:
|
||||
int retrieveFaceMarks(WXEdge *iEdge);
|
||||
OWXEdge FindNextWEdge(const OWXEdge& iEdge);
|
||||
OWXEdge FindPreviousWEdge(const OWXEdge& iEdge);
|
||||
FEdge * BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe);
|
||||
FEdge *BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe);
|
||||
|
||||
// GENERAL //
|
||||
/*! Instanciate a SVertex */
|
||||
SVertex * MakeSVertex(Vec3r& iPoint);
|
||||
SVertex *MakeSVertex(Vec3r& iPoint);
|
||||
/*! Instanciate a SVertex if it hasn't been already created */
|
||||
SVertex * MakeSVertex(Vec3r& iPoint, bool shared);
|
||||
SVertex *MakeSVertex(Vec3r& iPoint, bool shared);
|
||||
/*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */
|
||||
ViewVertex * MakeViewVertex(SVertex *iSVertex);
|
||||
ViewVertex *MakeViewVertex(SVertex *iSVertex);
|
||||
|
||||
//oldtmp values
|
||||
// IdHashTable _hashtable;
|
||||
// VVIdHashTable _multivertexHashTable;
|
||||
//IdHashTable _hashtable;
|
||||
//VVIdHashTable _multivertexHashTable;
|
||||
SVertexMap _SVertexMap;
|
||||
SShape *_pCurrentSShape;
|
||||
ViewShape * _pCurrentVShape;
|
||||
ViewShape *_pCurrentVShape;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,83 +1,88 @@
|
||||
//
|
||||
// Filename : ViewMapBuilder.h
|
||||
// Author(s) : Stephane Grabli
|
||||
// Purpose : Class to build silhouette edges from a
|
||||
// Winged-Edge structure
|
||||
// Date of creation : 25/03/2002
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_VIEW_MAP_BUILDER_H__
|
||||
#define __FREESTYLE_VIEW_MAP_BUILDER_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/ViewMapBuilder.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to build silhouette edges from a Winged-Edge structure
|
||||
* \author Stephane Grabli
|
||||
* \date 25/03/2002
|
||||
*/
|
||||
|
||||
#ifndef VIEWMAPBUILDER_H
|
||||
# define VIEWMAPBUILDER_H
|
||||
#include <vector>
|
||||
|
||||
# include "Silhouette.h"
|
||||
# include <vector>
|
||||
# include "../system/FreestyleConfig.h"
|
||||
# include "../geometry/Geom.h"
|
||||
# include "../scene_graph/NodeGroup.h"
|
||||
# include "../winged_edge/WXEdge.h"
|
||||
# include "../geometry/GeomUtils.h"
|
||||
# include "../geometry/Grid.h"
|
||||
# include "../system/ProgressBar.h"
|
||||
# include "../system/RenderMonitor.h"
|
||||
# include "../geometry/SweepLine.h"
|
||||
# include "ViewMap.h"
|
||||
# include "SilhouetteGeomEngine.h"
|
||||
# include "../scene_graph/TriangleRep.h"
|
||||
# include "../winged_edge/WEdge.h"
|
||||
# include "ViewEdgeXBuilder.h"
|
||||
# include "../system/TimeUtils.h"
|
||||
# include "GridDensityProvider.h"
|
||||
#include "GridDensityProvider.h"
|
||||
#include "Silhouette.h"
|
||||
#include "SilhouetteGeomEngine.h"
|
||||
#include "ViewEdgeXBuilder.h"
|
||||
#include "ViewMap.h"
|
||||
|
||||
#include "../geometry/Geom.h"
|
||||
#include "../geometry/GeomUtils.h"
|
||||
#include "../geometry/Grid.h"
|
||||
#include "../geometry/SweepLine.h"
|
||||
|
||||
#include "../scene_graph/NodeGroup.h"
|
||||
#include "../scene_graph/TriangleRep.h"
|
||||
|
||||
#include "../system/FreestyleConfig.h"
|
||||
#include "../system/ProgressBar.h"
|
||||
#include "../system/RenderMonitor.h"
|
||||
#include "../system/TimeUtils.h"
|
||||
|
||||
#include "../winged_edge/WEdge.h"
|
||||
#include "../winged_edge/WXEdge.h"
|
||||
|
||||
using namespace Geometry;
|
||||
|
||||
class LIB_VIEW_MAP_EXPORT ViewMapBuilder
|
||||
{
|
||||
private:
|
||||
|
||||
ViewMap * _ViewMap; // result
|
||||
ViewMap *_ViewMap; // result
|
||||
//SilhouetteGeomEngine _GeomEngine;
|
||||
ProgressBar *_pProgressBar;
|
||||
RenderMonitor *_pRenderMonitor;
|
||||
Vec3r _viewpoint;
|
||||
bool _orthographicProjection;
|
||||
Grid* _Grid;
|
||||
Grid *_Grid;
|
||||
ViewEdgeXBuilder *_pViewEdgeBuilder;
|
||||
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;
|
||||
@@ -104,9 +109,9 @@ public:
|
||||
|
||||
inline ~ViewMapBuilder()
|
||||
{
|
||||
if(_pViewEdgeBuilder){
|
||||
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,21 +241,17 @@ 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,
|
||||
Polygon3r** oaPolygon, unsigned timestamp);
|
||||
int ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
|
||||
Polygon3r **oaPolygon, unsigned timestamp);
|
||||
// FIXME
|
||||
void FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp);
|
||||
void FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp,
|
||||
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
|
||||
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
|
||||
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
|
||||
|
||||
};
|
||||
|
||||
#endif // VIEWMAPBUILDER_H
|
||||
#endif // __FREESTYLE_VIEW_MAP_BUILDER_H__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,116 +1,129 @@
|
||||
//
|
||||
// Filename : ViewMapIO.h
|
||||
// Author(s) : Emmanuel Turquin
|
||||
// Purpose : Functions to manage I/O for the view map
|
||||
// Date of creation : 09/01/2003
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_VIEW_MAP_IO_H__
|
||||
#define __FREESTYLE_VIEW_MAP_IO_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/ViewMapIO.h
|
||||
* \ingroup freestyle
|
||||
* \brief Functions to manage I/O for the view map
|
||||
* \author Emmanuel Turquin
|
||||
* \date 09/01/2003
|
||||
*/
|
||||
|
||||
#ifndef VIEWMAPIO_H
|
||||
# define VIEWMAPIO_H
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
# include "ViewMap.h"
|
||||
# include <fstream>
|
||||
# include <string>
|
||||
# include "../system/FreestyleConfig.h"
|
||||
# include "../system/ProgressBar.h"
|
||||
#include "ViewMap.h"
|
||||
|
||||
#include "../system/FreestyleConfig.h"
|
||||
#include "../system/ProgressBar.h"
|
||||
|
||||
namespace ViewMapIO {
|
||||
|
||||
static const unsigned ZERO = UINT_MAX;
|
||||
static const unsigned ZERO = UINT_MAX;
|
||||
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
int load(istream& in, ViewMap* vm, ProgressBar* pb = NULL);
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
int load(istream& in, ViewMap *vm, ProgressBar *pb = NULL);
|
||||
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
int save(ostream& out, ViewMap* vm, ProgressBar* pb = NULL);
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
int save(ostream& out, ViewMap *vm, ProgressBar *pb = NULL);
|
||||
|
||||
namespace Options {
|
||||
namespace Options {
|
||||
|
||||
static const unsigned char FLOAT_VECTORS = 1;
|
||||
static const unsigned char NO_OCCLUDERS = 2;
|
||||
static const unsigned char FLOAT_VECTORS = 1;
|
||||
static const unsigned char NO_OCCLUDERS = 2;
|
||||
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void setFlags(const unsigned char flags);
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void setFlags(const unsigned char flags);
|
||||
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void addFlags(const unsigned char flags);
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void addFlags(const unsigned char flags);
|
||||
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void rmFlags(const unsigned char flags);
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void rmFlags(const unsigned char flags);
|
||||
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
unsigned char getFlags();
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
unsigned char getFlags();
|
||||
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void setModelsPath(const string& path);
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
void setModelsPath(const string& path);
|
||||
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
string getModelsPath();
|
||||
LIB_VIEW_MAP_EXPORT
|
||||
string getModelsPath();
|
||||
|
||||
}; // End of namepace Options
|
||||
}; // End of namepace Options
|
||||
|
||||
# ifdef IRIX
|
||||
#ifdef IRIX
|
||||
|
||||
namespace Internal {
|
||||
namespace Internal {
|
||||
|
||||
template <unsigned S>
|
||||
ostream& write(ostream& out, const char* str) {
|
||||
template <unsigned S>
|
||||
ostream& write(ostream& out, const char *str)
|
||||
{
|
||||
out.put(str[S - 1]);
|
||||
return write<S - 1>(out, str);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
ostream& write<1>(ostream& out, const char* str) {
|
||||
template<>
|
||||
ostream& write<1>(ostream& out, const char *str)
|
||||
{
|
||||
return out.put(str[0]);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
ostream& write<0>(ostream& out, const char*) {
|
||||
template<>
|
||||
ostream& write<0>(ostream& out, const char*)
|
||||
{
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned S>
|
||||
istream& read(istream& in, char* str) {
|
||||
template <unsigned S>
|
||||
istream& read(istream& in, char *str)
|
||||
{
|
||||
in.get(str[S - 1]);
|
||||
return read<S - 1>(in, str);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
istream& read<1>(istream& in, char* str) {
|
||||
template<>
|
||||
istream& read<1>(istream& in, char *str)
|
||||
{
|
||||
return in.get(str[0]);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
istream& read<0>(istream& in, char*) {
|
||||
template<>
|
||||
istream& read<0>(istream& in, char*)
|
||||
{
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Internal
|
||||
} // End of namespace Internal
|
||||
|
||||
# endif // IRIX
|
||||
#endif // IRIX
|
||||
|
||||
} // End of namespace ViewMapIO
|
||||
|
||||
#endif // VIEWMAPIO_H
|
||||
#endif // __FREESTYLE_VIEW_MAP_IO_H__
|
||||
|
||||
@@ -1,67 +1,71 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* ViewMap */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* ViewMap */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* ViewVertex */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* ViewVertex */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
|
||||
namespace ViewVertexInternal{
|
||||
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
|
||||
{
|
||||
public:
|
||||
class orientedViewEdgeIterator : public Iterator
|
||||
{
|
||||
public:
|
||||
friend class ViewVertex;
|
||||
friend class TVertex;
|
||||
friend class NonTVertex;
|
||||
@@ -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;
|
||||
@@ -83,33 +87,35 @@ namespace ViewVertexInternal{
|
||||
edges_container::iterator _end;
|
||||
edges_container::iterator _nontvertex_iter;
|
||||
|
||||
public:
|
||||
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,
|
||||
public:
|
||||
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;
|
||||
@@ -127,48 +133,40 @@ namespace ViewVertexInternal{
|
||||
_nontvertex_iter = iter;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/*! Tells whether the ViewEdge pointed
|
||||
* by this iterator is the first one of the
|
||||
* iteration list or not.
|
||||
*/
|
||||
public:
|
||||
/*! Tells whether the ViewEdge pointed by this iterator is the first one of the iteration list or not. */
|
||||
virtual bool isBegin() const
|
||||
{
|
||||
if(_Nature & Nature::T_VERTEX)
|
||||
if (_Nature & Nature::T_VERTEX)
|
||||
return (_tvertex_iter == _tbegin);
|
||||
else
|
||||
return (_nontvertex_iter == _begin);
|
||||
}
|
||||
/*! Tells whether the ViewEdge pointed
|
||||
* by this iterator is after the last one of the
|
||||
* iteration list or not.
|
||||
*/
|
||||
|
||||
/*! 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)
|
||||
if (_Nature & Nature::T_VERTEX)
|
||||
return (_tvertex_iter == _tend);
|
||||
else
|
||||
return (_nontvertex_iter == _end);
|
||||
}
|
||||
|
||||
// operators
|
||||
/*! Increments.In the scripting language, call
|
||||
* "increment()".
|
||||
*/
|
||||
virtual orientedViewEdgeIterator& operator++() // operator corresponding to ++i
|
||||
/*! 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;
|
||||
}
|
||||
|
||||
@@ -176,7 +174,7 @@ namespace ViewVertexInternal{
|
||||
/*! operator != */
|
||||
virtual bool operator!=(const orientedViewEdgeIterator& b) const
|
||||
{
|
||||
if(_Nature & Nature::T_VERTEX)
|
||||
if (_Nature & Nature::T_VERTEX)
|
||||
return (_tvertex_iter != b._tvertex_iter);
|
||||
else
|
||||
return (_nontvertex_iter != b._nontvertex_iter);
|
||||
@@ -184,16 +182,17 @@ 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
|
||||
{
|
||||
if(_Nature & Nature::T_VERTEX)
|
||||
if (_Nature & Nature::T_VERTEX)
|
||||
//return _tvertex_iter;
|
||||
return **_tvertex_iter;
|
||||
else
|
||||
@@ -202,49 +201,54 @@ 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:
|
||||
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){
|
||||
if (_tvertex_iter != _tend) {
|
||||
// FIXME : pquoi deja ?
|
||||
::ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter);
|
||||
if(tmp2.first == tmp.first)
|
||||
if (tmp2.first == tmp.first)
|
||||
++_tvertex_iter;
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
++_nontvertex_iter;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* ViewEdge */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
} // ViewVertexInternal namespace
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* ViewEdge */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
|
||||
namespace ViewEdgeInternal {
|
||||
|
||||
//
|
||||
// SVertexIterator
|
||||
//
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
class SVertexIterator : public Interface0DIteratorNested
|
||||
class SVertexIterator : public Interface0DIteratorNested
|
||||
{
|
||||
public:
|
||||
SVertexIterator()
|
||||
{
|
||||
public:
|
||||
|
||||
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,14 +338,15 @@ 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)){
|
||||
if ((!_next_edge) && (!_vertex)) {
|
||||
_vertex = _previous_edge->vertexB();
|
||||
return 0;
|
||||
}
|
||||
@@ -341,41 +357,46 @@ 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 {
|
||||
return _t/(float)_next_edge->viewedge()->getLength2D();
|
||||
|
||||
virtual float u() const
|
||||
{
|
||||
return _t / (float)_next_edge->viewedge()->getLength2D();
|
||||
}
|
||||
|
||||
virtual bool operator==(const Interface0DIteratorNested& it) const {
|
||||
const SVertexIterator* it_exact = dynamic_cast<const SVertexIterator*>(&it);
|
||||
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;
|
||||
FEdge* _next_edge;
|
||||
private:
|
||||
SVertex *_vertex;
|
||||
SVertex *_begin;
|
||||
FEdge *_previous_edge;
|
||||
FEdge *_next_edge;
|
||||
float _t; // curvilinear abscissa
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
@@ -383,34 +404,31 @@ namespace ViewEdgeInternal {
|
||||
//
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
/*! Base class for iterators over ViewEdges of the ViewMap Graph.
|
||||
* Basically the "increment()" operator of this class should
|
||||
* be able to take the decision of "where" (on which ViewEdge) to go
|
||||
* when pointing on a given ViewEdge.
|
||||
* ::Caution::: the dereferencing operator returns a *pointer* to
|
||||
* the pointed ViewEdge.
|
||||
/*! Base class for iterators over ViewEdges of the ViewMap Graph.
|
||||
* Basically the "increment()" operator of this class should be able to take the decision of "where" (on which
|
||||
* ViewEdge) to go when pointing on a given ViewEdge.
|
||||
* ::Caution::: the dereferencing operator returns a *pointer* to the pointed ViewEdge.
|
||||
*/
|
||||
class ViewEdgeIterator : public Iterator
|
||||
{
|
||||
public:
|
||||
|
||||
/*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation.
|
||||
* \param begin
|
||||
* The ViewEdge from where to start the iteration.
|
||||
* \param orientation
|
||||
* If true, we'll look for the next ViewEdge among the
|
||||
* ViewEdges that surround the ending ViewVertex of begin.
|
||||
* If false, we'll search over the ViewEdges surrounding
|
||||
* the ending ViewVertex of begin.
|
||||
* 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,131 +437,138 @@ 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;
|
||||
ViewEdge *_edge;
|
||||
ViewEdge *_begin;
|
||||
};
|
||||
|
||||
} // end of namespace ViewEdgeInternal
|
||||
|
||||
#endif // VIEWMAPITERATORS_H
|
||||
|
||||
#endif // __FREESTYLE_VIEW_MAP_ITERATORS_H__
|
||||
|
||||
@@ -1,36 +1,49 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/ViewMapTesselator.cpp
|
||||
* \ingroup freestyle
|
||||
* \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
|
||||
* \author Stephane Grabli
|
||||
* \date 26/03/2002
|
||||
*/
|
||||
|
||||
#include "ViewMapTesselator.h"
|
||||
|
||||
NodeGroup* ViewMapTesselator::Tesselate(ViewMap *iViewMap)
|
||||
NodeGroup *ViewMapTesselator::Tesselate(ViewMap *iViewMap)
|
||||
{
|
||||
if(0 == iViewMap->ViewEdges().size())
|
||||
if (0 == iViewMap->ViewEdges().size())
|
||||
return NULL;
|
||||
|
||||
const vector<ViewEdge*>& viewedges = iViewMap->ViewEdges();
|
||||
return Tesselate(viewedges.begin(), viewedges.end());
|
||||
}
|
||||
|
||||
NodeGroup* ViewMapTesselator::Tesselate(WShape *)
|
||||
NodeGroup *ViewMapTesselator::Tesselate(WShape *)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,44 +1,50 @@
|
||||
//
|
||||
// Filename : ViewMapTesselator.h
|
||||
// Author(s) : Stephane Grabli
|
||||
// Purpose : Class to build a Node Tree designed to be displayed
|
||||
// from a Silhouette View Map structure.
|
||||
// Date of creation : 26/03/2002
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __FREESTYLE_VIEW_MAP_TESSELATOR_H__
|
||||
#define __FREESTYLE_VIEW_MAP_TESSELATOR_H__
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** \file blender/freestyle/intern/view_map/ViewMapTesselator.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
|
||||
* \author Stephane Grabli
|
||||
* \date 26/03/2002
|
||||
*/
|
||||
|
||||
#ifndef VIEWMAPTESSELATOR_H
|
||||
# define VIEWMAPTESSELATOR_H
|
||||
#include "Silhouette.h"
|
||||
#include "ViewMap.h"
|
||||
|
||||
# include "Silhouette.h"
|
||||
# include "ViewMap.h"
|
||||
# include "../scene_graph/NodeShape.h"
|
||||
# include "../winged_edge/WEdge.h"
|
||||
# include "../scene_graph/NodeGroup.h"
|
||||
# include "../scene_graph/LineRep.h"
|
||||
# include "../scene_graph/OrientedLineRep.h"
|
||||
# include "../scene_graph/VertexRep.h"
|
||||
#include "../scene_graph/LineRep.h"
|
||||
#include "../scene_graph/NodeShape.h"
|
||||
#include "../scene_graph/NodeGroup.h"
|
||||
#include "../scene_graph/OrientedLineRep.h"
|
||||
#include "../scene_graph/VertexRep.h"
|
||||
|
||||
#include "../winged_edge/WEdge.h"
|
||||
|
||||
class NodeShape;
|
||||
class NodeGroup;
|
||||
@@ -48,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
|
||||
*/
|
||||
NodeGroup* Tesselate(ViewMap* iViewMap) ;
|
||||
/*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a ViewMap */
|
||||
NodeGroup *Tesselate(ViewMap *iViewMap);
|
||||
|
||||
/*! Builds a set of lines rep contained under a
|
||||
* a NodeShape, itself contained under a NodeGroup from a
|
||||
* set of view edges
|
||||
/*! 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) ;
|
||||
NodeGroup *Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end);
|
||||
|
||||
/*! Builds a set of lines rep contained among a
|
||||
* a NodeShape, from a WShape
|
||||
*/
|
||||
NodeGroup* Tesselate(WShape* iWShape);
|
||||
/*! Builds a set of lines rep contained among a NodeShape, from a WShape */
|
||||
NodeGroup *Tesselate(WShape *iWShape);
|
||||
|
||||
inline void setNature(Nature::EdgeNature iNature)
|
||||
{
|
||||
_nature = iNature;
|
||||
}
|
||||
|
||||
inline void setNature(Nature::EdgeNature iNature) {_nature = iNature;}
|
||||
inline void setFrsMaterial(const FrsMaterial& iMaterial) {_FrsMaterial=iMaterial;_overloadFrsMaterial=true;}
|
||||
inline Nature::EdgeNature nature() {return _nature;}
|
||||
inline const FrsMaterial& frs_material() const {return _FrsMaterial;}
|
||||
inline void setFrsMaterial(const FrsMaterial& iMaterial)
|
||||
{
|
||||
_FrsMaterial = iMaterial;
|
||||
_overloadFrsMaterial = true;
|
||||
}
|
||||
|
||||
inline Nature::EdgeNature nature()
|
||||
{
|
||||
return _nature;
|
||||
}
|
||||
|
||||
inline const FrsMaterial& frs_material() const
|
||||
{
|
||||
return _FrsMaterial;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
|
||||
@@ -118,70 +139,64 @@ protected:
|
||||
///////////////////////////////////////////////
|
||||
|
||||
template<class ViewEdgesIterator>
|
||||
NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
|
||||
NodeGroup *ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
|
||||
{
|
||||
NodeGroup *group = new NodeGroup;
|
||||
NodeShape *tshape = new NodeShape;
|
||||
group->AddChild(tshape);
|
||||
//tshape->frs_material().setDiffuse(0.f, 0.f, 0.f, 1.f);
|
||||
//tshape->frs_material().setDiffuse(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
tshape->setFrsMaterial(_FrsMaterial);
|
||||
|
||||
LineRep* line;
|
||||
|
||||
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;
|
||||
//
|
||||
int id = 0;
|
||||
//for (vector<ViewEdge*>::const_iterator c = viewedges.begin(), cend = viewedges.end(); c != cend; c++)
|
||||
for (ViewEdgesIterator c = begin, cend = end; c != cend; c++) {
|
||||
#if 0
|
||||
if ((*c)->qi() > 0) {
|
||||
continue;
|
||||
}
|
||||
if (!((*c)->nature() & (_nature))) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
firstEdge = (*c)->fedgeA();
|
||||
|
||||
// if(firstEdge->invisibility() > 0)
|
||||
// continue;
|
||||
#if 0
|
||||
if (firstEdge->invisibility() > 0)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
line = new OrientedLineRep();
|
||||
if(_overloadFrsMaterial)
|
||||
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());
|
||||
//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;
|
||||
nextFEdge = nextFEdge->nextEdge();
|
||||
}while((nextFEdge != NULL) && (nextFEdge != firstEdge));
|
||||
} while ((nextFEdge != NULL) && (nextFEdge != firstEdge));
|
||||
// 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__
|
||||
|
||||
@@ -1,36 +1,68 @@
|
||||
/* 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>
|
||||
|
||||
static bool angle_obtuse (WVertex * v, WFace * f)
|
||||
#include "Curvature.h"
|
||||
#include "WEdge.h"
|
||||
|
||||
#include "../geometry/normal_cycle.h"
|
||||
|
||||
#include "../system/FreestyleConfig.h"
|
||||
|
||||
static bool angle_obtuse(WVertex *v, WFace *f)
|
||||
{
|
||||
WOEdge * e;
|
||||
f->getOppositeEdge (v, e);
|
||||
WOEdge *e;
|
||||
f->getOppositeEdge(v, e);
|
||||
|
||||
Vec3r vec1(e->GetaVertex()->GetVertex()-v->GetVertex());
|
||||
Vec3r vec2(e->GetbVertex()->GetVertex()-v->GetVertex());
|
||||
@@ -39,52 +71,49 @@ static bool angle_obtuse (WVertex * v, WFace * f)
|
||||
|
||||
// FIXME
|
||||
// WVvertex is useless but kept for history reasons
|
||||
static bool triangle_obtuse (WVertex*, WFace * f)
|
||||
static bool triangle_obtuse(WVertex *, WFace *f)
|
||||
{
|
||||
bool b=false;
|
||||
for (int i=0; i<3; i++)
|
||||
b = b ||
|
||||
((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i+1)%3]->GetVec()) < 0);
|
||||
bool b = false;
|
||||
for (int i = 0; i < 3; i++)
|
||||
b = b || ((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i + 1) % 3]->GetVec()) < 0);
|
||||
return b;
|
||||
}
|
||||
|
||||
static real cotan (WVertex * vo, WVertex * v1, WVertex * v2)
|
||||
static real cotan(WVertex *vo, WVertex *v1, WVertex *v2)
|
||||
{
|
||||
/* cf. Appendix B of [Meyer et al 2002] */
|
||||
real udotv, denom;
|
||||
|
||||
Vec3r u(v1->GetVertex()- vo->GetVertex());
|
||||
Vec3r v(v2->GetVertex()- vo->GetVertex());
|
||||
Vec3r u(v1->GetVertex() - vo->GetVertex());
|
||||
Vec3r v(v2->GetVertex() - vo->GetVertex());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static real angle_from_cotan (WVertex * vo, WVertex * v1, WVertex * v2)
|
||||
static real angle_from_cotan(WVertex *vo, WVertex *v1, WVertex *v2)
|
||||
{
|
||||
/* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */
|
||||
real udotv, denom;
|
||||
|
||||
Vec3r u (v1->GetVertex()-vo->GetVertex());
|
||||
Vec3r v(v2->GetVertex()-vo->GetVertex());
|
||||
Vec3r u (v1->GetVertex() - vo->GetVertex());
|
||||
Vec3r v(v2->GetVertex() - vo->GetVertex());
|
||||
|
||||
udotv = u * v;
|
||||
denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
|
||||
|
||||
/* Note: I assume this is what they mean by using atan2 (). -Ray Jones */
|
||||
/* Note: I assume this is what they mean by using atan2(). -Ray Jones */
|
||||
|
||||
/* tan = denom/udotv = y/x (see man page for atan2) */
|
||||
return (fabs (atan2 (denom, udotv)));
|
||||
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,56 +131,56 @@ 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)
|
||||
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++)
|
||||
area+=(*itE)->GetaFace()->getArea();
|
||||
for (itE=v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
|
||||
area += (*itE)->GetaFace()->getArea();
|
||||
|
||||
Kh=Vec3r(0.0, 0.0, 0.0);
|
||||
Kh = Vec3r(0.0, 0.0, 0.0);
|
||||
|
||||
for (itE=v->incoming_edges_begin();
|
||||
itE!=v->incoming_edges_end(); itE++)
|
||||
{
|
||||
WOEdge * e = (*itE)->getPrevOnFace();
|
||||
//if ((e->GetaVertex()==v) || (e->GetbVertex()==v)) cerr<< "BUG ";
|
||||
|
||||
WVertex * v1 = e->GetaVertex();
|
||||
WVertex * v2 = e->GetbVertex();
|
||||
for (itE=v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
|
||||
WOEdge *e = (*itE)->getPrevOnFace();
|
||||
#if 0
|
||||
if ((e->GetaVertex() == v) || (e->GetbVertex() == v))
|
||||
cerr<< "BUG ";
|
||||
#endif
|
||||
WVertex *v1 = e->GetaVertex();
|
||||
WVertex *v2 = e->GetbVertex();
|
||||
real temp;
|
||||
|
||||
temp = cotan (v1, v, v2);
|
||||
Kh = Vec3r(Kh+temp*(v2->GetVertex()-v->GetVertex()));
|
||||
temp = cotan(v1, v, v2);
|
||||
Kh = Vec3r(Kh + temp * (v2->GetVertex() - v->GetVertex()));
|
||||
|
||||
temp = cotan (v2, v, v1);
|
||||
Kh = Vec3r(Kh+temp*(v1->GetVertex()-v->GetVertex()));
|
||||
temp = cotan(v2, v, v1);
|
||||
Kh = Vec3r(Kh + temp * (v1->GetVertex() - v->GetVertex()));
|
||||
}
|
||||
if (area > 0.0)
|
||||
{
|
||||
Kh[0] /= 2*area;
|
||||
Kh[1] /= 2*area;
|
||||
Kh[2] /= 2*area;
|
||||
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,97 +193,92 @@ 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)
|
||||
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;}
|
||||
|
||||
WVertex::incoming_edge_iterator itE;
|
||||
for (itE=v->incoming_edges_begin();
|
||||
itE!=v->incoming_edges_end(); itE++)
|
||||
area+=(*itE)->GetaFace()->getArea();
|
||||
|
||||
for (itE=v->incoming_edges_begin();
|
||||
itE!=v->incoming_edges_end(); itE++)
|
||||
{
|
||||
WOEdge * e = (*itE)->getPrevOnFace();
|
||||
WVertex * v1 = e->GetaVertex();
|
||||
WVertex * v2 = e->GetbVertex();
|
||||
angle_sum += angle_from_cotan (v, v1, v2);
|
||||
if (v->isBoundary()) {
|
||||
*Kg = 0.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
*Kg = (2.0*M_PI - angle_sum)/area;
|
||||
WVertex::incoming_edge_iterator itE;
|
||||
for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
|
||||
area += (*itE)->GetaFace()->getArea();
|
||||
|
||||
for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
|
||||
WOEdge *e = (*itE)->getPrevOnFace();
|
||||
WVertex *v1 = e->GetaVertex();
|
||||
WVertex *v2 = e->GetbVertex();
|
||||
angle_sum += angle_from_cotan(v, v1, v2);
|
||||
}
|
||||
|
||||
*Kg = (2.0 * M_PI - angle_sum) / area;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
temp = 1.0 / (m21*m12 - m11*m22);
|
||||
*x1 = (m12*b2 - m22*b1)*temp;
|
||||
*x2 = (m11*b2 - m21*b1)*temp;
|
||||
temp = 1.0 / (m21 * m12 - m11 * m22);
|
||||
*x1 = (m12 * b2 - m22 * b1) * temp;
|
||||
*x2 = (m11 * b2 - m21 * b1) * temp;
|
||||
}
|
||||
|
||||
/* from Maple - largest eigenvector of [a b; b c] */
|
||||
static void eigenvector (real a, real b, real c,
|
||||
Vec3r e)
|
||||
static void eigenvector(real a, real b, real c, Vec3r e)
|
||||
{
|
||||
if (b == 0.0) {
|
||||
e[0] = 0.0;
|
||||
} else {
|
||||
e[0] = -(c - a - sqrt (c*c - 2*a*c + a*a + 4*b*b))/(2*b);
|
||||
}
|
||||
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,22 +315,21 @@ 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++)
|
||||
N=Vec3r(N+(*itE)->GetaFace()->GetNormal());
|
||||
for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
|
||||
N = Vec3r(N + (*itE)->GetaFace()->GetNormal());
|
||||
real normN = N.norm();
|
||||
if (normN <= 0.0)
|
||||
return;
|
||||
N.normalize();
|
||||
}
|
||||
|
||||
|
||||
/* construct a basis from N: */
|
||||
/* set basis1 to any component not the largest of N */
|
||||
basis1[0] = basis1[1] = basis1[2] = 0.0;
|
||||
@@ -332,90 +350,79 @@ void gts_vertex_principal_directions (WVertex * v,
|
||||
aterm_db = bterm_db = cterm_db = const_db = 0.0;
|
||||
int nb_edges=v->GetEdges().size();
|
||||
|
||||
weights = (real *) malloc (sizeof (real)*nb_edges);
|
||||
kappas = (real*) malloc (sizeof (real)*nb_edges);
|
||||
d1s = (real*) malloc (sizeof (real)*nb_edges);
|
||||
d2s = (real*) malloc (sizeof (real)*nb_edges);
|
||||
weights = (real *)malloc(sizeof (real) * nb_edges);
|
||||
kappas = (real *)malloc(sizeof (real) * nb_edges);
|
||||
d1s = (real *)malloc(sizeof (real) * nb_edges);
|
||||
d2s = (real *)malloc(sizeof (real) * nb_edges);
|
||||
edge_count = 0;
|
||||
|
||||
for (itE=v->incoming_edges_begin();
|
||||
itE!=v->incoming_edges_end(); itE++)
|
||||
{
|
||||
WOEdge * e;
|
||||
WFace * f1, * f2;
|
||||
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. */
|
||||
//g_assert (gts_edge_face_number (e, s) == 2);
|
||||
/* since this vertex passed the tests in gts_vertex_mean_curvature_normal(), this should be true. */
|
||||
//g_assert(gts_edge_face_number (e, s) == 2);
|
||||
|
||||
/* identify the two triangles bordering e in s */
|
||||
f1=e->GetaFace();
|
||||
f2=e->GetbFace();
|
||||
f1 = e->GetaFace();
|
||||
f2 = e->GetbFace();
|
||||
|
||||
/* We are solving for the values of the curvature tensor
|
||||
* B = [ a b ; b c ].
|
||||
* The computations here are from section 5 of [Meyer et al 2002].
|
||||
*
|
||||
* The first step is to calculate the linear equations governing
|
||||
* the values of (a,b,c). These can be computed by setting the
|
||||
* derivatives of the error E to zero (section 5.3).
|
||||
* 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 */
|
||||
vec_edge=Vec3r(-1*e->GetVec());
|
||||
vec_edge = Vec3r(-1 * e->GetVec());
|
||||
|
||||
ve2 = vec_edge.squareNorm();
|
||||
vdotN = vec_edge * N;
|
||||
|
||||
/* section 5.2 - There is a typo in the computation of kappa. The
|
||||
* edges should be x_j-x_i.
|
||||
*/
|
||||
/* 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 {
|
||||
if (angle_obtuse (v, f1)) {
|
||||
if (!triangle_obtuse(v, f1)) {
|
||||
weight += ve2 * cotan(f1->GetNextOEdge(e->twin())->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
|
||||
}
|
||||
else {
|
||||
if (angle_obtuse(v, f1)) {
|
||||
weight += ve2 * f1->getArea() / 4.0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
weight += ve2 * f1->getArea() / 8.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (! triangle_obtuse(v, f2)) {
|
||||
weight += ve2 *
|
||||
cotan (f2->GetNextOEdge(e)->GetbVertex(),
|
||||
e->GetaVertex(), e->GetbVertex()) / 8.0;
|
||||
} else {
|
||||
if (angle_obtuse (v, f2)) {
|
||||
if (!triangle_obtuse(v, f2)) {
|
||||
weight += ve2 * cotan (f2->GetNextOEdge(e)->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
|
||||
}
|
||||
else {
|
||||
if (angle_obtuse(v, f2)) {
|
||||
weight += ve2 * f1->getArea() / 4.0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
weight += ve2 * f1->getArea() / 8.0;
|
||||
}
|
||||
}
|
||||
@@ -441,13 +448,12 @@ void gts_vertex_principal_directions (WVertex * v,
|
||||
aterm_da += weight * d1 * d1 * d1 * d1;
|
||||
bterm_da += weight * d1 * d1 * 2 * d1 * d2;
|
||||
cterm_da += weight * d1 * d1 * d2 * d2;
|
||||
const_da += weight * d1 * d1 * (- kappa);
|
||||
const_da += weight * d1 * d1 * (-kappa);
|
||||
|
||||
aterm_db += weight * d1 * d2 * d1 * d1;
|
||||
bterm_db += weight * d1 * d2 * 2 * d1 * d2;
|
||||
cterm_db += weight * d1 * d2 * d2 * d2;
|
||||
const_db += weight * d1 * d2 * (- kappa);
|
||||
|
||||
const_db += weight * d1 * d2 * (-kappa);
|
||||
}
|
||||
|
||||
/* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */
|
||||
@@ -458,33 +464,28 @@ 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 {
|
||||
eigenvector(a, b, c, eig);
|
||||
}
|
||||
else {
|
||||
/* region of v is planar */
|
||||
eig[0] = 1.0;
|
||||
eig[1] = 0.0;
|
||||
}
|
||||
|
||||
/* Although the eigenvectors of B are good estimates of the
|
||||
* principal directions, it seems that which one is attached to
|
||||
* which curvature direction is a bit arbitrary. This may be a bug
|
||||
* in my implementation, or just a side-effect of the inaccuracy of
|
||||
* B due to the discrete nature of the sampling.
|
||||
/* 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);
|
||||
gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2);
|
||||
|
||||
err_e1 = err_e2 = 0.0;
|
||||
/* loop through the values previously saved */
|
||||
@@ -535,112 +536,107 @@ 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();
|
||||
real sine = (n1 ^ n2) * v / v.norm() ;
|
||||
if(sine >= 1.0) {
|
||||
return M_PI / 2.0 ;
|
||||
real sine = (n1 ^ n2) * v / v.norm();
|
||||
if (sine >= 1.0) {
|
||||
return M_PI / 2.0;
|
||||
}
|
||||
if(sine <= -1.0) {
|
||||
return -M_PI / 2.0 ;
|
||||
}
|
||||
return ::asin(sine) ;
|
||||
if (sine <= -1.0) {
|
||||
return -M_PI / 2.0;
|
||||
}
|
||||
return ::asin(sine);
|
||||
}
|
||||
|
||||
// precondition1: P is inside the sphere
|
||||
// precondition2: P,V points to the outside of
|
||||
// the sphere (i.e. OP.V > 0)
|
||||
static bool sphere_clip_vector(
|
||||
const Vec3r& O, real r,
|
||||
const Vec3r& P, Vec3r& V
|
||||
) {
|
||||
|
||||
Vec3r W = P - O ;
|
||||
real a = V.squareNorm() ;
|
||||
real b = 2.0 * V * W ;
|
||||
real c = W.squareNorm() - r*r ;
|
||||
real delta = b*b - 4*a*c ;
|
||||
if(delta < 0) {
|
||||
// precondition1: P is inside the sphere
|
||||
// precondition2: P,V points to the outside of the sphere (i.e. OP.V > 0)
|
||||
static bool sphere_clip_vector(const Vec3r& O, real r, const Vec3r& P, Vec3r& V)
|
||||
{
|
||||
Vec3r W = P - O;
|
||||
real a = V.squareNorm();
|
||||
real b = 2.0 * V * W;
|
||||
real c = W.squareNorm() - r * r;
|
||||
real delta = b * b - 4 * a * c;
|
||||
if (delta < 0) {
|
||||
// Should not happen, but happens sometimes (numerical precision)
|
||||
return true ;
|
||||
return true;
|
||||
}
|
||||
real t = - b + ::sqrt(delta) / (2.0 * a) ;
|
||||
if(t < 0.0) {
|
||||
real t = - b + ::sqrt(delta) / (2.0 * a);
|
||||
if (t < 0.0) {
|
||||
// Should not happen, but happens sometimes (numerical precision)
|
||||
return true ;
|
||||
return true;
|
||||
}
|
||||
if(t >= 1.0) {
|
||||
if (t >= 1.0) {
|
||||
// Inside the sphere
|
||||
return false ;
|
||||
return false;
|
||||
}
|
||||
|
||||
V[0] = (t * V.x()) ;
|
||||
V[1] = (t * V.y()) ;
|
||||
V[2] = (t * V.z()) ;
|
||||
V[0] = (t * V.x());
|
||||
V[1] = (t * V.y());
|
||||
V[2] = (t * V.z());
|
||||
|
||||
return true ;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: check optimizations:
|
||||
// use marking ? (measure *timings* ...)
|
||||
void compute_curvature_tensor(
|
||||
WVertex* start, real radius, NormalCycle& nc
|
||||
) {
|
||||
// TODO: check optimizations:
|
||||
// use marking ? (measure *timings* ...)
|
||||
void compute_curvature_tensor(WVertex *start, real radius, NormalCycle& nc)
|
||||
{
|
||||
// in case we have a non-manifold vertex, skip it...
|
||||
if(start->isBoundary())
|
||||
return;
|
||||
|
||||
std::set<WVertex*> vertices ;
|
||||
const Vec3r& O = start->GetVertex() ;
|
||||
std::stack<WVertex*> S ;
|
||||
S.push(start) ;
|
||||
vertices.insert(start) ;
|
||||
while(!S.empty()) {
|
||||
WVertex* v = S.top() ;
|
||||
S.pop() ;
|
||||
if(v->isBoundary())
|
||||
std::set<WVertex*> vertices;
|
||||
const Vec3r& O = start->GetVertex();
|
||||
std::stack<WVertex*> S;
|
||||
S.push(start);
|
||||
vertices.insert(start);
|
||||
while (!S.empty()) {
|
||||
WVertex *v = S.top();
|
||||
S.pop();
|
||||
if (v->isBoundary())
|
||||
continue;
|
||||
const Vec3r& P = v->GetVertex() ;
|
||||
const Vec3r& P = v->GetVertex();
|
||||
WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin();
|
||||
WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end();
|
||||
for(;woeit!=woeitend; ++woeit){
|
||||
for (; woeit != woeitend; ++woeit) {
|
||||
WOEdge *h = *woeit;
|
||||
if((v == start) || h->GetVec() * (O - P) > 0.0) {
|
||||
if ((v == start) || h->GetVec() * (O - P) > 0.0) {
|
||||
Vec3r V(-1 * h->GetVec());
|
||||
bool isect = sphere_clip_vector(O, radius, P, V) ;
|
||||
bool isect = sphere_clip_vector(O, radius, P, V);
|
||||
assert (h->GetOwner()->GetNumberOfOEdges() == 2); // Because otherwise v->isBoundary() would be true
|
||||
nc.accumulate_dihedral_angle(V, h->GetAngle()) ;
|
||||
nc.accumulate_dihedral_angle(V, h->GetAngle());
|
||||
|
||||
if(!isect) {
|
||||
WVertex* w = h->GetaVertex() ;
|
||||
if(vertices.find(w) == vertices.end()) {
|
||||
vertices.insert(w) ;
|
||||
S.push(w) ;
|
||||
}
|
||||
if (!isect) {
|
||||
WVertex *w = h->GetaVertex();
|
||||
if (vertices.find(w) == vertices.end()) {
|
||||
vertices.insert(w);
|
||||
S.push(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void compute_curvature_tensor_one_ring(
|
||||
WVertex* start, NormalCycle& nc
|
||||
) {
|
||||
void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc)
|
||||
{
|
||||
// in case we have a non-manifold vertex, skip it...
|
||||
if(start->isBoundary())
|
||||
if (start->isBoundary())
|
||||
return;
|
||||
|
||||
WVertex::incoming_edge_iterator woeit = start->incoming_edges_begin();
|
||||
WVertex::incoming_edge_iterator woeitend = start->incoming_edges_end();
|
||||
for(;woeit!=woeitend; ++woeit){
|
||||
for (; woeit != woeitend; ++woeit) {
|
||||
WOEdge *h = (*woeit)->twin();
|
||||
nc.accumulate_dihedral_angle(h->GetVec(), h->GetAngle()) ;
|
||||
nc.accumulate_dihedral_angle(h->GetVec(), h->GetAngle());
|
||||
WOEdge *hprev = h->getPrevOnFace();
|
||||
nc.accumulate_dihedral_angle(hprev->GetVec(), hprev->GetAngle()) ;
|
||||
nc.accumulate_dihedral_angle(hprev->GetVec(), hprev->GetAngle());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // OGF namespace
|
||||
|
||||
@@ -1,29 +1,59 @@
|
||||
|
||||
/* GTS - Library for the manipulation of triangulated surfaces
|
||||
* Copyright (C) 1999 Stéphane Popinet
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* This Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is:
|
||||
* GTS - Library for the manipulation of triangulated surfaces
|
||||
* Copyright (C) 1999 Stephane Popinet
|
||||
* and:
|
||||
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
|
||||
* Copyright (C) 2000-2003 Bruno Levy
|
||||
* Contact: Bruno Levy levy@loria.fr
|
||||
* ISA Project
|
||||
* LORIA, INRIA Lorraine,
|
||||
* Campus Scientifique, BP 239
|
||||
* 54506 VANDOEUVRE LES NANCY CEDEX
|
||||
* FRANCE
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __CURVATURE_H__
|
||||
#define __CURVATURE_H__
|
||||
#ifndef __FREESTYLE_CURVATURE_H__
|
||||
#define __FREESTYLE_CURVATURE_H__
|
||||
|
||||
/** \file blender/freestyle/intern/winged_edge/Curvature.h
|
||||
* \ingroup freestyle
|
||||
* \brief GTS - Library for the manipulation of triangulated surfaces
|
||||
* \author Stephane Popinet
|
||||
* \date 1999
|
||||
* \brief OGF/Graphite: Geometry and Graphics Programming Library + Utilities
|
||||
* \author Bruno Levy
|
||||
* \date 2000-2003
|
||||
*/
|
||||
|
||||
#include "../geometry/Geom.h"
|
||||
|
||||
#include "../system/FreestyleConfig.h"
|
||||
#include "../system/Precision.h"
|
||||
|
||||
# include "../system/FreestyleConfig.h"
|
||||
# include "../system/Precision.h"
|
||||
# include "../geometry/Geom.h"
|
||||
using namespace Geometry;
|
||||
|
||||
class WVertex;
|
||||
@@ -31,19 +61,19 @@ class WVertex;
|
||||
class LIB_WINGED_EDGE_EXPORT CurvatureInfo
|
||||
{
|
||||
public:
|
||||
|
||||
CurvatureInfo()
|
||||
{
|
||||
K1 = 0.0;
|
||||
K2 = 0.0;
|
||||
e1 = Vec3r(0.0,0.0,0.0);
|
||||
e2 = Vec3r(0.0,0.0,0.0);
|
||||
e1 = Vec3r(0.0, 0.0, 0.0);
|
||||
e2 = Vec3r(0.0, 0.0, 0.0);
|
||||
Kr = 0.0;
|
||||
dKr = 0.0;
|
||||
er = Vec3r(0.0,0.0,0.0);
|
||||
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(){
|
||||
for(vector<CurvatureInfo*>::iterator ci=vec_curvature_info.begin(), ciend=vec_curvature_info.end();
|
||||
ci!=ciend;
|
||||
++ci){
|
||||
|
||||
~Face_Curvature_Info()
|
||||
{
|
||||
for (vector<CurvatureInfo*>::iterator ci = vec_curvature_info.begin(), ciend = vec_curvature_info.end();
|
||||
ci != ciend;
|
||||
++ci)
|
||||
{
|
||||
delete (*ci);
|
||||
}
|
||||
vec_curvature_info.clear();
|
||||
}
|
||||
|
||||
vector<CurvatureInfo *> vec_curvature_info;
|
||||
};
|
||||
|
||||
bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal (WVertex * v,
|
||||
Vec3r &n);
|
||||
bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &n);
|
||||
|
||||
bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature (WVertex * v,
|
||||
real * Kg);
|
||||
bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature(WVertex *v, real *Kg);
|
||||
|
||||
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures (real Kh,
|
||||
real Kg,
|
||||
real * K1,
|
||||
real * K2);
|
||||
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2);
|
||||
|
||||
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions (WVertex * v,
|
||||
Vec3r Kh,
|
||||
real Kg,
|
||||
Vec3r &e1,
|
||||
Vec3r &e2);
|
||||
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2);
|
||||
|
||||
/*
|
||||
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
|
||||
* Copyright (C) 2000-2003 Bruno Levy
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* If you modify this software, you should include a notice giving the
|
||||
* name of the person performing the modification, the date of modification,
|
||||
* and the reason for such modification.
|
||||
*
|
||||
* Contact: Bruno Levy
|
||||
*
|
||||
* levy@loria.fr
|
||||
*
|
||||
* ISA Project
|
||||
* LORIA, INRIA Lorraine,
|
||||
* Campus Scientifique, BP 239
|
||||
* 54506 VANDOEUVRE LES NANCY CEDEX
|
||||
* FRANCE
|
||||
*
|
||||
* Note that the GNU General Public License does not permit incorporating
|
||||
* the Software into proprietary programs.
|
||||
*/
|
||||
namespace OGF {
|
||||
namespace OGF {
|
||||
|
||||
class NormalCycle ;
|
||||
class NormalCycle ;
|
||||
|
||||
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor(
|
||||
WVertex* start, double radius, NormalCycle& nc
|
||||
) ;
|
||||
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( WVertex *start, double radius, NormalCycle& nc);
|
||||
|
||||
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(
|
||||
WVertex* start, NormalCycle& nc
|
||||
) ;
|
||||
}
|
||||
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc);
|
||||
|
||||
} // OGF namespace
|
||||
|
||||
#endif /* __CURVATURE_H__ */
|
||||
|
||||
#endif /* __FREESTYLE_CURVATURE_H__ */
|
||||
|
||||
@@ -1,79 +1,79 @@
|
||||
//
|
||||
// Filename : Nature.h
|
||||
// Author(s) : Emmanuel Turquin
|
||||
// Purpose : Different natures for both vertices and edges
|
||||
// Date of creation : 01/07/2003
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef NATURE_H
|
||||
# define NATURE_H
|
||||
|
||||
/*! \file Nature.h
|
||||
* Definitions of Natures of the ViewMap's elements
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/*! Namespace gathering the different possible
|
||||
* natures of 0D and 1D elements of the ViewMap
|
||||
#ifndef __FREESTYLE_NATURE_H__
|
||||
#define __FREESTYLE_NATURE_H__
|
||||
|
||||
/** \file blender/freestyle/intern/winged_edge/Nature.h
|
||||
* \ingroup freestyle
|
||||
* \brief Different natures for both vertices and edges
|
||||
* \author Emmanuel Turquin
|
||||
* \date 01/07/2003
|
||||
*/
|
||||
|
||||
/*! Namespace gathering the different possible natures of 0D and 1D elements of the ViewMap */
|
||||
namespace Nature {
|
||||
|
||||
typedef unsigned short VertexNature;
|
||||
/* XXX Why not using enums??? */
|
||||
|
||||
/*! true for any 0D element */
|
||||
static const VertexNature POINT = 0; // 0
|
||||
/*! true for SVertex */
|
||||
static const VertexNature S_VERTEX = (1 << 0); // 1
|
||||
/*! true for ViewVertex */
|
||||
static const VertexNature VIEW_VERTEX = (1 << 1); // 2
|
||||
/*! true for NonTVertex */
|
||||
static const VertexNature NON_T_VERTEX = (1 << 2); // 4
|
||||
/*! true for TVertex */
|
||||
static const VertexNature T_VERTEX = (1 << 3); // 8
|
||||
/*! true for CUSP */
|
||||
static const VertexNature CUSP = (1 << 4); // 16
|
||||
typedef unsigned short VertexNature;
|
||||
/*! true for any 0D element */
|
||||
static const VertexNature POINT = 0; // 0
|
||||
/*! true for SVertex */
|
||||
static const VertexNature S_VERTEX = (1 << 0); // 1
|
||||
/*! true for ViewVertex */
|
||||
static const VertexNature VIEW_VERTEX = (1 << 1); // 2
|
||||
/*! true for NonTVertex */
|
||||
static const VertexNature NON_T_VERTEX = (1 << 2); // 4
|
||||
/*! true for TVertex */
|
||||
static const VertexNature T_VERTEX = (1 << 3); // 8
|
||||
/*! true for CUSP */
|
||||
static const VertexNature CUSP = (1 << 4); // 16
|
||||
|
||||
typedef unsigned short EdgeNature;
|
||||
/*! true for non feature edges (always false for 1D elements of the ViewMap) */
|
||||
static const EdgeNature NO_FEATURE = 0; // 0
|
||||
/*! true for silhouettes */
|
||||
static const EdgeNature SILHOUETTE = (1 << 0); // 1
|
||||
/*! true for borders */
|
||||
static const EdgeNature BORDER = (1 << 1); // 2
|
||||
/*! true for creases */
|
||||
static const EdgeNature CREASE = (1 << 2); // 4
|
||||
/*! true for ridges */
|
||||
static const EdgeNature RIDGE = (1 << 3); // 8
|
||||
/*! true for valleys */
|
||||
static const EdgeNature VALLEY = (1 << 4); // 16
|
||||
/*! true for suggestive contours */
|
||||
static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32
|
||||
/*! true for material boundaries */
|
||||
static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64
|
||||
/*! true for user-defined edge marks */
|
||||
static const EdgeNature EDGE_MARK = (1 << 7); // 128
|
||||
typedef unsigned short EdgeNature;
|
||||
/*! true for non feature edges (always false for 1D elements of the ViewMap) */
|
||||
static const EdgeNature NO_FEATURE = 0; // 0
|
||||
/*! true for silhouettes */
|
||||
static const EdgeNature SILHOUETTE = (1 << 0); // 1
|
||||
/*! true for borders */
|
||||
static const EdgeNature BORDER = (1 << 1); // 2
|
||||
/*! true for creases */
|
||||
static const EdgeNature CREASE = (1 << 2); // 4
|
||||
/*! true for ridges */
|
||||
static const EdgeNature RIDGE = (1 << 3); // 8
|
||||
/*! true for valleys */
|
||||
static const EdgeNature VALLEY = (1 << 4); // 16
|
||||
/*! true for suggestive contours */
|
||||
static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32
|
||||
/*! true for material boundaries */
|
||||
static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64
|
||||
/*! true for user-defined edge marks */
|
||||
static const EdgeNature EDGE_MARK = (1 << 7); // 128
|
||||
|
||||
} // end of namespace Nature
|
||||
|
||||
#endif // NATURE_H
|
||||
#endif // __FREESTYLE_NATURE_H__
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -67,106 +81,119 @@ WVertex::WVertex(WVertex& iBrother)
|
||||
_Border = iBrother._Border;
|
||||
userdata = NULL;
|
||||
iBrother.userdata = new vertexdata;
|
||||
((vertexdata*)(iBrother.userdata))->_copy = this;
|
||||
((vertexdata *)(iBrother.userdata))->_copy = this;
|
||||
}
|
||||
|
||||
WVertex* WVertex::duplicate()
|
||||
WVertex *WVertex::duplicate()
|
||||
{
|
||||
WVertex *clone = new WVertex(*this);
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
WOEdge* WVertex::incoming_edge_iterator::operator*()
|
||||
|
||||
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){
|
||||
if (!twin) {
|
||||
// we reached a hole
|
||||
_current = 0;
|
||||
return;
|
||||
}
|
||||
WOEdge *next = twin->getPrevOnFace();
|
||||
if(next == _begin){
|
||||
next = 0;
|
||||
if (next == _begin) {
|
||||
next = NULL;
|
||||
}
|
||||
_current = next;
|
||||
}
|
||||
|
||||
WFace* WVertex::face_iterator::operator*(){
|
||||
WOEdge * woedge = *_edge_it;
|
||||
if(woedge == 0)
|
||||
return 0;
|
||||
WFace *WVertex::face_iterator::operator*()
|
||||
{
|
||||
WOEdge *woedge = *_edge_it;
|
||||
if (!woedge)
|
||||
return NULL;
|
||||
return (woedge)->GetbFace();
|
||||
}
|
||||
|
||||
//bool WVertex::isBoundary () const{
|
||||
// return _Border;
|
||||
//}
|
||||
#if 0
|
||||
bool WVertex::isBoundary () const
|
||||
{
|
||||
return _Border;
|
||||
}
|
||||
#endif
|
||||
bool WVertex::isBoundary ()
|
||||
{
|
||||
if(_Border == 1)
|
||||
if (_Border == 1)
|
||||
return true;
|
||||
else if(_Border == 0)
|
||||
else if (_Border == 0)
|
||||
return false;
|
||||
|
||||
vector<WEdge *>::const_iterator it;
|
||||
for(it=_EdgeList.begin(); it!=_EdgeList.end(); it++){
|
||||
if((*it)->GetNumberOfOEdges() == 1){
|
||||
for (it = _EdgeList.begin(); it != _EdgeList.end(); it++) {
|
||||
if ((*it)->GetNumberOfOEdges() == 1) {
|
||||
_Border = 1;
|
||||
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();
|
||||
if(aOEdge->GetbVertex() == this)
|
||||
WEdge *wedge = _EdgeList.front();
|
||||
WOEdge *aOEdge = wedge->GetaOEdge();
|
||||
if (aOEdge->GetbVertex() == this)
|
||||
begin = aOEdge;
|
||||
else
|
||||
begin = _EdgeList.front()->GetbOEdge();
|
||||
return incoming_edge_iterator(this, begin, begin);
|
||||
}
|
||||
WVertex::incoming_edge_iterator WVertex::incoming_edges_end(){
|
||||
|
||||
WVertex::incoming_edge_iterator WVertex::incoming_edges_end()
|
||||
{
|
||||
WOEdge *begin;
|
||||
WOEdge* aOEdge = _EdgeList.front()->GetaOEdge();
|
||||
if(aOEdge->GetbVertex() == this)
|
||||
WOEdge *aOEdge = _EdgeList.front()->GetaOEdge();
|
||||
if (aOEdge->GetbVertex() == this)
|
||||
begin = aOEdge;
|
||||
else
|
||||
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)
|
||||
{
|
||||
@@ -177,42 +204,40 @@ WOEdge::WOEdge(WOEdge& iBrother)
|
||||
_pOwner = iBrother.GetOwner();
|
||||
userdata = NULL;
|
||||
iBrother.userdata = new oedgedata;
|
||||
((oedgedata*)(iBrother.userdata))->_copy = this;
|
||||
((oedgedata *)(iBrother.userdata))->_copy = this;
|
||||
|
||||
_vec = iBrother._vec;
|
||||
_angle = iBrother._angle;
|
||||
}
|
||||
|
||||
WOEdge * WOEdge::duplicate()
|
||||
WOEdge *WOEdge::duplicate()
|
||||
{
|
||||
WOEdge *clone = new WOEdge(*this);
|
||||
return clone;
|
||||
}
|
||||
|
||||
Vec3r
|
||||
WOEdge::getVec3r ()
|
||||
Vec3r WOEdge::getVec3r ()
|
||||
{
|
||||
return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex());
|
||||
}
|
||||
|
||||
WOEdge * WOEdge::twin ()
|
||||
WOEdge *WOEdge::twin ()
|
||||
{
|
||||
return GetOwner()->GetOtherOEdge(this);
|
||||
}
|
||||
|
||||
WOEdge *
|
||||
WOEdge::getPrevOnFace()
|
||||
WOEdge *WOEdge::getPrevOnFace()
|
||||
{
|
||||
return _pbFace->GetPrevOEdge(this);
|
||||
}
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* WEdge */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
/**********************************
|
||||
* *
|
||||
* *
|
||||
* WEdge *
|
||||
* *
|
||||
* *
|
||||
**********************************/
|
||||
|
||||
WEdge::WEdge(WEdge& iBrother)
|
||||
{
|
||||
@@ -222,33 +247,32 @@ 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();
|
||||
|
||||
_nOEdges = iBrother.GetNumberOfOEdges();
|
||||
_Id = iBrother.GetId();
|
||||
iBrother.userdata = new edgedata;
|
||||
((edgedata*)(iBrother.userdata))->_copy = this;
|
||||
((edgedata *)(iBrother.userdata))->_copy = this;
|
||||
}
|
||||
|
||||
WEdge * WEdge::duplicate()
|
||||
WEdge *WEdge::duplicate()
|
||||
{
|
||||
WEdge *clone = new WEdge(*this);
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* WFace */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
|
||||
/**********************************
|
||||
* *
|
||||
* *
|
||||
* WFace *
|
||||
* *
|
||||
* *
|
||||
**********************************/
|
||||
|
||||
WFace::WFace(WFace& iBrother)
|
||||
{
|
||||
@@ -261,36 +285,30 @@ WFace::WFace(WFace& iBrother)
|
||||
_Mark = iBrother._Mark;
|
||||
userdata = NULL;
|
||||
iBrother.userdata = new facedata;
|
||||
((facedata*)(iBrother.userdata))->_copy = this;
|
||||
((facedata *)(iBrother.userdata))->_copy = this;
|
||||
}
|
||||
|
||||
WFace * WFace::duplicate()
|
||||
WFace *WFace::duplicate()
|
||||
{
|
||||
WFace * clone = new WFace(*this);
|
||||
WFace *clone = new WFace(*this);
|
||||
return clone;
|
||||
}
|
||||
|
||||
const FrsMaterial& WFace::frs_material() {
|
||||
const FrsMaterial& WFace::frs_material()
|
||||
{
|
||||
return getShape()->frs_material(_FrsMaterialIndex);
|
||||
}
|
||||
|
||||
WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
||||
WOEdge *WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
||||
{
|
||||
// First check whether the same oriented edge already exists
|
||||
// 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++)
|
||||
{
|
||||
|
||||
WEdge *we=(*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 ((*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);
|
||||
@@ -379,11 +386,11 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
||||
pOEdge->setbVertex(v2);
|
||||
|
||||
// Debug:
|
||||
if(v1->GetId() == v2->GetId())
|
||||
if (v1->GetId() == v2->GetId())
|
||||
cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl;
|
||||
|
||||
edge->AddOEdge(pOEdge);
|
||||
//edge->setNumberOfOEdges(edge->GetNumberOfOEdges()+1);
|
||||
//edge->setNumberOfOEdges(edge->GetNumberOfOEdges() + 1);
|
||||
|
||||
// Add this face (the b face)
|
||||
pOEdge->setbFace(this);
|
||||
@@ -395,82 +402,83 @@ 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;
|
||||
e=NULL;
|
||||
for(it=_OEdgeList.begin(); it!=_OEdgeList.end(); it++)
|
||||
if (((*it)->GetaVertex()!=v) && ((*it)->GetbVertex()!=v)) e=*it;
|
||||
if (!e) return false;
|
||||
else return true;
|
||||
e = NULL;
|
||||
for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) {
|
||||
if ((*it)->GetaVertex() == v)
|
||||
e = *it;
|
||||
}
|
||||
if (!e)
|
||||
return false;
|
||||
e = NULL;
|
||||
for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) {
|
||||
if (((*it)->GetaVertex() != v) && ((*it)->GetbVertex() != v))
|
||||
e = *it;
|
||||
}
|
||||
if (!e)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
real
|
||||
WFace::getArea ()
|
||||
real WFace::getArea ()
|
||||
{
|
||||
vector<WOEdge *>::iterator it;
|
||||
Vec3r origin=(*(_OEdgeList.begin()))->GetaVertex()->GetVertex();
|
||||
it=_OEdgeList.begin();
|
||||
real a=0;
|
||||
for (it=it++; it!=_OEdgeList.end(); it++) {
|
||||
Vec3r v1=Vec3r((*it)->GetaVertex()->GetVertex() - origin);
|
||||
Vec3r v2=Vec3r((*it)->GetbVertex()->GetVertex() - origin);
|
||||
Vec3r origin = (*(_OEdgeList.begin()))->GetaVertex()->GetVertex();
|
||||
it = _OEdgeList.begin();
|
||||
real a = 0;
|
||||
for (it = it++; it != _OEdgeList.end(); it++) {
|
||||
Vec3r v1 = Vec3r((*it)->GetaVertex()->GetVertex() - origin);
|
||||
Vec3r v2 = Vec3r((*it)->GetbVertex()->GetVertex() - origin);
|
||||
a += (v1 ^ v2).norm() / 2.0;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
WOEdge*
|
||||
WFace::GetPrevOEdge(WOEdge* iOEdge)
|
||||
{
|
||||
vector<WOEdge*>::iterator woe,woend, woefirst;
|
||||
WOEdge *WFace::GetPrevOEdge(WOEdge* iOEdge)
|
||||
{
|
||||
vector<WOEdge *>::iterator woe, woend, woefirst;
|
||||
woefirst = _OEdgeList.begin();
|
||||
woend=_OEdgeList.end();
|
||||
WOEdge *prev =*woefirst;
|
||||
woe=woefirst;
|
||||
woe++;
|
||||
for(;
|
||||
woe!=woend;
|
||||
woe++)
|
||||
{
|
||||
if((*woe) == iOEdge)
|
||||
woend = _OEdgeList.end();
|
||||
WOEdge *prev = *woefirst;
|
||||
woe = woefirst;
|
||||
++woe;
|
||||
for (; woe != woend; woe++) {
|
||||
if ((*woe) == iOEdge)
|
||||
return prev;
|
||||
prev= *woe;
|
||||
prev = *woe;
|
||||
}
|
||||
// We left the loop. That means that the first
|
||||
// OEdge was the good one:
|
||||
if((*woefirst)==iOEdge)
|
||||
// We left the loop. That means that the first OEdge was the good one:
|
||||
if ((*woefirst) == iOEdge)
|
||||
return prev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
WShape * WFace::getShape()
|
||||
WShape *WFace::getShape()
|
||||
{
|
||||
return GetVertex(0)->shape();
|
||||
}
|
||||
|
||||
/**********************************/
|
||||
/* */
|
||||
/* */
|
||||
/* WShape */
|
||||
/* */
|
||||
/* */
|
||||
/**********************************/
|
||||
|
||||
/**********************************
|
||||
* *
|
||||
* *
|
||||
* WShape *
|
||||
* *
|
||||
* *
|
||||
**********************************/
|
||||
|
||||
LIB_WINGED_EDGE_EXPORT
|
||||
unsigned WShape::_SceneCurrentId = 0;
|
||||
|
||||
WShape * WShape::duplicate()
|
||||
WShape *WShape::duplicate()
|
||||
{
|
||||
WShape *clone = new WShape(*this);
|
||||
return clone;
|
||||
@@ -483,12 +491,9 @@ WShape::WShape(WShape& iBrother)
|
||||
_FrsMaterials = iBrother._FrsMaterials;
|
||||
_meanEdgeSize = iBrother._meanEdgeSize;
|
||||
iBrother.bbox(_min, _max);
|
||||
vector<WVertex*>& vertexList = iBrother.getVertexList();
|
||||
vector<WVertex*>::iterator v=vertexList.begin(), vend=vertexList.end();
|
||||
for(;
|
||||
v!=vend;
|
||||
v++)
|
||||
{
|
||||
vector<WVertex *>& vertexList = iBrother.getVertexList();
|
||||
vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end();
|
||||
for (; v != vend; ++v) {
|
||||
//WVertex *newVertex = new WVertex(*(*v));
|
||||
WVertex *newVertex = (*v)->duplicate();
|
||||
|
||||
@@ -496,90 +501,72 @@ WShape::WShape(WShape& iBrother)
|
||||
AddVertex(newVertex);
|
||||
}
|
||||
|
||||
vector<WEdge*>& edgeList = iBrother.getEdgeList();
|
||||
vector<WEdge*>::iterator e=edgeList.begin(), eend=edgeList.end();
|
||||
for(;
|
||||
e!=eend;
|
||||
e++)
|
||||
{
|
||||
vector<WEdge *>& edgeList = iBrother.getEdgeList();
|
||||
vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end();
|
||||
for (; e != eend; ++e) {
|
||||
//WEdge *newEdge = new WEdge(*(*e));
|
||||
WEdge *newEdge = (*e)->duplicate();
|
||||
AddEdge(newEdge);
|
||||
}
|
||||
|
||||
vector<WFace*>& faceList = iBrother.GetFaceList();
|
||||
vector<WFace*>::iterator f=faceList.begin(), fend=faceList.end();
|
||||
for(;
|
||||
f!=fend;
|
||||
f++)
|
||||
{
|
||||
vector<WFace *>& faceList = iBrother.GetFaceList();
|
||||
vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end();
|
||||
for (; f != fend; ++f) {
|
||||
//WFace *newFace = new WFace(*(*f));
|
||||
WFace *newFace = (*f)->duplicate();
|
||||
AddFace(newFace);
|
||||
}
|
||||
|
||||
// update all pointed addresses thanks to the newly created objects:
|
||||
vend=_VertexList.end();
|
||||
for(v=_VertexList.begin();
|
||||
v!=vend;
|
||||
v++)
|
||||
{
|
||||
const vector<WEdge*>& vedgeList = (*v)->GetEdges();
|
||||
vector<WEdge*> newvedgelist;
|
||||
vend = _VertexList.end();
|
||||
for (v = _VertexList.begin(); v != vend; ++v) {
|
||||
const vector<WEdge *>& vedgeList = (*v)->GetEdges();
|
||||
vector<WEdge *> newvedgelist;
|
||||
unsigned int i;
|
||||
for(i=0; i<vedgeList.size(); i++)
|
||||
{
|
||||
for (i = 0; i < vedgeList.size(); i++) {
|
||||
WEdge *current = vedgeList[i];
|
||||
edgedata * currentvedata = (edgedata*)current->userdata;
|
||||
edgedata *currentvedata = (edgedata *)current->userdata;
|
||||
newvedgelist.push_back(currentvedata->_copy);
|
||||
}
|
||||
(*v)->setEdges(newvedgelist);
|
||||
}
|
||||
|
||||
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())
|
||||
aoEdge->setaFace(((facedata*)(aoEdge->GetaFace()->userdata))->_copy);
|
||||
aoEdge->setbFace(((facedata*)(aoEdge->GetbFace()->userdata))->_copy);
|
||||
aoEdge->setOwner(((edgedata*)(aoEdge->GetOwner()->userdata))->_copy);
|
||||
// update bOedge:
|
||||
aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy);
|
||||
aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy);
|
||||
if (aoEdge->GetaFace())
|
||||
aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy);
|
||||
aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy);
|
||||
aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy);
|
||||
|
||||
// update bOedge:
|
||||
WOEdge *boEdge = (*e)->GetbOEdge();
|
||||
if(boEdge != 0)
|
||||
{
|
||||
boEdge->setaVertex(((vertexdata*)(boEdge->GetaVertex()->userdata))->_copy);
|
||||
boEdge->setbVertex(((vertexdata*)(boEdge->GetbVertex()->userdata))->_copy);
|
||||
if(NULL != boEdge->GetaFace())
|
||||
boEdge->setaFace(((facedata*)(boEdge->GetaFace()->userdata))->_copy);
|
||||
boEdge->setbFace(((facedata*)(boEdge->GetbFace()->userdata))->_copy);
|
||||
boEdge->setOwner(((edgedata*)(boEdge->GetOwner()->userdata))->_copy);
|
||||
if (boEdge) {
|
||||
boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy);
|
||||
boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy);
|
||||
if (boEdge->GetaFace())
|
||||
boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy);
|
||||
boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy);
|
||||
boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy);
|
||||
}
|
||||
}
|
||||
|
||||
fend = _FaceList.end();
|
||||
for(f=_FaceList.begin();
|
||||
f!=fend;
|
||||
f++)
|
||||
{
|
||||
unsigned i;
|
||||
const vector<WOEdge*>& oedgeList = (*f)->getEdgeList();
|
||||
vector<WOEdge*> newoedgelist;
|
||||
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;
|
||||
oedgedata *currentoedata = (oedgedata *)current->userdata;
|
||||
newoedgelist.push_back(currentoedata->_copy);
|
||||
//oedgeList[i] = currentoedata->_copy;
|
||||
//oedgeList[i] = ((oedgedata*)(oedgeList[i]->userdata))->_copy;
|
||||
//oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy;
|
||||
}
|
||||
(*f)->setEdgeList(newoedgelist);
|
||||
}
|
||||
@@ -587,65 +574,54 @@ WShape::WShape(WShape& iBrother)
|
||||
// Free all memory (arghh!)
|
||||
// Vertex
|
||||
vend = iBrother.getVertexList().end();
|
||||
for(v=iBrother.getVertexList().begin();
|
||||
v!=vend;
|
||||
v++)
|
||||
{
|
||||
delete (vertexdata*)((*v)->userdata);
|
||||
for (v = iBrother.getVertexList().begin(); v != vend; ++v) {
|
||||
delete (vertexdata *)((*v)->userdata);
|
||||
(*v)->userdata = NULL;
|
||||
}
|
||||
|
||||
// Edges and OEdges:
|
||||
eend = iBrother.getEdgeList().end();
|
||||
for(e=iBrother.getEdgeList().begin();
|
||||
e!=eend;
|
||||
e++)
|
||||
{
|
||||
delete (edgedata*)((*e)->userdata);
|
||||
for (e = iBrother.getEdgeList().begin(); e != eend; ++e) {
|
||||
delete (edgedata *)((*e)->userdata);
|
||||
(*e)->userdata = NULL;
|
||||
// OEdge a :
|
||||
delete (oedgedata*)((*e)->GetaOEdge()->userdata);
|
||||
// OEdge a:
|
||||
delete (oedgedata *)((*e)->GetaOEdge()->userdata);
|
||||
(*e)->GetaOEdge()->userdata = NULL;
|
||||
// OEdge b:
|
||||
WOEdge* oedgeb = (*e)->GetbOEdge();
|
||||
if(NULL != oedgeb)
|
||||
{
|
||||
delete (oedgedata*)(oedgeb->userdata);
|
||||
WOEdge *oedgeb = (*e)->GetbOEdge();
|
||||
if (oedgeb) {
|
||||
delete (oedgedata *)(oedgeb->userdata);
|
||||
oedgeb->userdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Faces
|
||||
fend = iBrother.GetFaceList().end();
|
||||
for(f=iBrother.GetFaceList().begin();
|
||||
f!=fend;
|
||||
f++)
|
||||
{
|
||||
delete (facedata*)((*f)->userdata);
|
||||
for (f = iBrother.GetFaceList().begin(); f != fend; ++f) {
|
||||
delete (facedata *)((*f)->userdata);
|
||||
(*f)->userdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
|
||||
WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
|
||||
{
|
||||
// allocate the new face
|
||||
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,26 +642,16 @@ 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;
|
||||
vector<WVertex *>::iterator it;
|
||||
|
||||
// compute the face normal (v1v2 ^ v1v3)
|
||||
WVertex *v1, *v2, *v3;
|
||||
@@ -696,8 +662,8 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
|
||||
it++;
|
||||
v3 = *it;
|
||||
|
||||
Vec3r vector1(v2->GetVertex()-v1->GetVertex());
|
||||
Vec3r vector2(v3->GetVertex()-v1->GetVertex());
|
||||
Vec3r vector1(v2->GetVertex() - v1->GetVertex());
|
||||
Vec3r vector2(v3->GetVertex() - v1->GetVertex());
|
||||
|
||||
Vec3r normal(vector1 ^ vector2);
|
||||
normal.normalize();
|
||||
@@ -708,32 +674,27 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
|
||||
mit++;
|
||||
|
||||
// vertex pointers used to build each edge
|
||||
vector<WVertex*>::iterator va, vb;
|
||||
vector<WVertex *>::iterator va, vb;
|
||||
|
||||
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);
|
||||
|
||||
WOEdge * oedge;
|
||||
if(*va == iVertexList.back())
|
||||
WOEdge *oedge;
|
||||
if (*va == iVertexList.back())
|
||||
oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge
|
||||
else
|
||||
oedge = face->MakeEdge(*va, *vb);
|
||||
|
||||
|
||||
if(oedge == 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
@@ -1,56 +1,64 @@
|
||||
/*
|
||||
* ***** 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;
|
||||
|
||||
vector<WShape*> wshapes = _winged_edge->getWShapes();
|
||||
vector<WVertex*> fvertices;
|
||||
vector<WShape *> wshapes = _winged_edge->getWShapes();
|
||||
vector<WVertex *> fvertices;
|
||||
vector<Vec3r> vectors;
|
||||
vector<WFace*> faces;
|
||||
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);
|
||||
occluder->userdata = (void *)(*f);
|
||||
_grid->insertOccluder(occluder);
|
||||
vectors.clear();
|
||||
fvertices.clear();
|
||||
|
||||
@@ -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"
|
||||
#include "../geometry/Grid.h"
|
||||
#include "../geometry/Polygon.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;
|
||||
Grid *_grid;
|
||||
WingedEdge *_winged_edge;
|
||||
unsigned _polygon_id;
|
||||
};
|
||||
|
||||
#endif // WS_FILL_GRID_H
|
||||
#endif // __FREESTYLE_W_FILL_GRID_H__
|
||||
@@ -1,56 +1,63 @@
|
||||
/*
|
||||
* ***** 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;
|
||||
|
||||
vector<WShape*> wshapes = _winged_edge->getWShapes();
|
||||
vector<WVertex*> fvertices;
|
||||
vector<WShape *> wshapes = _winged_edge->getWShapes();
|
||||
vector<WVertex *> fvertices;
|
||||
vector<Vec3r> vectors;
|
||||
vector<WFace*> faces;
|
||||
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);
|
||||
occluder->userdata = (void *)(*f);
|
||||
_grid->insertOccluder(occluder);
|
||||
vectors.clear();
|
||||
fvertices.clear();
|
||||
|
||||
@@ -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"
|
||||
#include "../geometry/Grid.h"
|
||||
#include "../geometry/Polygon.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;
|
||||
Grid *_grid;
|
||||
WingedEdge *_winged_edge;
|
||||
unsigned _polygon_id;
|
||||
};
|
||||
|
||||
#endif // WS_FILL_GRID_H
|
||||
#endif // __FREESTYLE_WS_FILL_GRID_H__
|
||||
@@ -1,69 +1,86 @@
|
||||
//
|
||||
// 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){
|
||||
if(_DotP[i] == 0){
|
||||
for (i = 0; i < nEdges; ++i) {
|
||||
if (_DotP[i] == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
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){
|
||||
if((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)){
|
||||
for (i = 0; i < nEdges; ++i) {
|
||||
if ((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){
|
||||
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges)
|
||||
{
|
||||
int i = 0;
|
||||
int nEdges = _pWXFace->numberOfEdges();
|
||||
for(i=0; i<nEdges; ++i){
|
||||
if(_DotP[i]*_DotP[(i+1)%nEdges] < 0){
|
||||
for (i = 0; i < nEdges; ++i) {
|
||||
if (_DotP[i] * _DotP[(i + 1) % nEdges] < 0) {
|
||||
// we got one
|
||||
oCuspEdges.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
|
||||
// if the smooth edge has already been
|
||||
// built: exit
|
||||
if(0 != _pSmoothEdge)
|
||||
WXSmoothEdge *WXFaceLayer::BuildSmoothEdge()
|
||||
{
|
||||
// if the smooth edge has already been built: exit
|
||||
if (_pSmoothEdge)
|
||||
return _pSmoothEdge;
|
||||
real ta, tb;
|
||||
WOEdge *woea(0), *woeb(0);
|
||||
@@ -71,33 +88,30 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
|
||||
vector<int> cuspEdgesIndices;
|
||||
int indexStart, indexEnd;
|
||||
unsigned nedges = _pWXFace->numberOfEdges();
|
||||
if(_nNullDotP == nedges){
|
||||
_pSmoothEdge = 0;
|
||||
if (_nNullDotP == nedges) {
|
||||
_pSmoothEdge = NULL;
|
||||
return _pSmoothEdge;
|
||||
}
|
||||
if((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)){
|
||||
// that means that we have a smooth edge that starts from
|
||||
// an edge and ends at an edge
|
||||
if ((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)) {
|
||||
// that means that we have a smooth edge that starts from an edge and ends at an edge
|
||||
//-----------------------------
|
||||
// We retrieve the 2 edges for which we have
|
||||
// opposite signs for each extremity
|
||||
// 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
|
||||
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){
|
||||
if (_DotP[cuspEdgesIndices[0]] > 0) {
|
||||
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
||||
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];
|
||||
@@ -105,70 +119,73 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
|
||||
}
|
||||
|
||||
// Compute the interpolation:
|
||||
ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]);
|
||||
tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]);
|
||||
ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
|
||||
tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
|
||||
ok = true;
|
||||
}else if(_nNullDotP == 1){
|
||||
// that means that we have exactly one of the
|
||||
// 2 extremities of our silhouette edge is
|
||||
// a vertex of the mesh
|
||||
if((_nPosDotP == 2) || (_nPosDotP == 0)){
|
||||
_pSmoothEdge = 0;
|
||||
}
|
||||
else if (_nNullDotP == 1) {
|
||||
// that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex of the mesh
|
||||
if ((_nPosDotP == 2) || (_nPosDotP == 0)) {
|
||||
_pSmoothEdge = NULL;
|
||||
return _pSmoothEdge;
|
||||
}
|
||||
RetrieveCuspEdgesIndices(cuspEdgesIndices);
|
||||
// We should have only one EdgeCusp:
|
||||
if(cuspEdgesIndices.size() != 1){
|
||||
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();
|
||||
if(_DotP[cuspEdgesIndices[0]] > 0){
|
||||
if (_DotP[cuspEdgesIndices[0]] > 0) {
|
||||
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
||||
woeb = _pWXFace->GetOEdge(index0);
|
||||
indexStart = cuspEdgesIndices[0];
|
||||
ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]);
|
||||
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];
|
||||
ta = 0.0;
|
||||
tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]);
|
||||
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 ?
|
||||
if (!_pWXFace->front()) { // is it in the right order ?
|
||||
// the order of the WOEdge index is wrong
|
||||
woea = _pWXFace->GetOEdge((index+1)%nedges);
|
||||
woeb = _pWXFace->GetOEdge((index-1)%nedges);
|
||||
woea = _pWXFace->GetOEdge((index + 1) % nedges);
|
||||
woeb = _pWXFace->GetOEdge((index - 1) % nedges);
|
||||
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){
|
||||
if (ok) {
|
||||
_pSmoothEdge = new WXSmoothEdge;
|
||||
_pSmoothEdge->setWOeA(woea);
|
||||
_pSmoothEdge->setWOeB(woeb);
|
||||
_pSmoothEdge->setTa(ta);
|
||||
_pSmoothEdge->setTb(tb);
|
||||
if(_Nature & Nature::SILHOUETTE){
|
||||
if(_nNullDotP != 2){
|
||||
if(_DotP[_ClosestPointIndex] + 0.01 > 0)
|
||||
if (_Nature & Nature::SILHOUETTE) {
|
||||
if (_nNullDotP != 2) {
|
||||
if (_DotP[_ClosestPointIndex] + 0.01 > 0)
|
||||
_pSmoothEdge->setFront(true);
|
||||
else
|
||||
_pSmoothEdge->setFront(false);
|
||||
@@ -176,121 +193,106 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
void WXFace::ComputeCenter()
|
||||
{
|
||||
vector<WVertex*> iVertexList;
|
||||
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 *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();
|
||||
((WXFace*)face)->setCenter(center);
|
||||
((WXFace *)face)->setCenter(center);
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
|
||||
WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
|
||||
vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
|
||||
{
|
||||
WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
|
||||
|
||||
// Vec3r center;
|
||||
// for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
|
||||
// wv!=wvend;
|
||||
// wv++)
|
||||
// {
|
||||
// center += (*wv)->GetVertex();
|
||||
// }
|
||||
// center /= (real)iVertexList.size();
|
||||
// ((WSFace*)face)->setCenter(center);
|
||||
#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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1,39 +1,44 @@
|
||||
#ifndef WXEDGEBUILDER_H
|
||||
# define WXEDGEBUILDER_H
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
//
|
||||
// Filename : WSBuilder.h
|
||||
// Author(s) : Stephane Grabli
|
||||
// Purpose : Class inherited from WingedEdgeBuilder and
|
||||
// designed to build a WX (WingedEdge + extended info(silhouette etc...))
|
||||
// structure from a polygonal model
|
||||
// Date of creation : 28/05/03
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef __FREESTYLE_WX_EDGE_BUILDER_H__
|
||||
#define __FREESTYLE_WX_EDGE_BUILDER_H__
|
||||
|
||||
/** \file blender/freestyle/intern/winged_edge/WSBuilder.h
|
||||
* \ingroup freestyle
|
||||
* \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info
|
||||
* (silhouette etc...)) structure from a polygonal model
|
||||
* \author Stephane Grabli
|
||||
* \date 28/05/2003
|
||||
*/
|
||||
|
||||
//
|
||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
||||
// with this source distribution.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include "WingedEdgeBuilder.h"
|
||||
|
||||
# include "WingedEdgeBuilder.h"
|
||||
# include "../scene_graph/IndexedFaceSet.h"
|
||||
#include "../scene_graph/IndexedFaceSet.h"
|
||||
|
||||
class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder
|
||||
{
|
||||
@@ -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__
|
||||
@@ -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,13 +53,15 @@ 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) {
|
||||
if(!_current_matrix) {
|
||||
void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn)
|
||||
{
|
||||
if (!_current_matrix) {
|
||||
_current_matrix = new Matrix44r(tn.matrix());
|
||||
return;
|
||||
}
|
||||
@@ -50,11 +71,12 @@ void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) {
|
||||
_current_matrix = new_matrix;
|
||||
}
|
||||
|
||||
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) {
|
||||
if(_current_matrix)
|
||||
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&)
|
||||
{
|
||||
if (_current_matrix)
|
||||
delete _current_matrix;
|
||||
|
||||
if(_matrices_stack.empty()) {
|
||||
if (_matrices_stack.empty()) {
|
||||
_current_matrix = NULL;
|
||||
return;
|
||||
}
|
||||
@@ -63,23 +85,24 @@ 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();
|
||||
const real* normals = ifs.normals();
|
||||
const real* texCoords = ifs.texCoords();
|
||||
const real *vertices = ifs.vertices();
|
||||
const real *normals = ifs.normals();
|
||||
const real *texCoords = ifs.texCoords();
|
||||
|
||||
real* new_vertices;
|
||||
real* new_normals;
|
||||
real *new_vertices;
|
||||
real *new_normals;
|
||||
|
||||
new_vertices = new real[vsize];
|
||||
new_normals = new real[nsize];
|
||||
|
||||
// transform coordinates from local to world system
|
||||
if(_current_matrix) {
|
||||
if (_current_matrix) {
|
||||
transformVertices(vertices, vsize, *_current_matrix, new_vertices);
|
||||
transformNormals(normals, nsize, *_current_matrix, new_normals);
|
||||
}
|
||||
@@ -88,22 +111,23 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
|
||||
memcpy(new_normals, normals, nsize * sizeof(*new_normals));
|
||||
}
|
||||
|
||||
const IndexedFaceSet::TRIANGLES_STYLE* faceStyle = ifs.trianglesStyle();
|
||||
const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle();
|
||||
|
||||
vector<FrsMaterial> frs_materials;
|
||||
if(ifs.msize()){
|
||||
const FrsMaterial*const* mats = ifs.frs_materials();
|
||||
for(unsigned i=0; i<ifs.msize(); ++i)
|
||||
if (ifs.msize()) {
|
||||
const FrsMaterial *const *mats = ifs.frs_materials();
|
||||
for (unsigned i = 0; i < ifs.msize(); ++i)
|
||||
frs_materials.push_back(*(mats[i]));
|
||||
shape.setFrsMaterials(frs_materials);
|
||||
}
|
||||
|
||||
// const FrsMaterial * mat = (ifs.frs_material());
|
||||
// if (mat)
|
||||
// shape.setFrsMaterial(*mat);
|
||||
// else if(_current_frs_material)
|
||||
// shape.setFrsMaterial(*_current_frs_material);
|
||||
|
||||
#if 0
|
||||
const FrsMaterial *mat = (ifs.frs_material());
|
||||
if (mat)
|
||||
shape.setFrsMaterial(*mat);
|
||||
else if (_current_frs_material)
|
||||
shape.setFrsMaterial(*_current_frs_material);
|
||||
#endif
|
||||
const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();
|
||||
|
||||
// sets the current WShape to shape
|
||||
@@ -112,63 +136,39 @@ 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;
|
||||
if(ifs.tsize()){
|
||||
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;
|
||||
if(ifs.msize())
|
||||
const unsigned int *mindices = NULL;
|
||||
if (ifs.msize())
|
||||
mindices = ifs.mindices();
|
||||
const unsigned* numVertexPerFace = ifs.numVertexPerFaces();
|
||||
const unsigned numfaces = ifs.numFaces();
|
||||
const unsigned int *numVertexPerFace = ifs.numVertexPerFaces();
|
||||
const unsigned int numfaces = ifs.numFaces();
|
||||
|
||||
for (unsigned index = 0; index < numfaces; index++) {
|
||||
switch(faceStyle[index]) {
|
||||
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];
|
||||
nindices += numVertexPerFace[index];
|
||||
if(mindices)
|
||||
if (mindices)
|
||||
mindices += numVertexPerFace[index];
|
||||
if(tindices)
|
||||
if (tindices)
|
||||
tindices += numVertexPerFace[index];
|
||||
faceEdgeMarks++;
|
||||
}
|
||||
@@ -183,26 +183,23 @@ 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){
|
||||
if((*wv)->isBoundary())
|
||||
vector<WVertex *>& wvertices = shape.getVertexList();
|
||||
for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
|
||||
if ((*wv)->isBoundary())
|
||||
continue;
|
||||
if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
|
||||
continue;
|
||||
normalsSet.clear();
|
||||
WVertex::face_iterator fit = (*wv)->faces_begin();
|
||||
WVertex::face_iterator fitend = (*wv)->faces_end();
|
||||
while(fit!=fitend){
|
||||
for (; fit != fitend; ++fit) {
|
||||
WFace *face = *fit;
|
||||
normalsSet.insert(face->GetVertexNormal(*wv));
|
||||
if(normalsSet.size()!=1){
|
||||
if (normalsSet.size() != 1) {
|
||||
break;
|
||||
}
|
||||
++fit;
|
||||
}
|
||||
if(normalsSet.size()!=1){
|
||||
if (normalsSet.size() !=1 ) {
|
||||
(*wv)->setSmooth(false);
|
||||
}
|
||||
}
|
||||
@@ -210,133 +207,127 @@ 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
|
||||
|
||||
WShape* currentShape = _current_wshape; // the current shape being built
|
||||
WShape *currentShape = _current_wshape; // the current shape being built
|
||||
vector<WVertex *> triangleVertices;
|
||||
vector<Vec3r> triangleNormals;
|
||||
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
|
||||
{
|
||||
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]);
|
||||
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]));
|
||||
if (texCoords) {
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
|
||||
texCoords[tindices[nTriangle + 1] + 1]));
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
|
||||
texCoords[tindices[nTriangle + 2] + 1]));
|
||||
}
|
||||
}
|
||||
else // if nTriangle is odd
|
||||
{
|
||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]);
|
||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]);
|
||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+1]/3]);
|
||||
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]));
|
||||
if (texCoords) {
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
|
||||
texCoords[tindices[nTriangle + 2] + 1]));
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
|
||||
texCoords[tindices[nTriangle + 1] + 1]));
|
||||
}
|
||||
}
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::FACE_MARK) != 0);
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
|
||||
if(mindices)
|
||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[nTriangle/3]);
|
||||
else
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != 0);
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
|
||||
if (mindices) {
|
||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
|
||||
mindices[nTriangle / 3]);
|
||||
}
|
||||
else {
|
||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
|
||||
}
|
||||
nDoneVertices++; // with a strip, each triangle is one vertex more
|
||||
nTriangle++;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
WShape * currentShape = _current_wshape; // the current shape begin built
|
||||
void WingedEdgeBuilder::buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
|
||||
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
||||
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
|
||||
const unsigned *tindices, const unsigned nvertices)
|
||||
{
|
||||
WShape *currentShape = _current_wshape; // the current shape begin built
|
||||
vector<WVertex *> triangleVertices;
|
||||
vector<Vec3r> triangleNormals;
|
||||
vector<Vec2r> triangleTexCoords;
|
||||
vector<bool> triangleFaceEdgeMarks;
|
||||
|
||||
// Each triplet of vertices is considered as an independent triangle
|
||||
for(unsigned i = 0; i < nvertices / 3; i++)
|
||||
{
|
||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i]/3]);
|
||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+1]/3]);
|
||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+2]/3]);
|
||||
for (unsigned int i = 0; i < nvertices / 3; i++) {
|
||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]);
|
||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]);
|
||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]);
|
||||
|
||||
triangleNormals.push_back(Vec3r(normals[nindices[3*i]],normals[nindices[3*i]+1], normals[nindices[3*i]+2]));
|
||||
triangleNormals.push_back(Vec3r(normals[nindices[3*i+1]],normals[nindices[3*i+1]+1],normals[nindices[3*i+1]+2]));
|
||||
triangleNormals.push_back(Vec3r(normals[nindices[3*i+2]], normals[nindices[3*i+2]+1], normals[nindices[3*i+2]+2]));
|
||||
triangleNormals.push_back(Vec3r(normals[nindices[3 * i]], normals[nindices[3 * i] + 1],
|
||||
normals[nindices[3 * i] + 2]));
|
||||
triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 1]], normals[nindices[3 * i + 1] + 1],
|
||||
normals[nindices[3 * i + 1] + 2]));
|
||||
triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 2]], normals[nindices[3 * i + 2] + 1],
|
||||
normals[nindices[3 * i + 2] + 2]));
|
||||
|
||||
if(texCoords){
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i]],texCoords[tindices[3*i]+1]));
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+1]],texCoords[tindices[3*i+1]+1]));
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+2]], texCoords[tindices[3*i+2]+1]));
|
||||
if (texCoords) {
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1]));
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1]));
|
||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 2]], texCoords[tindices[3 * i + 2] + 1]));
|
||||
}
|
||||
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
|
||||
@@ -344,41 +335,37 @@ void WingedEdgeBuilder::buildTriangles(const real *vertices,
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
|
||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
|
||||
}
|
||||
if(mindices)
|
||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]);
|
||||
if (mindices)
|
||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
|
||||
mindices[0]);
|
||||
else
|
||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
|
||||
|
||||
}
|
||||
|
||||
void WingedEdgeBuilder::transformVertices(const real *vertices,
|
||||
unsigned vsize,
|
||||
const Matrix44r& transform,
|
||||
real *res) {
|
||||
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;
|
||||
|
||||
@@ -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 "../system/FreestyleConfig.h"
|
||||
# include "../system/RenderMonitor.h"
|
||||
# include "../scene_graph/SceneVisitor.h"
|
||||
# include "WEdge.h"
|
||||
# include "../scene_graph/IndexedFaceSet.h"
|
||||
# include "../scene_graph/NodeTransform.h"
|
||||
#include "../scene_graph/IndexedFaceSet.h"
|
||||
#include "../scene_graph/NodeTransform.h"
|
||||
#include "../scene_graph/SceneVisitor.h"
|
||||
|
||||
#include "../system/FreestyleConfig.h"
|
||||
#include "../system/RenderMonitor.h"
|
||||
|
||||
class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
inline WingedEdgeBuilder() : SceneVisitor() {
|
||||
public:
|
||||
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,81 +100,58 @@ 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:
|
||||
|
||||
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:
|
||||
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;
|
||||
WingedEdge* _winged_edge;
|
||||
Matrix44r* _current_matrix;
|
||||
vector<Matrix44r*> _matrices_stack;
|
||||
WShape *_current_wshape;
|
||||
FrsMaterial *_current_frs_material;
|
||||
WingedEdge *_winged_edge;
|
||||
Matrix44r *_current_matrix;
|
||||
vector<Matrix44r *> _matrices_stack;
|
||||
};
|
||||
|
||||
#endif // WINGED_EDGE_BUILDER_H
|
||||
#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__
|
||||
Reference in New Issue
Block a user