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
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-2-5
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
|
||||||
//
|
* \ingroup freestyle
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
// with this source distribution.
|
* \author Alexander Beels
|
||||||
//
|
* \date 2011-2-5
|
||||||
// This program is free software; you can redistribute it and/or
|
*/
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "ArbitraryGridDensityProvider.h"
|
#include "ArbitraryGridDensityProvider.h"
|
||||||
|
|
||||||
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells)
|
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4],
|
||||||
: GridDensityProvider(source), numCells(numCells)
|
unsigned numCells)
|
||||||
|
: GridDensityProvider(source), numCells(numCells)
|
||||||
{
|
{
|
||||||
initialize (proscenium);
|
initialize (proscenium);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numCells)
|
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
: GridDensityProvider(source), numCells(numCells)
|
const GridHelpers::Transform& transform, unsigned numCells)
|
||||||
|
: GridDensityProvider(source), numCells(numCells)
|
||||||
{
|
{
|
||||||
real proscenium[4];
|
real proscenium[4];
|
||||||
calculateQuickProscenium(transform, bbox, proscenium);
|
calculateQuickProscenium(transform, bbox, proscenium);
|
||||||
@@ -46,7 +52,7 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& sourc
|
|||||||
}
|
}
|
||||||
|
|
||||||
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells)
|
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells)
|
||||||
: GridDensityProvider(source), numCells(numCells)
|
: GridDensityProvider(source), numCells(numCells)
|
||||||
{
|
{
|
||||||
real proscenium[4];
|
real proscenium[4];
|
||||||
calculateOptimalProscenium(source, proscenium);
|
calculateOptimalProscenium(source, proscenium);
|
||||||
@@ -54,9 +60,9 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource& sourc
|
|||||||
initialize (proscenium);
|
initialize (proscenium);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider () {}
|
ArbitraryGridDensityProvider::~ArbitraryGridDensityProvider() {}
|
||||||
|
|
||||||
void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
|
void ArbitraryGridDensityProvider::initialize(const real proscenium[4])
|
||||||
{
|
{
|
||||||
float prosceniumWidth = (proscenium[1] - proscenium[0]);
|
float prosceniumWidth = (proscenium[1] - proscenium[0]);
|
||||||
float prosceniumHeight = (proscenium[3] - proscenium[2]);
|
float prosceniumHeight = (proscenium[3] - proscenium[2]);
|
||||||
@@ -70,11 +76,11 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
|
|||||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||||
|
|
||||||
// Make sure the grid exceeds the proscenium by a small amount
|
// Make sure the grid exceeds the proscenium by a small amount
|
||||||
float safetyZone = 0.1;
|
float safetyZone = 0.1f;
|
||||||
if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
|
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
|
||||||
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
|
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
|
||||||
}
|
}
|
||||||
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
|
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
|
||||||
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
|
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
|
||||||
}
|
}
|
||||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||||
@@ -85,18 +91,21 @@ void ArbitraryGridDensityProvider::initialize (const real proscenium[4])
|
|||||||
}
|
}
|
||||||
|
|
||||||
ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigned numCells)
|
ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigned numCells)
|
||||||
: numCells(numCells)
|
: numCells(numCells)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory () {}
|
ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory() {}
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source,
|
||||||
|
const real proscenium[4])
|
||||||
{
|
{
|
||||||
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, proscenium, numCells));
|
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, proscenium, numCells));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
|
auto_ptr<GridDensityProvider>
|
||||||
|
ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform)
|
||||||
{
|
{
|
||||||
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
|
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
|
||||||
}
|
}
|
||||||
@@ -105,4 +114,3 @@ auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensit
|
|||||||
{
|
{
|
||||||
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
|
return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,54 @@
|
|||||||
//
|
/*
|
||||||
// Filename : ArbitraryGridDensityProvider.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-2-5
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
|
||||||
|
#define __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2011-2-5
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef ARBITRARYGRIDDENSITYPROVIDER_H
|
|
||||||
#define ARBITRARYGRIDDENSITYPROVIDER_H
|
|
||||||
|
|
||||||
#include "GridDensityProvider.h"
|
#include "GridDensityProvider.h"
|
||||||
|
|
||||||
class ArbitraryGridDensityProvider : public GridDensityProvider {
|
class ArbitraryGridDensityProvider : public GridDensityProvider
|
||||||
|
{
|
||||||
// Disallow copying and assignment
|
// Disallow copying and assignment
|
||||||
ArbitraryGridDensityProvider (const ArbitraryGridDensityProvider& other);
|
ArbitraryGridDensityProvider(const ArbitraryGridDensityProvider& other);
|
||||||
ArbitraryGridDensityProvider& operator= (const ArbitraryGridDensityProvider& other);
|
ArbitraryGridDensityProvider& operator=(const ArbitraryGridDensityProvider& other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells);
|
ArbitraryGridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numCells);
|
||||||
ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numCells);
|
ArbitraryGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform, unsigned numCells);
|
||||||
ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells);
|
ArbitraryGridDensityProvider(OccluderSource& source, unsigned numCells);
|
||||||
virtual ~ArbitraryGridDensityProvider ();
|
virtual ~ArbitraryGridDensityProvider();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned numCells;
|
unsigned numCells;
|
||||||
@@ -51,17 +57,19 @@ private:
|
|||||||
void initialize (const real proscenium[4]);
|
void initialize (const real proscenium[4]);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory {
|
class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
ArbitraryGridDensityProviderFactory(unsigned numCells);
|
ArbitraryGridDensityProviderFactory(unsigned numCells);
|
||||||
~ArbitraryGridDensityProviderFactory ();
|
~ArbitraryGridDensityProviderFactory();
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform);
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned numCells;
|
unsigned numCells;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ARBITRARYGRIDDENSITYPROVIDER_H
|
#endif // __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
|
||||||
|
|
||||||
|
|||||||
@@ -1,69 +1,75 @@
|
|||||||
//
|
/*
|
||||||
// Filename : AverageAreaGridDensityProvider.cpp
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-2-9
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
|
||||||
//
|
* \ingroup freestyle
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
// with this source distribution.
|
* \author Alexander Beels
|
||||||
//
|
* \date 2011-2-9
|
||||||
// This program is free software; you can redistribute it and/or
|
*/
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "AverageAreaGridDensityProvider.h"
|
#include "AverageAreaGridDensityProvider.h"
|
||||||
|
|
||||||
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor)
|
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4],
|
||||||
: GridDensityProvider(source)
|
real sizeFactor)
|
||||||
|
: GridDensityProvider(source)
|
||||||
{
|
{
|
||||||
initialize (proscenium, sizeFactor);
|
initialize (proscenium, sizeFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, real sizeFactor)
|
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
: GridDensityProvider(source)
|
const GridHelpers::Transform& transform, real sizeFactor)
|
||||||
|
: GridDensityProvider(source)
|
||||||
{
|
{
|
||||||
real proscenium[4];
|
real proscenium[4];
|
||||||
calculateQuickProscenium(transform, bbox, proscenium);
|
calculateQuickProscenium(transform, bbox, proscenium);
|
||||||
|
|
||||||
initialize (proscenium, sizeFactor);
|
initialize(proscenium, sizeFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor)
|
AverageAreaGridDensityProvider::AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor)
|
||||||
: GridDensityProvider(source)
|
: GridDensityProvider(source)
|
||||||
{
|
{
|
||||||
real proscenium[4];
|
real proscenium[4];
|
||||||
calculateOptimalProscenium(source, proscenium);
|
calculateOptimalProscenium(source, proscenium);
|
||||||
|
|
||||||
initialize (proscenium, sizeFactor);
|
initialize(proscenium, sizeFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider () {}
|
AverageAreaGridDensityProvider::~AverageAreaGridDensityProvider() {}
|
||||||
|
|
||||||
void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real sizeFactor)
|
void AverageAreaGridDensityProvider::initialize(const real proscenium[4], real sizeFactor)
|
||||||
{
|
{
|
||||||
float prosceniumWidth = (proscenium[1] - proscenium[0]);
|
float prosceniumWidth = (proscenium[1] - proscenium[0]);
|
||||||
float prosceniumHeight = (proscenium[3] - proscenium[2]);
|
float prosceniumHeight = (proscenium[3] - proscenium[2]);
|
||||||
|
|
||||||
real cellArea = 0.0;
|
real cellArea = 0.0;
|
||||||
unsigned numFaces = 0;
|
unsigned numFaces = 0;
|
||||||
for ( source.begin(); source.isValid(); source.next() ) {
|
for (source.begin(); source.isValid(); source.next()) {
|
||||||
Polygon3r& poly(source.getGridSpacePolygon());
|
Polygon3r& poly(source.getGridSpacePolygon());
|
||||||
Vec3r min, max;
|
Vec3r min, max;
|
||||||
poly.getBBox(min, max);
|
poly.getBBox(min, max);
|
||||||
@@ -82,11 +88,11 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
|
|||||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||||
|
|
||||||
// Make sure the grid exceeds the proscenium by a small amount
|
// Make sure the grid exceeds the proscenium by a small amount
|
||||||
float safetyZone = 0.1;
|
float safetyZone = 0.1f;
|
||||||
if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
|
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
|
||||||
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
|
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
|
||||||
}
|
}
|
||||||
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
|
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
|
||||||
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
|
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
|
||||||
}
|
}
|
||||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||||
@@ -97,18 +103,21 @@ void AverageAreaGridDensityProvider::initialize (const real proscenium[4], real
|
|||||||
}
|
}
|
||||||
|
|
||||||
AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(real sizeFactor)
|
AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(real sizeFactor)
|
||||||
: sizeFactor(sizeFactor)
|
: sizeFactor(sizeFactor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory () {}
|
AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory() {}
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
auto_ptr<GridDensityProvider>
|
||||||
|
AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||||
{
|
{
|
||||||
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
|
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
|
auto_ptr<GridDensityProvider>
|
||||||
|
AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform)
|
||||||
{
|
{
|
||||||
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
|
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
|
||||||
}
|
}
|
||||||
@@ -117,4 +126,3 @@ auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDens
|
|||||||
{
|
{
|
||||||
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
|
return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,67 +1,72 @@
|
|||||||
//
|
/*
|
||||||
// Filename : AverageAreaGridDensityProvider.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-2-9
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
|
||||||
|
#define __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2011-2-9
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef AVERAGEAREAGRIDDENSITYPROVIDER_H
|
|
||||||
#define AVERAGEAREAGRIDDENSITYPROVIDER_H
|
|
||||||
|
|
||||||
#include "GridDensityProvider.h"
|
#include "GridDensityProvider.h"
|
||||||
|
|
||||||
class AverageAreaGridDensityProvider : public GridDensityProvider {
|
class AverageAreaGridDensityProvider : public GridDensityProvider
|
||||||
|
{
|
||||||
// Disallow copying and assignment
|
// Disallow copying and assignment
|
||||||
AverageAreaGridDensityProvider (const AverageAreaGridDensityProvider& other);
|
AverageAreaGridDensityProvider(const AverageAreaGridDensityProvider& other);
|
||||||
AverageAreaGridDensityProvider& operator= (const AverageAreaGridDensityProvider& other);
|
AverageAreaGridDensityProvider& operator=(const AverageAreaGridDensityProvider& other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor);
|
AverageAreaGridDensityProvider(OccluderSource& source, const real proscenium[4], real sizeFactor);
|
||||||
AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, real sizeFactor);
|
AverageAreaGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform, real sizeFactor);
|
||||||
AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor);
|
AverageAreaGridDensityProvider(OccluderSource& source, real sizeFactor);
|
||||||
virtual ~AverageAreaGridDensityProvider ();
|
virtual ~AverageAreaGridDensityProvider();
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize (const real proscenium[4], real sizeFactor);
|
void initialize (const real proscenium[4], real sizeFactor);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory {
|
class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
AverageAreaGridDensityProviderFactory(real sizeFactor);
|
AverageAreaGridDensityProviderFactory(real sizeFactor);
|
||||||
~AverageAreaGridDensityProviderFactory ();
|
~AverageAreaGridDensityProviderFactory();
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform);
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
real sizeFactor;
|
real sizeFactor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AVERAGEAREAGRIDDENSITYPROVIDER_H
|
#endif // __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,42 @@
|
|||||||
//
|
/*
|
||||||
// Filename : BoxGrid.cpp
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-1-29
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/BoxGrid.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2011-1-29
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
#include <algorithm>
|
||||||
//
|
#include <stdexcept>
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "BoxGrid.h"
|
#include "BoxGrid.h"
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Helper Classes
|
// Helper Classes
|
||||||
@@ -42,11 +47,12 @@ using namespace std;
|
|||||||
// Cell
|
// Cell
|
||||||
/////////
|
/////////
|
||||||
|
|
||||||
BoxGrid::Cell::Cell () {}
|
BoxGrid::Cell::Cell() {}
|
||||||
|
|
||||||
BoxGrid::Cell::~Cell () {}
|
BoxGrid::Cell::~Cell() {}
|
||||||
|
|
||||||
void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
|
void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
|
||||||
|
{
|
||||||
const real epsilon = 1.0e-06;
|
const real epsilon = 1.0e-06;
|
||||||
boundary[0] = x - epsilon;
|
boundary[0] = x - epsilon;
|
||||||
boundary[1] = x + sizeX + epsilon;
|
boundary[1] = x + sizeX + epsilon;
|
||||||
@@ -54,11 +60,13 @@ void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
|
|||||||
boundary[3] = y + sizeY + epsilon;
|
boundary[3] = y + sizeY + epsilon;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BoxGrid::Cell::compareOccludersByShallowestPoint (const BoxGrid::OccluderData* a, const BoxGrid::OccluderData* b) {
|
bool BoxGrid::Cell::compareOccludersByShallowestPoint(const BoxGrid::OccluderData *a, const BoxGrid::OccluderData *b)
|
||||||
|
{
|
||||||
return a->shallowest < b->shallowest;
|
return a->shallowest < b->shallowest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoxGrid::Cell::indexPolygons() {
|
void BoxGrid::Cell::indexPolygons()
|
||||||
|
{
|
||||||
// Sort occluders by their shallowest points.
|
// Sort occluders by their shallowest points.
|
||||||
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
|
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
|
||||||
}
|
}
|
||||||
@@ -67,12 +75,11 @@ void BoxGrid::Cell::indexPolygons() {
|
|||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
BoxGrid::Iterator::Iterator (BoxGrid& grid, Vec3r& center, real epsilon)
|
BoxGrid::Iterator::Iterator (BoxGrid& grid, Vec3r& center, real epsilon)
|
||||||
: _target(grid.transform(center)),
|
: _target(grid.transform(center)), _foundOccludee(false)
|
||||||
_foundOccludee(false)
|
|
||||||
{
|
{
|
||||||
// Find target cell
|
// Find target cell
|
||||||
_cell = grid.findCell(_target);
|
_cell = grid.findCell(_target);
|
||||||
#if boxgridlogging == 1
|
#if BOX_GRID_LOGGING
|
||||||
cout << "Searching for occluders of edge centered at " << _target << " in cell ["
|
cout << "Searching for occluders of edge centered at " << _target << " in cell ["
|
||||||
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
|
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
|
||||||
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
|
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
|
||||||
@@ -82,31 +89,34 @@ BoxGrid::Iterator::Iterator (BoxGrid& grid, Vec3r& center, real epsilon)
|
|||||||
_current = _cell->faces.begin();
|
_current = _cell->faces.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
BoxGrid::Iterator::~Iterator () {}
|
BoxGrid::Iterator::~Iterator() {}
|
||||||
|
|
||||||
// BoxGrid
|
// BoxGrid
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|
||||||
BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI)
|
BoxGrid::BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
|
||||||
: _viewpoint(viewpoint),
|
bool enableQI)
|
||||||
_enableQI(enableQI)
|
: _viewpoint(viewpoint), _enableQI(enableQI)
|
||||||
{
|
{
|
||||||
cout << "Generate Cell structure" << endl;
|
|
||||||
// Generate Cell structure
|
// Generate Cell structure
|
||||||
|
cout << "Generate Cell structure" << endl;
|
||||||
assignCells(source, density, viewMap);
|
assignCells(source, density, viewMap);
|
||||||
cout << "Distribute occluders" << endl;
|
|
||||||
// Fill Cells
|
// Fill Cells
|
||||||
|
cout << "Distribute occluders" << endl;
|
||||||
distributePolygons(source);
|
distributePolygons(source);
|
||||||
cout << "Reorganize cells" << endl;
|
|
||||||
// Reorganize Cells
|
// Reorganize Cells
|
||||||
|
cout << "Reorganize cells" << endl;
|
||||||
reorganizeCells();
|
reorganizeCells();
|
||||||
|
|
||||||
cout << "Ready to use BoxGrid" << endl;
|
cout << "Ready to use BoxGrid" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
BoxGrid::~BoxGrid () {
|
BoxGrid::~BoxGrid() {}
|
||||||
}
|
|
||||||
|
|
||||||
void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap) {
|
void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap)
|
||||||
|
{
|
||||||
_cellSize = density.cellSize();
|
_cellSize = density.cellSize();
|
||||||
_cellsX = density.cellsX();
|
_cellsX = density.cellsX();
|
||||||
_cellsY = density.cellsY();
|
_cellsY = density.cellsY();
|
||||||
@@ -115,20 +125,19 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
|
|||||||
|
|
||||||
// Now allocate the cell table and fill it with default (empty) cells
|
// Now allocate the cell table and fill it with default (empty) cells
|
||||||
_cells.resize(_cellsX * _cellsY);
|
_cells.resize(_cellsX * _cellsY);
|
||||||
for ( cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
|
for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
|
||||||
(*i) = NULL;
|
(*i) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identify cells that will be used, and set the dimensions for each
|
// Identify cells that will be used, and set the dimensions for each
|
||||||
ViewMap::fedges_container& fedges = viewMap->FEdges();
|
ViewMap::fedges_container& fedges = viewMap->FEdges();
|
||||||
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f ) {
|
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
|
||||||
if ( (*f)->isInImage() ) {
|
if ((*f)->isInImage()) {
|
||||||
Vec3r point = transform((*f)->center3d());
|
Vec3r point = transform((*f)->center3d());
|
||||||
unsigned i, j;
|
unsigned int i, j;
|
||||||
getCellCoordinates(point, i, j);
|
getCellCoordinates(point, i, j);
|
||||||
if ( _cells[i * _cellsY + j] == NULL ) {
|
if (_cells[i * _cellsY + j] == NULL) {
|
||||||
// This is an uninitialized cell
|
// This is an uninitialized cell
|
||||||
|
|
||||||
real x, y, width, height;
|
real x, y, width, height;
|
||||||
|
|
||||||
x = _cellOrigin[0] + _cellSize * i;
|
x = _cellOrigin[0] + _cellSize * i;
|
||||||
@@ -145,19 +154,21 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoxGrid::distributePolygons (OccluderSource& source) {
|
void BoxGrid::distributePolygons(OccluderSource& source)
|
||||||
|
{
|
||||||
unsigned long nFaces = 0;
|
unsigned long nFaces = 0;
|
||||||
unsigned long nKeptFaces = 0;
|
unsigned long nKeptFaces = 0;
|
||||||
|
|
||||||
for ( source.begin(); source.isValid(); source.next() ) {
|
for (source.begin(); source.isValid(); source.next()) {
|
||||||
OccluderData* occluder = NULL;
|
OccluderData *occluder = NULL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( insertOccluder(source, occluder) ) {
|
if (insertOccluder(source, occluder)) {
|
||||||
_faces.push_back(occluder);
|
_faces.push_back(occluder);
|
||||||
++nKeptFaces;
|
++nKeptFaces;
|
||||||
}
|
}
|
||||||
} catch (...) {
|
}
|
||||||
|
catch (...) {
|
||||||
// If an exception was thrown, _faces.push_back() cannot have succeeded.
|
// If an exception was thrown, _faces.push_back() cannot have succeeded.
|
||||||
// occluder is not owned by anyone, and must be deleted.
|
// occluder is not owned by anyone, and must be deleted.
|
||||||
// If the exception was thrown before or during new OccluderData(), then
|
// If the exception was thrown before or during new OccluderData(), then
|
||||||
@@ -170,41 +181,47 @@ void BoxGrid::distributePolygons (OccluderSource& source) {
|
|||||||
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
|
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoxGrid::reorganizeCells () {
|
void BoxGrid::reorganizeCells()
|
||||||
|
{
|
||||||
// Sort the occluders by shallowest point
|
// Sort the occluders by shallowest point
|
||||||
for ( vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
|
for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
|
||||||
if ( *i != NULL ) {
|
if (*i != NULL) {
|
||||||
(*i)->indexPolygons();
|
(*i)->indexPolygons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) {
|
void BoxGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
|
||||||
|
{
|
||||||
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
|
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
|
||||||
y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
|
y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point) {
|
BoxGrid::Cell* BoxGrid::findCell(const Vec3r& point)
|
||||||
unsigned x, y;
|
{
|
||||||
|
unsigned int x, y;
|
||||||
getCellCoordinates(point, x, y);
|
getCellCoordinates(point, x, y);
|
||||||
return _cells[x * _cellsY + y];
|
return _cells[x * _cellsY + y];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BoxGrid::orthographicProjection () const {
|
bool BoxGrid::orthographicProjection() const
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vec3r& BoxGrid::viewpoint() const {
|
const Vec3r& BoxGrid::viewpoint() const
|
||||||
|
{
|
||||||
return _viewpoint;
|
return _viewpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BoxGrid::enableQI() const {
|
bool BoxGrid::enableQI() const
|
||||||
|
{
|
||||||
return _enableQI;
|
return _enableQI;
|
||||||
}
|
}
|
||||||
|
|
||||||
BoxGrid::Transform::Transform () : GridHelpers::Transform() {}
|
BoxGrid::Transform::Transform() : GridHelpers::Transform() {}
|
||||||
|
|
||||||
Vec3r BoxGrid::Transform::operator() (const Vec3r& point) const {
|
Vec3r BoxGrid::Transform::operator()(const Vec3r& point) const
|
||||||
|
{
|
||||||
return Vec3r(point[0], point[1], -point[2]);
|
return Vec3r(point[0], point[1], -point[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,78 +1,87 @@
|
|||||||
//
|
/*
|
||||||
// Filename : BoxGrid.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-1-29
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_BOX_GRID_H__
|
||||||
|
#define __FREESTYLE_BOX_GRID_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/BoxGrid.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2011-1-29
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef BOXGRID_H
|
#define BOX_GRID_LOGGING FALSE
|
||||||
#define BOXGRID_H
|
|
||||||
|
|
||||||
#define boxgridlogging 0
|
|
||||||
|
|
||||||
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector>
|
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector>
|
||||||
// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
|
// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
|
||||||
// so it should be a safe fall-back.
|
// so it should be a safe fall-back.
|
||||||
//#include <vector>
|
//#include <vector>
|
||||||
//#include <deque>
|
//#include <deque>
|
||||||
|
|
||||||
|
#include "GridDensityProvider.h"
|
||||||
|
#include "OccluderSource.h"
|
||||||
#include "ViewMap.h"
|
#include "ViewMap.h"
|
||||||
#include "../winged_edge/WEdge.h"
|
|
||||||
#include "../geometry/Polygon.h"
|
|
||||||
#include "../system/PointerSequence.h"
|
|
||||||
#include "../geometry/BBox.h"
|
#include "../geometry/BBox.h"
|
||||||
#include "../geometry/GridHelpers.h"
|
#include "../geometry/GridHelpers.h"
|
||||||
#include "OccluderSource.h"
|
#include "../geometry/Polygon.h"
|
||||||
#include "GridDensityProvider.h"
|
|
||||||
|
#include "../system/PointerSequence.h"
|
||||||
|
|
||||||
|
#include "../winged_edge/WEdge.h"
|
||||||
|
|
||||||
class BoxGrid
|
class BoxGrid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Helper classes
|
// Helper classes
|
||||||
struct OccluderData {
|
struct OccluderData
|
||||||
explicit OccluderData (OccluderSource& source, Polygon3r& p);
|
{
|
||||||
|
explicit OccluderData(OccluderSource& source, Polygon3r& p);
|
||||||
Polygon3r poly;
|
Polygon3r poly;
|
||||||
Polygon3r cameraSpacePolygon;
|
Polygon3r cameraSpacePolygon;
|
||||||
real shallowest, deepest;
|
real shallowest, deepest;
|
||||||
// N.B. We could, of course, store face in poly's userdata
|
// N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
|
||||||
// member, like the old ViewMapBuilder code does. However,
|
// However, code comments make it clear that userdata is deprecated, so we avoid the temptation
|
||||||
// code comments make it clear that userdata is deprecated,
|
// to save 4 or 8 bytes.
|
||||||
// so we avoid the temptation to save 4 or 8 bytes.
|
|
||||||
WFace* face;
|
WFace* face;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Cell {
|
struct Cell
|
||||||
|
{
|
||||||
// Can't store Cell in a vector without copy and assign
|
// Can't store Cell in a vector without copy and assign
|
||||||
//Cell(const Cell& other);
|
// Cell(const Cell& other);
|
||||||
//Cell& operator= (const Cell& other);
|
// Cell& operator=(const Cell& other);
|
||||||
|
|
||||||
explicit Cell ();
|
explicit Cell();
|
||||||
~Cell ();
|
~Cell();
|
||||||
|
|
||||||
static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b);
|
static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
|
||||||
|
|
||||||
void setDimensions(real x, real y, real sizeX, real sizeY);
|
void setDimensions(real x, real y, real sizeX, real sizeY);
|
||||||
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
|
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
|
||||||
@@ -84,43 +93,37 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*****
|
/* Iterator needs to allow the user to avoid full 3D comparison in two cases:
|
||||||
|
*
|
||||||
Iterator needs to allow the user to avoid full 3D comparison in
|
* (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
|
||||||
two cases:
|
*
|
||||||
|
* (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
|
||||||
(1) Where (*current)->deepest < target[2], where the occluder is
|
*
|
||||||
unambiguously in front of the target point.
|
* In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an
|
||||||
|
* occludee candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder
|
||||||
(2) Where (*current)->shallowest > target[2], where the occluder
|
* could possibly be a better occludee.
|
||||||
is unambiguously in back of the target point.
|
*/
|
||||||
|
class Iterator
|
||||||
In addition, when used by OptimizedFindOccludee, Iterator should
|
{
|
||||||
stop iterating as soon as it has an occludee candidate and
|
|
||||||
(*current)->shallowest > candidate[2], because at that point forward
|
|
||||||
no new occluder could possibly be a better occludee.
|
|
||||||
|
|
||||||
*****/
|
|
||||||
|
|
||||||
class Iterator {
|
|
||||||
public:
|
public:
|
||||||
// epsilon is not used in this class, but other grids with the same interface may need an epsilon
|
// epsilon is not used in this class, but other grids with the same interface may need an epsilon
|
||||||
explicit Iterator (BoxGrid& grid, Vec3r& center, real epsilon=1e-06);
|
explicit Iterator(BoxGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
|
||||||
~Iterator ();
|
~Iterator();
|
||||||
void initBeforeTarget ();
|
void initBeforeTarget();
|
||||||
void initAfterTarget ();
|
void initAfterTarget();
|
||||||
void nextOccluder ();
|
void nextOccluder();
|
||||||
void nextOccludee ();
|
void nextOccludee();
|
||||||
bool validBeforeTarget();
|
bool validBeforeTarget();
|
||||||
bool validAfterTarget();
|
bool validAfterTarget();
|
||||||
WFace* getWFace() const;
|
WFace *getWFace() const;
|
||||||
Polygon3r* getCameraSpacePolygon();
|
Polygon3r *getCameraSpacePolygon();
|
||||||
void reportDepth(Vec3r origin, Vec3r u, real t);
|
void reportDepth(Vec3r origin, Vec3r u, real t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool testOccluder(bool wantOccludee);
|
bool testOccluder(bool wantOccludee);
|
||||||
void markCurrentOccludeeCandidate(real depth);
|
void markCurrentOccludeeCandidate(real depth);
|
||||||
|
|
||||||
Cell* _cell;
|
Cell *_cell;
|
||||||
Vec3r _target;
|
Vec3r _target;
|
||||||
bool _foundOccludee;
|
bool _foundOccludee;
|
||||||
real _occludeeDepth;
|
real _occludeeDepth;
|
||||||
@@ -128,32 +131,34 @@ public:
|
|||||||
vector<OccluderData*>::iterator _current, _occludeeCandidate;
|
vector<OccluderData*>::iterator _current, _occludeeCandidate;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Transform : public GridHelpers::Transform {
|
class Transform : public GridHelpers::Transform
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
explicit Transform ();
|
explicit Transform();
|
||||||
explicit Transform (Transform& other);
|
explicit Transform(Transform& other);
|
||||||
Vec3r operator() (const Vec3r& point) const;
|
Vec3r operator()(const Vec3r& point) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Prevent implicit copies and assignments.
|
// Prevent implicit copies and assignments.
|
||||||
BoxGrid(const BoxGrid& other);
|
BoxGrid(const BoxGrid& other);
|
||||||
BoxGrid& operator= (const BoxGrid& other);
|
BoxGrid& operator=(const BoxGrid& other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BoxGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
|
explicit BoxGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint,
|
||||||
|
bool enableQI);
|
||||||
virtual ~BoxGrid();
|
virtual ~BoxGrid();
|
||||||
|
|
||||||
// Generate Cell structure
|
// Generate Cell structure
|
||||||
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
|
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
|
||||||
// Fill Cells
|
// Fill Cells
|
||||||
void distributePolygons(OccluderSource& source);
|
void distributePolygons(OccluderSource& source);
|
||||||
// Insert one polygon into each matching cell,
|
// Insert one polygon into each matching cell, return true if any cell consumes the polygon
|
||||||
// return true if any cell consumes the polygon
|
|
||||||
bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
|
bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
|
||||||
// Sort occluders in each cell
|
// Sort occluders in each cell
|
||||||
void reorganizeCells();
|
void reorganizeCells();
|
||||||
|
|
||||||
Cell* findCell(const Vec3r& point);
|
Cell *findCell(const Vec3r& point);
|
||||||
|
|
||||||
// Accessors:
|
// Accessors:
|
||||||
bool orthographicProjection() const;
|
bool orthographicProjection() const;
|
||||||
@@ -176,51 +181,52 @@ private:
|
|||||||
bool _enableQI;
|
bool _enableQI;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void BoxGrid::Iterator::initBeforeTarget () {
|
inline void BoxGrid::Iterator::initBeforeTarget()
|
||||||
|
{
|
||||||
_current = _cell->faces.begin();
|
_current = _cell->faces.begin();
|
||||||
while ( _current != _cell->faces.end() && ! testOccluder(false) ) {
|
while (_current != _cell->faces.end() && !testOccluder(false)) {
|
||||||
++_current;
|
++_current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BoxGrid::Iterator::initAfterTarget () {
|
inline void BoxGrid::Iterator::initAfterTarget()
|
||||||
if ( _foundOccludee ) {
|
{
|
||||||
#if boxgridlogging == 1
|
if (_foundOccludee) {
|
||||||
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
|
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
|
||||||
#endif
|
#endif
|
||||||
_current = _occludeeCandidate;
|
_current = _occludeeCandidate;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if boxgridlogging == 1
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << "\tStarting occludee search from current position" << std::endl;
|
std::cout << "\tStarting occludee search from current position" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while ( _current != _cell->faces.end() && ! testOccluder(true) ) {
|
while (_current != _cell->faces.end() && !testOccluder(true)) {
|
||||||
++_current;
|
++_current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
|
inline bool BoxGrid::Iterator::testOccluder(bool wantOccludee)
|
||||||
|
{
|
||||||
// End-of-list is not even a valid iterator position
|
// End-of-list is not even a valid iterator position
|
||||||
if ( _current == _cell->faces.end() ) {
|
if (_current == _cell->faces.end()) {
|
||||||
// Returning true seems strange, but it will break us out of whatever loop
|
// Returning true seems strange, but it will break us out of whatever loop is calling testOccluder,
|
||||||
// is calling testOccluder, and _current=_cell->face.end() will make
|
// and _current = _cell->face.end() will make the calling routine give up.
|
||||||
// the calling routine give up.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#if boxgridlogging == 1
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
|
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
|
||||||
for ( unsigned i = 1; i < (*_current)->poly.getVertices().size(); ++i ) {
|
for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
|
||||||
std::cout << ", " << (*_current)->poly.getVertices()[i];
|
std::cout << ", " << (*_current)->poly.getVertices()[i];
|
||||||
}
|
}
|
||||||
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
|
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// If we have an occluder candidate and we are unambiguously after it, abort
|
// If we have an occluder candidate and we are unambiguously after it, abort
|
||||||
if ( _foundOccludee && (*_current)->shallowest > _occludeeDepth ) {
|
if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
|
||||||
#if boxgridlogging == 1
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
|
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
_current = _cell->faces.end();
|
_current = _cell->faces.end();
|
||||||
@@ -230,16 +236,17 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Specific continue or stop conditions when searching for each type
|
// Specific continue or stop conditions when searching for each type
|
||||||
if ( wantOccludee ) {
|
if (wantOccludee) {
|
||||||
if ( (*_current)->deepest < _target[2] ) {
|
if ((*_current)->deepest < _target[2]) {
|
||||||
#if boxgridlogging == 1
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
|
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if ( (*_current)->shallowest > _target[2] ) {
|
else {
|
||||||
#if boxgridlogging == 1
|
if ((*_current)->shallowest > _target[2]) {
|
||||||
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
|
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
@@ -251,67 +258,73 @@ inline bool BoxGrid::Iterator::testOccluder (bool wantOccludee) {
|
|||||||
// Check to see if target is in the 2D bounding box
|
// Check to see if target is in the 2D bounding box
|
||||||
Vec3r bbMin, bbMax;
|
Vec3r bbMin, bbMax;
|
||||||
(*_current)->poly.getBBox(bbMin, bbMax);
|
(*_current)->poly.getBBox(bbMin, bbMax);
|
||||||
if ( _target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1] ) {
|
if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
|
||||||
#if boxgridlogging == 1
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
|
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've done all the corner cutting we can.
|
// We've done all the corner cutting we can.
|
||||||
// Let the caller work out whether or not
|
// Let the caller work out whether or not the geometry is correct.
|
||||||
// the geometry is correct.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BoxGrid::Iterator::reportDepth (Vec3r origin, Vec3r u, real t) {
|
inline void BoxGrid::Iterator::reportDepth(Vec3r origin, Vec3r u, real t)
|
||||||
|
{
|
||||||
// The reported depth is the length of a ray in camera space
|
// The reported depth is the length of a ray in camera space
|
||||||
// We need to convert it into a Z-value in grid space
|
// We need to convert it into a Z-value in grid space
|
||||||
real depth = -(origin + (u * t))[2];
|
real depth = -(origin + (u * t))[2];
|
||||||
#if boxgridlogging == 1
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
|
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
|
||||||
#endif
|
#endif
|
||||||
if ( depth > _target[2] ) {
|
if (depth > _target[2]) {
|
||||||
#if boxgridlogging == 1
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << " is deeper than target" << std::endl;
|
std::cout << " is deeper than target" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
// If the current occluder is the best occludee so far, save it.
|
// If the current occluder is the best occludee so far, save it.
|
||||||
if ( ! _foundOccludee || _occludeeDepth > depth ) {
|
if (! _foundOccludee || _occludeeDepth > depth) {
|
||||||
markCurrentOccludeeCandidate(depth);
|
markCurrentOccludeeCandidate(depth);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
#if boxgridlogging == 1
|
else {
|
||||||
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BoxGrid::Iterator::nextOccluder () {
|
inline void BoxGrid::Iterator::nextOccluder()
|
||||||
if ( _current != _cell->faces.end() ) {
|
{
|
||||||
|
if (_current != _cell->faces.end()) {
|
||||||
do {
|
do {
|
||||||
++_current;
|
++_current;
|
||||||
} while ( _current != _cell->faces.end() && ! testOccluder(false) );
|
} while (_current != _cell->faces.end() && ! testOccluder(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BoxGrid::Iterator::nextOccludee () {
|
inline void BoxGrid::Iterator::nextOccludee()
|
||||||
if ( _current != _cell->faces.end() ) {
|
{
|
||||||
|
if (_current != _cell->faces.end()) {
|
||||||
do {
|
do {
|
||||||
++_current;
|
++_current;
|
||||||
} while ( _current != _cell->faces.end() && ! testOccluder(true) );
|
} while (_current != _cell->faces.end() && ! testOccluder(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool BoxGrid::Iterator::validBeforeTarget () {
|
inline bool BoxGrid::Iterator::validBeforeTarget()
|
||||||
|
{
|
||||||
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
|
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool BoxGrid::Iterator::validAfterTarget () {
|
inline bool BoxGrid::Iterator::validAfterTarget()
|
||||||
|
{
|
||||||
return _current != _cell->faces.end();
|
return _current != _cell->faces.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
|
inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth)
|
||||||
#if boxgridlogging == 1
|
{
|
||||||
|
#if BOX_GRID_LOGGING
|
||||||
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
|
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
|
||||||
#endif
|
#endif
|
||||||
_occludeeCandidate = _current;
|
_occludeeCandidate = _current;
|
||||||
@@ -319,16 +332,18 @@ inline void BoxGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
|
|||||||
_foundOccludee = true;
|
_foundOccludee = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline WFace* BoxGrid::Iterator::getWFace() const {
|
inline WFace* BoxGrid::Iterator::getWFace() const
|
||||||
|
{
|
||||||
return (*_current)->face;
|
return (*_current)->face;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon() {
|
inline Polygon3r* BoxGrid::Iterator::getCameraSpacePolygon()
|
||||||
|
{
|
||||||
return &((*_current)->cameraSpacePolygon);
|
return &((*_current)->cameraSpacePolygon);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
|
inline BoxGrid::OccluderData::OccluderData(OccluderSource& source, Polygon3r& p)
|
||||||
: poly(p),
|
: poly(p),
|
||||||
cameraSpacePolygon(source.getCameraSpacePolygon()),
|
cameraSpacePolygon(source.getCameraSpacePolygon()),
|
||||||
face(source.getWFace())
|
face(source.getWFace())
|
||||||
{
|
{
|
||||||
@@ -339,9 +354,10 @@ inline BoxGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p
|
|||||||
deepest = max[2];
|
deepest = max[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
|
inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
|
||||||
if ( GridHelpers::insideProscenium (boundary, poly) ) {
|
{
|
||||||
if ( occluder == NULL) {
|
if (GridHelpers::insideProscenium (boundary, poly)) {
|
||||||
|
if (occluder == NULL) {
|
||||||
// Disposal of occluder will be handled in BoxGrid::distributePolygons(),
|
// Disposal of occluder will be handled in BoxGrid::distributePolygons(),
|
||||||
// or automatically by BoxGrid::_faces;
|
// or automatically by BoxGrid::_faces;
|
||||||
occluder = new OccluderData(source, poly);
|
occluder = new OccluderData(source, poly);
|
||||||
@@ -350,7 +366,8 @@ inline void BoxGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& pol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) {
|
inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
|
||||||
|
{
|
||||||
Polygon3r& poly(source.getGridSpacePolygon());
|
Polygon3r& poly(source.getGridSpacePolygon());
|
||||||
occluder = NULL;
|
occluder = NULL;
|
||||||
|
|
||||||
@@ -361,9 +378,9 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
|
|||||||
getCellCoordinates(bbMin, startX, startY);
|
getCellCoordinates(bbMin, startX, startY);
|
||||||
getCellCoordinates(bbMax, endX, endY);
|
getCellCoordinates(bbMax, endX, endY);
|
||||||
|
|
||||||
for ( unsigned i = startX; i <= endX; ++i ) {
|
for (unsigned int i = startX; i <= endX; ++i) {
|
||||||
for ( unsigned j = startY; j <= endY; ++j ) {
|
for (unsigned int j = startY; j <= endY; ++j) {
|
||||||
if ( _cells[i * _cellsY + j] != NULL ) {
|
if (_cells[i * _cellsY + j] != NULL) {
|
||||||
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
|
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,5 +389,4 @@ inline bool BoxGrid::insertOccluder(OccluderSource& source, OccluderData*& occlu
|
|||||||
return occluder != NULL;
|
return occluder != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BOXGRID_H
|
#endif // __FREESTYLE_BOX_GRID_H__
|
||||||
|
|
||||||
|
|||||||
@@ -1,67 +1,74 @@
|
|||||||
//
|
/*
|
||||||
// Filename : CulledOccluderSource.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2010-12-21
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/view_map/CulledOccluderSource.cpp
|
||||||
//
|
* \ingroup freestyle
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
// with this source distribution.
|
* \author Alexander Beels
|
||||||
//
|
* \date 2010-12-21
|
||||||
// This program is free software; you can redistribute it and/or
|
*/
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "CulledOccluderSource.h"
|
#include "CulledOccluderSource.h"
|
||||||
#include "../geometry/GridHelpers.h"
|
|
||||||
#include "FRS_freestyle.h"
|
#include "FRS_freestyle.h"
|
||||||
|
|
||||||
CulledOccluderSource::CulledOccluderSource (const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap, bool extensiveFEdgeSearch)
|
#include "../geometry/GridHelpers.h"
|
||||||
: OccluderSource(t, we),
|
|
||||||
rejected(0),
|
CulledOccluderSource::CulledOccluderSource(const GridHelpers::Transform& t, WingedEdge& we, ViewMap& viewMap,
|
||||||
gridSpaceOccluderProsceniumInitialized(false)
|
bool extensiveFEdgeSearch)
|
||||||
|
: OccluderSource(t, we), rejected(0), gridSpaceOccluderProsceniumInitialized(false)
|
||||||
{
|
{
|
||||||
cullViewEdges(viewMap, extensiveFEdgeSearch);
|
cullViewEdges(viewMap, extensiveFEdgeSearch);
|
||||||
|
|
||||||
// If we have not found any visible FEdges during our cull, then there is nothing
|
// If we have not found any visible FEdges during our cull, then there is nothing to iterate over.
|
||||||
// to iterate over. Short-circuit everything.
|
// Short-circuit everything.
|
||||||
valid = gridSpaceOccluderProsceniumInitialized;
|
valid = gridSpaceOccluderProsceniumInitialized;
|
||||||
|
|
||||||
if ( valid && ! testCurrent() ) {
|
if (valid && ! testCurrent()) {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CulledOccluderSource::~CulledOccluderSource() {
|
CulledOccluderSource::~CulledOccluderSource() {}
|
||||||
}
|
|
||||||
|
|
||||||
bool CulledOccluderSource::testCurrent() {
|
bool CulledOccluderSource::testCurrent()
|
||||||
if ( valid ) {
|
{
|
||||||
|
if (valid) {
|
||||||
// The test for gridSpaceOccluderProsceniumInitialized should not be necessary
|
// The test for gridSpaceOccluderProsceniumInitialized should not be necessary
|
||||||
return gridSpaceOccluderProsceniumInitialized && GridHelpers::insideProscenium (gridSpaceOccluderProscenium, cachedPolygon);
|
return gridSpaceOccluderProsceniumInitialized &&
|
||||||
|
GridHelpers::insideProscenium(gridSpaceOccluderProscenium, cachedPolygon);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CulledOccluderSource::next() {
|
bool CulledOccluderSource::next()
|
||||||
while ( OccluderSource::next() ) {
|
{
|
||||||
if ( testCurrent() ) {
|
while (OccluderSource::next()) {
|
||||||
|
if (testCurrent()) {
|
||||||
++rejected;
|
++rejected;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -70,17 +77,20 @@ bool CulledOccluderSource::next() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CulledOccluderSource::getOccluderProscenium(real proscenium[4]) {
|
void CulledOccluderSource::getOccluderProscenium(real proscenium[4])
|
||||||
for ( unsigned i = 0; i < 4; ++i ) {
|
{
|
||||||
|
for (unsigned int i = 0; i < 4; ++i) {
|
||||||
proscenium[i] = gridSpaceOccluderProscenium[i];
|
proscenium[i] = gridSpaceOccluderProscenium[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline real distance2D(const Vec3r & point, const real origin[2]) {
|
static inline real distance2D(const Vec3r & point, const real origin[2])
|
||||||
|
{
|
||||||
return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
|
return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
|
static inline bool crossesProscenium(real proscenium[4], FEdge *fe)
|
||||||
|
{
|
||||||
Vec2r min(proscenium[0], proscenium[2]);
|
Vec2r min(proscenium[0], proscenium[2]);
|
||||||
Vec2r max(proscenium[1], proscenium[3]);
|
Vec2r max(proscenium[1], proscenium[3]);
|
||||||
Vec2r A(fe->vertexA()->getProjectedX(), fe->vertexA()->getProjectedY());
|
Vec2r A(fe->vertexA()->getProjectedX(), fe->vertexA()->getProjectedY());
|
||||||
@@ -89,20 +99,20 @@ static inline bool crossesProscenium(real proscenium[4], FEdge *fe) {
|
|||||||
return GeomUtils::intersect2dSeg2dArea (min, max, A, B);
|
return GeomUtils::intersect2dSeg2dArea (min, max, A, B);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool insideProscenium(real proscenium[4], const Vec3r& point) {
|
static inline bool insideProscenium(real proscenium[4], const Vec3r& point)
|
||||||
return ! ( point[0] < proscenium[0] || point[0] > proscenium[1] || point[1] < proscenium[2] || point[1] > proscenium[3] );
|
{
|
||||||
|
return !(point[0] < proscenium[0] || point[0] > proscenium[1] ||
|
||||||
|
point[1] < proscenium[2] || point[1] > proscenium[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch) {
|
void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch)
|
||||||
|
{
|
||||||
// Cull view edges by marking them as non-displayable.
|
// Cull view edges by marking them as non-displayable.
|
||||||
// This avoids the complications of trying to delete
|
// This avoids the complications of trying to delete edges from the ViewMap.
|
||||||
// edges from the ViewMap.
|
|
||||||
|
|
||||||
// Non-displayable view edges will be skipped over during
|
// Non-displayable view edges will be skipped over during visibility calculation.
|
||||||
// visibility calculation.
|
|
||||||
|
|
||||||
// View edges will be culled according to their position
|
// View edges will be culled according to their position w.r.t. the viewport proscenium (viewport + 5% border,
|
||||||
// w.r.t. the viewport proscenium (viewport + 5% border,
|
|
||||||
// or some such).
|
// or some such).
|
||||||
|
|
||||||
// Get proscenium boundary for culling
|
// Get proscenium boundary for culling
|
||||||
@@ -112,34 +122,30 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
|||||||
prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
|
prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
|
||||||
prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
|
prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
|
||||||
cout << "Proscenium culling:" << endl;
|
cout << "Proscenium culling:" << endl;
|
||||||
cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2] << ", " << viewProscenium[3] << "]"<< endl;
|
cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2]
|
||||||
|
<< ", " << viewProscenium[3] << "]"<< endl;
|
||||||
cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]"<< endl;
|
cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]"<< endl;
|
||||||
|
|
||||||
// A separate occluder proscenium will also be maintained,
|
// A separate occluder proscenium will also be maintained, starting out the same as the viewport proscenium, and
|
||||||
// starting out the same as the viewport proscenium, and
|
// expanding as necessary so that it encompasses the center point of at least one feature edge in each
|
||||||
// expanding as necessary so that it encompasses the center
|
// retained view edge.
|
||||||
// point of at least one feature edge in each retained view
|
// The occluder proscenium will be used later to cull occluding triangles before they are inserted into the Grid.
|
||||||
// edge.
|
// The occluder proscenium starts out the same size as the view proscenium
|
||||||
// The occluder proscenium will be used later to cull occluding
|
|
||||||
// triangles before they are inserted into the Grid.
|
|
||||||
// The occluder proscenium starts out the same size as the view
|
|
||||||
// proscenium
|
|
||||||
GridHelpers::getDefaultViewProscenium(occluderProscenium);
|
GridHelpers::getDefaultViewProscenium(occluderProscenium);
|
||||||
|
|
||||||
// N.B. Freestyle is inconsistent in its use of ViewMap::viewedges_container
|
// XXX Freestyle is inconsistent in its use of ViewMap::viewedges_container and vector<ViewEdge*>::iterator.
|
||||||
// and vector<ViewEdge*>::iterator. Probably all occurences of vector<ViewEdge*>::iterator
|
// Probably all occurences of vector<ViewEdge*>::iterator should be replaced ViewMap::viewedges_container
|
||||||
// should be replaced ViewMap::viewedges_container throughout the code.
|
// throughout the code.
|
||||||
// For each view edge
|
// For each view edge
|
||||||
ViewMap::viewedges_container::iterator ve, veend;
|
ViewMap::viewedges_container::iterator ve, veend;
|
||||||
|
|
||||||
for(ve=viewMap.ViewEdges().begin(), veend=viewMap.ViewEdges().end(); ve!=veend; ve++) {
|
for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
|
||||||
// Overview:
|
// Overview:
|
||||||
// Search for a visible feature edge
|
// Search for a visible feature edge
|
||||||
// If none: mark view edge as non-displayable
|
// If none: mark view edge as non-displayable
|
||||||
// Otherwise:
|
// Otherwise:
|
||||||
// Find a feature edge with center point inside occluder proscenium.
|
// Find a feature edge with center point inside occluder proscenium.
|
||||||
// If none exists, find the feature edge with center point
|
// If none exists, find the feature edge with center point closest to viewport origin.
|
||||||
// closest to viewport origin.
|
|
||||||
// Expand occluder proscenium to enclose center point.
|
// Expand occluder proscenium to enclose center point.
|
||||||
|
|
||||||
// For each feature edge, while bestOccluderTarget not found and view edge not visibile
|
// For each feature edge, while bestOccluderTarget not found and view edge not visibile
|
||||||
@@ -151,28 +157,27 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
|||||||
// All ViewEdges start culled
|
// All ViewEdges start culled
|
||||||
(*ve)->setIsInImage(false);
|
(*ve)->setIsInImage(false);
|
||||||
|
|
||||||
// For simple visibility calculation: mark a feature edge
|
// For simple visibility calculation: mark a feature edge that is known to have a center point inside
|
||||||
// that is known to have a center point inside the occluder proscenium.
|
// the occluder proscenium. Cull all other feature edges.
|
||||||
// Cull all other feature edges.
|
|
||||||
do {
|
do {
|
||||||
// All FEdges start culled
|
// All FEdges start culled
|
||||||
fe->setIsInImage(false);
|
fe->setIsInImage(false);
|
||||||
|
|
||||||
// Look for the visible edge that can most easily be included
|
// Look for the visible edge that can most easily be included in the occluder proscenium.
|
||||||
// in the occluder proscenium.
|
if (!bestOccluderTargetFound) {
|
||||||
if ( ! bestOccluderTargetFound ) {
|
|
||||||
// If center point is inside occluder proscenium,
|
// If center point is inside occluder proscenium,
|
||||||
if ( insideProscenium(occluderProscenium, fe->center2d()) ) {
|
if (insideProscenium(occluderProscenium, fe->center2d())) {
|
||||||
// Use this feature edge for visibility deterimination
|
// Use this feature edge for visibility deterimination
|
||||||
fe->setIsInImage(true);
|
fe->setIsInImage(true);
|
||||||
expandGridSpaceOccluderProscenium(fe);
|
expandGridSpaceOccluderProscenium(fe);
|
||||||
// Mark bestOccluderTarget as found
|
// Mark bestOccluderTarget as found
|
||||||
bestOccluderTargetFound = true;
|
bestOccluderTargetFound = true;
|
||||||
bestOccluderTarget = fe;
|
bestOccluderTarget = fe;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
real d = distance2D(fe->center2d(), prosceniumOrigin);
|
real d = distance2D(fe->center2d(), prosceniumOrigin);
|
||||||
// If center point is closer to viewport origin than current target
|
// If center point is closer to viewport origin than current target
|
||||||
if ( bestOccluderTarget == NULL || d < bestOccluderDistance ) {
|
if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
|
||||||
// Then store as bestOccluderTarget
|
// Then store as bestOccluderTarget
|
||||||
bestOccluderDistance = d;
|
bestOccluderDistance = d;
|
||||||
bestOccluderTarget = fe;
|
bestOccluderTarget = fe;
|
||||||
@@ -181,33 +186,35 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If feature edge crosses the view proscenium
|
// If feature edge crosses the view proscenium
|
||||||
if ( ! (*ve)->isInImage() && crossesProscenium(viewProscenium, fe) ) {
|
if (!(*ve)->isInImage() && crossesProscenium(viewProscenium, fe)) {
|
||||||
// Then the view edge will be included in the image
|
// Then the view edge will be included in the image
|
||||||
(*ve)->setIsInImage(true);
|
(*ve)->setIsInImage(true);
|
||||||
}
|
}
|
||||||
fe = fe->nextEdge();
|
fe = fe->nextEdge();
|
||||||
} while ( fe != NULL && fe != festart && ! ( bestOccluderTargetFound && (*ve)->isInImage() ) );
|
} while (fe != NULL && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));
|
||||||
|
|
||||||
// Either we have run out of FEdges, or we already have the one edge we need to determine visibility
|
// Either we have run out of FEdges, or we already have the one edge we need to determine visibility
|
||||||
// Cull all remaining edges.
|
// Cull all remaining edges.
|
||||||
while ( fe != NULL && fe != festart ) {
|
while (fe != NULL && fe != festart) {
|
||||||
fe->setIsInImage(false);
|
fe->setIsInImage(false);
|
||||||
fe = fe->nextEdge();
|
fe = fe->nextEdge();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If bestOccluderTarget was not found inside the occluder proscenium,
|
// If bestOccluderTarget was not found inside the occluder proscenium,
|
||||||
// we need to expand the occluder proscenium to include it.
|
// we need to expand the occluder proscenium to include it.
|
||||||
if ( (*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound ) {
|
if ((*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound) {
|
||||||
// Expand occluder proscenium to enclose bestOccluderTarget
|
// Expand occluder proscenium to enclose bestOccluderTarget
|
||||||
Vec3r point = bestOccluderTarget->center2d();
|
Vec3r point = bestOccluderTarget->center2d();
|
||||||
if ( point[0] < occluderProscenium[0] ) {
|
if (point[0] < occluderProscenium[0]) {
|
||||||
occluderProscenium[0] = point[0];
|
occluderProscenium[0] = point[0];
|
||||||
} else if ( point[0] > occluderProscenium[1] ) {
|
}
|
||||||
|
else if (point[0] > occluderProscenium[1]) {
|
||||||
occluderProscenium[1] = point[0];
|
occluderProscenium[1] = point[0];
|
||||||
}
|
}
|
||||||
if ( point[1] < occluderProscenium[2] ) {
|
if (point[1] < occluderProscenium[2]) {
|
||||||
occluderProscenium[2] = point[1];
|
occluderProscenium[2] = point[1];
|
||||||
} else if ( point[1] > occluderProscenium[3] ) {
|
}
|
||||||
|
else if (point[1] > occluderProscenium[3]) {
|
||||||
occluderProscenium[3] = point[1];
|
occluderProscenium[3] = point[1];
|
||||||
}
|
}
|
||||||
// Use bestOccluderTarget for visibility determination
|
// Use bestOccluderTarget for visibility determination
|
||||||
@@ -225,22 +232,18 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
|||||||
|
|
||||||
// For "Normal" or "Fast" style visibility computation only:
|
// For "Normal" or "Fast" style visibility computation only:
|
||||||
|
|
||||||
// For more detailed visibility calculation, make a second pass through
|
// For more detailed visibility calculation, make a second pass through the view map, marking all feature edges
|
||||||
// the view map, marking all feature edges with center points inside
|
// with center points inside the final occluder proscenium. All of these feature edges can be considered during
|
||||||
// the final occluder proscenium. All of these feature edges can be
|
// visibility calculation.
|
||||||
// considered during visibility calculation.
|
|
||||||
|
|
||||||
// So far we have only found one FEdge per ViewEdge. The "Normal" and
|
// So far we have only found one FEdge per ViewEdge. The "Normal" and "Fast" styles of visibility computation
|
||||||
// "Fast" styles of visibility computation want to consider many
|
// want to consider many FEdges for each ViewEdge.
|
||||||
// FEdges for each ViewEdge.
|
// Here we re-scan the view map to find any usable FEdges that we skipped on the first pass, or that have become
|
||||||
// Here we re-scan the view map to find any usable FEdges that we
|
// usable because the occluder proscenium has been expanded since the edge was visited on the first pass.
|
||||||
// skipped on the first pass, or that have become usable because the
|
if (extensiveFEdgeSearch) {
|
||||||
// occluder proscenium has been expanded since the edge was visited
|
|
||||||
// on the first pass.
|
|
||||||
if ( extensiveFEdgeSearch ) {
|
|
||||||
// For each view edge,
|
// For each view edge,
|
||||||
for(ve=viewMap.ViewEdges().begin(), veend=viewMap.ViewEdges().end(); ve!=veend; ve++) {
|
for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
|
||||||
if ( ! (*ve)->isInImage() ) {
|
if (!(*ve)->isInImage()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// For each feature edge,
|
// For each feature edge,
|
||||||
@@ -248,30 +251,31 @@ void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSe
|
|||||||
FEdge *fe = festart;
|
FEdge *fe = festart;
|
||||||
do {
|
do {
|
||||||
// If not (already) visible and center point inside occluder proscenium,
|
// If not (already) visible and center point inside occluder proscenium,
|
||||||
if ( ! fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d()) ) {
|
if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
|
||||||
// Use the feature edge for visibility determination
|
// Use the feature edge for visibility determination
|
||||||
fe->setIsInImage(true);
|
fe->setIsInImage(true);
|
||||||
expandGridSpaceOccluderProscenium(fe);
|
expandGridSpaceOccluderProscenium(fe);
|
||||||
}
|
}
|
||||||
fe = fe->nextEdge();
|
fe = fe->nextEdge();
|
||||||
} while ( fe != NULL && fe != festart );
|
} while (fe != NULL && fe != festart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Up until now, all calculations have been done in camera space.
|
// Up until now, all calculations have been done in camera space.
|
||||||
// However, the occluder source's iteration and the grid that consumes the occluders
|
// However, the occluder source's iteration and the grid that consumes the occluders both work in gridspace,
|
||||||
// both work in gridspace, so we need a version of the occluder proscenium in gridspace.
|
// so we need a version of the occluder proscenium in gridspace.
|
||||||
// Set the gridspace occlude proscenium
|
// Set the gridspace occlude proscenium
|
||||||
}
|
}
|
||||||
|
|
||||||
void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge* fe) {
|
void CulledOccluderSource::expandGridSpaceOccluderProscenium(FEdge *fe)
|
||||||
if ( gridSpaceOccluderProsceniumInitialized ) {
|
{
|
||||||
GridHelpers::expandProscenium (gridSpaceOccluderProscenium, transform(fe->center3d()));
|
if (gridSpaceOccluderProsceniumInitialized) {
|
||||||
} else {
|
GridHelpers::expandProscenium(gridSpaceOccluderProscenium, transform(fe->center3d()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
const Vec3r& point = transform(fe->center3d());
|
const Vec3r& point = transform(fe->center3d());
|
||||||
gridSpaceOccluderProscenium[0] = gridSpaceOccluderProscenium[1] = point[0];
|
gridSpaceOccluderProscenium[0] = gridSpaceOccluderProscenium[1] = point[0];
|
||||||
gridSpaceOccluderProscenium[2] = gridSpaceOccluderProscenium[3] = point[1];
|
gridSpaceOccluderProscenium[2] = gridSpaceOccluderProscenium[3] = point[1];
|
||||||
gridSpaceOccluderProsceniumInitialized = true;
|
gridSpaceOccluderProsceniumInitialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +1,52 @@
|
|||||||
//
|
/*
|
||||||
// Filename : CulledOccluderSource.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2010-12-21
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
|
||||||
|
#define __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/CulledOccluderSource.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2010-12-21
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef CULLEDOCCLUDERSOURCE_H
|
|
||||||
#define CULLEDOCCLUDERSOURCE_H
|
|
||||||
|
|
||||||
#include "OccluderSource.h"
|
#include "OccluderSource.h"
|
||||||
#include "ViewMap.h"
|
#include "ViewMap.h"
|
||||||
|
|
||||||
class CulledOccluderSource : public OccluderSource {
|
class CulledOccluderSource : public OccluderSource
|
||||||
|
{
|
||||||
// Disallow copying and assignment
|
// Disallow copying and assignment
|
||||||
CulledOccluderSource (const CulledOccluderSource& other);
|
CulledOccluderSource(const CulledOccluderSource& other);
|
||||||
CulledOccluderSource& operator= (const CulledOccluderSource& other);
|
CulledOccluderSource& operator=(const CulledOccluderSource& other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CulledOccluderSource (const GridHelpers::Transform& transform, WingedEdge& we, ViewMap& viewMap, bool extensiveFEdgeSearch = true);
|
CulledOccluderSource(const GridHelpers::Transform& transform, WingedEdge& we, ViewMap& viewMap,
|
||||||
|
bool extensiveFEdgeSearch = true);
|
||||||
virtual ~CulledOccluderSource();
|
virtual ~CulledOccluderSource();
|
||||||
|
|
||||||
void cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch);
|
void cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch);
|
||||||
@@ -51,7 +57,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool testCurrent();
|
bool testCurrent();
|
||||||
void expandGridSpaceOccluderProscenium(FEdge* fe);
|
void expandGridSpaceOccluderProscenium(FEdge *fe);
|
||||||
|
|
||||||
real occluderProscenium[4];
|
real occluderProscenium[4];
|
||||||
real gridSpaceOccluderProscenium[4];
|
real gridSpaceOccluderProscenium[4];
|
||||||
@@ -60,4 +66,4 @@ private:
|
|||||||
bool gridSpaceOccluderProsceniumInitialized;
|
bool gridSpaceOccluderProsceniumInitialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CULLEDOCCLUDERSOURCE_H
|
#endif // __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
|
||||||
|
|||||||
@@ -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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/FEdgeXDetector.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Detects/flags/builds extended features edges on the WXEdge structure
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 26/10/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
#include <float.h>
|
||||||
//
|
#include <math.h>
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "FEdgeXDetector.h"
|
#include "FEdgeXDetector.h"
|
||||||
#include "float.h"
|
|
||||||
#include "../geometry/GeomUtils.h"
|
#include "../geometry/GeomUtils.h"
|
||||||
#include <math.h>
|
|
||||||
#include "../geometry/normal_cycle.h"
|
#include "../geometry/normal_cycle.h"
|
||||||
|
|
||||||
void FEdgeXDetector::processShapes(WingedEdge& we) {
|
void FEdgeXDetector::processShapes(WingedEdge& we)
|
||||||
|
{
|
||||||
bool progressBarDisplay = false;
|
bool progressBarDisplay = false;
|
||||||
Vec3r Min, Max;
|
Vec3r Min, Max;
|
||||||
vector<WShape*> wshapes = we.getWShapes();
|
vector<WShape*> wshapes = we.getWShapes();
|
||||||
WXShape * wxs;
|
WXShape *wxs;
|
||||||
|
|
||||||
if(_pProgressBar != NULL) {
|
if (_pProgressBar != NULL) {
|
||||||
_pProgressBar->reset();
|
_pProgressBar->reset();
|
||||||
_pProgressBar->setLabelText("Detecting feature lines");
|
_pProgressBar->setLabelText("Detecting feature lines");
|
||||||
_pProgressBar->setTotalSteps(wshapes.size() * 3);
|
_pProgressBar->setTotalSteps(wshapes.size() * 3);
|
||||||
@@ -39,39 +55,37 @@ void FEdgeXDetector::processShapes(WingedEdge& we) {
|
|||||||
progressBarDisplay = true;
|
progressBarDisplay = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(vector<WShape*>::const_iterator it = wshapes.begin();
|
for (vector<WShape*>::const_iterator it = wshapes.begin(); it != wshapes.end(); it++) {
|
||||||
it != wshapes.end();
|
|
||||||
it++){
|
|
||||||
if (_pRenderMonitor && _pRenderMonitor->testBreak())
|
if (_pRenderMonitor && _pRenderMonitor->testBreak())
|
||||||
break;
|
break;
|
||||||
wxs = dynamic_cast<WXShape*>(*it);
|
wxs = dynamic_cast<WXShape*>(*it);
|
||||||
wxs->bbox(Min, Max);
|
wxs->bbox(Min, Max);
|
||||||
_bbox_diagonal = (Max-Min).norm();
|
_bbox_diagonal = (Max - Min).norm();
|
||||||
if(_changes){
|
if (_changes) {
|
||||||
vector<WFace*>& wfaces = wxs->GetFaceList();
|
vector<WFace*>& wfaces = wxs->GetFaceList();
|
||||||
for(vector<WFace*>::iterator wf=wfaces.begin(), wfend=wfaces.end();
|
for (vector<WFace*>::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; ++wf) {
|
||||||
wf!=wfend;
|
WXFace *wxf = dynamic_cast<WXFace*>(*wf);
|
||||||
++wf){
|
|
||||||
WXFace* wxf = dynamic_cast<WXFace*>(*wf);
|
|
||||||
wxf->Clear();
|
wxf->Clear();
|
||||||
}
|
}
|
||||||
_computeViewIndependant = true;
|
_computeViewIndependant = true;
|
||||||
} else if (!(wxs)->getComputeViewIndependantFlag()) {
|
}
|
||||||
|
else if (!(wxs)->getComputeViewIndependantFlag()) {
|
||||||
wxs->Reset();
|
wxs->Reset();
|
||||||
_computeViewIndependant = false;
|
_computeViewIndependant = false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
_computeViewIndependant = true;
|
_computeViewIndependant = true;
|
||||||
}
|
}
|
||||||
preProcessShape(wxs);
|
preProcessShape(wxs);
|
||||||
if (progressBarDisplay)
|
if (progressBarDisplay)
|
||||||
_pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
|
_pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
|
||||||
processBorderShape(wxs);
|
processBorderShape(wxs);
|
||||||
if(_computeMaterialBoundaries)
|
if (_computeMaterialBoundaries)
|
||||||
processMaterialBoundaryShape(wxs);
|
processMaterialBoundaryShape(wxs);
|
||||||
processCreaseShape(wxs);
|
processCreaseShape(wxs);
|
||||||
if(_computeRidgesAndValleys)
|
if (_computeRidgesAndValleys)
|
||||||
processRidgesAndValleysShape(wxs);
|
processRidgesAndValleysShape(wxs);
|
||||||
if(_computeSuggestiveContours)
|
if (_computeSuggestiveContours)
|
||||||
processSuggestiveContourShape(wxs);
|
processSuggestiveContourShape(wxs);
|
||||||
processSilhouetteShape(wxs);
|
processSilhouetteShape(wxs);
|
||||||
processEdgeMarksShape(wxs);
|
processEdgeMarksShape(wxs);
|
||||||
@@ -82,7 +96,7 @@ void FEdgeXDetector::processShapes(WingedEdge& we) {
|
|||||||
buildSmoothEdges(wxs);
|
buildSmoothEdges(wxs);
|
||||||
|
|
||||||
// Post processing for suggestive contours
|
// Post processing for suggestive contours
|
||||||
if(_computeSuggestiveContours)
|
if (_computeSuggestiveContours)
|
||||||
postProcessSuggestiveContourShape(wxs);
|
postProcessSuggestiveContourShape(wxs);
|
||||||
if (progressBarDisplay)
|
if (progressBarDisplay)
|
||||||
_pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
|
_pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
|
||||||
@@ -98,7 +112,8 @@ void FEdgeXDetector::processShapes(WingedEdge& we) {
|
|||||||
|
|
||||||
// GENERAL STUFF
|
// GENERAL STUFF
|
||||||
////////////////
|
////////////////
|
||||||
void FEdgeXDetector::preProcessShape(WXShape* iWShape) {
|
void FEdgeXDetector::preProcessShape(WXShape *iWShape)
|
||||||
|
{
|
||||||
_meanK1 = 0;
|
_meanK1 = 0;
|
||||||
_meanKr = 0;
|
_meanKr = 0;
|
||||||
_minK1 = FLT_MAX;
|
_minK1 = FLT_MAX;
|
||||||
@@ -109,21 +124,17 @@ void FEdgeXDetector::preProcessShape(WXShape* iWShape) {
|
|||||||
_meanEdgeSize = iWShape->getMeanEdgeSize();
|
_meanEdgeSize = iWShape->getMeanEdgeSize();
|
||||||
|
|
||||||
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
||||||
vector<WFace*>::iterator f,fend;
|
vector<WFace*>::iterator f, fend;
|
||||||
// view dependant stuff
|
// view dependant stuff
|
||||||
for(f=wfaces.begin(), fend=wfaces.end();
|
for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
|
||||||
f!=fend;
|
|
||||||
++f){
|
|
||||||
preProcessFace((WXFace*)(*f));
|
preProcessFace((WXFace*)(*f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_computeRidgesAndValleys || _computeSuggestiveContours ) {
|
if (_computeRidgesAndValleys || _computeSuggestiveContours) {
|
||||||
vector<WVertex*>& wvertices = iWShape->getVertexList();
|
vector<WVertex*>& wvertices = iWShape->getVertexList();
|
||||||
for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end();
|
for (vector<WVertex*>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
|
||||||
wv!=wvend;
|
|
||||||
++wv){
|
|
||||||
// Compute curvatures
|
// Compute curvatures
|
||||||
WXVertex * wxv = dynamic_cast<WXVertex*>(*wv);
|
WXVertex *wxv = dynamic_cast<WXVertex*>(*wv);
|
||||||
computeCurvatures(wxv);
|
computeCurvatures(wxv);
|
||||||
}
|
}
|
||||||
_meanK1 /= (real)(_nPoints);
|
_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 firstPoint = iFace->GetVertex(0)->GetVertex();
|
||||||
Vec3r N = iFace->GetNormal();
|
Vec3r N = iFace->GetNormal();
|
||||||
|
|
||||||
@@ -139,7 +151,8 @@ void FEdgeXDetector::preProcessFace(WXFace *iFace){
|
|||||||
Vec3r V;
|
Vec3r V;
|
||||||
if (_orthographicProjection) {
|
if (_orthographicProjection) {
|
||||||
V = Vec3r(0.0, 0.0, _Viewpoint.z() - firstPoint.z());
|
V = Vec3r(0.0, 0.0, _Viewpoint.z() - firstPoint.z());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
V = Vec3r(_Viewpoint - firstPoint);
|
V = Vec3r(_Viewpoint - firstPoint);
|
||||||
}
|
}
|
||||||
N.normalize();
|
N.normalize();
|
||||||
@@ -149,13 +162,15 @@ void FEdgeXDetector::preProcessFace(WXFace *iFace){
|
|||||||
// compute the distance between the face center and the viewpoint:
|
// compute the distance between the face center and the viewpoint:
|
||||||
if (_orthographicProjection) {
|
if (_orthographicProjection) {
|
||||||
iFace->setZ(iFace->center().z() - _Viewpoint.z());
|
iFace->setZ(iFace->center().z() - _Viewpoint.z());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Vec3r dist_vec(iFace->center() - _Viewpoint);
|
Vec3r dist_vec(iFace->center() - _Viewpoint);
|
||||||
iFace->setZ(dist_vec.norm());
|
iFace->setZ(dist_vec.norm());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
|
void FEdgeXDetector::computeCurvatures(WXVertex *vertex)
|
||||||
|
{
|
||||||
// CURVATURE LAYER
|
// CURVATURE LAYER
|
||||||
// store all the curvature datas for each vertex
|
// store all the curvature datas for each vertex
|
||||||
|
|
||||||
@@ -164,42 +179,44 @@ void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
|
|||||||
Vec3r e1, n, v;
|
Vec3r e1, n, v;
|
||||||
// one vertex curvature info :
|
// one vertex curvature info :
|
||||||
CurvatureInfo *C;
|
CurvatureInfo *C;
|
||||||
float radius = _sphereRadius*_meanEdgeSize;
|
float radius = _sphereRadius * _meanEdgeSize;
|
||||||
|
|
||||||
// view independant stuff
|
// view independant stuff
|
||||||
if(_computeViewIndependant){
|
if (_computeViewIndependant) {
|
||||||
C = new CurvatureInfo();
|
C = new CurvatureInfo();
|
||||||
vertex->setCurvatures(C);
|
vertex->setCurvatures(C);
|
||||||
OGF::NormalCycle ncycle ;
|
OGF::NormalCycle ncycle;
|
||||||
ncycle.begin() ;
|
ncycle.begin();
|
||||||
if(radius > 0) {
|
if (radius > 0) {
|
||||||
OGF::compute_curvature_tensor(vertex, radius, ncycle) ;
|
OGF::compute_curvature_tensor(vertex, radius, ncycle);
|
||||||
} else {
|
|
||||||
OGF::compute_curvature_tensor_one_ring(vertex, ncycle) ;
|
|
||||||
}
|
}
|
||||||
ncycle.end() ;
|
else {
|
||||||
|
OGF::compute_curvature_tensor_one_ring(vertex, ncycle);
|
||||||
|
}
|
||||||
|
ncycle.end();
|
||||||
C->K1 = ncycle.kmin();
|
C->K1 = ncycle.kmin();
|
||||||
C->K2 = ncycle.kmax();
|
C->K2 = ncycle.kmax();
|
||||||
C->e1 = ncycle.Kmax(); //ncycle.kmin() * 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);
|
real absK1 = fabs(C->K1);
|
||||||
_meanK1 += absK1;
|
_meanK1 += absK1;
|
||||||
if(absK1 > _maxK1)
|
if (absK1 > _maxK1)
|
||||||
_maxK1 = absK1;
|
_maxK1 = absK1;
|
||||||
if(absK1 < _minK1)
|
if (absK1 < _minK1)
|
||||||
_minK1 = absK1;
|
_minK1 = absK1;
|
||||||
}
|
}
|
||||||
// view dependant
|
// view dependant
|
||||||
C = vertex->curvatures();
|
C = vertex->curvatures();
|
||||||
if(C == 0)
|
if (C == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// compute radial curvature :
|
// compute radial curvature :
|
||||||
n = C->e1 ^ C->e2;
|
n = C->e1 ^ C->e2;
|
||||||
if (_orthographicProjection) {
|
if (_orthographicProjection) {
|
||||||
v = Vec3r(0.0, 0.0, _Viewpoint.z() - vertex->GetVertex().z());
|
v = Vec3r(0.0, 0.0, _Viewpoint.z() - vertex->GetVertex().z());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
v = Vec3r(_Viewpoint - vertex->GetVertex());
|
v = Vec3r(_Viewpoint - vertex->GetVertex());
|
||||||
}
|
}
|
||||||
C->er = v - (v * n) * n;
|
C->er = v - (v * n) * n;
|
||||||
@@ -212,9 +229,9 @@ void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
|
|||||||
C->Kr = C->K1 * cos2theta + C->K2 * sin2theta;
|
C->Kr = C->K1 * cos2theta + C->K2 * sin2theta;
|
||||||
real absKr = fabs(C->Kr);
|
real absKr = fabs(C->Kr);
|
||||||
_meanKr += absKr;
|
_meanKr += absKr;
|
||||||
if(absKr > _maxKr)
|
if (absKr > _maxKr)
|
||||||
_maxKr = absKr;
|
_maxKr = absKr;
|
||||||
if(absKr < _minKr)
|
if (absKr < _minKr)
|
||||||
_minKr = absKr;
|
_minKr = absKr;
|
||||||
|
|
||||||
++_nPoints;
|
++_nPoints;
|
||||||
@@ -222,52 +239,42 @@ void FEdgeXDetector::computeCurvatures(WXVertex *vertex){
|
|||||||
|
|
||||||
// SILHOUETTE
|
// SILHOUETTE
|
||||||
/////////////
|
/////////////
|
||||||
void FEdgeXDetector::processSilhouetteShape(WXShape* iWShape) {
|
void FEdgeXDetector::processSilhouetteShape(WXShape *iWShape)
|
||||||
// Make a first pass on every polygons in order
|
{
|
||||||
// to compute all their silhouette relative values:
|
// Make a first pass on every polygons in order to compute all their silhouette relative values:
|
||||||
//------------------------------------------------
|
|
||||||
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
||||||
vector<WFace*>::iterator f,fend;
|
vector<WFace*>::iterator f, fend;
|
||||||
for(f=wfaces.begin(), fend=wfaces.end();
|
for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
|
||||||
f!=fend;
|
|
||||||
++f)
|
|
||||||
{
|
|
||||||
ProcessSilhouetteFace((WXFace*)(*f));
|
ProcessSilhouetteFace((WXFace*)(*f));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a pass on the edges to detect
|
// Make a pass on the edges to detect the silhouette edges that are not smooth
|
||||||
// the silhouette edges that are not smooth
|
|
||||||
// --------------------
|
|
||||||
vector<WEdge*>::iterator we, weend;
|
vector<WEdge*>::iterator we, weend;
|
||||||
vector<WEdge*> &wedges = iWShape->getEdgeList();
|
vector<WEdge*> &wedges = iWShape->getEdgeList();
|
||||||
for(we=wedges.begin(), weend=wedges.end();
|
for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
|
||||||
we!=weend;
|
|
||||||
++we)
|
|
||||||
{
|
|
||||||
ProcessSilhouetteEdge((WXEdge*)(*we));
|
ProcessSilhouetteEdge((WXEdge*)(*we));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
|
void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
|
||||||
{
|
{
|
||||||
|
|
||||||
// SILHOUETTE LAYER
|
// SILHOUETTE LAYER
|
||||||
Vec3r normal;
|
Vec3r normal;
|
||||||
// Compute the dot products between View direction and N at each vertex
|
// Compute the dot products between View direction and N at each vertex of the face:
|
||||||
// of the face:
|
|
||||||
Vec3r point;
|
Vec3r point;
|
||||||
int closestPointId = 0;
|
int closestPointId = 0;
|
||||||
real dist, minDist = FLT_MAX;
|
real dist, minDist = FLT_MAX;
|
||||||
int numVertices = iFace->numberOfVertices();
|
int numVertices = iFace->numberOfVertices();
|
||||||
WXFaceLayer * faceLayer = new WXFaceLayer(iFace, Nature::SILHOUETTE, true);
|
WXFaceLayer *faceLayer = new WXFaceLayer(iFace, Nature::SILHOUETTE, true);
|
||||||
for(int i=0; i<numVertices; i++){
|
for (int i = 0; i < numVertices; i++) {
|
||||||
point = iFace->GetVertex(i)->GetVertex();
|
point = iFace->GetVertex(i)->GetVertex();
|
||||||
normal = iFace->GetVertexNormal(i);
|
normal = iFace->GetVertexNormal(i);
|
||||||
normal.normalize();
|
normal.normalize();
|
||||||
Vec3r V;
|
Vec3r V;
|
||||||
if (_orthographicProjection) {
|
if (_orthographicProjection) {
|
||||||
V = Vec3r(0.0, 0.0, _Viewpoint.z() - point.z());
|
V = Vec3r(0.0, 0.0, _Viewpoint.z() - point.z());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
V = Vec3r(_Viewpoint - point);
|
V = Vec3r(_Viewpoint - point);
|
||||||
}
|
}
|
||||||
V.normalize();
|
V.normalize();
|
||||||
@@ -276,11 +283,12 @@ void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
|
|||||||
// Find the point the closest to the viewpoint
|
// Find the point the closest to the viewpoint
|
||||||
if (_orthographicProjection) {
|
if (_orthographicProjection) {
|
||||||
dist = point.z() - _Viewpoint.z();
|
dist = point.z() - _Viewpoint.z();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Vec3r dist_vec(point - _Viewpoint);
|
Vec3r dist_vec(point - _Viewpoint);
|
||||||
dist = dist_vec.norm();
|
dist = dist_vec.norm();
|
||||||
}
|
}
|
||||||
if(dist < minDist) {
|
if (dist < minDist) {
|
||||||
minDist = dist;
|
minDist = dist;
|
||||||
closestPointId = i;
|
closestPointId = i;
|
||||||
}
|
}
|
||||||
@@ -293,54 +301,47 @@ void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace)
|
|||||||
|
|
||||||
void FEdgeXDetector::ProcessSilhouetteEdge(WXEdge *iEdge)
|
void FEdgeXDetector::ProcessSilhouetteEdge(WXEdge *iEdge)
|
||||||
{
|
{
|
||||||
if(iEdge->nature() & Nature::BORDER)
|
if (iEdge->nature() & Nature::BORDER)
|
||||||
return;
|
return;
|
||||||
// SILHOUETTE ?
|
// SILHOUETTE ?
|
||||||
//-------------
|
//-------------
|
||||||
WXFace * fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
|
WXFace *fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
|
||||||
WXFace * fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
|
WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
|
||||||
|
|
||||||
if((fA->front())^(fB->front())){ // fA->visible XOR fB->visible (true if one is 0 and the other is 1)
|
if ((fA->front()) ^ (fB->front())) { // fA->visible XOR fB->visible (true if one is 0 and the other is 1)
|
||||||
// The only edges we want to set as silhouette edges in this
|
// The only edges we want to set as silhouette edges in this way are the ones with 2 different normals for 1 vertex
|
||||||
// way are the ones with 2 different normals for 1 vertex
|
|
||||||
// for these two faces
|
// for these two faces
|
||||||
//--------------------
|
//--------------------
|
||||||
// In reality we only test the normals for 1 of the 2 vertices.
|
// In reality we only test the normals for 1 of the 2 vertices.
|
||||||
if(fA->GetVertexNormal(iEdge->GetaVertex()) == fB->GetVertexNormal(iEdge->GetaVertex()))
|
if (fA->GetVertexNormal(iEdge->GetaVertex()) == fB->GetVertexNormal(iEdge->GetaVertex()))
|
||||||
return;
|
return;
|
||||||
iEdge->AddNature(Nature::SILHOUETTE);
|
iEdge->AddNature(Nature::SILHOUETTE);
|
||||||
if(fB->front())
|
if (fB->front())
|
||||||
iEdge->setOrder(1);
|
iEdge->setOrder(1);
|
||||||
else
|
else
|
||||||
iEdge->setOrder(-1);
|
iEdge->setOrder(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// BORDER
|
// BORDER
|
||||||
/////////
|
/////////
|
||||||
void FEdgeXDetector::processBorderShape(WXShape* iWShape) {
|
void FEdgeXDetector::processBorderShape(WXShape *iWShape)
|
||||||
|
{
|
||||||
if(!_computeViewIndependant)
|
if (!_computeViewIndependant)
|
||||||
return;
|
return;
|
||||||
// Make a pass on the edges to detect
|
// Make a pass on the edges to detect the BORDER
|
||||||
// the BORDER
|
|
||||||
// --------------------
|
|
||||||
vector<WEdge*>::iterator we, weend;
|
vector<WEdge*>::iterator we, weend;
|
||||||
vector<WEdge*> &wedges = iWShape->getEdgeList();
|
vector<WEdge*> &wedges = iWShape->getEdgeList();
|
||||||
for(we=wedges.begin(), weend=wedges.end();
|
for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
|
||||||
we!=weend;
|
ProcessBorderEdge((WXEdge *)(*we));
|
||||||
++we){
|
|
||||||
ProcessBorderEdge((WXEdge*)(*we));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge)
|
void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge)
|
||||||
{
|
{
|
||||||
// first check whether it is a border edge:
|
// first check whether it is a border edge: BORDER ?
|
||||||
// BORDER ?
|
|
||||||
//---------
|
//---------
|
||||||
if(iEdge->GetaFace() == 0){
|
if (iEdge->GetaFace() == 0) {
|
||||||
// it is a border edge
|
// it is a border edge
|
||||||
iEdge->AddNature(Nature::BORDER);
|
iEdge->AddNature(Nature::BORDER);
|
||||||
}
|
}
|
||||||
@@ -349,19 +350,16 @@ void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge)
|
|||||||
|
|
||||||
// CREASE
|
// CREASE
|
||||||
/////////
|
/////////
|
||||||
void FEdgeXDetector::processCreaseShape(WXShape* iWShape) {
|
void FEdgeXDetector::processCreaseShape(WXShape *iWShape)
|
||||||
if(!_computeViewIndependant)
|
{
|
||||||
|
if (!_computeViewIndependant)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Make a pass on the edges to detect
|
// Make a pass on the edges to detect the CREASE
|
||||||
// the CREASE
|
|
||||||
// --------------------
|
|
||||||
vector<WEdge*>::iterator we, weend;
|
vector<WEdge*>::iterator we, weend;
|
||||||
vector<WEdge*> &wedges = iWShape->getEdgeList();
|
vector<WEdge*> &wedges = iWShape->getEdgeList();
|
||||||
for(we=wedges.begin(), weend=wedges.end();
|
for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
|
||||||
we!=weend;
|
ProcessCreaseEdge((WXEdge *)(*we));
|
||||||
++we){
|
|
||||||
ProcessCreaseEdge((WXEdge*)(*we));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,34 +367,30 @@ void FEdgeXDetector::ProcessCreaseEdge(WXEdge *iEdge)
|
|||||||
{
|
{
|
||||||
// CREASE ?
|
// CREASE ?
|
||||||
//---------
|
//---------
|
||||||
if(iEdge->nature() & Nature::BORDER)
|
if (iEdge->nature() & Nature::BORDER)
|
||||||
return;
|
return;
|
||||||
WXFace * fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
|
WXFace *fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
|
||||||
WXFace * fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
|
WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
|
||||||
|
|
||||||
WVertex * aVertex = iEdge->GetaVertex();
|
WVertex *aVertex = iEdge->GetaVertex();
|
||||||
if((fA->GetVertexNormal(aVertex) * fB->GetVertexNormal(aVertex)) <= _creaseAngle)
|
if ((fA->GetVertexNormal(aVertex) * fB->GetVertexNormal(aVertex)) <= _creaseAngle)
|
||||||
iEdge->AddNature(Nature::CREASE);
|
iEdge->AddNature(Nature::CREASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RIDGES AND VALLEYS
|
// RIDGES AND VALLEYS
|
||||||
/////////////////////
|
/////////////////////
|
||||||
|
void FEdgeXDetector::processRidgesAndValleysShape(WXShape *iWShape)
|
||||||
void FEdgeXDetector::processRidgesAndValleysShape(WXShape* iWShape) {
|
{
|
||||||
// Don't forget to add the built layer to the face at the end
|
// Don't forget to add the built layer to the face at the end of the ProcessFace:
|
||||||
// of the ProcessFace:
|
|
||||||
//iFace->AddSmoothLayer(faceLayer);
|
//iFace->AddSmoothLayer(faceLayer);
|
||||||
|
|
||||||
if((!_computeViewIndependant))
|
if (!_computeViewIndependant)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Here the curvatures must already have been computed
|
// Here the curvatures must already have been computed
|
||||||
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
||||||
vector<WFace*>::iterator f, fend;
|
vector<WFace*>::iterator f, fend;
|
||||||
for(f=wfaces.begin(), fend=wfaces.end();
|
for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
|
||||||
f!=fend;
|
|
||||||
++f)
|
|
||||||
{
|
|
||||||
ProcessRidgeFace((WXFace*)(*f));
|
ProcessRidgeFace((WXFace*)(*f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -404,24 +398,25 @@ void FEdgeXDetector::processRidgesAndValleysShape(WXShape* iWShape) {
|
|||||||
|
|
||||||
// RIDGES
|
// RIDGES
|
||||||
/////////
|
/////////
|
||||||
|
|
||||||
void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
|
void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
|
||||||
{
|
{
|
||||||
WXFaceLayer * flayer = new WXFaceLayer(iFace, Nature::RIDGE|Nature::VALLEY, false);
|
WXFaceLayer *flayer = new WXFaceLayer(iFace, Nature::RIDGE|Nature::VALLEY, false);
|
||||||
iFace->AddSmoothLayer(flayer);
|
iFace->AddSmoothLayer(flayer);
|
||||||
|
|
||||||
unsigned int numVertices = iFace->numberOfVertices();
|
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);
|
WVertex *wv = iFace->GetVertex(i);
|
||||||
WXVertex * wxv = dynamic_cast<WXVertex*>(wv);
|
WXVertex *wxv = dynamic_cast<WXVertex*>(wv);
|
||||||
flayer->PushDotP(wxv->curvatures()->K1);
|
flayer->PushDotP(wxv->curvatures()->K1);
|
||||||
}
|
}
|
||||||
|
|
||||||
real threshold = 0;
|
real threshold = 0;
|
||||||
//real threshold = _maxK1 - (_maxK1-_meanK1)/20.0;
|
//real threshold = _maxK1 - (_maxK1 - _meanK1) / 20.0;
|
||||||
|
|
||||||
if(flayer->nPosDotP()!=numVertices){
|
if (flayer->nPosDotP() != numVertices) {
|
||||||
if((fabs(flayer->dotP(0)) < threshold) && (fabs(flayer->dotP(1)) < threshold) && (fabs(flayer->dotP(2)) < threshold)){
|
if ((fabs(flayer->dotP(0)) < threshold) && (fabs(flayer->dotP(1)) < threshold) &&
|
||||||
|
(fabs(flayer->dotP(2)) < threshold))
|
||||||
|
{
|
||||||
flayer->ReplaceDotP(0, 0);
|
flayer->ReplaceDotP(0, 0);
|
||||||
flayer->ReplaceDotP(1, 0);
|
flayer->ReplaceDotP(1, 0);
|
||||||
flayer->ReplaceDotP(2, 0);
|
flayer->ReplaceDotP(2, 0);
|
||||||
@@ -429,124 +424,119 @@ void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
|
#if 0
|
||||||
// {
|
void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
|
||||||
|
{
|
||||||
|
// RIDGE LAYER
|
||||||
|
// Compute the RidgeFunction, that is the derivative of the ppal curvature along e1 at each vertex of the face
|
||||||
|
WVertex *v;
|
||||||
|
Vec3r v1v2;
|
||||||
|
real t;
|
||||||
|
vector<WXFaceLayer*> SmoothLayers;
|
||||||
|
WXFaceLayer *faceLayer;
|
||||||
|
Face_Curvature_Info *layer_info;
|
||||||
|
real K1_a(0), K1_b(0);
|
||||||
|
Vec3r Inter_a, Inter_b;
|
||||||
|
|
||||||
// // RIDGE LAYER
|
// find the ridge layer of the face
|
||||||
// // compute the RidgeFunction, that is the derivative of the ppal curvature
|
iFace->retrieveSmoothLayers(Nature::RIDGE, SmoothLayers);
|
||||||
// // along e1 at each vertex of the face
|
if ( SmoothLayers.size()!=1 )
|
||||||
|
return;
|
||||||
|
faceLayer = SmoothLayers[0];
|
||||||
|
// retrieve the curvature info of this layer
|
||||||
|
layer_info = (Face_Curvature_Info *)faceLayer->userdata;
|
||||||
|
|
||||||
// WVertex *v;
|
int numVertices = iFace->numberOfVertices();
|
||||||
// Vec3r v1v2;
|
for (int i = 0; i < numVertices; i++) {
|
||||||
// real t;
|
v = iFace->GetVertex(i);
|
||||||
// vector<WXFaceLayer*> SmoothLayers;
|
// vec_curvature_info[i] contains the curvature info of this vertex
|
||||||
// WXFaceLayer *faceLayer;
|
Vec3r e2 = layer_info->vec_curvature_info[i]->K2*layer_info->vec_curvature_info[i]->e2;
|
||||||
// Face_Curvature_Info *layer_info;
|
Vec3r e1 = layer_info->vec_curvature_info[i]->K1*layer_info->vec_curvature_info[i]->e1;
|
||||||
// real K1_a(0), K1_b(0);
|
e2.normalize();
|
||||||
// Vec3r Inter_a, Inter_b;
|
|
||||||
|
|
||||||
// // find the ridge layer of the face
|
WVertex::face_iterator fit = v->faces_begin();
|
||||||
// iFace->retrieveSmoothLayers(Nature::RIDGE, SmoothLayers);
|
WVertex::face_iterator fitend = v->faces_end();
|
||||||
// if(SmoothLayers.size()!=1)
|
for (; fit != fitend; ++fit) {
|
||||||
// return;
|
WXFace *wxf = dynamic_cast<WXFace*>(*fit);
|
||||||
// faceLayer = SmoothLayers[0];
|
WOEdge *oppositeEdge;
|
||||||
// // retrieve the curvature info of this layer
|
if (!(wxf->getOppositeEdge(v, oppositeEdge)))
|
||||||
// layer_info = (Face_Curvature_Info *)faceLayer->userdata;
|
continue;
|
||||||
|
v1v2 = oppositeEdge->GetbVertex()->GetVertex() - oppositeEdge->GetaVertex()->GetVertex();
|
||||||
|
GeomUtils::intersection_test res;
|
||||||
|
res = GeomUtils::intersectRayPlane(oppositeEdge->GetaVertex()->GetVertex(), v1v2, e2, -(v->GetVertex()*e2),
|
||||||
|
t, 1.0e-06);
|
||||||
|
if ((res == GeomUtils::DO_INTERSECT) && (t >= 0.0) && (t <= 1.0)) {
|
||||||
|
vector<WXFaceLayer*> second_ridge_layer;
|
||||||
|
wxf->retrieveSmoothLayers(Nature::RIDGE, second_ridge_layer);
|
||||||
|
if (second_ridge_layer.size() != 1)
|
||||||
|
continue;
|
||||||
|
Face_Curvature_Info *second_layer_info = (Face_Curvature_Info*)second_ridge_layer[0]->userdata;
|
||||||
|
|
||||||
// int numVertices = iFace->numberOfVertices();
|
unsigned index1 = wxf->GetIndex(oppositeEdge->GetaVertex());
|
||||||
// for(int i=0; i<numVertices; i++){
|
unsigned index2 = wxf->GetIndex(oppositeEdge->GetbVertex());
|
||||||
// v = iFace->GetVertex(i);
|
real K1_1 = second_layer_info->vec_curvature_info[index1]->K1;
|
||||||
// // vec_curvature_info[i] contains the curvature info of this vertex
|
real K1_2 = second_layer_info->vec_curvature_info[index2]->K1;
|
||||||
// Vec3r e2 = layer_info->vec_curvature_info[i]->K2*layer_info->vec_curvature_info[i]->e2;
|
real K1 = (1.0 - t) * K1_1 + t * K1_2;
|
||||||
// Vec3r e1 = layer_info->vec_curvature_info[i]->K1*layer_info->vec_curvature_info[i]->e1;
|
Vec3r inter((1.0 - t) * oppositeEdge->GetaVertex()->GetVertex() +
|
||||||
// e2.normalize();
|
t * oppositeEdge->GetbVertex()->GetVertex());
|
||||||
|
Vec3r vtmp(inter - v->GetVertex());
|
||||||
|
// is it K1_a or K1_b ?
|
||||||
|
if (vtmp * e1 > 0) {
|
||||||
|
K1_b = K1;
|
||||||
|
Inter_b = inter;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
K1_a = K1;
|
||||||
|
Inter_a = inter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Once we have K1 along the the ppal direction compute the derivative : K1b - K1a put it in DotP
|
||||||
|
//real d = fabs(K1_b) - fabs(K1_a);
|
||||||
|
real d = 0;
|
||||||
|
real threshold = _meanK1 + (_maxK1 - _meanK1) / 7.0;
|
||||||
|
//real threshold = _meanK1;
|
||||||
|
//if ((fabs(K1_b) > threshold) || ((fabs(K1_a) > threshold)))
|
||||||
|
d = (K1_b) - (K1_a) / (Inter_b - Inter_a).norm();
|
||||||
|
faceLayer->PushDotP(d);
|
||||||
|
//faceLayer->PushDotP(layer_info->vec_curvature_info[i]->K1);
|
||||||
|
}
|
||||||
|
|
||||||
// WVertex::face_iterator fit = v->faces_begin();
|
// Make the values relevant by checking whether all principal directions have the "same" direction:
|
||||||
// WVertex::face_iterator fitend = v->faces_end();
|
Vec3r e0((layer_info->vec_curvature_info[0]->K1 * layer_info->vec_curvature_info[0]->e1));
|
||||||
// for(; fit!=fitend; ++fit){
|
e0.normalize();
|
||||||
// WXFace * wxf = dynamic_cast<WXFace*>(*fit);
|
Vec3r e1((layer_info->vec_curvature_info[1]->K1 * layer_info->vec_curvature_info[1]->e1));
|
||||||
// WOEdge * oppositeEdge;
|
e1.normalize();
|
||||||
// if(!(wxf->getOppositeEdge(v, oppositeEdge)))
|
Vec3r e2((layer_info->vec_curvature_info[2]->K1 * layer_info->vec_curvature_info[2]->e1));
|
||||||
// continue;
|
e2.normalize();
|
||||||
// v1v2 = oppositeEdge->GetbVertex()->GetVertex() - oppositeEdge->GetaVertex()->GetVertex();
|
if (e0 * e1 < 0)
|
||||||
// GeomUtils::intersection_test res;
|
// invert dotP[1]
|
||||||
// res = GeomUtils::intersectRayPlane(oppositeEdge->GetaVertex()->GetVertex(), v1v2,
|
faceLayer->ReplaceDotP(1, -faceLayer->dotP(1));
|
||||||
// e2, -(v->GetVertex()*e2),
|
if (e0 * e2 < 0)
|
||||||
// t,1.e-06);
|
// invert dotP[2]
|
||||||
// if((res == GeomUtils::DO_INTERSECT) && (t>=0.0) && (t<=1.0)){
|
faceLayer->ReplaceDotP(2, -faceLayer->dotP(2));
|
||||||
// vector<WXFaceLayer*> second_ridge_layer;
|
|
||||||
// wxf->retrieveSmoothLayers(Nature::RIDGE, second_ridge_layer);
|
|
||||||
// if(second_ridge_layer.size()!=1)
|
|
||||||
// continue;
|
|
||||||
// Face_Curvature_Info *second_layer_info = (Face_Curvature_Info*)second_ridge_layer[0]->userdata;
|
|
||||||
|
|
||||||
// unsigned index1 = wxf->GetIndex(oppositeEdge->GetaVertex());
|
#if 0 // remove the weakest values;
|
||||||
// unsigned index2 = wxf->GetIndex(oppositeEdge->GetbVertex());
|
real minDiff = (_maxK1 - _minK1) / 10.0;
|
||||||
// real K1_1 = second_layer_info->vec_curvature_info[index1]->K1;
|
real minDiff = _meanK1;
|
||||||
// real K1_2 = second_layer_info->vec_curvature_info[index2]->K1;
|
if ((faceLayer->dotP(0) < minDiff) && (faceLayer->dotP(1) < minDiff) && (faceLayer->dotP(2) < minDiff)) {
|
||||||
// real K1 = (1.0-t)*K1_1 + t*K1_2;
|
faceLayer->ReplaceDotP(0, 0);
|
||||||
// Vec3r inter((1.0-t)*oppositeEdge->GetaVertex()->GetVertex() + t*oppositeEdge->GetbVertex()->GetVertex());
|
faceLayer->ReplaceDotP(1, 0);
|
||||||
// Vec3r vtmp(inter - v->GetVertex());
|
faceLayer->ReplaceDotP(2, 0);
|
||||||
// // is it K1_a or K1_b ?
|
}
|
||||||
// if(vtmp*e1 > 0){
|
#endif
|
||||||
// K1_b = K1;
|
}
|
||||||
// Inter_b = inter;
|
#endif
|
||||||
// }else{
|
|
||||||
// K1_a = K1;
|
|
||||||
// Inter_a = inter;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // Once we have K1 along the the ppal direction
|
|
||||||
// // compute the derivative : K1b - K1a
|
|
||||||
// // put it in DotP
|
|
||||||
// //real d = fabs(K1_b)-fabs(K1_a);
|
|
||||||
// real d = 0;
|
|
||||||
// real threshold = _meanK1 + (_maxK1-_meanK1)/7.0;
|
|
||||||
// //real threshold = _meanK1;
|
|
||||||
// //if((fabs(K1_b) > threshold) || ((fabs(K1_a) > threshold)))
|
|
||||||
// d = (K1_b)-(K1_a)/(Inter_b-Inter_a).norm();
|
|
||||||
// faceLayer->PushDotP(d);
|
|
||||||
// //faceLayer->PushDotP(layer_info->vec_curvature_info[i]->K1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Make the values relevant by checking whether all principal
|
|
||||||
// // directions have the "same" direction:
|
|
||||||
// Vec3r e0((layer_info->vec_curvature_info[0]->K1*layer_info->vec_curvature_info[0]->e1));
|
|
||||||
// e0.normalize();
|
|
||||||
// Vec3r e1((layer_info->vec_curvature_info[1]->K1*layer_info->vec_curvature_info[1]->e1));
|
|
||||||
// e1.normalize();
|
|
||||||
// Vec3r e2((layer_info->vec_curvature_info[2]->K1*layer_info->vec_curvature_info[2]->e1));
|
|
||||||
// e2.normalize();
|
|
||||||
// if (e0 * e1 < 0)
|
|
||||||
// // invert dotP[1]
|
|
||||||
// faceLayer->ReplaceDotP(1, -faceLayer->dotP(1));
|
|
||||||
// if (e0 * e2 < 0)
|
|
||||||
// // invert dotP[2]
|
|
||||||
// faceLayer->ReplaceDotP(2, -faceLayer->dotP(2));
|
|
||||||
|
|
||||||
// // remove the weakest values;
|
|
||||||
// //real minDiff = (_maxK1 - _minK1)/10.0;
|
|
||||||
// // real minDiff = _meanK1;
|
|
||||||
// // if((faceLayer->dotP(0) < minDiff) && (faceLayer->dotP(1) < minDiff) && (faceLayer->dotP(2) < minDiff)){
|
|
||||||
// // faceLayer->ReplaceDotP(0, 0);
|
|
||||||
// // faceLayer->ReplaceDotP(1, 0);
|
|
||||||
// // faceLayer->ReplaceDotP(2, 0);
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// SUGGESTIVE CONTOURS
|
// SUGGESTIVE CONTOURS
|
||||||
//////////////////////
|
//////////////////////
|
||||||
|
|
||||||
void FEdgeXDetector::processSuggestiveContourShape(WXShape* iWShape) {
|
void FEdgeXDetector::processSuggestiveContourShape(WXShape *iWShape)
|
||||||
|
{
|
||||||
// Here the curvatures must already have been computed
|
// Here the curvatures must already have been computed
|
||||||
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
||||||
vector<WFace*>::iterator f, fend;
|
vector<WFace*>::iterator f, fend;
|
||||||
for(f=wfaces.begin(), fend=wfaces.end();
|
for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
|
||||||
f!=fend;
|
|
||||||
++f)
|
|
||||||
{
|
|
||||||
ProcessSuggestiveContourFace((WXFace*)(*f));
|
ProcessSuggestiveContourFace((WXFace*)(*f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -557,45 +547,43 @@ void FEdgeXDetector::ProcessSuggestiveContourFace(WXFace *iFace)
|
|||||||
iFace->AddSmoothLayer(faceLayer);
|
iFace->AddSmoothLayer(faceLayer);
|
||||||
|
|
||||||
unsigned int numVertices = iFace->numberOfVertices();
|
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);
|
WVertex *wv = iFace->GetVertex(i);
|
||||||
WXVertex * wxv = dynamic_cast<WXVertex*>(wv);
|
WXVertex *wxv = dynamic_cast<WXVertex*>(wv);
|
||||||
faceLayer->PushDotP(wxv->curvatures()->Kr);
|
faceLayer->PushDotP(wxv->curvatures()->Kr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: find a more clever way to compute the threshold
|
#if 0 // FIXME: find a more clever way to compute the threshold
|
||||||
// real threshold = _meanKr;
|
real threshold = _meanKr;
|
||||||
// if(faceLayer->nPosDotP()!=numVertices){
|
if (faceLayer->nPosDotP()!=numVertices) {
|
||||||
// if((fabs(faceLayer->dotP(0)) < threshold) && (fabs(faceLayer->dotP(1)) < threshold) && (fabs(faceLayer->dotP(2)) < threshold)){
|
if ((fabs(faceLayer->dotP(0)) < threshold) && (fabs(faceLayer->dotP(1)) < threshold) &&
|
||||||
// faceLayer->ReplaceDotP(0, 0);
|
(fabs(faceLayer->dotP(2)) < threshold)) {
|
||||||
// faceLayer->ReplaceDotP(1, 0);
|
faceLayer->ReplaceDotP(0, 0);
|
||||||
// faceLayer->ReplaceDotP(2, 0);
|
faceLayer->ReplaceDotP(1, 0);
|
||||||
// }
|
faceLayer->ReplaceDotP(2, 0);
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FEdgeXDetector::postProcessSuggestiveContourShape(WXShape* iShape) {
|
void FEdgeXDetector::postProcessSuggestiveContourShape(WXShape *iShape)
|
||||||
|
{
|
||||||
vector<WFace*>& wfaces = iShape->GetFaceList();
|
vector<WFace*>& wfaces = iShape->GetFaceList();
|
||||||
vector<WFace*>::iterator f, fend;
|
vector<WFace*>::iterator f, fend;
|
||||||
for(f=wfaces.begin(), fend=wfaces.end();
|
for (f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
|
||||||
f!=fend;
|
|
||||||
++f)
|
|
||||||
{
|
|
||||||
postProcessSuggestiveContourFace((WXFace*)(*f));
|
postProcessSuggestiveContourFace((WXFace*)(*f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
|
void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace)
|
||||||
|
{
|
||||||
// Compute the derivative of the radial curvature in the radial direction,
|
// Compute the derivative of the radial curvature in the radial direction, at the two extremities of the smooth edge.
|
||||||
// at the two extremities of the smooth edge.
|
// If the derivative is smaller than a given threshold _kr_derivative_epsilon, discard the edge.
|
||||||
// If the derivative is smaller than a given threshold _kr_derivative_epsilon,
|
|
||||||
// discard the edge.
|
|
||||||
|
|
||||||
// Find the suggestive contour layer of the face (zero or one edge).
|
// Find the suggestive contour layer of the face (zero or one edge).
|
||||||
vector<WXFaceLayer*> sc_layers;
|
vector<WXFaceLayer*> sc_layers;
|
||||||
iFace->retrieveSmoothEdgesLayers(Nature::SUGGESTIVE_CONTOUR, sc_layers);
|
iFace->retrieveSmoothEdgesLayers(Nature::SUGGESTIVE_CONTOUR, sc_layers);
|
||||||
if(sc_layers.empty())
|
if (sc_layers.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WXFaceLayer *sc_layer;
|
WXFaceLayer *sc_layer;
|
||||||
@@ -612,7 +600,7 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
|
|||||||
GeomUtils::intersection_test res;
|
GeomUtils::intersection_test res;
|
||||||
real kr(0), kr1(0), kr2(0), t;
|
real kr(0), kr1(0), kr2(0), t;
|
||||||
|
|
||||||
for (unsigned i = 0; i < vertices_nb; ++i) {
|
for (unsigned int i = 0; i < vertices_nb; ++i) {
|
||||||
v = (WXVertex*)(iFace->GetVertex(i));
|
v = (WXVertex*)(iFace->GetVertex(i));
|
||||||
|
|
||||||
// v is a singular vertex, skip it.
|
// v is a singular vertex, skip it.
|
||||||
@@ -625,23 +613,20 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
|
|||||||
er_vec = v->curvatures()->er;
|
er_vec = v->curvatures()->er;
|
||||||
|
|
||||||
// For each vertex, iterate on its adjacent faces.
|
// For each vertex, iterate on its adjacent faces.
|
||||||
for (WVertex::face_iterator fit = v->faces_begin(), fitend = v->faces_end();
|
for (WVertex::face_iterator fit = v->faces_begin(), fitend = v->faces_end(); fit != fitend; ++fit) {
|
||||||
fit != fitend;
|
|
||||||
++fit) {
|
|
||||||
wxf = dynamic_cast<WXFace*>(*fit);
|
wxf = dynamic_cast<WXFace*>(*fit);
|
||||||
if(!(wxf->getOppositeEdge(v, opposite_edge)))
|
if (!wxf->getOppositeEdge(v, opposite_edge))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
opposite_vertex_a = (WXVertex*)opposite_edge->GetaVertex();
|
opposite_vertex_a = (WXVertex *)opposite_edge->GetaVertex();
|
||||||
opposite_vertex_b = (WXVertex*)opposite_edge->GetbVertex();
|
opposite_vertex_b = (WXVertex *)opposite_edge->GetbVertex();
|
||||||
normal_vec = wxf->GetVertexNormal(v); // FIXME: what about e1 ^ e2 ?
|
normal_vec = wxf->GetVertexNormal(v); // FIXME: what about e1 ^ e2 ?
|
||||||
radial_normal_vec = er_vec ^ normal_vec;
|
radial_normal_vec = er_vec ^ normal_vec;
|
||||||
|
|
||||||
// Test wether the radial plan intersects with the edge at the opposite of v.
|
// Test wether the radial plan intersects with the edge at the opposite of v.
|
||||||
res = GeomUtils::intersectRayPlane(opposite_vertex_a->GetVertex(), opposite_edge->GetVec(),
|
res = GeomUtils::intersectRayPlane(opposite_vertex_a->GetVertex(), opposite_edge->GetVec(),
|
||||||
radial_normal_vec, -(v_vec * radial_normal_vec),
|
radial_normal_vec, -(v_vec * radial_normal_vec),
|
||||||
t,
|
t, 1.0e-06);
|
||||||
1.e-06);
|
|
||||||
|
|
||||||
// If there is an intersection, compute the value of the derivative ath that point.
|
// If there is an intersection, compute the value of the derivative ath that point.
|
||||||
if ((res == GeomUtils::DO_INTERSECT) && (t >= 0) && (t <= 1)) {
|
if ((res == GeomUtils::DO_INTERSECT) && (t >= 0) && (t <= 1)) {
|
||||||
@@ -652,7 +637,8 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
|
|||||||
if (tmp_vec * er_vec > 0) {
|
if (tmp_vec * er_vec > 0) {
|
||||||
kr2 = kr;
|
kr2 = kr;
|
||||||
inter2 = inter;
|
inter2 = inter;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
kr1 = kr;
|
kr1 = kr;
|
||||||
inter1 = inter;
|
inter1 = inter;
|
||||||
}
|
}
|
||||||
@@ -668,13 +654,13 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// At that point, we have the derivatives for each vertex of iFace.
|
// At that point, we have the derivatives for each vertex of iFace.
|
||||||
// All we have to do now is to use linear interpolation to compute the values at
|
// All we have to do now is to use linear interpolation to compute the values at the extremities of the smooth edge.
|
||||||
// the extremities of the smooth edge.
|
|
||||||
WXSmoothEdge *sc_edge = sc_layer->getSmoothEdge();
|
WXSmoothEdge *sc_edge = sc_layer->getSmoothEdge();
|
||||||
WOEdge *sc_oedge = sc_edge->woea();
|
WOEdge *sc_oedge = sc_edge->woea();
|
||||||
t = sc_edge->ta();
|
t = sc_edge->ta();
|
||||||
if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
|
if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
|
||||||
(1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon) {
|
(1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon)
|
||||||
|
{
|
||||||
sc_layer->removeSmoothEdge();
|
sc_layer->removeSmoothEdge();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -682,21 +668,21 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) {
|
|||||||
t = sc_edge->tb();
|
t = sc_edge->tb();
|
||||||
if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
|
if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] +
|
||||||
(1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon)
|
(1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon)
|
||||||
|
{
|
||||||
sc_layer->removeSmoothEdge();
|
sc_layer->removeSmoothEdge();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MATERIAL_BOUNDARY
|
// MATERIAL_BOUNDARY
|
||||||
////////////////////
|
////////////////////
|
||||||
void FEdgeXDetector::processMaterialBoundaryShape(WXShape* iWShape) {
|
void FEdgeXDetector::processMaterialBoundaryShape(WXShape *iWShape)
|
||||||
|
{
|
||||||
if(!_computeViewIndependant)
|
if (!_computeViewIndependant)
|
||||||
return;
|
return;
|
||||||
// Make a pass on the edges to detect material boundaries
|
// Make a pass on the edges to detect material boundaries
|
||||||
vector<WEdge*>::iterator we, weend;
|
vector<WEdge*>::iterator we, weend;
|
||||||
vector<WEdge*> &wedges = iWShape->getEdgeList();
|
vector<WEdge*> &wedges = iWShape->getEdgeList();
|
||||||
for(we=wedges.begin(), weend=wedges.end();
|
for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
|
||||||
we!=weend;
|
|
||||||
++we){
|
|
||||||
ProcessMaterialBoundaryEdge((WXEdge*)(*we));
|
ProcessMaterialBoundaryEdge((WXEdge*)(*we));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -706,26 +692,25 @@ void FEdgeXDetector::ProcessMaterialBoundaryEdge(WXEdge *iEdge)
|
|||||||
// check whether the edge is a material boundary?
|
// check whether the edge is a material boundary?
|
||||||
WFace *aFace = iEdge->GetaFace();
|
WFace *aFace = iEdge->GetaFace();
|
||||||
WFace *bFace = iEdge->GetbFace();
|
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);
|
iEdge->AddNature(Nature::MATERIAL_BOUNDARY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EDGE MARKS
|
// EDGE MARKS
|
||||||
/////////////
|
/////////////
|
||||||
|
void FEdgeXDetector::processEdgeMarksShape(WXShape *iShape)
|
||||||
void FEdgeXDetector::processEdgeMarksShape(WXShape* iShape) {
|
{
|
||||||
// Make a pass on the edges to detect material boundaries
|
// Make a pass on the edges to detect material boundaries
|
||||||
vector<WEdge*>::iterator we, weend;
|
vector<WEdge*>::iterator we, weend;
|
||||||
vector<WEdge*> &wedges = iShape->getEdgeList();
|
vector<WEdge*> &wedges = iShape->getEdgeList();
|
||||||
for(we=wedges.begin(), weend=wedges.end();
|
for (we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
|
||||||
we!=weend;
|
|
||||||
++we){
|
|
||||||
ProcessEdgeMarks((WXEdge*)(*we));
|
ProcessEdgeMarks((WXEdge*)(*we));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge) {
|
void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge)
|
||||||
|
{
|
||||||
if (iEdge->GetMark()) {
|
if (iEdge->GetMark()) {
|
||||||
iEdge->AddNature(Nature::EDGE_MARK);
|
iEdge->AddNature(Nature::EDGE_MARK);
|
||||||
}
|
}
|
||||||
@@ -733,20 +718,19 @@ void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge) {
|
|||||||
|
|
||||||
// Build Smooth edges
|
// Build Smooth edges
|
||||||
/////////////////////
|
/////////////////////
|
||||||
void FEdgeXDetector::buildSmoothEdges(WXShape* iShape){
|
void FEdgeXDetector::buildSmoothEdges(WXShape *iShape)
|
||||||
|
{
|
||||||
bool hasSmoothEdges = false;
|
bool hasSmoothEdges = false;
|
||||||
|
|
||||||
// Make a last pass to build smooth edges from the previous stored values:
|
// Make a last pass to build smooth edges from the previous stored values:
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
vector<WFace*>& wfaces = iShape->GetFaceList();
|
vector<WFace*>& wfaces = iShape->GetFaceList();
|
||||||
for(vector<WFace*>::iterator f=wfaces.begin(), fend=wfaces.end();
|
for (vector<WFace*>::iterator f = wfaces.begin(), fend = wfaces.end(); f != fend; ++f) {
|
||||||
f!=fend;
|
|
||||||
++f)
|
|
||||||
{
|
|
||||||
vector<WXFaceLayer*>& faceLayers = ((WXFace*)(*f))->getSmoothLayers();
|
vector<WXFaceLayer*>& faceLayers = ((WXFace*)(*f))->getSmoothLayers();
|
||||||
for(vector<WXFaceLayer*>::iterator wxfl = faceLayers.begin(), wxflend=faceLayers.end();
|
for (vector<WXFaceLayer*>::iterator wxfl = faceLayers.begin(), wxflend = faceLayers.end();
|
||||||
wxfl!=wxflend;
|
wxfl != wxflend;
|
||||||
++wxfl){
|
++wxfl)
|
||||||
|
{
|
||||||
if ((*wxfl)->BuildSmoothEdge())
|
if ((*wxfl)->BuildSmoothEdge())
|
||||||
hasSmoothEdges = true;
|
hasSmoothEdges = true;
|
||||||
}
|
}
|
||||||
@@ -754,11 +738,9 @@ void FEdgeXDetector::buildSmoothEdges(WXShape* iShape){
|
|||||||
|
|
||||||
if (hasSmoothEdges && !_computeRidgesAndValleys && !_computeSuggestiveContours) {
|
if (hasSmoothEdges && !_computeRidgesAndValleys && !_computeSuggestiveContours) {
|
||||||
vector<WVertex*>& wvertices = iShape->getVertexList();
|
vector<WVertex*>& wvertices = iShape->getVertexList();
|
||||||
for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end();
|
for (vector<WVertex*>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
|
||||||
wv!=wvend;
|
|
||||||
++wv){
|
|
||||||
// Compute curvatures
|
// Compute curvatures
|
||||||
WXVertex * wxv = dynamic_cast<WXVertex*>(*wv);
|
WXVertex *wxv = dynamic_cast<WXVertex*>(*wv);
|
||||||
computeCurvatures(wxv);
|
computeCurvatures(wxv);
|
||||||
}
|
}
|
||||||
_meanK1 /= (real)(_nPoints);
|
_meanK1 /= (real)(_nPoints);
|
||||||
|
|||||||
@@ -1,57 +1,61 @@
|
|||||||
//
|
/*
|
||||||
// Filename : FEdgeXDetector.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Purpose : Detects/flags/builds extended features edges on the
|
* This program is free software; you can redistribute it and/or
|
||||||
// WXEdge structure
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 26/10/2003
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_FEDGE_X_DETECTOR_H__
|
||||||
|
#define __FREESTYLE_FEDGE_X_DETECTOR_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/FEdgeXDetector.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Detects/flags/builds extended features edges on the WXEdge structure
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 26/10/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#ifndef FEDGEXDETECTOR_H
|
#include "../geometry/Geom.h"
|
||||||
# define FEDGEXDETECTOR_H
|
|
||||||
|
|
||||||
# include <vector>
|
#include "../system/FreestyleConfig.h"
|
||||||
# include "../system/FreestyleConfig.h"
|
#include "../system/ProgressBar.h"
|
||||||
# include "../geometry/Geom.h"
|
#include "../system/RenderMonitor.h"
|
||||||
# include "../winged_edge/WXEdge.h"
|
|
||||||
# include "../winged_edge/Curvature.h"
|
#include "../winged_edge/Curvature.h"
|
||||||
# include "../system/ProgressBar.h"
|
#include "../winged_edge/WXEdge.h"
|
||||||
# include "../system/RenderMonitor.h"
|
|
||||||
|
|
||||||
using namespace Geometry;
|
using namespace Geometry;
|
||||||
|
|
||||||
/*! This class takes as input a WXEdge structure and fills it
|
/*! This class takes as input a WXEdge structure and fills it */
|
||||||
*/
|
|
||||||
|
|
||||||
class LIB_VIEW_MAP_EXPORT FEdgeXDetector
|
class LIB_VIEW_MAP_EXPORT FEdgeXDetector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
FEdgeXDetector()
|
||||||
FEdgeXDetector() {
|
{
|
||||||
_pProgressBar = 0;
|
_pProgressBar = NULL;
|
||||||
_pRenderMonitor = 0;
|
_pRenderMonitor = NULL;
|
||||||
_computeViewIndependant = true;
|
_computeViewIndependant = true;
|
||||||
_bbox_diagonal = 1.0;
|
_bbox_diagonal = 1.0;
|
||||||
_meanEdgeSize = 0;
|
_meanEdgeSize = 0;
|
||||||
@@ -65,112 +69,146 @@ public:
|
|||||||
_kr_derivative_epsilon = 0.0;
|
_kr_derivative_epsilon = 0.0;
|
||||||
_creaseAngle = 0.7; // angle of 134.43 degrees
|
_creaseAngle = 0.7; // angle of 134.43 degrees
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~FEdgeXDetector() {}
|
virtual ~FEdgeXDetector() {}
|
||||||
|
|
||||||
/*! Process shapes from a WingedEdge containing a list of WShapes */
|
/*! Process shapes from a WingedEdge containing a list of WShapes */
|
||||||
virtual void processShapes(WingedEdge&);
|
virtual void processShapes(WingedEdge&);
|
||||||
|
|
||||||
// GENERAL STUFF
|
// GENERAL STUFF
|
||||||
virtual void preProcessShape(WXShape* iShape);
|
virtual void preProcessShape(WXShape *iShape);
|
||||||
virtual void preProcessFace(WXFace* iFace);
|
virtual void preProcessFace(WXFace *iFace);
|
||||||
virtual void computeCurvatures(WXVertex *iVertex);
|
virtual void computeCurvatures(WXVertex *iVertex);
|
||||||
|
|
||||||
// SILHOUETTE
|
// SILHOUETTE
|
||||||
virtual void processSilhouetteShape(WXShape* iShape);
|
virtual void processSilhouetteShape(WXShape *iShape);
|
||||||
virtual void ProcessSilhouetteFace(WXFace *iFace);
|
virtual void ProcessSilhouetteFace(WXFace *iFace);
|
||||||
virtual void ProcessSilhouetteEdge(WXEdge *iEdge);
|
virtual void ProcessSilhouetteEdge(WXEdge *iEdge);
|
||||||
|
|
||||||
// CREASE
|
// CREASE
|
||||||
virtual void processCreaseShape(WXShape* iShape);
|
virtual void processCreaseShape(WXShape *iShape);
|
||||||
virtual void ProcessCreaseEdge(WXEdge *iEdge);
|
virtual void ProcessCreaseEdge(WXEdge *iEdge);
|
||||||
|
|
||||||
/*! Sets the minimum angle for detecting crease edges
|
/*! Sets the minimum angle for detecting crease edges
|
||||||
* \param angle
|
* \param angle
|
||||||
* The angular threshold in degrees (between 0 and 180) for detecting crease
|
* The angular threshold in degrees (between 0 and 180) for detecting crease edges. An edge is considered
|
||||||
* edges. An edge is considered a crease edge if the angle between two faces
|
* a crease edge if the angle between two faces sharing the edge is smaller than the given threshold.
|
||||||
* sharing the edge is smaller than the given threshold.
|
|
||||||
*/
|
*/
|
||||||
inline void setCreaseAngle(real angle) {
|
// XXX angle should be in radian...
|
||||||
|
inline void setCreaseAngle(real angle)
|
||||||
|
{
|
||||||
if (angle < 0.0)
|
if (angle < 0.0)
|
||||||
angle = 0.0;
|
angle = 0.0;
|
||||||
else if (angle > 180.0)
|
else if (angle > 180.0)
|
||||||
angle = 180.0;
|
angle = 180.0;
|
||||||
angle = cos(M_PI * (180.0 - angle) / 180.0);
|
angle = cos(M_PI * (180.0 - angle) / 180.0);
|
||||||
if (angle != _creaseAngle){
|
if (angle != _creaseAngle) {
|
||||||
_creaseAngle = angle;
|
_creaseAngle = angle;
|
||||||
_changes = true;
|
_changes = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BORDER
|
// BORDER
|
||||||
virtual void processBorderShape(WXShape* iShape);
|
virtual void processBorderShape(WXShape *iShape);
|
||||||
virtual void ProcessBorderEdge(WXEdge *iEdge);
|
virtual void ProcessBorderEdge(WXEdge *iEdge);
|
||||||
|
|
||||||
// RIDGES AND VALLEYS
|
// RIDGES AND VALLEYS
|
||||||
virtual void processRidgesAndValleysShape(WXShape* iShape);
|
virtual void processRidgesAndValleysShape(WXShape *iShape);
|
||||||
virtual void ProcessRidgeFace(WXFace *iFace);
|
virtual void ProcessRidgeFace(WXFace *iFace);
|
||||||
|
|
||||||
// SUGGESTIVE CONTOURS
|
// SUGGESTIVE CONTOURS
|
||||||
virtual void processSuggestiveContourShape(WXShape* iShape);
|
virtual void processSuggestiveContourShape(WXShape *iShape);
|
||||||
virtual void ProcessSuggestiveContourFace(WXFace *iFace);
|
virtual void ProcessSuggestiveContourFace(WXFace *iFace);
|
||||||
virtual void postProcessSuggestiveContourShape(WXShape* iShape);
|
virtual void postProcessSuggestiveContourShape(WXShape *iShape);
|
||||||
virtual void postProcessSuggestiveContourFace(WXFace *iFace);
|
virtual void postProcessSuggestiveContourFace(WXFace *iFace);
|
||||||
/*! Sets the minimal derivative of the radial curvature for suggestive contours
|
/*! Sets the minimal derivative of the radial curvature for suggestive contours
|
||||||
* \param dkr
|
* \param dkr
|
||||||
* The minimal derivative of the radial curvature
|
* The minimal derivative of the radial curvature
|
||||||
*/
|
*/
|
||||||
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr) {
|
inline void setSuggestiveContourKrDerivativeEpsilon(real dkr)
|
||||||
if (dkr != _kr_derivative_epsilon){
|
{
|
||||||
|
if (dkr != _kr_derivative_epsilon) {
|
||||||
_kr_derivative_epsilon = dkr;
|
_kr_derivative_epsilon = dkr;
|
||||||
_changes = true;
|
_changes = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MATERIAL BOUNDARY
|
// MATERIAL BOUNDARY
|
||||||
virtual void processMaterialBoundaryShape(WXShape* iWShape);
|
virtual void processMaterialBoundaryShape(WXShape *iWShape);
|
||||||
virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge);
|
virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge);
|
||||||
|
|
||||||
// EDGE MARKS
|
// EDGE MARKS
|
||||||
virtual void processEdgeMarksShape(WXShape* iShape);
|
virtual void processEdgeMarksShape(WXShape *iShape);
|
||||||
virtual void ProcessEdgeMarks(WXEdge *iEdge);
|
virtual void ProcessEdgeMarks(WXEdge *iEdge);
|
||||||
|
|
||||||
// EVERYBODY
|
// EVERYBODY
|
||||||
virtual void buildSmoothEdges(WXShape* iShape);
|
virtual void buildSmoothEdges(WXShape *iShape);
|
||||||
|
|
||||||
/*! Sets the current viewpoint */
|
/*! Sets the current viewpoint */
|
||||||
inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;}
|
inline void setViewpoint(const Vec3r& ivp)
|
||||||
inline void enableOrthographicProjection(bool b) {_orthographicProjection = b;}
|
{
|
||||||
inline void enableRidgesAndValleysFlag(bool b) {_computeRidgesAndValleys = b;}
|
_Viewpoint = ivp;
|
||||||
inline void enableSuggestiveContours(bool b) {_computeSuggestiveContours = b;}
|
}
|
||||||
inline void enableMaterialBoundaries(bool b) {_computeMaterialBoundaries = b;}
|
|
||||||
inline void enableFaceSmoothness(bool b) {
|
inline void enableOrthographicProjection(bool b)
|
||||||
|
{
|
||||||
|
_orthographicProjection = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void enableRidgesAndValleysFlag(bool b)
|
||||||
|
{
|
||||||
|
_computeRidgesAndValleys = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void enableSuggestiveContours(bool b)
|
||||||
|
{
|
||||||
|
_computeSuggestiveContours = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void enableMaterialBoundaries(bool b)
|
||||||
|
{
|
||||||
|
_computeMaterialBoundaries = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void enableFaceSmoothness(bool b)
|
||||||
|
{
|
||||||
if (b != _faceSmoothness) {
|
if (b != _faceSmoothness) {
|
||||||
_faceSmoothness = b;
|
_faceSmoothness = b;
|
||||||
_changes=true;
|
_changes=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline void enableFaceMarks(bool b) {
|
|
||||||
|
inline void enableFaceMarks(bool b)
|
||||||
|
{
|
||||||
if (b != _faceMarks) {
|
if (b != _faceMarks) {
|
||||||
_faceMarks = b;
|
_faceMarks = b;
|
||||||
_changes=true;
|
_changes=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation)
|
/*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation)
|
||||||
* \param r
|
* \param r
|
||||||
* The radius of the sphere expressed as a ratio of the mean edge size
|
* The radius of the sphere expressed as a ratio of the mean edge size
|
||||||
*/
|
*/
|
||||||
inline void setSphereRadius(real r) {
|
inline void setSphereRadius(real r)
|
||||||
if(r!=_sphereRadius){
|
{
|
||||||
|
if (r != _sphereRadius) {
|
||||||
_sphereRadius = r;
|
_sphereRadius = r;
|
||||||
_changes=true;
|
_changes=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;}
|
inline void setProgressBar(ProgressBar *iProgressBar)
|
||||||
|
{
|
||||||
|
_pProgressBar = iProgressBar;
|
||||||
|
}
|
||||||
|
|
||||||
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;}
|
inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
|
||||||
|
{
|
||||||
|
_pRenderMonitor = iRenderMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Vec3r _Viewpoint;
|
Vec3r _Viewpoint;
|
||||||
real _bbox_diagonal; // diagonal of the current processed shape bbox
|
real _bbox_diagonal; // diagonal of the current processed shape bbox
|
||||||
//oldtmp values
|
//oldtmp values
|
||||||
@@ -200,4 +238,4 @@ protected:
|
|||||||
RenderMonitor *_pRenderMonitor;
|
RenderMonitor *_pRenderMonitor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FEDGEDXETECTOR_H
|
#endif // __FREESTYLE_FEDGE_X_DETECTOR_H__
|
||||||
|
|||||||
@@ -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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/Functions0D.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Functions taking 0D input
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Emmanuel Turquin
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 01/07/2003
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
# include "Functions0D.h"
|
#include "Functions0D.h"
|
||||||
# include "ViewMap.h"
|
#include "ViewMap.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace Functions0D {
|
namespace Functions0D {
|
||||||
|
|
||||||
// Internal function
|
// Internal function
|
||||||
FEdge* getFEdge(Interface0D& it1, Interface0D& it2){
|
FEdge *getFEdge(Interface0D& it1, Interface0D& it2)
|
||||||
|
{
|
||||||
return it1.getFEdge(it2);
|
return it1.getFEdge(it2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getFEdges(Interface0DIterator& it,
|
void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2)
|
||||||
FEdge*& fe1,
|
{
|
||||||
FEdge*& fe2) {
|
|
||||||
// count number of vertices
|
// count number of vertices
|
||||||
Interface0DIterator prev = it, next = it;
|
Interface0DIterator prev = it, next = it;
|
||||||
++next;
|
++next;
|
||||||
@@ -41,242 +55,235 @@ namespace Functions0D {
|
|||||||
if (!it.isBegin() && !next.isEnd()) {
|
if (!it.isBegin() && !next.isEnd()) {
|
||||||
count = 3;
|
count = 3;
|
||||||
}
|
}
|
||||||
if(count < 3)
|
if (count < 3) {
|
||||||
{
|
|
||||||
// if we only have 2 vertices
|
// if we only have 2 vertices
|
||||||
FEdge * fe = 0;
|
FEdge *fe = 0;
|
||||||
Interface0DIterator tmp = it;
|
Interface0DIterator tmp = it;
|
||||||
if(it.isBegin())
|
if (it.isBegin()) {
|
||||||
{
|
|
||||||
++tmp;
|
++tmp;
|
||||||
fe = it->getFEdge(*tmp);
|
fe = it->getFEdge(*tmp);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
--tmp;
|
--tmp;
|
||||||
fe = it->getFEdge(*tmp);
|
fe = it->getFEdge(*tmp);
|
||||||
}
|
}
|
||||||
fe1 = fe;
|
fe1 = fe;
|
||||||
fe2 = 0;
|
fe2 = NULL;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
// we have more than 2 vertices
|
// we have more than 2 vertices
|
||||||
bool begin=false,last=false;
|
bool begin = false, last = false;
|
||||||
Interface0DIterator previous = it;
|
Interface0DIterator previous = it;
|
||||||
if(!previous.isBegin())
|
if (!previous.isBegin())
|
||||||
--previous;
|
--previous;
|
||||||
else
|
else
|
||||||
begin=true;
|
begin = true;
|
||||||
Interface0DIterator next = it;
|
Interface0DIterator next = it;
|
||||||
++next;
|
++next;
|
||||||
if(next.isEnd())
|
if (next.isEnd())
|
||||||
last = true;
|
last = true;
|
||||||
if(begin)
|
if (begin) {
|
||||||
{
|
|
||||||
fe1 = it->getFEdge(*next);
|
fe1 = it->getFEdge(*next);
|
||||||
fe2 = 0;
|
fe2 = NULL;
|
||||||
}
|
}
|
||||||
else if(last)
|
else if (last) {
|
||||||
{
|
|
||||||
fe1 = previous->getFEdge(*it);
|
fe1 = previous->getFEdge(*it);
|
||||||
fe2 = 0;
|
fe2 = NULL;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
fe1 = previous->getFEdge(*it);
|
fe1 = previous->getFEdge(*it);
|
||||||
fe2 = it->getFEdge(*next);
|
fe2 = it->getFEdge(*next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getViewEdges(Interface0DIterator &it,
|
void getViewEdges(Interface0DIterator &it, ViewEdge *&ve1, ViewEdge *&ve2)
|
||||||
ViewEdge *&ve1,
|
{
|
||||||
ViewEdge *&ve2)
|
FEdge *fe1, *fe2;
|
||||||
{
|
|
||||||
FEdge * fe1, *fe2;
|
|
||||||
getFEdges(it, fe1, fe2);
|
getFEdges(it, fe1, fe2);
|
||||||
ve1 = fe1->viewedge();
|
ve1 = fe1->viewedge();
|
||||||
if(fe2 != 0)
|
if (fe2 != NULL) {
|
||||||
{
|
|
||||||
ve2 = fe2->viewedge();
|
ve2 = fe2->viewedge();
|
||||||
if(ve2 == ve1)
|
if (ve2 == ve1)
|
||||||
ve2 = 0;
|
ve2 = NULL;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
ve2 = 0;
|
ve2 = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ViewShape* getShapeF0D(Interface0DIterator& it)
|
ViewShape *getShapeF0D(Interface0DIterator& it)
|
||||||
{
|
{
|
||||||
ViewEdge *ve1, *ve2;
|
ViewEdge *ve1, *ve2;
|
||||||
getViewEdges(it, ve1, ve2);
|
getViewEdges(it, ve1, ve2);
|
||||||
return ve1->viewShape();
|
return ve1->viewShape();
|
||||||
}
|
}
|
||||||
|
|
||||||
void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders){
|
void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders)
|
||||||
ViewEdge * ve1, *ve2;
|
{
|
||||||
|
ViewEdge *ve1, *ve2;
|
||||||
getViewEdges(it, ve1, ve2);
|
getViewEdges(it, ve1, ve2);
|
||||||
occluder_container::const_iterator oit = ve1->occluders_begin();
|
occluder_container::const_iterator oit = ve1->occluders_begin();
|
||||||
occluder_container::const_iterator oitend = ve1->occluders_end();
|
occluder_container::const_iterator oitend = ve1->occluders_end();
|
||||||
|
|
||||||
for(;oit!=oitend; ++oit)
|
for (; oit != oitend; ++oit)
|
||||||
oOccluders.insert((*oit));
|
oOccluders.insert((*oit));
|
||||||
|
|
||||||
if(ve2!=0){
|
if (ve2 != NULL) {
|
||||||
oit = ve2->occluders_begin();
|
oit = ve2->occluders_begin();
|
||||||
oitend = ve2->occluders_end();
|
oitend = ve2->occluders_end();
|
||||||
for(;oit!=oitend; ++oit)
|
for (; oit != oitend; ++oit)
|
||||||
oOccluders.insert((*oit));
|
oOccluders.insert((*oit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewShape * getOccludeeF0D(Interface0DIterator& it){
|
ViewShape *getOccludeeF0D(Interface0DIterator& it)
|
||||||
ViewEdge * ve1, *ve2;
|
{
|
||||||
|
ViewEdge *ve1, *ve2;
|
||||||
getViewEdges(it, ve1, ve2);
|
getViewEdges(it, ve1, ve2);
|
||||||
ViewShape *aShape = ve1->aShape();
|
ViewShape *aShape = ve1->aShape();
|
||||||
return aShape;
|
return aShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
int VertexOrientation2DF0D::operator()(Interface0DIterator& iter) {
|
int VertexOrientation2DF0D::operator()(Interface0DIterator& iter)
|
||||||
Vec2f A,C;
|
{
|
||||||
|
Vec2f A, C;
|
||||||
Vec2f B(iter->getProjectedX(), iter->getProjectedY());
|
Vec2f B(iter->getProjectedX(), iter->getProjectedY());
|
||||||
if(iter.isBegin())
|
if (iter.isBegin()) {
|
||||||
A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
|
A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
|
||||||
else
|
}
|
||||||
{
|
else {
|
||||||
Interface0DIterator previous = iter;
|
Interface0DIterator previous = iter;
|
||||||
--previous ;
|
--previous ;
|
||||||
A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
|
A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
|
||||||
}
|
}
|
||||||
Interface0DIterator next = iter;
|
Interface0DIterator next = iter;
|
||||||
++next ;
|
++next;
|
||||||
if(next.isEnd())
|
if (next.isEnd())
|
||||||
C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
|
C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
|
||||||
else
|
else
|
||||||
C = Vec2f(next->getProjectedX(), next->getProjectedY());
|
C = Vec2f(next->getProjectedX(), next->getProjectedY());
|
||||||
|
|
||||||
Vec2f AB(B-A);
|
Vec2f AB(B - A);
|
||||||
if(AB.norm() != 0)
|
if (AB.norm() != 0)
|
||||||
AB.normalize();
|
AB.normalize();
|
||||||
Vec2f BC(C-B);
|
Vec2f BC(C - B);
|
||||||
if(BC.norm() != 0)
|
if (BC.norm() != 0)
|
||||||
BC.normalize();
|
BC.normalize();
|
||||||
result = AB + BC;
|
result = AB + BC;
|
||||||
if(result.norm() != 0)
|
if (result.norm() != 0)
|
||||||
result.normalize();
|
result.normalize();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VertexOrientation3DF0D::operator()(Interface0DIterator& iter) {
|
int VertexOrientation3DF0D::operator()(Interface0DIterator& iter)
|
||||||
Vec3r A,C;
|
{
|
||||||
|
Vec3r A, C;
|
||||||
Vec3r B(iter->getX(), iter->getY(), iter->getZ());
|
Vec3r B(iter->getX(), iter->getY(), iter->getZ());
|
||||||
if(iter.isBegin())
|
if (iter.isBegin()) {
|
||||||
A = Vec3r(iter->getX(), iter->getY(), iter->getZ());
|
A = Vec3r(iter->getX(), iter->getY(), iter->getZ());
|
||||||
else
|
}
|
||||||
{
|
else {
|
||||||
Interface0DIterator previous = iter;
|
Interface0DIterator previous = iter;
|
||||||
--previous ;
|
--previous ;
|
||||||
A = Vec3r(previous->getX(), previous->getY(), previous->getZ());
|
A = Vec3r(previous->getX(), previous->getY(), previous->getZ());
|
||||||
}
|
}
|
||||||
Interface0DIterator next = iter;
|
Interface0DIterator next = iter;
|
||||||
++next ;
|
++next ;
|
||||||
if(next.isEnd())
|
if (next.isEnd())
|
||||||
C = Vec3r(iter->getX(), iter->getY(), iter->getZ());
|
C = Vec3r(iter->getX(), iter->getY(), iter->getZ());
|
||||||
else
|
else
|
||||||
C = Vec3r(next->getX(), next->getY(), next->getZ());
|
C = Vec3r(next->getX(), next->getY(), next->getZ());
|
||||||
|
|
||||||
Vec3r AB(B-A);
|
Vec3r AB(B - A);
|
||||||
if(AB.norm() != 0)
|
if (AB.norm() != 0)
|
||||||
AB.normalize();
|
AB.normalize();
|
||||||
Vec3r BC(C-B);
|
Vec3r BC(C - B);
|
||||||
if(BC.norm() != 0)
|
if (BC.norm() != 0)
|
||||||
BC.normalize();
|
BC.normalize();
|
||||||
result = AB + BC;
|
result = AB + BC;
|
||||||
if(result.norm() != 0)
|
if (result.norm() != 0)
|
||||||
result.normalize();
|
result.normalize();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Curvature2DAngleF0D::operator()(Interface0DIterator& iter) {
|
int Curvature2DAngleF0D::operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
Interface0DIterator tmp1 = iter, tmp2 = iter;
|
Interface0DIterator tmp1 = iter, tmp2 = iter;
|
||||||
++tmp2;
|
++tmp2;
|
||||||
unsigned count = 1;
|
unsigned count = 1;
|
||||||
while((!tmp1.isBegin()) && (count < 3))
|
while ((!tmp1.isBegin()) && (count < 3)) {
|
||||||
{
|
|
||||||
--tmp1;
|
--tmp1;
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
while((!tmp2.isEnd()) && (count < 3))
|
while ((!tmp2.isEnd()) && (count < 3)) {
|
||||||
{
|
|
||||||
++tmp2;
|
++tmp2;
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
if(count < 3) {
|
if (count < 3) {
|
||||||
// if we only have 2 vertices
|
// if we only have 2 vertices
|
||||||
result = 0;
|
result = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Interface0DIterator v = iter;
|
Interface0DIterator v = iter;
|
||||||
if(iter.isBegin())
|
if (iter.isBegin())
|
||||||
++v;
|
++v;
|
||||||
Interface0DIterator next=v;
|
Interface0DIterator next = v;
|
||||||
++next;
|
++next;
|
||||||
if(next.isEnd())
|
if (next.isEnd()) {
|
||||||
{
|
|
||||||
next = v;
|
next = v;
|
||||||
--v;
|
--v;
|
||||||
}
|
}
|
||||||
Interface0DIterator prev=v;
|
Interface0DIterator prev = v;
|
||||||
--prev;
|
--prev;
|
||||||
|
|
||||||
Vec2r A(prev->getProjectedX(), prev->getProjectedY());
|
Vec2r A(prev->getProjectedX(), prev->getProjectedY());
|
||||||
Vec2r B(v->getProjectedX(), v->getProjectedY());
|
Vec2r B(v->getProjectedX(), v->getProjectedY());
|
||||||
Vec2r C(next->getProjectedX(), next->getProjectedY());
|
Vec2r C(next->getProjectedX(), next->getProjectedY());
|
||||||
Vec2r AB(B-A);
|
Vec2r AB(B - A);
|
||||||
Vec2r BC(C-B);
|
Vec2r BC(C - B);
|
||||||
Vec2r N1(-AB[1], AB[0]);
|
Vec2r N1(-AB[1], AB[0]);
|
||||||
if(N1.norm() != 0)
|
if (N1.norm() != 0)
|
||||||
N1.normalize();
|
N1.normalize();
|
||||||
Vec2r N2(-BC[1], BC[0]);
|
Vec2r N2(-BC[1], BC[0]);
|
||||||
if(N2.norm() != 0)
|
if (N2.norm() != 0)
|
||||||
N2.normalize();
|
N2.normalize();
|
||||||
if((N1.norm() == 0) && (N2.norm() == 0))
|
if ((N1.norm() == 0) && (N2.norm() == 0)) {
|
||||||
{
|
|
||||||
Exception::raiseException();
|
Exception::raiseException();
|
||||||
result = 0;
|
result = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
double cosin = N1*N2;
|
double cosin = N1 * N2;
|
||||||
if(cosin > 1)
|
if (cosin > 1)
|
||||||
cosin = 1;
|
cosin = 1;
|
||||||
if(cosin < -1)
|
if (cosin < -1)
|
||||||
cosin = -1;
|
cosin = -1;
|
||||||
result = acos(cosin);
|
result = acos(cosin);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZDiscontinuityF0D::operator()(Interface0DIterator& iter) {
|
int ZDiscontinuityF0D::operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
FEdge *fe1, *fe2;
|
FEdge *fe1, *fe2;
|
||||||
getFEdges(iter, fe1, fe2);
|
getFEdges(iter, fe1, fe2);
|
||||||
result = fe1->z_discontinuity();
|
result = fe1->z_discontinuity();
|
||||||
if(fe2!=0){
|
if (fe2 != NULL) {
|
||||||
result += fe2->z_discontinuity();
|
result += fe2->z_discontinuity();
|
||||||
result /= 2.f;
|
result /= 2.0f;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Normal2DF0D::operator()(Interface0DIterator& iter) {
|
int Normal2DF0D::operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
FEdge *fe1, *fe2;
|
FEdge *fe1, *fe2;
|
||||||
getFEdges(iter,fe1,fe2);
|
getFEdges(iter, fe1, fe2);
|
||||||
Vec3f e1(fe1->orientation2d());
|
Vec3f e1(fe1->orientation2d());
|
||||||
Vec2f n1(e1[1], -e1[0]);
|
Vec2f n1(e1[1], -e1[0]);
|
||||||
Vec2f n(n1);
|
Vec2f n(n1);
|
||||||
if(fe2 != 0)
|
if (fe2 != NULL) {
|
||||||
{
|
|
||||||
Vec3f e2(fe2->orientation2d());
|
Vec3f e2(fe2->orientation2d());
|
||||||
Vec2f n2(e2[1], -e2[0]);
|
Vec2f n2(e2[1], -e2[0]);
|
||||||
n += n2;
|
n += n2;
|
||||||
@@ -284,74 +291,81 @@ namespace Functions0D {
|
|||||||
n.normalize();
|
n.normalize();
|
||||||
result = n;
|
result = n;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MaterialF0D::operator()(Interface0DIterator& iter) {
|
int MaterialF0D::operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
FEdge *fe1, *fe2;
|
FEdge *fe1, *fe2;
|
||||||
getFEdges(iter,fe1,fe2);
|
getFEdges(iter, fe1, fe2);
|
||||||
if(fe1 == 0)
|
if (fe1 == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if(fe1->isSmooth())
|
if (fe1->isSmooth())
|
||||||
result = ((FEdgeSmooth*)fe1)->frs_material();
|
result = ((FEdgeSmooth*)fe1)->frs_material();
|
||||||
else
|
else
|
||||||
result = ((FEdgeSharp*)fe1)->bFrsMaterial();
|
result = ((FEdgeSharp*)fe1)->bFrsMaterial();
|
||||||
// const SShape * sshape = getShapeF0D(iter);
|
#if 0
|
||||||
// return sshape->material();
|
const SShape *sshape = getShapeF0D(iter);
|
||||||
|
return sshape->material();
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ShapeIdF0D::operator()(Interface0DIterator& iter) {
|
int ShapeIdF0D::operator()(Interface0DIterator& iter)
|
||||||
ViewShape * vshape = getShapeF0D(iter);
|
{
|
||||||
|
ViewShape *vshape = getShapeF0D(iter);
|
||||||
result = vshape->getId();
|
result = vshape->getId();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter) {
|
int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter)
|
||||||
ViewEdge * ve1, *ve2;
|
{
|
||||||
getViewEdges(iter,ve1,ve2);
|
ViewEdge *ve1, *ve2;
|
||||||
|
getViewEdges(iter, ve1, ve2);
|
||||||
unsigned int qi1, qi2;
|
unsigned int qi1, qi2;
|
||||||
qi1 = ve1->qi();
|
qi1 = ve1->qi();
|
||||||
if(ve2 != 0){
|
if (ve2 != NULL) {
|
||||||
qi2 = ve2->qi();
|
qi2 = ve2->qi();
|
||||||
if(qi2!=qi1)
|
if (qi2 != qi1)
|
||||||
cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
|
cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl;
|
||||||
}
|
}
|
||||||
result = qi1;
|
result = qi1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CurveNatureF0D::operator()(Interface0DIterator& iter) {
|
int CurveNatureF0D::operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
Nature::EdgeNature nat = 0;
|
Nature::EdgeNature nat = 0;
|
||||||
ViewEdge * ve1, *ve2;
|
ViewEdge *ve1, *ve2;
|
||||||
getViewEdges(iter, ve1, ve2);
|
getViewEdges(iter, ve1, ve2);
|
||||||
nat |= ve1->getNature();
|
nat |= ve1->getNature();
|
||||||
if(ve2!=0)
|
if (ve2 != NULL)
|
||||||
nat |= ve2->getNature();
|
nat |= ve2->getNature();
|
||||||
result = nat;
|
result = nat;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetOccludersF0D::operator()(Interface0DIterator& iter) {
|
int GetOccludersF0D::operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
set<ViewShape*> occluders;
|
set<ViewShape*> occluders;
|
||||||
getOccludersF0D(iter,occluders);
|
getOccludersF0D(iter, occluders);
|
||||||
result.clear();
|
result.clear();
|
||||||
// vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end());
|
//vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end());
|
||||||
for(set<ViewShape*>::iterator it=occluders.begin(), itend=occluders.end();
|
for (set<ViewShape*>::iterator it = occluders.begin(), itend = occluders.end(); it != itend; ++it) {
|
||||||
it!=itend;
|
|
||||||
++it){
|
|
||||||
result.push_back((*it));
|
result.push_back((*it));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetShapeF0D::operator()(Interface0DIterator& iter) {
|
int GetShapeF0D::operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = getShapeF0D(iter);
|
result = getShapeF0D(iter);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetOccludeeF0D::operator()(Interface0DIterator& iter) {
|
int GetOccludeeF0D::operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = getOccludeeF0D(iter);
|
result = getOccludeeF0D(iter);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace Functions0D
|
} // end of namespace Functions0D
|
||||||
|
|||||||
@@ -1,64 +1,70 @@
|
|||||||
//
|
/*
|
||||||
// Filename : Functions0D.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli, Emmanuel Turquin
|
*
|
||||||
// Purpose : Functions taking 0D input
|
* This program is free software; you can redistribute it and/or
|
||||||
// Date of creation : 01/07/2003
|
* modify it under the terms of the GNU General Public License
|
||||||
//
|
* as published by the Free Software Foundation; either version 2
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_FUNCTIONS_0D_H__
|
||||||
|
#define __FREESTYLE_FUNCTIONS_0D_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/Functions0D.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Functions taking 0D input
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Emmanuel Turquin
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 01/07/2003
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef FUNCTIONS0D_H
|
#include <set>
|
||||||
# define FUNCTIONS0D_H
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Interface0D.h"
|
||||||
|
|
||||||
|
#include "../geometry/Geom.h"
|
||||||
|
|
||||||
|
#include "../python/Director.h"
|
||||||
|
|
||||||
|
#include "../scene_graph/FrsMaterial.h"
|
||||||
|
|
||||||
|
#include "../system/Exception.h"
|
||||||
|
#include "../system/Precision.h"
|
||||||
|
|
||||||
# include "../system/Precision.h"
|
|
||||||
# include "Interface0D.h"
|
|
||||||
# include "../geometry/Geom.h"
|
|
||||||
# include "../system/Exception.h"
|
|
||||||
# include "../scene_graph/FrsMaterial.h"
|
|
||||||
# include <set>
|
|
||||||
# include <vector>
|
|
||||||
class FEdge;
|
class FEdge;
|
||||||
class ViewEdge;
|
class ViewEdge;
|
||||||
class SShape;
|
class SShape;
|
||||||
|
|
||||||
using namespace Geometry;
|
using namespace Geometry;
|
||||||
|
|
||||||
#include "../python/Director.h"
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// UnaryFunction0D (base class for functions in 0D)
|
// UnaryFunction0D (base class for functions in 0D)
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template <class T>
|
/*! Base class for Unary Functions (functors) working on Interface0DIterator.
|
||||||
/*! Base class for Unary Functions (functors) working
|
* A unary function will be used by calling its operator() on an Interface0DIterator.
|
||||||
* on Interface0DIterator.
|
* \attention In the scripting language, there exists several prototypes depending on the returned value type.
|
||||||
* A unary function will be used by calling
|
* For example, you would inherit from a UnaryFunction0DDouble if you wish to define a function that returns a double.
|
||||||
* its operator() on an Interface0DIterator.
|
|
||||||
* \attention In the scripting language, there exists
|
|
||||||
* several prototypes depending on the returned value type.
|
|
||||||
* For example, you would inherit from a UnaryFunction0DDouble
|
|
||||||
* if you wish to define a function that returns a double.
|
|
||||||
* The different existing prototypes are:
|
* The different existing prototypes are:
|
||||||
* - UnaryFunction0DVoid
|
* - UnaryFunction0DVoid
|
||||||
* - UnaryFunction0DUnsigned
|
* - UnaryFunction0DUnsigned
|
||||||
@@ -68,39 +74,43 @@ template <class T>
|
|||||||
* - UnaryFunction0DVec2f
|
* - UnaryFunction0DVec2f
|
||||||
* - UnaryFunction0DVec3f
|
* - UnaryFunction0DVec3f
|
||||||
*/
|
*/
|
||||||
|
template <class T>
|
||||||
class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction0D
|
class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction0D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
T result;
|
T result;
|
||||||
PyObject *py_uf0D;
|
PyObject *py_uf0D;
|
||||||
|
|
||||||
/*! The type of the value
|
/*! The type of the value returned by the functor. */
|
||||||
* returned by the functor.
|
|
||||||
*/
|
|
||||||
typedef T ReturnedValueType;
|
typedef T ReturnedValueType;
|
||||||
|
|
||||||
/*! Default constructor. */
|
/*! Default constructor. */
|
||||||
UnaryFunction0D() { py_uf0D = 0;}
|
UnaryFunction0D()
|
||||||
|
{
|
||||||
|
py_uf0D = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Destructor; */
|
/*! Destructor; */
|
||||||
virtual ~UnaryFunction0D() {}
|
virtual ~UnaryFunction0D() {}
|
||||||
|
|
||||||
/*! Returns the string "UnaryFunction0D" */
|
/*! Returns the string "UnaryFunction0D" */
|
||||||
virtual string getName() const {
|
virtual string getName() const
|
||||||
|
{
|
||||||
return "UnaryFunction0D";
|
return "UnaryFunction0D";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! The operator ().
|
/*! The operator ().
|
||||||
* \param iter
|
* \param iter
|
||||||
* An Interface0DIterator pointing onto
|
* An Interface0DIterator pointing onto the point at which we wish to evaluate the function.
|
||||||
* the point at which we wish to evaluate
|
|
||||||
* the function.
|
|
||||||
* \return the result of the function of type T.
|
* \return the result of the function of type T.
|
||||||
*/
|
*/
|
||||||
virtual int operator()(Interface0DIterator& iter) {
|
virtual int operator()(Interface0DIterator& iter)
|
||||||
return Director_BPy_UnaryFunction0D___call__( this, py_uf0D, iter );
|
{
|
||||||
|
return Director_BPy_UnaryFunction0D___call__(this, py_uf0D, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# ifdef SWIG
|
#ifdef SWIG
|
||||||
%feature("director") UnaryFunction0D<void>;
|
%feature("director") UnaryFunction0D<void>;
|
||||||
%feature("director") UnaryFunction0D<unsigned>;
|
%feature("director") UnaryFunction0D<unsigned>;
|
||||||
%feature("director") UnaryFunction0D<float>;
|
%feature("director") UnaryFunction0D<float>;
|
||||||
@@ -118,383 +128,405 @@ UnaryFunction0D() { py_uf0D = 0;}
|
|||||||
%template(UnaryFunction0DId) UnaryFunction0D<Id>;
|
%template(UnaryFunction0DId) UnaryFunction0D<Id>;
|
||||||
%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
|
%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>;
|
||||||
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
|
%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >;
|
||||||
# endif // SWIG
|
#endif // SWIG
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Functions definitions
|
// Functions definitions
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
class ViewShape;
|
class ViewShape;
|
||||||
|
|
||||||
namespace Functions0D {
|
namespace Functions0D {
|
||||||
|
|
||||||
// GetXF0D
|
// GetXF0D
|
||||||
/*! Returns the X 3D coordinate of an Interface0D. */
|
/*! Returns the X 3D coordinate of an Interface0D. */
|
||||||
class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
|
class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*! Returns the string "GetXF0D" */
|
||||||
|
string getName() const
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
/*! Returns the string "GetXF0D"*/
|
|
||||||
string getName() const {
|
|
||||||
return "GetXF0D";
|
return "GetXF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter) {
|
/*! the () operator. */
|
||||||
|
int operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = iter->getX();
|
result = iter->getX();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// GetYF0D
|
// GetYF0D
|
||||||
/*! Returns the Y 3D coordinate of an Interface0D. */
|
/*! Returns the Y 3D coordinate of an Interface0D. */
|
||||||
class LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real>
|
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";
|
return "GetYF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter) {
|
/*! the () operator. */
|
||||||
|
int operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = iter->getY();
|
result = iter->getY();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// GetZF0D
|
// GetZF0D
|
||||||
/*! Returns the Z 3D coordinate of an Interface0D. */
|
/*! Returns the Z 3D coordinate of an Interface0D. */
|
||||||
class LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real>
|
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";
|
return "GetZF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter) {
|
/*! the () operator. */
|
||||||
|
int operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = iter->getZ();
|
result = iter->getZ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// GetProjectedXF0D
|
// GetProjectedXF0D
|
||||||
/*! Returns the X 3D projected coordinate of an Interface0D. */
|
/*! Returns the X 3D projected coordinate of an Interface0D. */
|
||||||
class LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real>
|
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";
|
return "GetProjectedXF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter) {
|
/*! the () operator. */
|
||||||
|
int operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = iter->getProjectedX();
|
result = iter->getProjectedX();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// GetProjectedYF0D
|
// GetProjectedYF0D
|
||||||
/*! Returns the Y projected 3D coordinate of an Interface0D. */
|
/*! Returns the Y projected 3D coordinate of an Interface0D. */
|
||||||
class LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real>
|
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";
|
return "GetProjectedYF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter) {
|
/*! the () operator. */
|
||||||
|
int operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = iter->getProjectedY();
|
result = iter->getProjectedY();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// GetProjectedZF0D
|
// GetProjectedZF0D
|
||||||
/*! Returns the Z projected 3D coordinate of an Interface0D. */
|
/*! Returns the Z projected 3D coordinate of an Interface0D. */
|
||||||
class LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real>
|
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";
|
return "GetProjectedZF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter) {
|
/*! the () operator. */
|
||||||
|
int operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = iter->getProjectedZ();
|
result = iter->getProjectedZ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// GetCurvilinearAbscissaF0D
|
// GetCurvilinearAbscissaF0D
|
||||||
/*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
|
/*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
|
||||||
class LIB_VIEW_MAP_EXPORT GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
|
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";
|
return "GetCurvilinearAbscissaF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter) {
|
/*! the () operator. */
|
||||||
|
int operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = iter.t();
|
result = iter.t();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// GetParameterF0D
|
// GetParameterF0D
|
||||||
/*! Returns the parameter of an Interface0D in the context of its 1D element. */
|
/*! Returns the parameter of an Interface0D in the context of its 1D element. */
|
||||||
class LIB_VIEW_MAP_EXPORT GetParameterF0D : public UnaryFunction0D<float>
|
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";
|
return "GetParameterF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter) {
|
/*! the () operator. */
|
||||||
|
int operator()(Interface0DIterator& iter)
|
||||||
|
{
|
||||||
result = iter.u();
|
result = iter.u();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// VertexOrientation2DF0D
|
// VertexOrientation2DF0D
|
||||||
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element
|
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
|
||||||
* to which the Interface0DIterator& belongs to and
|
|
||||||
* evaluated at the Interface0D pointed by this Interface0DIterator&.
|
* evaluated at the Interface0D pointed by this Interface0DIterator&.
|
||||||
*/
|
*/
|
||||||
class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
|
class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*! Returns the string "VertexOrientation2DF0D" */
|
||||||
|
string getName() const
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
/*! Returns the string "VertexOrientation2DF0D"*/
|
|
||||||
string getName() const {
|
|
||||||
return "VertexOrientation2DF0D";
|
return "VertexOrientation2DF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// VertexOrientation3DF0D
|
/*! the () operator. */
|
||||||
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element
|
int operator()(Interface0DIterator& iter);
|
||||||
* to which the Interface0DIterator& belongs to and
|
};
|
||||||
|
|
||||||
|
// 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&.
|
* 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";
|
return "VertexOrientation3DF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Curvature2DAngleF0D
|
/*! the () operator. */
|
||||||
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element
|
int operator()(Interface0DIterator& iter);
|
||||||
* to which the Interface0DIterator& belongs to and
|
};
|
||||||
* evaluated at the Interface0D pointed by this Interface0DIterator&.
|
|
||||||
|
// 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";
|
return "Curvature2DAngleF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ZDiscontinuity
|
/*! the () operator. */
|
||||||
/*! Returns a real giving the distance between
|
int operator()(Interface0DIterator& iter);
|
||||||
* and Interface0D and the shape that lies behind (occludee).
|
};
|
||||||
* This distance is evaluated in the camera space and normalized
|
|
||||||
* between 0 and 1. Therefore, if no oject is occluded by the
|
// ZDiscontinuity
|
||||||
* shape to which the Interface0D belongs to, 1 is returned.
|
/*! Returns a real giving the distance between and Interface0D and the shape that lies behind (occludee).
|
||||||
|
* This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no oject is occluded
|
||||||
|
* by the shape to which the Interface0D belongs to, 1 is returned.
|
||||||
*/
|
*/
|
||||||
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
|
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";
|
return "ZDiscontinuityF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Normal2DF0D
|
/*! the () operator. */
|
||||||
/*! Returns a Vec2f giving the normalized 2D normal to the 1D element
|
int operator()(Interface0DIterator& iter);
|
||||||
* to which the Interface0DIterator& belongs to and
|
};
|
||||||
|
|
||||||
|
// 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&.
|
* 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";
|
return "Normal2DF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// MaterialF0D
|
/*! the () operator. */
|
||||||
/*! Returns the material of the object evaluated at the Interface0D.
|
int operator()(Interface0DIterator& iter);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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 evaluation can be ambiguous (in the case of a TVertex for example.
|
||||||
* This functor tries to remove this ambiguity using the context
|
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
|
||||||
* offered by the 1D element to which the Interface0DIterator& belongs
|
* Interface0DIterator& belongs to and by arbitrary chosing the material of the face that lies on its left when
|
||||||
* to and by arbitrary chosing the material of the face
|
* following the 1D element if there are two different materials on each side of the point.
|
||||||
* that lies on its left when following the 1D element if there
|
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
|
||||||
* are two different materials on each side of the point.
|
* should implement its own getMaterial functor.
|
||||||
* However, there still can be problematic cases, and the user willing
|
|
||||||
* to deal with this cases in a specific way should implement
|
|
||||||
* its own getMaterial functor.
|
|
||||||
*/
|
*/
|
||||||
class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
|
class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*! Returns the string "MaterialF0D" */
|
||||||
|
string getName() const
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
/*! Returns the string "MaterialF0D"*/
|
|
||||||
string getName() const {
|
|
||||||
return "MaterialF0D";
|
return "MaterialF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ShapeIdF0D
|
/*! the () operator. */
|
||||||
/*! Returns the Id of the Shape the Interface0D belongs to.
|
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 evaluation can be ambiguous (in the case of a TVertex for example).
|
||||||
* This functor tries to remove this ambiguity using the context
|
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
|
||||||
* offered by the 1D element to which the Interface0DIterator& belongs
|
* Interface0DIterator& belongs to.
|
||||||
* to.
|
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
|
||||||
* However, there still can be problematic cases, and the user willing
|
* should implement its own getShapeIdF0D functor.
|
||||||
* to deal with this cases in a specific way should implement
|
|
||||||
* its own getShapeIdF0D functor.
|
|
||||||
*/
|
*/
|
||||||
class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
|
class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*! Returns the string "ShapeIdF0D" */
|
||||||
|
string getName() const
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
/*! Returns the string "ShapeIdF0D"*/
|
|
||||||
string getName() const {
|
|
||||||
return "ShapeIdF0D";
|
return "ShapeIdF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// QiF0D
|
/*! the () operator. */
|
||||||
/*! Returns the quantitative invisibility of this Interface0D.
|
int operator()(Interface0DIterator& iter);
|
||||||
* This evaluation can be ambiguous (in the case of a TVertex for example).
|
};
|
||||||
* This functor tries to remove this ambiguity using the context
|
|
||||||
* offered by the 1D element to which the Interface0DIterator& belongs
|
// QiF0D
|
||||||
* to.
|
/*! Returns the quantitative invisibility of this Interface0D.
|
||||||
* However, there still can be problematic cases, and the user willing
|
* This evaluation can be ambiguous (in the case of a TVertex for example).
|
||||||
* to deal with this cases in a specific way should implement
|
* This functor tries to remove this ambiguity using the context offered by the 1D element to which the
|
||||||
* its own getQIF0D functor.
|
* Interface0DIterator& belongs to.
|
||||||
*/
|
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
|
||||||
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
|
* 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";
|
return "QuantitativeInvisibilityF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// CurveNatureF0D
|
/*! the () operator. */
|
||||||
/*! Returns the Nature::EdgeNature of the 1D element the
|
int operator()(Interface0DIterator& iter);
|
||||||
* Interface0DIterator& belongs to.
|
};
|
||||||
*/
|
|
||||||
class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
|
// 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";
|
return "CurveNatureF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetShapeF0D
|
/*! the () operator. */
|
||||||
/*! Returns the ViewShape*
|
int operator()(Interface0DIterator& iter);
|
||||||
* containing the Interface0D
|
};
|
||||||
*/
|
|
||||||
class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*>
|
// 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";
|
return "GetShapeF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetOccludersF0D
|
/*! the () operator. */
|
||||||
/*! Returns a vector containing the ViewShape*
|
int operator()(Interface0DIterator& iter);
|
||||||
* occluding the Interface0D
|
};
|
||||||
*/
|
|
||||||
class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
|
// 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";
|
return "GetOccludersF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface0DIterator& iter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetOccludeeF0D
|
/*! the () operator. */
|
||||||
/*! Returns the ViewShape*
|
int operator()(Interface0DIterator& iter);
|
||||||
* "occluded" by the Interface0D
|
};
|
||||||
*/
|
|
||||||
class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
|
// 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";
|
return "GetOccludeeF0D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
|
/*! the () operator. */
|
||||||
int operator()(Interface0DIterator& iter);
|
int operator()(Interface0DIterator& iter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////// Internal ////////////////////////////
|
||||||
|
|
||||||
/////////////////////////// Internal ////////////////////////////
|
// getFEdge
|
||||||
|
LIB_VIEW_MAP_EXPORT
|
||||||
|
FEdge *getFEdge(Interface0D& it1, Interface0D& it2);
|
||||||
|
|
||||||
// getFEdge
|
// getFEdges
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
FEdge* getFEdge(Interface0D& it1, Interface0D& it2);
|
void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
|
||||||
|
|
||||||
// getFEdges
|
// getViewEdges
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void getFEdges(Interface0DIterator& it,
|
void getViewEdges(Interface0DIterator& it, ViewEdge *&ve1, ViewEdge *&ve2);
|
||||||
FEdge*& fe1,
|
|
||||||
FEdge*& fe2);
|
|
||||||
|
|
||||||
// getViewEdges
|
// getShapeF0D
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void getViewEdges(Interface0DIterator& it,
|
ViewShape *getShapeF0D(Interface0DIterator& it);
|
||||||
ViewEdge *&ve1,
|
|
||||||
ViewEdge *&ve2);
|
|
||||||
|
|
||||||
// getShapeF0D
|
// getOccludersF0D
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
ViewShape* getShapeF0D(Interface0DIterator& it);
|
void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
|
||||||
|
|
||||||
// getOccludersF0D
|
// getOccludeeF0D
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
|
ViewShape *getOccludeeF0D(Interface0DIterator& it);
|
||||||
|
|
||||||
// getOccludeeF0D
|
|
||||||
LIB_VIEW_MAP_EXPORT
|
|
||||||
ViewShape* getOccludeeF0D(Interface0DIterator& it);
|
|
||||||
|
|
||||||
} // end of namespace Functions0D
|
} // end of namespace Functions0D
|
||||||
|
|
||||||
#endif // FUNCTIONS0D_H
|
#endif // __FREESTYLE_FUNCTIONS_0D_H__
|
||||||
|
|||||||
@@ -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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/Functions1D.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Functions taking 1D input
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Emmanuel Turquin
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 01/07/2003
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
# include "Functions1D.h"
|
# include "Functions1D.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace Functions1D {
|
namespace Functions1D {
|
||||||
|
|
||||||
int GetXF1D::operator()(Interface1D& inter) {
|
int GetXF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetYF1D::operator()(Interface1D& inter) {
|
int GetYF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetZF1D::operator()(Interface1D& inter) {
|
int GetZF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetProjectedXF1D::operator()(Interface1D& inter) {
|
int GetProjectedXF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetProjectedYF1D::operator()(Interface1D& inter) {
|
int GetProjectedYF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetProjectedZF1D::operator()(Interface1D& inter) {
|
int GetProjectedZF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Orientation2DF1D::operator()(Interface1D& inter) {
|
int Orientation2DF1D::operator()(Interface1D& inter)
|
||||||
FEdge * fe = dynamic_cast<FEdge*>(&inter);
|
{
|
||||||
if(fe){
|
FEdge *fe = dynamic_cast<FEdge*>(&inter);
|
||||||
|
if (fe) {
|
||||||
Vec3r res = fe->orientation2d();
|
Vec3r res = fe->orientation2d();
|
||||||
result = Vec2f(res[0], res[1]);
|
result = Vec2f(res[0], res[1]);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Orientation3DF1D::operator()(Interface1D& inter) {
|
int Orientation3DF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZDiscontinuityF1D::operator()(Interface1D& inter) {
|
int ZDiscontinuityF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QuantitativeInvisibilityF1D::operator()(Interface1D& inter) {
|
int QuantitativeInvisibilityF1D::operator()(Interface1D& inter)
|
||||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
{
|
||||||
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
if (ve) {
|
if (ve) {
|
||||||
result = ve->qi();
|
result = ve->qi();
|
||||||
return 0;
|
return 0;
|
||||||
@@ -88,144 +114,158 @@ namespace Functions1D {
|
|||||||
}
|
}
|
||||||
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CurveNatureF1D::operator()(Interface1D& inter) {
|
int CurveNatureF1D::operator()(Interface1D& inter)
|
||||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
{
|
||||||
if (ve)
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
|
if (ve) {
|
||||||
result = ve->getNature();
|
result = ve->getNature();
|
||||||
else{
|
}
|
||||||
// we return a nature that contains every
|
else {
|
||||||
// natures of the viewedges spanned by the chain.
|
// we return a nature that contains every natures of the viewedges spanned by the chain.
|
||||||
Nature::EdgeNature nat = Nature::NO_FEATURE;
|
Nature::EdgeNature nat = Nature::NO_FEATURE;
|
||||||
Interface0DIterator it = inter.verticesBegin();
|
Interface0DIterator it = inter.verticesBegin();
|
||||||
while(!it.isEnd()){
|
while (!it.isEnd()) {
|
||||||
nat |= _func(it);
|
nat |= _func(it);
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
result = nat;
|
result = nat;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TimeStampF1D::operator()(Interface1D& inter) {
|
int TimeStampF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
TimeStamp *timestamp = TimeStamp::instance();
|
TimeStamp *timestamp = TimeStamp::instance();
|
||||||
inter.setTimeStamp(timestamp->getTimeStamp());
|
inter.setTimeStamp(timestamp->getTimeStamp());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChainingTimeStampF1D::operator()(Interface1D& inter) {
|
int ChainingTimeStampF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
TimeStamp *timestamp = TimeStamp::instance();
|
TimeStamp *timestamp = TimeStamp::instance();
|
||||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
if(ve)
|
if (ve)
|
||||||
ve->setChainingTimeStamp(timestamp->getTimeStamp());
|
ve->setChainingTimeStamp(timestamp->getTimeStamp());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int IncrementChainingTimeStampF1D::operator()(Interface1D& inter) {
|
int IncrementChainingTimeStampF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
if(ve)
|
if (ve)
|
||||||
ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1);
|
ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetShapeF1D::operator()(Interface1D& inter) {
|
int GetShapeF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
vector<ViewShape*> shapesVector;
|
vector<ViewShape*> shapesVector;
|
||||||
set<ViewShape*> shapesSet;
|
set<ViewShape*> shapesSet;
|
||||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
if (ve){
|
if (ve) {
|
||||||
shapesVector.push_back(ve->viewShape());
|
shapesVector.push_back(ve->viewShape());
|
||||||
}else{
|
}
|
||||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
else {
|
||||||
for(;it!=itend;++it)
|
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||||
|
for (; it != itend; ++it)
|
||||||
shapesSet.insert(Functions0D::getShapeF0D(it));
|
shapesSet.insert(Functions0D::getShapeF0D(it));
|
||||||
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
|
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
|
||||||
}
|
}
|
||||||
result = shapesVector;
|
result = shapesVector;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetOccludersF1D::operator()(Interface1D& inter) {
|
int GetOccludersF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
vector<ViewShape*> shapesVector;
|
vector<ViewShape*> shapesVector;
|
||||||
set<ViewShape*> shapesSet;
|
set<ViewShape*> shapesSet;
|
||||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
if (ve){
|
if (ve) {
|
||||||
result = ve->occluders();
|
result = ve->occluders();
|
||||||
}else{
|
}
|
||||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
else {
|
||||||
for(;it!=itend;++it){
|
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||||
|
for (; it != itend; ++it) {
|
||||||
Functions0D::getOccludersF0D(it, shapesSet);
|
Functions0D::getOccludersF0D(it, shapesSet);
|
||||||
}
|
}
|
||||||
shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
|
shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
|
||||||
result = shapesVector;
|
result = shapesVector;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetOccludeeF1D::operator()(Interface1D& inter) {
|
int GetOccludeeF1D::operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
vector<ViewShape*> shapesVector;
|
vector<ViewShape*> shapesVector;
|
||||||
set<ViewShape*> shapesSet;
|
set<ViewShape*> shapesSet;
|
||||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
if (ve){
|
if (ve) {
|
||||||
ViewShape * aShape = ve->aShape();
|
ViewShape *aShape = ve->aShape();
|
||||||
shapesVector.push_back(aShape);
|
shapesVector.push_back(aShape);
|
||||||
}else{
|
}
|
||||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
else {
|
||||||
for(;it!=itend;++it){
|
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||||
|
for (; it != itend; ++it) {
|
||||||
shapesSet.insert(Functions0D::getOccludeeF0D(it));
|
shapesSet.insert(Functions0D::getOccludeeF0D(it));
|
||||||
}
|
}
|
||||||
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
|
shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end());
|
||||||
}
|
}
|
||||||
result = shapesVector;
|
result = shapesVector;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Internal
|
|
||||||
////////////
|
|
||||||
|
|
||||||
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes){
|
// Internal
|
||||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
////////////
|
||||||
if (ve){
|
|
||||||
ViewShape * aShape = ve->aShape();
|
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
|
||||||
if(aShape == 0){
|
{
|
||||||
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
|
if (ve) {
|
||||||
|
ViewShape *aShape = ve->aShape();
|
||||||
|
if (aShape == 0) {
|
||||||
oShapes.insert(0);
|
oShapes.insert(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
oShapes.insert(aShape);
|
oShapes.insert(aShape);
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||||
for(;it!=itend;++it)
|
for (; it != itend; ++it)
|
||||||
oShapes.insert(Functions0D::getOccludeeF0D(it));
|
oShapes.insert(Functions0D::getOccludeeF0D(it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes){
|
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes)
|
||||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
{
|
||||||
if (ve){
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
|
if (ve) {
|
||||||
vector<ViewShape*>& occluders = ve->occluders();
|
vector<ViewShape*>& occluders = ve->occluders();
|
||||||
oShapes.insert<vector<ViewShape*>::iterator>(occluders.begin(), occluders.end());
|
oShapes.insert<vector<ViewShape*>::iterator>(occluders.begin(), occluders.end());
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||||
for(;it!=itend;++it){
|
for (; it != itend; ++it) {
|
||||||
set<ViewShape*> shapes;
|
set<ViewShape*> shapes;
|
||||||
Functions0D::getOccludersF0D(it, shapes);
|
Functions0D::getOccludersF0D(it, shapes);
|
||||||
for(set<ViewShape*>::iterator s=shapes.begin(), send=shapes.end();
|
for (set<ViewShape*>::iterator s = shapes.begin(), send = shapes.end(); s != send; ++s)
|
||||||
s!=send;
|
|
||||||
++s)
|
|
||||||
oShapes.insert(*s);
|
oShapes.insert(*s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes){
|
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes)
|
||||||
ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter);
|
{
|
||||||
if (ve){
|
ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter);
|
||||||
|
if (ve) {
|
||||||
oShapes.insert(ve->viewShape());
|
oShapes.insert(ve->viewShape());
|
||||||
}else{
|
}
|
||||||
Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd();
|
else {
|
||||||
for(;it!=itend;++it)
|
Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
|
||||||
|
for (; it != itend; ++it)
|
||||||
oShapes.insert(Functions0D::getShapeF0D(it));
|
oShapes.insert(Functions0D::getShapeF0D(it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace Functions1D
|
} // end of namespace Functions1D
|
||||||
|
|||||||
@@ -1,41 +1,48 @@
|
|||||||
//
|
/*
|
||||||
// Filename : Functions1D.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli, Emmanuel Turquin
|
*
|
||||||
// Purpose : Functions taking 1D input
|
* This program is free software; you can redistribute it and/or
|
||||||
// Date of creation : 01/07/2003
|
* modify it under the terms of the GNU General Public License
|
||||||
//
|
* as published by the Free Software Foundation; either version 2
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_FUNCTIONS_1D_H__
|
||||||
|
#define __FREESTYLE_FUNCTIONS_1D_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/Functions1D.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Functions taking 1D input
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Emmanuel Turquin
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 01/07/2003
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef FUNCTIONS1D_HPP
|
#include "Functions0D.h"
|
||||||
# define FUNCTIONS1D_HPP
|
#include "Interface1D.h"
|
||||||
|
#include "ViewMap.h"
|
||||||
|
|
||||||
# include "ViewMap.h"
|
#include "../system/FreestyleConfig.h"
|
||||||
# include "Functions0D.h"
|
#include "../system/Precision.h"
|
||||||
# include "Interface1D.h"
|
#include "../system/TimeStamp.h"
|
||||||
# include "../system/Precision.h"
|
|
||||||
# include "../system/TimeStamp.h"
|
|
||||||
# include "../system/FreestyleConfig.h"
|
|
||||||
|
|
||||||
#include "../python/Director.h"
|
#include "../python/Director.h"
|
||||||
|
|
||||||
@@ -44,14 +51,10 @@
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*! Base class for Unary Functions (functors) working
|
/*! Base class for Unary Functions (functors) working on Interface1D.
|
||||||
* on Interface1D.
|
* A unary function will be used by calling its operator() on an Interface1D.
|
||||||
* A unary function will be used by calling
|
* \attention In the scripting language, there exists several prototypes depending on the returned value type.
|
||||||
* its operator() on an Interface1D.
|
* For example, you would inherit from a UnaryFunction1DDouble if you wish to define a function that returns a double.
|
||||||
* \attention In the scripting language, there exists
|
|
||||||
* several prototypes depending on the returned value type.
|
|
||||||
* For example, you would inherit from a UnaryFunction1DDouble
|
|
||||||
* if you wish to define a function that returns a double.
|
|
||||||
* The different existing prototypes are:
|
* The different existing prototypes are:
|
||||||
* - UnaryFunction1DVoid
|
* - UnaryFunction1DVoid
|
||||||
* - UnaryFunction1DUnsigned
|
* - UnaryFunction1DUnsigned
|
||||||
@@ -65,54 +68,61 @@ template <class T>
|
|||||||
class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction1D
|
class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction1D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
T result;
|
T result;
|
||||||
PyObject *py_uf1D;
|
PyObject *py_uf1D;
|
||||||
|
|
||||||
/*! The type of the value
|
/*! The type of the value returned by the functor. */
|
||||||
* returned by the functor.
|
|
||||||
*/
|
|
||||||
typedef T ReturnedValueType;
|
typedef T ReturnedValueType;
|
||||||
|
|
||||||
/*! Default constructor */
|
/*! Default constructor */
|
||||||
UnaryFunction1D(){_integration = MEAN;}
|
UnaryFunction1D()
|
||||||
|
{
|
||||||
|
_integration = MEAN;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Builds a UnaryFunction1D from an integration type.
|
/*! Builds a UnaryFunction1D from an integration type.
|
||||||
* \param iType
|
* \param iType
|
||||||
* In case the result for the Interface1D would be
|
* In case the result for the Interface1D would be obtained by evaluating a 0D function over the different
|
||||||
* obtained by evaluating a 0D function over the different
|
* Interface0D of the Interface1D, \a iType tells which integration method to use.
|
||||||
* Interface0D of the Interface1D, \a iType tells which
|
|
||||||
* integration method to use.
|
|
||||||
* The default integration method is the MEAN.
|
* The default integration method is the MEAN.
|
||||||
*/
|
*/
|
||||||
UnaryFunction1D(IntegrationType iType){_integration = iType;}
|
UnaryFunction1D(IntegrationType iType)
|
||||||
|
{
|
||||||
|
_integration = iType;
|
||||||
|
}
|
||||||
|
|
||||||
/*! destructor. */
|
/*! destructor. */
|
||||||
virtual ~UnaryFunction1D() {}
|
virtual ~UnaryFunction1D() {}
|
||||||
|
|
||||||
/*! returns the string "UnaryFunction1D". */
|
/*! returns the string "UnaryFunction1D". */
|
||||||
virtual string getName() const {
|
virtual string getName() const
|
||||||
|
{
|
||||||
return "UnaryFunction1D";
|
return "UnaryFunction1D";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! The operator ().
|
/*! The operator ().
|
||||||
* \param inter
|
* \param inter
|
||||||
* The Interface1D on which we wish to evaluate
|
* The Interface1D on which we wish to evaluate the function.
|
||||||
* the function.
|
|
||||||
* \return the result of the function of type T.
|
* \return the result of the function of type T.
|
||||||
*/
|
*/
|
||||||
virtual int operator()(Interface1D& inter) {
|
virtual int operator()(Interface1D& inter)
|
||||||
return Director_BPy_UnaryFunction1D___call__( this, py_uf1D, inter );
|
{
|
||||||
|
return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sets the integration method */
|
/*! Sets the integration method */
|
||||||
void setIntegrationType(IntegrationType integration) {
|
void setIntegrationType(IntegrationType integration)
|
||||||
|
{
|
||||||
_integration = integration;
|
_integration = integration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the integration method. */
|
/*! Returns the integration method. */
|
||||||
IntegrationType getIntegrationType() const {
|
IntegrationType getIntegrationType() const
|
||||||
|
{
|
||||||
return _integration;
|
return _integration;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
IntegrationType _integration;
|
IntegrationType _integration;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -120,25 +130,41 @@ protected:
|
|||||||
class UnaryFunction1D_void
|
class UnaryFunction1D_void
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PyObject *py_uf1D;
|
PyObject *py_uf1D;
|
||||||
|
|
||||||
UnaryFunction1D_void(){_integration = MEAN;}
|
UnaryFunction1D_void()
|
||||||
UnaryFunction1D_void(IntegrationType iType){_integration = iType;}
|
{
|
||||||
|
_integration = MEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnaryFunction1D_void(IntegrationType iType)
|
||||||
|
{
|
||||||
|
_integration = iType;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~UnaryFunction1D_void() {}
|
virtual ~UnaryFunction1D_void() {}
|
||||||
|
|
||||||
virtual string getName() const {
|
virtual string getName() const
|
||||||
|
{
|
||||||
return "UnaryFunction1D_void";
|
return "UnaryFunction1D_void";
|
||||||
}
|
}
|
||||||
|
|
||||||
int operator()(Interface1D& inter) {
|
int operator()(Interface1D& inter)
|
||||||
return Director_BPy_UnaryFunction1D___call__( this, py_uf1D, inter );
|
{
|
||||||
|
return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIntegrationType(IntegrationType integration) { _integration = integration; }
|
void setIntegrationType(IntegrationType integration)
|
||||||
IntegrationType getIntegrationType() const { return _integration; }
|
{
|
||||||
|
_integration = integration;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
IntegrationType getIntegrationType() const
|
||||||
|
{
|
||||||
|
return _integration;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
IntegrationType _integration;
|
IntegrationType _integration;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -150,406 +176,452 @@ public:
|
|||||||
|
|
||||||
namespace Functions1D {
|
namespace Functions1D {
|
||||||
|
|
||||||
// GetXF1D
|
// GetXF1D
|
||||||
/*! Returns the X 3D coordinate of an Interface1D. */
|
/*! Returns the X 3D coordinate of an Interface1D. */
|
||||||
class LIB_VIEW_MAP_EXPORT GetXF1D : public UnaryFunction1D<real>
|
class LIB_VIEW_MAP_EXPORT GetXF1D : public UnaryFunction1D<real>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Functions0D::GetXF0D _func;
|
Functions0D::GetXF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
GetXF1D(IntegrationType iType) : UnaryFunction1D<real>(iType){}
|
GetXF1D(IntegrationType iType) : UnaryFunction1D<real>(iType) {}
|
||||||
/*! Returns the string "GetXF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "GetXF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "GetXF1D";
|
return "GetXF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter) ;
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetYF1D
|
/*! the () operator. */
|
||||||
/*! Returns the Y 3D coordinate of an Interface1D. */
|
int operator()(Interface1D& inter);
|
||||||
class LIB_VIEW_MAP_EXPORT GetYF1D : public UnaryFunction1D<real>
|
};
|
||||||
{
|
|
||||||
private:
|
// GetYF1D
|
||||||
Functions0D::GetYF0D _func;
|
/*! Returns the Y 3D coordinate of an Interface1D. */
|
||||||
public:
|
class LIB_VIEW_MAP_EXPORT GetYF1D : public UnaryFunction1D<real>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Functions0D::GetYF0D _func;
|
||||||
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){}
|
GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||||
/*! Returns the string "GetYF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "GetYF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "GetYF1D";
|
return "GetYF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter) ;
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetZF1D
|
/*! the () operator. */
|
||||||
/*! Returns the Z 3D coordinate of an Interface1D. */
|
int operator()(Interface1D& inter);
|
||||||
class LIB_VIEW_MAP_EXPORT GetZF1D : public UnaryFunction1D<real>
|
};
|
||||||
{
|
|
||||||
private:
|
// GetZF1D
|
||||||
|
/*! Returns the Z 3D coordinate of an Interface1D. */
|
||||||
|
class LIB_VIEW_MAP_EXPORT GetZF1D : public UnaryFunction1D<real>
|
||||||
|
{
|
||||||
|
private:
|
||||||
Functions0D::GetZF0D _func;
|
Functions0D::GetZF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){}
|
GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||||
/*! Returns the string "GetZF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "GetZF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "GetZF1D";
|
return "GetZF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter) ;
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetProjectedXF1D
|
/*! the () operator. */
|
||||||
/*! Returns the projected X 3D coordinate of an Interface1D. */
|
int operator()(Interface1D& inter);
|
||||||
class LIB_VIEW_MAP_EXPORT GetProjectedXF1D : public UnaryFunction1D<real>
|
};
|
||||||
{
|
|
||||||
private:
|
// GetProjectedXF1D
|
||||||
|
/*! Returns the projected X 3D coordinate of an Interface1D. */
|
||||||
|
class LIB_VIEW_MAP_EXPORT GetProjectedXF1D : public UnaryFunction1D<real>
|
||||||
|
{
|
||||||
|
private:
|
||||||
Functions0D::GetProjectedXF0D _func;
|
Functions0D::GetProjectedXF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){}
|
GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||||
public:
|
|
||||||
/*! Returns the string "GetProjectedXF1D"*/
|
/*! Returns the string "GetProjectedXF1D" */
|
||||||
string getName() const {
|
string getName() const
|
||||||
|
{
|
||||||
return "GetProjectedXF1D";
|
return "GetProjectedXF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetProjectedYF1D
|
/*! the () operator. */
|
||||||
/*! Returns the projected Y 3D coordinate of an Interface1D. */
|
int operator()(Interface1D& inter);
|
||||||
class LIB_VIEW_MAP_EXPORT GetProjectedYF1D : public UnaryFunction1D<real>
|
};
|
||||||
{
|
|
||||||
private:
|
// GetProjectedYF1D
|
||||||
|
/*! Returns the projected Y 3D coordinate of an Interface1D. */
|
||||||
|
class LIB_VIEW_MAP_EXPORT GetProjectedYF1D : public UnaryFunction1D<real>
|
||||||
|
{
|
||||||
|
private:
|
||||||
Functions0D::GetProjectedYF0D _func;
|
Functions0D::GetProjectedYF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){}
|
GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||||
public:
|
|
||||||
/*! Returns the string "GetProjectedYF1D"*/
|
/*! Returns the string "GetProjectedYF1D" */
|
||||||
string getName() const {
|
string getName() const
|
||||||
|
{
|
||||||
return "GetProjectedYF1D";
|
return "GetProjectedYF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetProjectedZF1D
|
/*! the () operator. */
|
||||||
/*! Returns the projected Z 3D coordinate of an Interface1D. */
|
int operator()(Interface1D& inter);
|
||||||
class LIB_VIEW_MAP_EXPORT GetProjectedZF1D : public UnaryFunction1D<real>
|
};
|
||||||
{
|
|
||||||
private:
|
// GetProjectedZF1D
|
||||||
|
/*! Returns the projected Z 3D coordinate of an Interface1D. */
|
||||||
|
class LIB_VIEW_MAP_EXPORT GetProjectedZF1D : public UnaryFunction1D<real>
|
||||||
|
{
|
||||||
|
private:
|
||||||
Functions0D::GetProjectedZF0D _func;
|
Functions0D::GetProjectedZF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){}
|
GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||||
public:
|
|
||||||
/*! Returns the string "GetProjectedZF1D"*/
|
/*! Returns the string "GetProjectedZF1D" */
|
||||||
string getName() const {
|
string getName() const
|
||||||
|
{
|
||||||
return "GetProjectedZF1D";
|
return "GetProjectedZF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Orientation2DF1D
|
/*! the () operator. */
|
||||||
/*! Returns the 2D orientation as a Vec2f*/
|
int operator()(Interface1D& inter);
|
||||||
class LIB_VIEW_MAP_EXPORT Orientation2DF1D : public UnaryFunction1D<Vec2f>
|
};
|
||||||
{
|
|
||||||
private:
|
// Orientation2DF1D
|
||||||
|
/*! Returns the 2D orientation as a Vec2f*/
|
||||||
|
class LIB_VIEW_MAP_EXPORT Orientation2DF1D : public UnaryFunction1D<Vec2f>
|
||||||
|
{
|
||||||
|
private:
|
||||||
Functions0D::VertexOrientation2DF0D _func;
|
Functions0D::VertexOrientation2DF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
Orientation2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType){}
|
Orientation2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {}
|
||||||
/*! Returns the string "Orientation2DF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "Orientation2DF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "Orientation2DF1D";
|
return "Orientation2DF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Orientation3DF1D
|
/*! the () operator. */
|
||||||
/*! Returns the 3D orientation as a Vec3f. */
|
int operator()(Interface1D& inter);
|
||||||
class LIB_VIEW_MAP_EXPORT Orientation3DF1D : public UnaryFunction1D<Vec3f>
|
};
|
||||||
{
|
|
||||||
private:
|
// Orientation3DF1D
|
||||||
|
/*! Returns the 3D orientation as a Vec3f. */
|
||||||
|
class LIB_VIEW_MAP_EXPORT Orientation3DF1D : public UnaryFunction1D<Vec3f>
|
||||||
|
{
|
||||||
|
private:
|
||||||
Functions0D::VertexOrientation3DF0D _func;
|
Functions0D::VertexOrientation3DF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
Orientation3DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec3f>(iType){}
|
Orientation3DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec3f>(iType) {}
|
||||||
/*! Returns the string "Orientation3DF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "Orientation3DF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "Orientation3DF1D";
|
return "Orientation3DF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ZDiscontinuityF1D
|
/*! the () operator. */
|
||||||
/*! Returns a real giving the distance between
|
int operator()(Interface1D& inter);
|
||||||
* 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
|
// ZDiscontinuityF1D
|
||||||
* shape to which the Interface1D belongs to, 1 is returned.
|
/*! Returns a real giving the distance between and Interface1D and the shape that lies behind (occludee).
|
||||||
|
* This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no oject is occluded
|
||||||
|
* by the shape to which the Interface1D belongs to, 1 is returned.
|
||||||
*/
|
*/
|
||||||
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF1D : public UnaryFunction1D<real>
|
class LIB_VIEW_MAP_EXPORT ZDiscontinuityF1D : public UnaryFunction1D<real>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Functions0D::ZDiscontinuityF0D _func;
|
Functions0D::ZDiscontinuityF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){}
|
ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||||
/*! Returns the string "ZDiscontinuityF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "ZDiscontinuityF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "ZDiscontinuityF1D";
|
return "ZDiscontinuityF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// QuantitativeInvisibilityF1D
|
/*! the () operator. */
|
||||||
/*! Returns the Quantitative Invisibility of an Interface1D element.
|
int operator()(Interface1D& inter);
|
||||||
* 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
|
// QuantitativeInvisibilityF1D
|
||||||
* of different Quantitative Invisibilities.
|
/*! 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>
|
class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Functions0D::QuantitativeInvisibilityF0D _func;
|
Functions0D::QuantitativeInvisibilityF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
QuantitativeInvisibilityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<unsigned int>(iType) {}
|
QuantitativeInvisibilityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<unsigned int>(iType) {}
|
||||||
/*! Returns the string "QuantitativeInvisibilityF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "QuantitativeInvisibilityF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "QuantitativeInvisibilityF1D";
|
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...).
|
/*! Returns the nature of the Interface1D (silhouette, ridge, crease...).
|
||||||
* Except if the Interface1D is a ViewEdge, this result might be ambiguous.
|
* Except if the Interface1D is a ViewEdge, this result might be ambiguous.
|
||||||
* Indeed, the Interface1D might result from the gathering of several 1D elements,
|
* Indeed, the Interface1D might result from the gathering of several 1D elements, each one being of a different
|
||||||
* each one being of a different nature. An integration method, such as
|
* nature. An integration method, such as the MEAN, might give, in this case, irrelevant results.
|
||||||
* the MEAN, might give, in this case, irrelevant results.
|
|
||||||
*/
|
*/
|
||||||
class LIB_VIEW_MAP_EXPORT CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature>
|
class LIB_VIEW_MAP_EXPORT CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Functions0D::CurveNatureF0D _func;
|
Functions0D::CurveNatureF0D _func;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
CurveNatureF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Nature::EdgeNature>(iType) {}
|
CurveNatureF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Nature::EdgeNature>(iType) {}
|
||||||
/*! Returns the string "CurveNatureF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "CurveNatureF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "CurveNatureF1D";
|
return "CurveNatureF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// TimeStampF1D
|
/*! the () operator. */
|
||||||
|
int operator()(Interface1D& inter);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TimeStampF1D
|
||||||
/*! Returns the time stamp of the Interface1D. */
|
/*! 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";
|
return "TimeStampF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// IncrementChainingTimeStampF1D
|
/*! the () operator. */
|
||||||
|
int operator()(Interface1D& inter);
|
||||||
|
};
|
||||||
|
|
||||||
|
// IncrementChainingTimeStampF1D
|
||||||
/*! Increments the chaining time stamp of the Interface1D. */
|
/*! 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";
|
return "IncrementChainingTimeStampF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ChainingTimeStampF1D
|
/*! the () operator. */
|
||||||
|
int operator()(Interface1D& inter);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ChainingTimeStampF1D
|
||||||
/*! Sets the chaining time stamp of the Interface1D. */
|
/*! 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";
|
return "ChainingTimeStampF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
|
/*! the () operator. */
|
||||||
int operator()(Interface1D& inter);
|
int operator()(Interface1D& inter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Curvature2DAngleF1D
|
// Curvature2DAngleF1D
|
||||||
/*! Returns the 2D curvature as an angle for an Interface1D. */
|
/*! Returns the 2D curvature as an angle for an Interface1D. */
|
||||||
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF1D : public UnaryFunction1D<real>
|
class LIB_VIEW_MAP_EXPORT Curvature2DAngleF1D : public UnaryFunction1D<real>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
Curvature2DAngleF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
Curvature2DAngleF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
|
||||||
/*! Returns the string "Curvature2DAngleF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "Curvature2DAngleF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "Curvature2DAngleF1D";
|
return "Curvature2DAngleF1D";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! the () operator.*/
|
/*! the () operator.*/
|
||||||
int operator()(Interface1D& inter) {
|
int operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
Functions0D::Curvature2DAngleF0D _fun;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Normal2DF1D
|
private:
|
||||||
/*! Returns the 2D normal for an interface 1D. */
|
Functions0D::Curvature2DAngleF0D _fun;
|
||||||
class LIB_VIEW_MAP_EXPORT Normal2DF1D : public UnaryFunction1D<Vec2f>
|
};
|
||||||
{
|
|
||||||
public:
|
// Normal2DF1D
|
||||||
|
/*! Returns the 2D normal for an interface 1D. */
|
||||||
|
class LIB_VIEW_MAP_EXPORT Normal2DF1D : public UnaryFunction1D<Vec2f>
|
||||||
|
{
|
||||||
|
public:
|
||||||
/*! Builds the functor.
|
/*! Builds the functor.
|
||||||
* \param iType
|
* \param iType
|
||||||
* The integration method used to compute
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a single value from a set of values.
|
|
||||||
*/
|
*/
|
||||||
Normal2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {}
|
Normal2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {}
|
||||||
/*! Returns the string "Normal2DF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "Normal2DF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "Normal2DF1D";
|
return "Normal2DF1D";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! the () operator.*/
|
/*! the () operator.*/
|
||||||
int operator()(Interface1D& inter) {
|
int operator()(Interface1D& inter)
|
||||||
|
{
|
||||||
result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
Functions0D::Normal2DF0D _fun;
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetShapeF1D
|
private:
|
||||||
/*! Returns list of shapes covered by this Interface1D. */
|
Functions0D::Normal2DF0D _fun;
|
||||||
class LIB_VIEW_MAP_EXPORT GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
|
};
|
||||||
{
|
|
||||||
public:
|
// GetShapeF1D
|
||||||
/*! Builds the functor.
|
/*! 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*> >() {}
|
GetShapeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
|
||||||
/*! Returns the string "GetShapeF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "GetShapeF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "GetShapeF1D";
|
return "GetShapeF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetOccludersF1D
|
/*! the () operator. */
|
||||||
/*! Returns list of occluding shapes covered by this Interface1D. */
|
int operator()(Interface1D& inter);
|
||||||
class LIB_VIEW_MAP_EXPORT GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape*> >
|
};
|
||||||
{
|
|
||||||
public:
|
// GetOccludersF1D
|
||||||
/*! Builds the functor.
|
/*! 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*> >() {}
|
GetOccludersF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
|
||||||
/*! Returns the string "GetOccludersF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "GetOccludersF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "GetOccludersF1D";
|
return "GetOccludersF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
int operator()(Interface1D& inter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// GetOccludeeF1D
|
/*! the () operator. */
|
||||||
/*! Returns list of occluded shapes covered by this Interface1D. */
|
int operator()(Interface1D& inter);
|
||||||
class LIB_VIEW_MAP_EXPORT GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
|
};
|
||||||
{
|
|
||||||
public:
|
// GetOccludeeF1D
|
||||||
/*! Builds the functor.
|
/*! 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*> >() {}
|
GetOccludeeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {}
|
||||||
/*! Returns the string "GetOccludeeF1D"*/
|
|
||||||
string getName() const {
|
/*! Returns the string "GetOccludeeF1D" */
|
||||||
|
string getName() const
|
||||||
|
{
|
||||||
return "GetOccludeeF1D";
|
return "GetOccludeeF1D";
|
||||||
}
|
}
|
||||||
/*! the () operator.*/
|
|
||||||
|
/*! the () operator. */
|
||||||
int operator()(Interface1D& inter);
|
int operator()(Interface1D& inter);
|
||||||
};
|
};
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
////////////
|
////////////
|
||||||
|
|
||||||
// getOccludeeF1D
|
// getOccludeeF1D
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
||||||
|
|
||||||
// getOccludersF1D
|
// getOccludersF1D
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
||||||
|
|
||||||
// getShapeF1D
|
// getShapeF1D
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
|
||||||
|
|
||||||
} // end of namespace Functions1D
|
} // end of namespace Functions1D
|
||||||
|
|
||||||
#endif // FUNCTIONS1D_HPP
|
#endif // __FREESTYLE_FUNCTIONS_1D_H__
|
||||||
|
|||||||
@@ -1,93 +1,108 @@
|
|||||||
//
|
/*
|
||||||
// Filename : GridDensityProvider.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-2-5
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_GRID_DENSITY_PROVIDER_H__
|
||||||
|
#define __FREESTYLE_GRID_DENSITY_PROVIDER_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/GridDensityProvider.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2011-2-5
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef GRIDDENSITYPROVIDER_H
|
|
||||||
#define GRIDDENSITYPROVIDER_H
|
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "OccluderSource.h"
|
#include "OccluderSource.h"
|
||||||
|
|
||||||
#include "../geometry/BBox.h"
|
#include "../geometry/BBox.h"
|
||||||
|
|
||||||
class GridDensityProvider {
|
class GridDensityProvider
|
||||||
|
{
|
||||||
// Disallow copying and assignment
|
// Disallow copying and assignment
|
||||||
GridDensityProvider (const GridDensityProvider& other);
|
GridDensityProvider(const GridDensityProvider& other);
|
||||||
GridDensityProvider& operator= (const GridDensityProvider& other);
|
GridDensityProvider& operator=(const GridDensityProvider& other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GridDensityProvider (OccluderSource& source)
|
GridDensityProvider(OccluderSource& source) : source(source) {}
|
||||||
: source(source) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~GridDensityProvider() {};
|
virtual ~GridDensityProvider() {};
|
||||||
|
|
||||||
float cellSize() {
|
float cellSize()
|
||||||
|
{
|
||||||
return _cellSize;
|
return _cellSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cellsX() {
|
unsigned cellsX()
|
||||||
|
{
|
||||||
return _cellsX;
|
return _cellsX;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cellsY() {
|
unsigned cellsY()
|
||||||
|
{
|
||||||
return _cellsY;
|
return _cellsY;
|
||||||
}
|
}
|
||||||
|
|
||||||
float cellOrigin(int index) {
|
float cellOrigin(int index)
|
||||||
if ( index < 2 ) {
|
{
|
||||||
|
if (index < 2) {
|
||||||
return _cellOrigin[index];
|
return _cellOrigin[index];
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw new out_of_range("GridDensityProvider::cellOrigin can take only indexes of 0 or 1.");
|
throw new out_of_range("GridDensityProvider::cellOrigin can take only indexes of 0 or 1.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calculateOptimalProscenium(OccluderSource& source, real proscenium[4]) {
|
static void calculateOptimalProscenium(OccluderSource& source, real proscenium[4])
|
||||||
|
{
|
||||||
source.begin();
|
source.begin();
|
||||||
if ( source.isValid() ) {
|
if (source.isValid()) {
|
||||||
const Vec3r& initialPoint = source.getGridSpacePolygon().getVertices()[0];
|
const Vec3r& initialPoint = source.getGridSpacePolygon().getVertices()[0];
|
||||||
proscenium[0] = proscenium[1] = initialPoint[0];
|
proscenium[0] = proscenium[1] = initialPoint[0];
|
||||||
proscenium[2] = proscenium[3] = initialPoint[1];
|
proscenium[2] = proscenium[3] = initialPoint[1];
|
||||||
while ( source.isValid() ) {
|
while (source.isValid()) {
|
||||||
GridHelpers::expandProscenium (proscenium, source.getGridSpacePolygon());
|
GridHelpers::expandProscenium (proscenium, source.getGridSpacePolygon());
|
||||||
source.next();
|
source.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << ")" << endl;
|
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2]
|
||||||
|
<< ", " << proscenium[3] << ")" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox, real proscenium[4]) {
|
static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox,
|
||||||
|
real proscenium[4])
|
||||||
|
{
|
||||||
real z;
|
real z;
|
||||||
// We want to use the z-coordinate closest to the camera to determine the proscenium face
|
// We want to use the z-coordinate closest to the camera to determine the proscenium face
|
||||||
if ( ::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2]) ) {
|
if (::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2])) {
|
||||||
z = bbox.getMin()[2];
|
z = bbox.getMin()[2];
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
z = bbox.getMax()[2];
|
z = bbox.getMax()[2];
|
||||||
}
|
}
|
||||||
// Now calculate the proscenium according to the min and max values of the x and y coordinates
|
// Now calculate the proscenium according to the min and max values of the x and y coordinates
|
||||||
@@ -98,7 +113,8 @@ public:
|
|||||||
proscenium[1] = std::max(minPoint[0], maxPoint[0]);
|
proscenium[1] = std::max(minPoint[0], maxPoint[0]);
|
||||||
proscenium[2] = std::min(minPoint[1], maxPoint[1]);
|
proscenium[2] = std::min(minPoint[1], maxPoint[1]);
|
||||||
proscenium[3] = std::max(minPoint[1], maxPoint[1]);
|
proscenium[3] = std::max(minPoint[1], maxPoint[1]);
|
||||||
cout << "Proscenium : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << endl;
|
cout << "Proscenium : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", "
|
||||||
|
<< proscenium[3] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -108,24 +124,23 @@ protected:
|
|||||||
float _cellOrigin[2];
|
float _cellOrigin[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
class GridDensityProviderFactory {
|
class GridDensityProviderFactory
|
||||||
|
{
|
||||||
// Disallow copying and assignment
|
// Disallow copying and assignment
|
||||||
GridDensityProviderFactory (const GridDensityProviderFactory& other);
|
GridDensityProviderFactory (const GridDensityProviderFactory& other);
|
||||||
GridDensityProviderFactory& operator= (const GridDensityProviderFactory& other);
|
GridDensityProviderFactory& operator= (const GridDensityProviderFactory& other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GridDensityProviderFactory()
|
GridDensityProviderFactory() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) =0;
|
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) = 0;
|
||||||
|
|
||||||
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform) =0;
|
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform) = 0;
|
||||||
|
|
||||||
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) =0;
|
virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) = 0;
|
||||||
|
|
||||||
virtual ~GridDensityProviderFactory () {}
|
virtual ~GridDensityProviderFactory () {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GRIDDENSITYPROVIDER_H
|
#endif // __FREESTYLE_GRID_DENSITY_PROVIDER_H__
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +1,70 @@
|
|||||||
//
|
/*
|
||||||
// Filename : HeuristicGridDensityProviderFactory.cpp
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-2-8
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
|
||||||
//
|
* \ingroup freestyle
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
// with this source distribution.
|
* \author Alexander Beels
|
||||||
//
|
* \date 2011-2-8
|
||||||
// This program is free software; you can redistribute it and/or
|
*/
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "HeuristicGridDensityProviderFactory.h"
|
#include "HeuristicGridDensityProviderFactory.h"
|
||||||
|
|
||||||
HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces)
|
HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces)
|
||||||
: sizeFactor(sizeFactor), numFaces(numFaces)
|
: sizeFactor(sizeFactor), numFaces(numFaces)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory () {}
|
HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory() {}
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
auto_ptr<GridDensityProvider>
|
||||||
|
HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||||
{
|
{
|
||||||
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
|
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
|
||||||
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
|
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
|
||||||
if ( avg->cellSize() > p23->cellSize() ) {
|
if (avg->cellSize() > p23->cellSize()) {
|
||||||
return (auto_ptr<GridDensityProvider>) p23;
|
return (auto_ptr<GridDensityProvider>) p23;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return (auto_ptr<GridDensityProvider>) avg;
|
return (auto_ptr<GridDensityProvider>) avg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
|
auto_ptr<GridDensityProvider>
|
||||||
|
HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform)
|
||||||
{
|
{
|
||||||
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
|
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox,
|
||||||
|
transform, sizeFactor));
|
||||||
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
|
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
|
||||||
if ( avg->cellSize() > p23->cellSize() ) {
|
if (avg->cellSize() > p23->cellSize()) {
|
||||||
return (auto_ptr<GridDensityProvider>) p23;
|
return (auto_ptr<GridDensityProvider>) p23;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return (auto_ptr<GridDensityProvider>) avg;
|
return (auto_ptr<GridDensityProvider>) avg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,10 +75,10 @@ auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensit
|
|||||||
GridDensityProvider::calculateOptimalProscenium(source, proscenium);
|
GridDensityProvider::calculateOptimalProscenium(source, proscenium);
|
||||||
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
|
auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
|
||||||
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
|
auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
|
||||||
if ( avg->cellSize() > p23->cellSize() ) {
|
if (avg->cellSize() > p23->cellSize()) {
|
||||||
return (auto_ptr<GridDensityProvider>) p23;
|
return (auto_ptr<GridDensityProvider>) p23;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return (auto_ptr<GridDensityProvider>) avg;
|
return (auto_ptr<GridDensityProvider>) avg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,55 @@
|
|||||||
//
|
/*
|
||||||
// Filename : HeuristicGridDensityProviderFactory.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-2-8
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
|
||||||
|
#define __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2011-2-8
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef HEURISTICGRIDDENSITYPROVIDERFACTORY_H
|
//#include <memory> // provided by GridDensityProvider.h
|
||||||
#define HEURISTICGRIDDENSITYPROVIDERFACTORY_H
|
|
||||||
|
|
||||||
// #include <memory> // provided by GridDensityProvider.h
|
|
||||||
// #include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
|
|
||||||
#include "Pow23GridDensityProvider.h"
|
|
||||||
#include "AverageAreaGridDensityProvider.h"
|
#include "AverageAreaGridDensityProvider.h"
|
||||||
|
//#include "GridDensityProvider.h" // provided by *GridDensityProvider.h below
|
||||||
|
#include "Pow23GridDensityProvider.h"
|
||||||
|
|
||||||
class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory {
|
class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
|
HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
|
||||||
~HeuristicGridDensityProviderFactory ();
|
~HeuristicGridDensityProviderFactory();
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform);
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -50,5 +57,4 @@ protected:
|
|||||||
unsigned numFaces;
|
unsigned numFaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HEURISTICGRIDDENSITYPROVIDERFACTORY_H
|
#endif // __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
|
||||||
|
|
||||||
|
|||||||
@@ -1,45 +1,53 @@
|
|||||||
//
|
/*
|
||||||
// Filename : Interface0D.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Emmanuel Turquin
|
*
|
||||||
// Purpose : Interface to 0D elts
|
* This program is free software; you can redistribute it and/or
|
||||||
// Date of creation : 01/07/2003
|
* modify it under the terms of the GNU General Public License
|
||||||
//
|
* as published by the Free Software Foundation; either version 2
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_INTERFACE_0D_H__
|
||||||
|
#define __FREESTYLE_INTERFACE_0D_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/Interface0D.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Interface to 0D elts
|
||||||
//
|
* \author Emmanuel Turquin
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 01/07/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef INTERFACE0D_H
|
#include <iostream>
|
||||||
# define INTERFACE0D_H
|
#include <Python.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
# include <Python.h>
|
#include "../geometry/Geom.h"
|
||||||
# include <string>
|
|
||||||
# include <iostream>
|
|
||||||
# include "../system/Id.h"
|
|
||||||
# include "../system/Precision.h"
|
|
||||||
# include "../winged_edge/Nature.h"
|
|
||||||
# include "../geometry/Geom.h"
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
|
#include "../system/Id.h"
|
||||||
#include "../system/Iterator.h" //soc
|
#include "../system/Iterator.h" //soc
|
||||||
|
#include "../system/Precision.h"
|
||||||
|
|
||||||
|
#include "../winged_edge/Nature.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Interface0D
|
// Interface0D
|
||||||
@@ -51,114 +59,128 @@ class SVertex;
|
|||||||
class ViewVertex;
|
class ViewVertex;
|
||||||
class NonTVertex;
|
class NonTVertex;
|
||||||
class TVertex;
|
class TVertex;
|
||||||
|
|
||||||
/*! Base class for any 0D element. */
|
/*! Base class for any 0D element. */
|
||||||
class Interface0D
|
class Interface0D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*! Default constructor */
|
/*! Default constructor */
|
||||||
Interface0D() {}
|
Interface0D() {}
|
||||||
virtual ~Interface0D() {}; //soc
|
virtual ~Interface0D() {}; //soc
|
||||||
|
|
||||||
/*! Returns the string "Interface0D".*/
|
/*! Returns the string "Interface0D". */
|
||||||
virtual string getExactTypeName() const {
|
virtual string getExactTypeName() const
|
||||||
|
{
|
||||||
return "Interface0D";
|
return "Interface0D";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data access methods
|
// Data access methods
|
||||||
|
|
||||||
/*! Returns the 3D x coordinate of the point. */
|
/*! Returns the 3D x coordinate of the point. */
|
||||||
virtual real getX() const {
|
virtual real getX() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the 3D y coordinate of the point. */
|
/*! Returns the 3D y coordinate of the point. */
|
||||||
virtual real getY() const {
|
virtual real getY() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the 3D z coordinate of the point. */
|
/*! Returns the 3D z coordinate of the point. */
|
||||||
virtual real getZ() const {
|
virtual real getZ() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the 3D point. */
|
/*! Returns the 3D point. */
|
||||||
virtual Geometry::Vec3f getPoint3D() const {
|
virtual Geometry::Vec3f getPoint3D() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the 2D x coordinate of the point. */
|
/*! Returns the 2D x coordinate of the point. */
|
||||||
virtual real getProjectedX() const {
|
virtual real getProjectedX() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the 2D y coordinate of the point. */
|
/*! Returns the 2D y coordinate of the point. */
|
||||||
virtual real getProjectedY() const {
|
virtual real getProjectedY() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the 2D z coordinate of the point. */
|
/*! Returns the 2D z coordinate of the point. */
|
||||||
virtual real getProjectedZ() const {
|
virtual real getProjectedZ() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the 2D point. */
|
/*! Returns the 2D point. */
|
||||||
virtual Geometry::Vec2f getPoint2D() const {
|
virtual Geometry::Vec2f getPoint2D() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the FEdge that lies between this Interface0D and the
|
/*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */
|
||||||
* Interface0D given as argument. */
|
virtual FEdge* getFEdge(Interface0D&)
|
||||||
virtual FEdge* getFEdge(Interface0D&) {
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the Id of the point. */
|
/*! Returns the Id of the point. */
|
||||||
virtual Id getId() const {
|
virtual Id getId() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the nature of the point. */
|
/*! Returns the nature of the point. */
|
||||||
virtual Nature::VertexNature getNature() const {
|
virtual Nature::VertexNature getNature() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
|
||||||
return Nature::POINT;
|
return Nature::POINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Cast the Interface0D in SVertex if it can be. */
|
/*! Cast the Interface0D in SVertex if it can be. */
|
||||||
virtual SVertex * castToSVertex(){
|
virtual SVertex *castToSVertex()
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Cast the Interface0D in ViewVertex if it can be. */
|
/*! Cast the Interface0D in ViewVertex if it can be. */
|
||||||
virtual ViewVertex * castToViewVertex(){
|
virtual ViewVertex * castToViewVertex()
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Cast the Interface0D in NonTVertex if it can be. */
|
/*! Cast the Interface0D in NonTVertex if it can be. */
|
||||||
virtual NonTVertex * castToNonTVertex(){
|
virtual NonTVertex *castToNonTVertex()
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Cast the Interface0D in TVertex if it can be. */
|
/*! Cast the Interface0D in TVertex if it can be. */
|
||||||
virtual TVertex * castToTVertex(){
|
virtual TVertex *castToTVertex()
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -170,16 +192,17 @@ public:
|
|||||||
class Interface0DIteratorNested : public Iterator
|
class Interface0DIteratorNested : public Iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~Interface0DIteratorNested() {}
|
virtual ~Interface0DIteratorNested() {}
|
||||||
|
|
||||||
virtual string getExactTypeName() const {
|
virtual string getExactTypeName() const
|
||||||
|
{
|
||||||
return "Interface0DIteratorNested";
|
return "Interface0DIteratorNested";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Interface0D& operator*() = 0;
|
virtual Interface0D& operator*() = 0;
|
||||||
|
|
||||||
virtual Interface0D* operator->() {
|
virtual Interface0D* operator->()
|
||||||
|
{
|
||||||
return &(operator*());
|
return &(operator*());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,12 +216,14 @@ public:
|
|||||||
|
|
||||||
virtual bool operator==(const Interface0DIteratorNested& it) const = 0;
|
virtual bool operator==(const Interface0DIteratorNested& it) const = 0;
|
||||||
|
|
||||||
virtual bool operator!=(const Interface0DIteratorNested& it) const {
|
virtual bool operator!=(const Interface0DIteratorNested& it) const
|
||||||
|
{
|
||||||
return !(*this == it);
|
return !(*this == it);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the curvilinear abscissa */
|
/*! Returns the curvilinear abscissa */
|
||||||
virtual float t() const = 0;
|
virtual float t() const = 0;
|
||||||
|
|
||||||
/*! Returns the point parameter 0<u<1 */
|
/*! Returns the point parameter 0<u<1 */
|
||||||
virtual float u() const = 0;
|
virtual float u() const = 0;
|
||||||
|
|
||||||
@@ -212,39 +237,39 @@ public:
|
|||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
/*! Class defining an iterator over Interface0D elements.
|
/*! Class defining an iterator over Interface0D elements.
|
||||||
* An instance of this iterator is always obtained
|
* An instance of this iterator is always obtained from a 1D element.
|
||||||
* from a 1D element.
|
* \attention In the scripting language, you must call \code it2 = Interface0DIterator(it1) \endcode instead of
|
||||||
* \attention In the scripting language, you must call
|
* \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
|
||||||
* \code it2 = Interface0DIterator(it1) \endcode instead of \code it2 = it1 \endcode
|
|
||||||
* where \a it1 and \a it2 are 2 Interface0DIterator.
|
|
||||||
* Otherwise, incrementing \a it1 will also increment \a it2.
|
* Otherwise, incrementing \a it1 will also increment \a it2.
|
||||||
*/
|
*/
|
||||||
class Interface0DIterator : public Iterator
|
class Interface0DIterator : public Iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Interface0DIterator(Interface0DIteratorNested* it = NULL)
|
||||||
Interface0DIterator(Interface0DIteratorNested* it = NULL) {
|
{
|
||||||
_iterator = it;
|
_iterator = it;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Copy constructor */
|
/*! Copy constructor */
|
||||||
Interface0DIterator(const Interface0DIterator& it) {
|
Interface0DIterator(const Interface0DIterator& it)
|
||||||
|
{
|
||||||
_iterator = it._iterator->copy();
|
_iterator = it._iterator->copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Destructor */
|
/*! Destructor */
|
||||||
virtual ~Interface0DIterator() {
|
virtual ~Interface0DIterator()
|
||||||
|
{
|
||||||
if (_iterator)
|
if (_iterator)
|
||||||
delete _iterator;
|
delete _iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Operator =
|
/*! Operator =
|
||||||
* \attention In the scripting language, you must call
|
* \attention In the scripting language, you must call \code it2 = Interface0DIterator(it1) \endcode instead of
|
||||||
* \code it2 = Interface0DIterator(it1) \endcode instead of \code it2 = it1 \endcode
|
* \code it2 = it1 \endcode where \a it1 and \a it2 are 2 Interface0DIterator.
|
||||||
* where \a it1 and \a it2 are 2 Interface0DIterator.
|
|
||||||
* Otherwise, incrementing \a it1 will also increment \a it2.
|
* Otherwise, incrementing \a it1 will also increment \a it2.
|
||||||
*/
|
*/
|
||||||
Interface0DIterator& operator=(const Interface0DIterator& it) {
|
Interface0DIterator& operator=(const Interface0DIterator& it)
|
||||||
|
{
|
||||||
if(_iterator)
|
if(_iterator)
|
||||||
delete _iterator;
|
delete _iterator;
|
||||||
_iterator = it._iterator->copy();
|
_iterator = it._iterator->copy();
|
||||||
@@ -252,7 +277,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the string "Interface0DIterator". */
|
/*! Returns the string "Interface0DIterator". */
|
||||||
virtual string getExactTypeName() const {
|
virtual string getExactTypeName() const
|
||||||
|
{
|
||||||
if (!_iterator)
|
if (!_iterator)
|
||||||
return "Interface0DIterator";
|
return "Interface0DIterator";
|
||||||
return _iterator->getExactTypeName() + "Proxy";
|
return _iterator->getExactTypeName() + "Proxy";
|
||||||
@@ -261,100 +287,104 @@ public:
|
|||||||
// FIXME test it != 0 (exceptions ?)
|
// FIXME test it != 0 (exceptions ?)
|
||||||
|
|
||||||
/*! Returns a reference to the pointed Interface0D.
|
/*! Returns a reference to the pointed Interface0D.
|
||||||
* In the scripting language, you must call
|
* In the scripting language, you must call "getObject()" instead using this operator.
|
||||||
* "getObject()" instead using this operator.
|
|
||||||
*/
|
*/
|
||||||
Interface0D& operator*() {
|
Interface0D& operator*()
|
||||||
|
{
|
||||||
return _iterator->operator*();
|
return _iterator->operator*();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns a pointer to the pointed Interface0D.
|
/*! Returns a pointer to the pointed Interface0D.
|
||||||
* Can't be called in the scripting language.
|
* Can't be called in the scripting language.
|
||||||
*/
|
*/
|
||||||
Interface0D* operator->() {
|
Interface0D *operator->()
|
||||||
|
{
|
||||||
return &(operator*());
|
return &(operator*());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Increments. In the scripting language, call
|
/*! Increments. In the scripting language, call "increment()". */
|
||||||
* "increment()".
|
Interface0DIterator& operator++()
|
||||||
*/
|
{
|
||||||
Interface0DIterator& operator++() {
|
|
||||||
_iterator->increment();
|
_iterator->increment();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Increments. In the scripting language, call
|
/*! Increments. In the scripting language, call "increment()". */
|
||||||
* "increment()".
|
Interface0DIterator operator++(int)
|
||||||
*/
|
{
|
||||||
Interface0DIterator operator++(int) {
|
|
||||||
Interface0DIterator ret(*this);
|
Interface0DIterator ret(*this);
|
||||||
_iterator->increment();
|
_iterator->increment();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Decrements. In the scripting language, call
|
/*! Decrements. In the scripting language, call "decrement()". */
|
||||||
* "decrement()".
|
Interface0DIterator& operator--()
|
||||||
*/
|
{
|
||||||
Interface0DIterator& operator--() {
|
|
||||||
_iterator->decrement();
|
_iterator->decrement();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Decrements. In the scripting language, call
|
/*! Decrements. In the scripting language, call "decrement()". */
|
||||||
* "decrement()".
|
Interface0DIterator operator--(int)
|
||||||
*/
|
{
|
||||||
Interface0DIterator operator--(int) {
|
|
||||||
Interface0DIterator ret(*this);
|
Interface0DIterator ret(*this);
|
||||||
_iterator->decrement();
|
_iterator->decrement();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Increments. */
|
/*! Increments. */
|
||||||
virtual int increment() {
|
virtual int increment()
|
||||||
|
{
|
||||||
return _iterator->increment();
|
return _iterator->increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Decrements. */
|
/*! Decrements. */
|
||||||
virtual int decrement() {
|
virtual int decrement()
|
||||||
|
{
|
||||||
return _iterator->decrement();
|
return _iterator->decrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns true if the pointed Interface0D is the
|
/*! Returns true if the pointed Interface0D is the first of the 1D element containing the points over which
|
||||||
* first of the 1D element containing the points over
|
* we're iterating.
|
||||||
* which we're iterating.
|
|
||||||
*/
|
*/
|
||||||
virtual bool isBegin() const {
|
virtual bool isBegin() const
|
||||||
|
{
|
||||||
return _iterator->isBegin();
|
return _iterator->isBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns true if the pointed Interface0D is after the
|
/*! Returns true if the pointed Interface0D is after the after the last point of the 1D element we're
|
||||||
* after the last point of the 1D element we're iterating from.
|
* iterating from. */
|
||||||
*/
|
virtual bool isEnd() const
|
||||||
virtual bool isEnd() const {
|
{
|
||||||
return _iterator->isEnd();
|
return _iterator->isEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! operator == . */
|
/*! operator == . */
|
||||||
bool operator==(const Interface0DIterator& it) const {
|
bool operator==(const Interface0DIterator& it) const
|
||||||
|
{
|
||||||
return _iterator->operator==(*(it._iterator));
|
return _iterator->operator==(*(it._iterator));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! operator != . */
|
/*! operator != . */
|
||||||
bool operator!=(const Interface0DIterator& it) const {
|
bool operator!=(const Interface0DIterator& it) const
|
||||||
|
{
|
||||||
return !(*this == it);
|
return !(*this == it);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the curvilinear abscissa. */
|
/*! Returns the curvilinear abscissa. */
|
||||||
inline float t() const {
|
inline float t() const
|
||||||
|
{
|
||||||
return _iterator->t();
|
return _iterator->t();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the point parameter in the curve 0<=u<=1. */
|
/*! Returns the point parameter in the curve 0<=u<=1. */
|
||||||
inline float u() const {
|
inline float u() const
|
||||||
|
{
|
||||||
return _iterator->u();
|
return _iterator->u();
|
||||||
}
|
}
|
||||||
protected:
|
|
||||||
|
|
||||||
Interface0DIteratorNested* _iterator;
|
protected:
|
||||||
|
Interface0DIteratorNested *_iterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INTERFACE0D_H
|
#endif // __FREESTYLE_INTERFACE_0D_H__
|
||||||
|
|||||||
@@ -1,90 +1,89 @@
|
|||||||
//
|
/*
|
||||||
// Filename : Interface1D.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Emmanuel Turquin
|
*
|
||||||
// Purpose : Interface to 1D elts
|
* This program is free software; you can redistribute it and/or
|
||||||
// Date of creation : 01/07/2003
|
* modify it under the terms of the GNU General Public License
|
||||||
//
|
* as published by the Free Software Foundation; either version 2
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_INTERFACE_1D_H__
|
||||||
|
#define __FREESTYLE_INTERFACE_1D_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/Interface1D.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Interface 1D and related tools definitions
|
||||||
//
|
* \author Emmanuel Turquin
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 01/07/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef INTERFACE1D_H
|
#include <float.h>
|
||||||
# define INTERFACE1D_H
|
#include <iostream>
|
||||||
|
#include <Python.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
# include <Python.h>
|
#include "Functions0D.h"
|
||||||
# include <string>
|
|
||||||
# include <iostream>
|
#include "../system/Id.h"
|
||||||
# include <float.h>
|
#include "../system/Precision.h"
|
||||||
# include "../system/Id.h"
|
|
||||||
# include "../system/Precision.h"
|
#include "../winged_edge/Nature.h"
|
||||||
# include "../winged_edge/Nature.h"
|
|
||||||
# include "Functions0D.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
/*! \file Interface1D.h
|
|
||||||
* Interface1D and related tools definitions
|
|
||||||
*/
|
|
||||||
// Integration method
|
// Integration method
|
||||||
/*! The different integration
|
/*! The different integration methods that can be invoked to integrate into a single value the set of values obtained
|
||||||
* methods that can be invoked
|
|
||||||
* to integrate into a single value the set of values obtained
|
|
||||||
* from each 0D element of a 1D element.
|
* from each 0D element of a 1D element.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MEAN,/*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/
|
MEAN, /*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/
|
||||||
MIN,/*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/
|
MIN, /*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/
|
||||||
MAX,/*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/
|
MAX, /*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/
|
||||||
FIRST,/*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/
|
FIRST, /*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/
|
||||||
LAST/*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/
|
LAST /*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/
|
||||||
} IntegrationType;
|
} IntegrationType;
|
||||||
|
|
||||||
/*! Returns a single
|
/*! Returns a single value from a set of values evaluated at each 0D element of this 1D element.
|
||||||
* value from a set of values evaluated at each 0D element
|
|
||||||
* of this 1D element.
|
|
||||||
* \param fun
|
* \param fun
|
||||||
* The UnaryFunction0D used to compute a value at each Interface0D.
|
* The UnaryFunction0D used to compute a value at each Interface0D.
|
||||||
* \param it
|
* \param it
|
||||||
* The Interface0DIterator used to iterate over the 0D elements of
|
* The Interface0DIterator used to iterate over the 0D elements of this 1D element. The integration will occur
|
||||||
* this 1D element. The integration will occur over the 0D elements
|
* over the 0D elements starting from the one pointed by it.
|
||||||
* starting from the one pointed by it.
|
|
||||||
* \param it_end
|
* \param it_end
|
||||||
* The Interface0DIterator pointing the end of the 0D elements of the
|
* The Interface0DIterator pointing the end of the 0D elements of the 1D element.
|
||||||
* 1D element.
|
|
||||||
* \param integration_type
|
* \param integration_type
|
||||||
* The integration method used to compute a single value from
|
* The integration method used to compute a single value from a set of values.
|
||||||
* a set of values.
|
|
||||||
* \return the single value obtained for the 1D element.
|
* \return the single value obtained for the 1D element.
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
T integrate(UnaryFunction0D<T>& fun,
|
T integrate(UnaryFunction0D<T>& fun, Interface0DIterator it, Interface0DIterator it_end,
|
||||||
Interface0DIterator it,
|
IntegrationType integration_type = MEAN)
|
||||||
Interface0DIterator it_end,
|
{
|
||||||
IntegrationType integration_type = MEAN) {
|
|
||||||
T res;
|
T res;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
switch (integration_type) {
|
switch (integration_type) {
|
||||||
case MIN:
|
case MIN:
|
||||||
fun(it);
|
fun(it);
|
||||||
res = fun.result;++it;
|
res = fun.result;
|
||||||
|
++it;
|
||||||
for (; !it.isEnd(); ++it) {
|
for (; !it.isEnd(); ++it) {
|
||||||
fun(it);
|
fun(it);
|
||||||
if (fun.result < res)
|
if (fun.result < res)
|
||||||
@@ -93,7 +92,8 @@ T integrate(UnaryFunction0D<T>& fun,
|
|||||||
break;
|
break;
|
||||||
case MAX:
|
case MAX:
|
||||||
fun(it);
|
fun(it);
|
||||||
res = fun.result;++it;
|
res = fun.result;
|
||||||
|
++it;
|
||||||
for (; !it.isEnd(); ++it) {
|
for (; !it.isEnd(); ++it) {
|
||||||
fun(it);
|
fun(it);
|
||||||
if (fun.result > res)
|
if (fun.result > res)
|
||||||
@@ -111,7 +111,8 @@ T integrate(UnaryFunction0D<T>& fun,
|
|||||||
case MEAN:
|
case MEAN:
|
||||||
default:
|
default:
|
||||||
fun(it);
|
fun(it);
|
||||||
res = fun.result;++it;
|
res = fun.result;
|
||||||
|
++it;
|
||||||
for (size = 1; !it.isEnd(); ++it, ++size) {
|
for (size = 1; !it.isEnd(); ++it, ++size) {
|
||||||
fun(it);
|
fun(it);
|
||||||
res += fun.result;
|
res += fun.result;
|
||||||
@@ -131,58 +132,56 @@ T integrate(UnaryFunction0D<T>& fun,
|
|||||||
class Interface1D
|
class Interface1D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*! Default constructor */
|
/*! Default constructor */
|
||||||
Interface1D() {_timeStamp=0;}
|
Interface1D()
|
||||||
|
{
|
||||||
|
_timeStamp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~Interface1D() {}; //soc
|
virtual ~Interface1D() {}; //soc
|
||||||
|
|
||||||
/*! Returns the string "Interface1D" .*/
|
/*! Returns the string "Interface1D". */
|
||||||
virtual string getExactTypeName() const {
|
virtual string getExactTypeName() const
|
||||||
|
{
|
||||||
return "Interface1D";
|
return "Interface1D";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterator access
|
// Iterator access
|
||||||
|
|
||||||
/*! Returns an iterator over the Interface1D vertices,
|
/*! Returns an iterator over the Interface1D vertices, pointing to the first vertex. */
|
||||||
* pointing to the first vertex.
|
virtual Interface0DIterator verticesBegin()
|
||||||
*/
|
{
|
||||||
virtual Interface0DIterator verticesBegin() {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
|
||||||
return Interface0DIterator();
|
return Interface0DIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns an iterator over the Interface1D vertices,
|
/*! Returns an iterator over the Interface1D vertices, pointing after the last vertex. */
|
||||||
* pointing after the last vertex.
|
virtual Interface0DIterator verticesEnd()
|
||||||
*/
|
{
|
||||||
virtual Interface0DIterator verticesEnd(){
|
|
||||||
PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
|
||||||
return Interface0DIterator();
|
return Interface0DIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns an iterator over the Interface1D points,
|
/*! Returns an iterator over the Interface1D points, pointing to the first point. The difference with
|
||||||
* pointing to the first point. The difference with
|
* verticesBegin() is that here we can iterate over points of the 1D element at a any given sampling.
|
||||||
* verticesBegin() is that here we can iterate over
|
|
||||||
* points of the 1D element at a any given sampling.
|
|
||||||
* Indeed, for each iteration, a virtual point is created.
|
* Indeed, for each iteration, a virtual point is created.
|
||||||
* \param t
|
* \param t
|
||||||
* The sampling with which we want to iterate over points of
|
* The sampling with which we want to iterate over points of this 1D element.
|
||||||
* this 1D element.
|
|
||||||
*/
|
*/
|
||||||
virtual Interface0DIterator pointsBegin(float t=0.f) {
|
virtual Interface0DIterator pointsBegin(float t = 0.0f)
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
|
||||||
return Interface0DIterator();
|
return Interface0DIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns an iterator over the Interface1D points,
|
/*! Returns an iterator over the Interface1D points, pointing after the last point. The difference with
|
||||||
* pointing after the last point. The difference with
|
* verticesEnd() is that here we can iterate over points of the 1D element at a any given sampling.
|
||||||
* verticesEnd() is that here we can iterate over
|
|
||||||
* points of the 1D element at a any given sampling.
|
|
||||||
* Indeed, for each iteration, a virtual point is created.
|
* Indeed, for each iteration, a virtual point is created.
|
||||||
* \param t
|
* \param t
|
||||||
* The sampling with which we want to iterate over points of
|
* The sampling with which we want to iterate over points of this 1D element.
|
||||||
* this 1D element.
|
|
||||||
*/
|
*/
|
||||||
virtual Interface0DIterator pointsEnd(float t=0.f) {
|
virtual Interface0DIterator pointsEnd(float t = 0.0f)
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
|
||||||
return Interface0DIterator();
|
return Interface0DIterator();
|
||||||
}
|
}
|
||||||
@@ -190,13 +189,15 @@ public:
|
|||||||
// Data access methods
|
// Data access methods
|
||||||
|
|
||||||
/*! Returns the 2D length of the 1D element. */
|
/*! Returns the 2D length of the 1D element. */
|
||||||
virtual real getLength2D() const {
|
virtual real getLength2D() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the Id of the 1D element .*/
|
/*! Returns the Id of the 1D element. */
|
||||||
virtual Id getId() const {
|
virtual Id getId() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
|
||||||
return Id(0, 0);
|
return Id(0, 0);
|
||||||
}
|
}
|
||||||
@@ -204,18 +205,21 @@ public:
|
|||||||
|
|
||||||
// FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D)
|
// FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D)
|
||||||
/*! Returns the nature of the 1D element. */
|
/*! Returns the nature of the 1D element. */
|
||||||
virtual Nature::EdgeNature getNature() const {
|
virtual Nature::EdgeNature getNature() const
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
|
PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
|
||||||
return Nature::NO_FEATURE;
|
return Nature::NO_FEATURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the time stamp of the 1D element. Mainly used for selection. */
|
/*! Returns the time stamp of the 1D element. Mainly used for selection. */
|
||||||
virtual unsigned getTimeStamp() const {
|
virtual unsigned getTimeStamp() const
|
||||||
|
{
|
||||||
return _timeStamp;
|
return _timeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sets the time stamp for the 1D element. */
|
/*! Sets the time stamp for the 1D element. */
|
||||||
inline void setTimeStamp(unsigned iTimeStamp){
|
inline void setTimeStamp(unsigned iTimeStamp)
|
||||||
|
{
|
||||||
_timeStamp = iTimeStamp;
|
_timeStamp = iTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,4 +227,4 @@ protected:
|
|||||||
unsigned _timeStamp;
|
unsigned _timeStamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INTERFACE1D_H
|
#endif // __FREESTYLE_INTERFACE_1D_H__
|
||||||
|
|||||||
@@ -1,65 +1,73 @@
|
|||||||
//
|
/*
|
||||||
// Filename : OccluderSource.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2010-12-21
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/view_map/OccluderSource.cpp
|
||||||
|
* \ingroup freestyle
|
||||||
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
|
* \author Alexander Beels
|
||||||
|
* \date 2010-12-21
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
|
||||||
// with this source distribution.
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "OccluderSource.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
OccluderSource::OccluderSource (const GridHelpers::Transform& t, WingedEdge& we) : wingedEdge(we), valid(false), transform(t) {
|
#include "OccluderSource.h"
|
||||||
|
|
||||||
|
OccluderSource::OccluderSource(const GridHelpers::Transform& t, WingedEdge& we)
|
||||||
|
: wingedEdge(we), valid(false), transform(t)
|
||||||
|
{
|
||||||
begin();
|
begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
OccluderSource::~OccluderSource() {
|
OccluderSource::~OccluderSource() {}
|
||||||
}
|
|
||||||
|
|
||||||
void OccluderSource::buildCachedPolygon() {
|
void OccluderSource::buildCachedPolygon()
|
||||||
|
{
|
||||||
vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()));
|
vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()));
|
||||||
// This doesn't work, because our functor's polymorphism won't survive the copy:
|
// This doesn't work, because our functor's polymorphism won't survive the copy:
|
||||||
// std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform);
|
// std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform);
|
||||||
// so we have to do:
|
// so we have to do:
|
||||||
for ( vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i ) {
|
for (vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i) {
|
||||||
(*i) = transform(*i);
|
(*i) = transform(*i);
|
||||||
}
|
}
|
||||||
cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
|
cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OccluderSource::begin() {
|
void OccluderSource::begin()
|
||||||
|
{
|
||||||
vector<WShape*>& wshapes = wingedEdge.getWShapes();
|
vector<WShape*>& wshapes = wingedEdge.getWShapes();
|
||||||
currentShape = wshapes.begin();
|
currentShape = wshapes.begin();
|
||||||
shapesEnd = wshapes.end();
|
shapesEnd = wshapes.end();
|
||||||
valid = false;
|
valid = false;
|
||||||
if ( currentShape != shapesEnd ) {
|
if (currentShape != shapesEnd) {
|
||||||
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
|
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
|
||||||
currentFace = wFaces.begin();
|
currentFace = wFaces.begin();
|
||||||
facesEnd = wFaces.end();
|
facesEnd = wFaces.end();
|
||||||
|
|
||||||
if ( currentFace != facesEnd ) {
|
if (currentFace != facesEnd) {
|
||||||
buildCachedPolygon();
|
buildCachedPolygon();
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
}
|
||||||
@@ -67,14 +75,15 @@ void OccluderSource::begin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OccluderSource::next() {
|
bool OccluderSource::next() {
|
||||||
if ( valid ) {
|
if (valid) {
|
||||||
++currentFace;
|
++currentFace;
|
||||||
while ( currentFace == facesEnd ) {
|
while (currentFace == facesEnd) {
|
||||||
++currentShape;
|
++currentShape;
|
||||||
if ( currentShape == shapesEnd ) {
|
if (currentShape == shapesEnd) {
|
||||||
valid = false;
|
valid = false;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
|
vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
|
||||||
currentFace = wFaces.begin();
|
currentFace = wFaces.begin();
|
||||||
facesEnd = wFaces.end();
|
facesEnd = wFaces.end();
|
||||||
@@ -86,40 +95,47 @@ bool OccluderSource::next() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OccluderSource::isValid() {
|
bool OccluderSource::isValid()
|
||||||
|
{
|
||||||
// Or:
|
// Or:
|
||||||
// return currentShapes != shapesEnd && currentFace != facesEnd;
|
// return currentShapes != shapesEnd && currentFace != facesEnd;
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
WFace* OccluderSource::getWFace() {
|
WFace *OccluderSource::getWFace()
|
||||||
|
{
|
||||||
return valid ? *currentFace : NULL;
|
return valid ? *currentFace : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygon3r OccluderSource::getCameraSpacePolygon() {
|
Polygon3r OccluderSource::getCameraSpacePolygon()
|
||||||
|
{
|
||||||
return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()), (*currentFace)->GetNormal());
|
return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()), (*currentFace)->GetNormal());
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygon3r& OccluderSource::getGridSpacePolygon() {
|
Polygon3r& OccluderSource::getGridSpacePolygon()
|
||||||
|
{
|
||||||
return cachedPolygon;
|
return cachedPolygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OccluderSource::getOccluderProscenium(real proscenium[4]) {
|
void OccluderSource::getOccluderProscenium(real proscenium[4])
|
||||||
|
{
|
||||||
begin();
|
begin();
|
||||||
const Vec3r& initialPoint = cachedPolygon.getVertices()[0];
|
const Vec3r& initialPoint = cachedPolygon.getVertices()[0];
|
||||||
proscenium[0] = proscenium[1] = initialPoint[0];
|
proscenium[0] = proscenium[1] = initialPoint[0];
|
||||||
proscenium[2] = proscenium[3] = initialPoint[1];
|
proscenium[2] = proscenium[3] = initialPoint[1];
|
||||||
while ( isValid() ) {
|
while (isValid()) {
|
||||||
GridHelpers::expandProscenium (proscenium, cachedPolygon);
|
GridHelpers::expandProscenium (proscenium, cachedPolygon);
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << ")" << endl;
|
cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", "
|
||||||
|
<< proscenium[3] << ")" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
real OccluderSource::averageOccluderArea() {
|
real OccluderSource::averageOccluderArea()
|
||||||
|
{
|
||||||
real area = 0.0;
|
real area = 0.0;
|
||||||
unsigned numFaces = 0;
|
unsigned numFaces = 0;
|
||||||
for ( begin(); isValid(); next() ) {
|
for (begin(); isValid(); next()) {
|
||||||
Vec3r min, max;
|
Vec3r min, max;
|
||||||
cachedPolygon.getBBox(min, max);
|
cachedPolygon.getBBox(min, max);
|
||||||
area += (max[0] - min[0]) * (max[1] - min[1]);
|
area += (max[0] - min[0]) * (max[1] - min[1]);
|
||||||
@@ -128,5 +144,3 @@ real OccluderSource::averageOccluderArea() {
|
|||||||
area /= numFaces;
|
area /= numFaces;
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,53 +1,59 @@
|
|||||||
//
|
/*
|
||||||
// Filename : OccluderSource.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2010-12-21
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_OCCLUDER_SOURCE_H__
|
||||||
|
#define __FREESTYLE_OCCLUDER_SOURCE_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/OccluderSource.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2010-12-21
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef OCCLUDERSOURCE_H
|
|
||||||
#define OCCLUDERSOURCE_H
|
|
||||||
|
|
||||||
#include "../winged_edge/WEdge.h"
|
|
||||||
#include "../geometry/GridHelpers.h"
|
#include "../geometry/GridHelpers.h"
|
||||||
|
|
||||||
class OccluderSource {
|
#include "../winged_edge/WEdge.h"
|
||||||
|
|
||||||
|
class OccluderSource
|
||||||
|
{
|
||||||
// Disallow copying and assignment
|
// Disallow copying and assignment
|
||||||
OccluderSource (const OccluderSource& other);
|
OccluderSource(const OccluderSource& other);
|
||||||
OccluderSource& operator= (const OccluderSource& other);
|
OccluderSource& operator=(const OccluderSource& other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OccluderSource (const GridHelpers::Transform& transform, WingedEdge& we);
|
OccluderSource(const GridHelpers::Transform& transform, WingedEdge& we);
|
||||||
virtual ~OccluderSource();
|
virtual ~OccluderSource();
|
||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
virtual bool next();
|
virtual bool next();
|
||||||
bool isValid();
|
bool isValid();
|
||||||
|
|
||||||
WFace* getWFace();
|
WFace *getWFace();
|
||||||
Polygon3r getCameraSpacePolygon();
|
Polygon3r getCameraSpacePolygon();
|
||||||
Polygon3r& getGridSpacePolygon();
|
Polygon3r& getGridSpacePolygon();
|
||||||
|
|
||||||
@@ -67,4 +73,4 @@ protected:
|
|||||||
void buildCachedPolygon();
|
void buildCachedPolygon();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OCCLUDERSOURCE_H
|
#endif // __FREESTYLE_OCCLUDER_SOURCE_H__
|
||||||
|
|||||||
@@ -1,43 +1,48 @@
|
|||||||
//
|
/*
|
||||||
// Filename : Pow23GridDensityProvider.cpp
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-2-8
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
|
||||||
//
|
* \ingroup freestyle
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
// with this source distribution.
|
* \author Alexander Beels
|
||||||
//
|
* \date 2011-2-8
|
||||||
// This program is free software; you can redistribute it and/or
|
*/
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "Pow23GridDensityProvider.h"
|
#include "Pow23GridDensityProvider.h"
|
||||||
|
|
||||||
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces)
|
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces)
|
||||||
: GridDensityProvider(source), numFaces(numFaces)
|
: GridDensityProvider(source), numFaces(numFaces)
|
||||||
{
|
{
|
||||||
initialize (proscenium);
|
initialize (proscenium);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numFaces)
|
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
: GridDensityProvider(source), numFaces(numFaces)
|
const GridHelpers::Transform& transform, unsigned numFaces)
|
||||||
|
: GridDensityProvider(source), numFaces(numFaces)
|
||||||
{
|
{
|
||||||
real proscenium[4];
|
real proscenium[4];
|
||||||
calculateQuickProscenium(transform, bbox, proscenium);
|
calculateQuickProscenium(transform, bbox, proscenium);
|
||||||
@@ -46,7 +51,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces)
|
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces)
|
||||||
: GridDensityProvider(source), numFaces(numFaces)
|
: GridDensityProvider(source), numFaces(numFaces)
|
||||||
{
|
{
|
||||||
real proscenium[4];
|
real proscenium[4];
|
||||||
calculateOptimalProscenium(source, proscenium);
|
calculateOptimalProscenium(source, proscenium);
|
||||||
@@ -56,7 +61,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource& source, unsig
|
|||||||
|
|
||||||
Pow23GridDensityProvider::~Pow23GridDensityProvider () {}
|
Pow23GridDensityProvider::~Pow23GridDensityProvider () {}
|
||||||
|
|
||||||
void Pow23GridDensityProvider::initialize (const real proscenium[4])
|
void Pow23GridDensityProvider::initialize(const real proscenium[4])
|
||||||
{
|
{
|
||||||
float prosceniumWidth = (proscenium[1] - proscenium[0]);
|
float prosceniumWidth = (proscenium[1] - proscenium[0]);
|
||||||
float prosceniumHeight = (proscenium[3] - proscenium[2]);
|
float prosceniumHeight = (proscenium[3] - proscenium[2]);
|
||||||
@@ -71,10 +76,10 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
|
|||||||
|
|
||||||
// Make sure the grid exceeds the proscenium by a small amount
|
// Make sure the grid exceeds the proscenium by a small amount
|
||||||
float safetyZone = 0.1;
|
float safetyZone = 0.1;
|
||||||
if ( _cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone) ) {
|
if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
|
||||||
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
|
_cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
|
||||||
}
|
}
|
||||||
if ( _cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone) ) {
|
if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
|
||||||
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
|
_cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
|
||||||
}
|
}
|
||||||
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
|
||||||
@@ -85,18 +90,21 @@ void Pow23GridDensityProvider::initialize (const real proscenium[4])
|
|||||||
}
|
}
|
||||||
|
|
||||||
Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFaces)
|
Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFaces)
|
||||||
: numFaces(numFaces)
|
: numFaces(numFaces)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Pow23GridDensityProviderFactory::~Pow23GridDensityProviderFactory () {}
|
Pow23GridDensityProviderFactory::~Pow23GridDensityProviderFactory () {}
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
auto_ptr<GridDensityProvider>
|
||||||
|
Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
|
||||||
{
|
{
|
||||||
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, proscenium, numFaces));
|
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, proscenium, numFaces));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform)
|
auto_ptr<GridDensityProvider>
|
||||||
|
Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform)
|
||||||
{
|
{
|
||||||
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
|
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
|
||||||
}
|
}
|
||||||
@@ -105,5 +113,3 @@ auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityPro
|
|||||||
{
|
{
|
||||||
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
|
return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,67 +1,75 @@
|
|||||||
//
|
/*
|
||||||
// Filename : Pow23GridDensityProvider.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2011-2-8
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
|
||||||
|
#define __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2011-2-8
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef POW23GRIDDENSITYPROVIDER_H
|
|
||||||
#define POW23GRIDDENSITYPROVIDER_H
|
|
||||||
|
|
||||||
#include "GridDensityProvider.h"
|
#include "GridDensityProvider.h"
|
||||||
|
|
||||||
class Pow23GridDensityProvider : public GridDensityProvider {
|
class Pow23GridDensityProvider : public GridDensityProvider
|
||||||
|
{
|
||||||
// Disallow copying and assignment
|
// Disallow copying and assignment
|
||||||
Pow23GridDensityProvider (const Pow23GridDensityProvider& other);
|
Pow23GridDensityProvider(const Pow23GridDensityProvider& other);
|
||||||
Pow23GridDensityProvider& operator= (const Pow23GridDensityProvider& other);
|
Pow23GridDensityProvider& operator=(const Pow23GridDensityProvider& other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces);
|
Pow23GridDensityProvider(OccluderSource& source, const real proscenium[4], unsigned numFaces);
|
||||||
Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform, unsigned numFaces);
|
Pow23GridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform,
|
||||||
|
unsigned numFaces);
|
||||||
Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces);
|
Pow23GridDensityProvider(OccluderSource& source, unsigned numFaces);
|
||||||
virtual ~Pow23GridDensityProvider ();
|
virtual ~Pow23GridDensityProvider();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned numFaces;
|
unsigned numFaces;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize (const real proscenium[4]);
|
void initialize(const real proscenium[4]);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Pow23GridDensityProviderFactory : public GridDensityProviderFactory {
|
class Pow23GridDensityProviderFactory : public GridDensityProviderFactory
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
Pow23GridDensityProviderFactory(unsigned numFaces);
|
Pow23GridDensityProviderFactory(unsigned numFaces);
|
||||||
~Pow23GridDensityProviderFactory ();
|
~Pow23GridDensityProviderFactory();
|
||||||
|
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox, const GridHelpers::Transform& transform);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
|
||||||
|
const GridHelpers::Transform& transform);
|
||||||
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned numFaces;
|
unsigned numFaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // POW23GRIDDENSITYPROVIDER_H
|
#endif // __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
|
||||||
|
|
||||||
|
|||||||
@@ -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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/Silhouette.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Classes to define a silhouette structure
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 25/03/2002
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "Silhouette.h"
|
#include "Silhouette.h"
|
||||||
#include "ViewMap.h"
|
#include "ViewMap.h"
|
||||||
|
|
||||||
/**********************************/
|
/**********************************/
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* SVertex */
|
/* SVertex */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
|
||||||
Nature::VertexNature SVertex::getNature() const {
|
Nature::VertexNature SVertex::getNature() const
|
||||||
|
{
|
||||||
Nature::VertexNature nature = Nature::S_VERTEX;
|
Nature::VertexNature nature = Nature::S_VERTEX;
|
||||||
if (_pViewVertex)
|
if (_pViewVertex)
|
||||||
nature |= _pViewVertex->getNature();
|
nature |= _pViewVertex->getNature();
|
||||||
return nature;
|
return nature;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVertex * SVertex::castToSVertex(){
|
SVertex *SVertex::castToSVertex()
|
||||||
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewVertex * SVertex::castToViewVertex(){
|
ViewVertex *SVertex::castToViewVertex()
|
||||||
|
{
|
||||||
return _pViewVertex;
|
return _pViewVertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
NonTVertex * SVertex::castToNonTVertex(){
|
NonTVertex *SVertex::castToNonTVertex()
|
||||||
|
{
|
||||||
return dynamic_cast<NonTVertex*>(_pViewVertex);
|
return dynamic_cast<NonTVertex*>(_pViewVertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
TVertex * SVertex::castToTVertex(){
|
TVertex *SVertex::castToTVertex()
|
||||||
|
{
|
||||||
return dynamic_cast<TVertex*>(_pViewVertex);
|
return dynamic_cast<TVertex*>(_pViewVertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +76,22 @@ float SVertex::shape_importance() const
|
|||||||
return shape()->importance();
|
return shape()->importance();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Material SVertex::material() const {return _Shape->material();}
|
#if 0
|
||||||
Id SVertex::shape_id() const {return _Shape->getId();}
|
Material SVertex::material() const
|
||||||
const SShape * SVertex::shape() const {return _Shape;}
|
{
|
||||||
|
return _Shape->material();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Id SVertex::shape_id() const
|
||||||
|
{
|
||||||
|
return _Shape->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
const SShape *SVertex::shape() const
|
||||||
|
{
|
||||||
|
return _Shape;
|
||||||
|
}
|
||||||
|
|
||||||
const int SVertex::qi() const
|
const int SVertex::qi() const
|
||||||
{
|
{
|
||||||
@@ -104,7 +135,7 @@ const Polygon3r& SVertex::occludee() const
|
|||||||
return (_FEdges[0])->occludee();
|
return (_FEdges[0])->occludee();
|
||||||
}
|
}
|
||||||
|
|
||||||
const SShape* SVertex::occluded_shape() const
|
const SShape *SVertex::occluded_shape() const
|
||||||
{
|
{
|
||||||
if (getNature() & Nature::T_VERTEX)
|
if (getNature() & Nature::T_VERTEX)
|
||||||
Exception::raiseException();
|
Exception::raiseException();
|
||||||
@@ -125,65 +156,52 @@ real SVertex::z_discontinuity() const
|
|||||||
return (_FEdges[0])->z_discontinuity();
|
return (_FEdges[0])->z_discontinuity();
|
||||||
}
|
}
|
||||||
|
|
||||||
FEdge* SVertex::fedge()
|
FEdge *SVertex::fedge()
|
||||||
{
|
{
|
||||||
if (getNature() & Nature::T_VERTEX)
|
if (getNature() & Nature::T_VERTEX)
|
||||||
return 0;
|
return NULL;
|
||||||
return _FEdges[0];
|
return _FEdges[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
FEdge* SVertex::getFEdge(Interface0D& inter)
|
FEdge *SVertex::getFEdge(Interface0D& inter)
|
||||||
{
|
{
|
||||||
FEdge * result = 0;
|
FEdge *result = NULL;
|
||||||
SVertex* iVertexB = dynamic_cast<SVertex*>(&inter);
|
SVertex *iVertexB = dynamic_cast<SVertex*>(&inter);
|
||||||
if (!iVertexB)
|
if (!iVertexB)
|
||||||
return result;
|
return result;
|
||||||
vector<FEdge*>::const_iterator fe=_FEdges.begin(), feend=_FEdges.end();
|
vector<FEdge*>::const_iterator fe = _FEdges.begin(), feend = _FEdges.end();
|
||||||
for(;
|
for (; fe != feend; ++fe) {
|
||||||
fe!=feend;
|
if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB)) ||
|
||||||
++fe)
|
(((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB)))
|
||||||
{
|
|
||||||
if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB))
|
|
||||||
|| (((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB)))
|
|
||||||
result = (*fe);
|
result = (*fe);
|
||||||
}
|
}
|
||||||
if((result == 0) && (getNature() & Nature::T_VERTEX))
|
if ((result == 0) && (getNature() & Nature::T_VERTEX)) {
|
||||||
{
|
|
||||||
SVertex *brother;
|
SVertex *brother;
|
||||||
ViewVertex *vvertex = viewvertex();
|
ViewVertex *vvertex = viewvertex();
|
||||||
TVertex * tvertex = dynamic_cast<TVertex*>(vvertex);
|
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
|
||||||
if(tvertex)
|
if (tvertex) {
|
||||||
{
|
|
||||||
brother = tvertex->frontSVertex();
|
brother = tvertex->frontSVertex();
|
||||||
if(this == brother)
|
if (this == brother)
|
||||||
brother = tvertex->backSVertex();
|
brother = tvertex->backSVertex();
|
||||||
const vector<FEdge*>& fedges = brother->fedges();
|
const vector<FEdge*>& fedges = brother->fedges();
|
||||||
for(fe=fedges.begin(),feend=fedges.end();
|
for (fe = fedges.begin(), feend = fedges.end(); fe != feend; ++fe) {
|
||||||
fe!=feend;
|
if ((((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB)) ||
|
||||||
++fe)
|
(((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB)))
|
||||||
{
|
|
||||||
if( (((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB))
|
|
||||||
|| (((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB)))
|
|
||||||
result = (*fe);
|
result = (*fe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX))
|
if ((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) {
|
||||||
{
|
|
||||||
SVertex *brother;
|
SVertex *brother;
|
||||||
ViewVertex *vvertex = iVertexB->viewvertex();
|
ViewVertex *vvertex = iVertexB->viewvertex();
|
||||||
TVertex * tvertex = dynamic_cast<TVertex*>(vvertex);
|
TVertex *tvertex = dynamic_cast<TVertex*>(vvertex);
|
||||||
if(tvertex)
|
if (tvertex) {
|
||||||
{
|
|
||||||
brother = tvertex->frontSVertex();
|
brother = tvertex->frontSVertex();
|
||||||
if(iVertexB == brother)
|
if (iVertexB == brother)
|
||||||
brother = tvertex->backSVertex();
|
brother = tvertex->backSVertex();
|
||||||
for(fe=_FEdges.begin(),feend=_FEdges.end();
|
for (fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; ++fe) {
|
||||||
fe!=feend;
|
if ((((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother)) ||
|
||||||
++fe)
|
(((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother)))
|
||||||
{
|
|
||||||
if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother))
|
|
||||||
|| (((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother)))
|
|
||||||
result = (*fe);
|
result = (*fe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,21 +211,31 @@ FEdge* SVertex::getFEdge(Interface0D& inter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************/
|
/**********************************/
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* FEdge */
|
/* FEdge */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
|
||||||
|
|
||||||
int FEdge::viewedge_nature() const {return _ViewEdge->getNature();}
|
int FEdge::viewedge_nature() const
|
||||||
//float FEdge::viewedge_length() const {return _ViewEdge->viewedge_length();}
|
|
||||||
const SShape* FEdge::occluded_shape() const
|
|
||||||
{
|
{
|
||||||
ViewShape * aShape = _ViewEdge->aShape();
|
return _ViewEdge->getNature();
|
||||||
if(aShape == 0)
|
}
|
||||||
|
|
||||||
|
#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 0;
|
||||||
return aShape->sshape();
|
return aShape->sshape();
|
||||||
}
|
}
|
||||||
@@ -222,30 +250,44 @@ int FEdge::invisibility() const
|
|||||||
return _ViewEdge->qi();
|
return _ViewEdge->qi();
|
||||||
}
|
}
|
||||||
|
|
||||||
occluder_container::const_iterator FEdge::occluders_begin() const {return _ViewEdge->occluders_begin();}
|
occluder_container::const_iterator FEdge::occluders_begin() const
|
||||||
occluder_container::const_iterator FEdge::occluders_end() const {return _ViewEdge->occluders_end();}
|
{
|
||||||
bool FEdge::occluders_empty() const {return _ViewEdge->occluders_empty();}
|
return _ViewEdge->occluders_begin();
|
||||||
int FEdge::occluders_size() const {return _ViewEdge->occluders_size();}
|
}
|
||||||
|
|
||||||
|
occluder_container::const_iterator FEdge::occluders_end() const
|
||||||
|
{
|
||||||
|
return _ViewEdge->occluders_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FEdge::occluders_empty() const
|
||||||
|
{
|
||||||
|
return _ViewEdge->occluders_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FEdge::occluders_size() const
|
||||||
|
{
|
||||||
|
return _ViewEdge->occluders_size();
|
||||||
|
}
|
||||||
|
|
||||||
const bool FEdge::occludee_empty() const
|
const bool FEdge::occludee_empty() const
|
||||||
{
|
{
|
||||||
return _ViewEdge->occludee_empty();
|
return _ViewEdge->occludee_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Id FEdge::shape_id() const
|
Id FEdge::shape_id() const
|
||||||
{
|
{
|
||||||
return _VertexA->shape()->getId();
|
return _VertexA->shape()->getId();
|
||||||
}
|
}
|
||||||
const SShape* FEdge::shape() const
|
|
||||||
|
const SShape *FEdge::shape() const
|
||||||
{
|
{
|
||||||
return _VertexA->shape();
|
return _VertexA->shape();
|
||||||
}
|
}
|
||||||
|
|
||||||
real FEdge::z_discontinuity() const
|
real FEdge::z_discontinuity() const
|
||||||
{
|
{
|
||||||
if(!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER))
|
if (!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,118 +295,120 @@ real FEdge::z_discontinuity() const
|
|||||||
|
|
||||||
Vec3r bbox_size_vec(box.getMax() - box.getMin());
|
Vec3r bbox_size_vec(box.getMax() - box.getMin());
|
||||||
real bboxsize = bbox_size_vec.norm();
|
real bboxsize = bbox_size_vec.norm();
|
||||||
if(occludee_empty())
|
if (occludee_empty()) {
|
||||||
|
|
||||||
{
|
|
||||||
//return FLT_MAX;
|
//return FLT_MAX;
|
||||||
|
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
|
||||||
//return bboxsize;
|
//return bboxsize;
|
||||||
|
|
||||||
}
|
}
|
||||||
// real result;
|
|
||||||
// z_discontinuity_functor<SVertex> _functor;
|
|
||||||
|
|
||||||
// Evaluate<SVertex,z_discontinuity_functor<SVertex> >(&_functor, iCombination, result )
|
|
||||||
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;
|
middle /= 2;
|
||||||
Vec3r disc_vec(middle - _occludeeIntersection);
|
Vec3r disc_vec(middle - _occludeeIntersection);
|
||||||
real res = disc_vec.norm() / bboxsize;
|
real res = disc_vec.norm() / bboxsize;
|
||||||
return res;
|
|
||||||
|
|
||||||
//return 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
|
return result;
|
||||||
//{
|
}
|
||||||
//
|
|
||||||
// float result;
|
|
||||||
// local_average_depth_functor<SVertex> functor;
|
|
||||||
// Evaluate(&functor, iCombination, result);
|
|
||||||
//
|
|
||||||
// return result;
|
|
||||||
//}
|
|
||||||
//float FEdge::local_depth_variance(int iCombination ) const
|
|
||||||
//{
|
|
||||||
// float result;
|
|
||||||
//
|
|
||||||
// local_depth_variance_functor<SVertex> functor;
|
|
||||||
//
|
|
||||||
// Evaluate(&functor, iCombination, result);
|
|
||||||
//
|
|
||||||
// return result;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//real FEdge::local_average_density( float sigma, int iCombination) const
|
|
||||||
//{
|
|
||||||
// float result;
|
|
||||||
//
|
|
||||||
// density_functor<SVertex> functor(sigma);
|
|
||||||
//
|
|
||||||
// Evaluate(&functor, iCombination, result);
|
|
||||||
//
|
|
||||||
// return result;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */)
|
|
||||||
////{
|
|
||||||
//// Vec3r Na = _VertexA->normal(oException);
|
|
||||||
//// if(oException != Exception::NO_EXCEPTION)
|
|
||||||
//// return Na;
|
|
||||||
//// Vec3r Nb = _VertexB->normal(oException);
|
|
||||||
//// if(oException != Exception::NO_EXCEPTION)
|
|
||||||
//// return Nb;
|
|
||||||
//// return (Na+Nb)/2.0;
|
|
||||||
////}
|
|
||||||
//
|
|
||||||
//Vec3r FEdge::curvature2d_as_vector(int iCombination) const
|
|
||||||
//{
|
|
||||||
// Vec3r result;
|
|
||||||
// curvature2d_as_vector_functor<SVertex> _functor;
|
|
||||||
// Evaluate<Vec3r,curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result );
|
|
||||||
// return result;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//real FEdge::curvature2d_as_angle(int iCombination) const
|
|
||||||
//{
|
|
||||||
// real result;
|
|
||||||
// curvature2d_as_angle_functor<SVertex> _functor;
|
|
||||||
// Evaluate<real,curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result );
|
|
||||||
// return result;
|
|
||||||
//}
|
|
||||||
|
|
||||||
/**********************************/
|
float FEdge::local_depth_variance(int iCombination ) const
|
||||||
/* */
|
{
|
||||||
/* */
|
float result;
|
||||||
/* FEdgeSharp */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/**********************************/
|
|
||||||
|
|
||||||
//Material FEdge::material() const
|
local_depth_variance_functor<SVertex> functor;
|
||||||
//{
|
|
||||||
// return _VertexA->shape()->material();
|
Evaluate(&functor, iCombination, result);
|
||||||
//}
|
|
||||||
const FrsMaterial& FEdgeSharp::aFrsMaterial() const {
|
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);
|
return _VertexA->shape()->frs_material(_aFrsMaterialIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FrsMaterial& FEdgeSharp::bFrsMaterial() const {
|
const FrsMaterial& FEdgeSharp::bFrsMaterial() const
|
||||||
|
{
|
||||||
return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
|
return _VertexA->shape()->frs_material(_bFrsMaterialIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************/
|
/**********************************/
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* FEdgeSmooth */
|
/* FEdgeSmooth */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
|
||||||
const FrsMaterial& FEdgeSmooth::frs_material() const {
|
const FrsMaterial& FEdgeSmooth::frs_material() const
|
||||||
|
{
|
||||||
return _VertexA->shape()->frs_material(_FrsMaterialIndex);
|
return _VertexA->shape()->frs_material(_FrsMaterialIndex);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to perform all geometric operations dedicated to silhouette. That, for example, implies that
|
||||||
//
|
* this geom engine has as member data the viewpoint, transformations, projections...
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Stephane Grabli
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 03/09/2002
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "Silhouette.h"
|
#include "Silhouette.h"
|
||||||
#include "SilhouetteGeomEngine.h"
|
#include "SilhouetteGeomEngine.h"
|
||||||
|
|
||||||
#include "../geometry/GeomUtils.h"
|
#include "../geometry/GeomUtils.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0,0,0);
|
Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0, 0, 0);
|
||||||
real SilhouetteGeomEngine::_translation[3] = {0,0,0};
|
real SilhouetteGeomEngine::_translation[3] = {0, 0, 0};
|
||||||
real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {{1,0,0,0},
|
real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {
|
||||||
{0,1,0,0},
|
{1, 0, 0, 0},
|
||||||
{0,0,1,0},
|
{0, 1, 0, 0},
|
||||||
{0,0,0,1}};
|
{0, 0, 1, 0},
|
||||||
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {{1,0,0,0},
|
{0, 0, 0, 1}
|
||||||
{0,1,0,0},
|
};
|
||||||
{0,0,1,0},
|
real SilhouetteGeomEngine::_projectionMatrix[4][4] = {
|
||||||
{0,0,0,1}};
|
{1, 0, 0, 0},
|
||||||
real SilhouetteGeomEngine::_transform[4][4] = {{1,0,0,0},
|
{0, 1, 0, 0},
|
||||||
{0,1,0,0},
|
{0, 0, 1, 0},
|
||||||
{0,0,1,0},
|
{0, 0, 0, 1}
|
||||||
{0,0,0,1}};
|
};
|
||||||
int SilhouetteGeomEngine::_viewport[4] = {1,1,1,1}; // the viewport
|
real SilhouetteGeomEngine::_transform[4][4] = {
|
||||||
|
{1, 0, 0, 0},
|
||||||
|
{0, 1, 0, 0},
|
||||||
|
{0, 0, 1, 0},
|
||||||
|
{0, 0, 0, 1}
|
||||||
|
};
|
||||||
|
int SilhouetteGeomEngine::_viewport[4] = {1, 1, 1, 1};
|
||||||
real SilhouetteGeomEngine::_Focal = 0.0;
|
real SilhouetteGeomEngine::_Focal = 0.0;
|
||||||
|
|
||||||
real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {{1,0,0,0},
|
real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {
|
||||||
{0,1,0,0},
|
{1, 0, 0, 0},
|
||||||
{0,0,1,0},
|
{0, 1, 0, 0},
|
||||||
{0,0,0,1}};
|
{0, 0, 1, 0},
|
||||||
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {{1,0,0,0},
|
{0, 0, 0, 1}
|
||||||
{0,1,0,0},
|
};
|
||||||
{0,0,1,0},
|
real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {
|
||||||
{0,0,0,1}};
|
{1, 0, 0, 0},
|
||||||
|
{0, 1, 0, 0},
|
||||||
|
{0, 0, 1, 0},
|
||||||
|
{0, 0, 0, 1}
|
||||||
|
};
|
||||||
real SilhouetteGeomEngine::_znear = 0.0;
|
real SilhouetteGeomEngine::_znear = 0.0;
|
||||||
real SilhouetteGeomEngine::_zfar = 100.0;
|
real SilhouetteGeomEngine::_zfar = 100.0;
|
||||||
bool SilhouetteGeomEngine::_isOrthographicProjection = false;
|
bool SilhouetteGeomEngine::_isOrthographicProjection = false;
|
||||||
|
|
||||||
SilhouetteGeomEngine * SilhouetteGeomEngine::_pInstance = 0;
|
SilhouetteGeomEngine *SilhouetteGeomEngine::_pInstance = NULL;
|
||||||
|
|
||||||
void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocal)
|
void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
|
||||||
|
const int iViewport[4], real iFocal)
|
||||||
{
|
{
|
||||||
unsigned int i,j;
|
unsigned int i, j;
|
||||||
_translation[0] = iModelViewMatrix[3][0];
|
_translation[0] = iModelViewMatrix[3][0];
|
||||||
_translation[1] = iModelViewMatrix[3][1];
|
_translation[1] = iModelViewMatrix[3][1];
|
||||||
_translation[2] = iModelViewMatrix[3][2];
|
_translation[2] = iModelViewMatrix[3][2];
|
||||||
|
|
||||||
for(i=0; i<4; i++){
|
for (i = 0; i < 4; i++) {
|
||||||
for(j=0; j<4; j++)
|
for (j = 0; j < 4; j++) {
|
||||||
{
|
|
||||||
_modelViewMatrix[i][j] = iModelViewMatrix[j][i];
|
_modelViewMatrix[i][j] = iModelViewMatrix[j][i];
|
||||||
_glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
|
_glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i<4; i++){
|
for (i = 0; i < 4; i++) {
|
||||||
for(j=0; j<4; j++)
|
for (j = 0; j < 4; j++) {
|
||||||
{
|
|
||||||
_projectionMatrix[i][j] = iProjectionMatrix[j][i];
|
_projectionMatrix[i][j] = iProjectionMatrix[j][i];
|
||||||
_glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
|
_glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i<4; i++){
|
for (i = 0; i < 4; i++) {
|
||||||
for(j=0; j<4; j++)
|
for (j = 0; j < 4; j++) {
|
||||||
{
|
|
||||||
_transform[i][j] = 0;
|
_transform[i][j] = 0;
|
||||||
for(unsigned int k=0; k<4; k++)
|
for (unsigned int k = 0; k < 4; k++)
|
||||||
_transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
|
_transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i<4; i++){
|
for (i = 0; i < 4; i++) {
|
||||||
_viewport[i] = iViewport[i];
|
_viewport[i] = iViewport[i];
|
||||||
}
|
}
|
||||||
_Focal = iFocal;
|
_Focal = iFocal;
|
||||||
@@ -102,62 +125,67 @@ void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
|
|||||||
_zfar = iZFar;
|
_zfar = iZFar;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SilhouetteGeomEngine::retrieveViewport(int viewport[4]){
|
void SilhouetteGeomEngine::retrieveViewport(int viewport[4])
|
||||||
memcpy(viewport, _viewport, 4*sizeof(int));
|
{
|
||||||
|
memcpy(viewport, _viewport, 4 * sizeof(int));
|
||||||
}
|
}
|
||||||
//#define HUGE 1e9
|
|
||||||
|
//#define HUGE 1.0e9
|
||||||
|
|
||||||
void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices)
|
void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices)
|
||||||
{
|
{
|
||||||
Vec3r newPoint;
|
Vec3r newPoint;
|
||||||
// real min=HUGE;
|
#if 0
|
||||||
// real max=-HUGE;
|
real min = HUGE;
|
||||||
|
real max = -HUGE;
|
||||||
|
#endif
|
||||||
vector<SVertex*>::iterator sv, svend;
|
vector<SVertex*>::iterator sv, svend;
|
||||||
const real depth = _zfar - _znear;
|
const real depth = _zfar - _znear;
|
||||||
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
|
const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
|
||||||
|
|
||||||
for(sv=ioVertices.begin(), svend=ioVertices.end();
|
for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
|
||||||
sv!=svend;
|
|
||||||
sv++)
|
|
||||||
{
|
|
||||||
GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
|
GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
|
||||||
newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1
|
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
|
||||||
(*sv)->setPoint2D(newPoint);
|
(*sv)->setPoint2D(newPoint);
|
||||||
//cerr << (*sv)->point2d().z() << " ";
|
#if 0
|
||||||
// real d=(*sv)->point2d()[2];
|
cerr << (*sv)->point2d().z() << " ";
|
||||||
// if (d>max) max =d;
|
real d = (*sv)->point2d()[2];
|
||||||
// if (d<min) min =d;
|
if (d > max)
|
||||||
|
max =d;
|
||||||
|
if (d < min)
|
||||||
|
min =d;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// for(sv=ioVertices.begin(), svend=ioVertices.end();
|
#if 0
|
||||||
// sv!=svend;
|
for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
|
||||||
// sv++)
|
Vec3r P((*sv)->point2d());
|
||||||
// {
|
(*sv)->setPoint2D(Vec3r(P[0], P[1], 1.0 - (P[2] - min) / (max - min)));
|
||||||
// Vec3r P((*sv)->point2d());
|
//cerr << (*sv)->point2d()[2] << " ";
|
||||||
// (*sv)->setPoint2D(Vec3r(P[0], P[1], 1.0-(P[2]-min)/(max-min)));
|
}
|
||||||
// //cerr<<(*sv)->point2d()[2]<<" ";
|
#endif
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SilhouetteGeomEngine::ProjectSilhouette(SVertex* ioVertex)
|
void SilhouetteGeomEngine::ProjectSilhouette(SVertex *ioVertex)
|
||||||
{
|
{
|
||||||
Vec3r newPoint;
|
Vec3r newPoint;
|
||||||
// real min=HUGE;
|
#if 0
|
||||||
// real max=-HUGE;
|
real min = HUGE;
|
||||||
|
real max = -HUGE;
|
||||||
vector<SVertex*>::iterator sv, svend;
|
vector<SVertex*>::iterator sv, svend;
|
||||||
|
#endif
|
||||||
const real depth = _zfar - _znear;
|
const real depth = _zfar - _znear;
|
||||||
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
|
const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
|
||||||
GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
|
GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
|
||||||
newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1
|
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
|
||||||
ioVertex->setPoint2D(newPoint);
|
ioVertex->setPoint2D(newPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
|
real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
|
||||||
{
|
{
|
||||||
if( _isOrthographicProjection )
|
if (_isOrthographicProjection)
|
||||||
return t;
|
return t;
|
||||||
|
|
||||||
// we need to compute for each parameter t the corresponding
|
// we need to compute for each parameter t the corresponding parameter T which gives the intersection in 3D.
|
||||||
// parameter T which gives the intersection in 3D.
|
|
||||||
real T;
|
real T;
|
||||||
|
|
||||||
// suffix w for world, c for camera, r for retina, i for image
|
// suffix w for world, c for camera, r for retina, i for image
|
||||||
@@ -184,44 +212,48 @@ real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
|
|||||||
real m22 = _projectionMatrix[1][1];
|
real m22 = _projectionMatrix[1][1];
|
||||||
real m23 = _projectionMatrix[1][2];
|
real m23 = _projectionMatrix[1][2];
|
||||||
|
|
||||||
if (fabs(ABc[0]) > 1e-6) {
|
if (fabs(ABc[0]) > 1.0e-6) {
|
||||||
|
|
||||||
alpha = ABc[2] / ABc[0];
|
alpha = ABc[2] / ABc[0];
|
||||||
beta = Ac[2] - alpha * Ac[0];
|
beta = Ac[2] - alpha * Ac[0];
|
||||||
denom = alpha * (Ir[0] + m13) + m11;
|
denom = alpha * (Ir[0] + m13) + m11;
|
||||||
if (fabs(denom) < 1e-6)
|
if (fabs(denom) < 1.0e-6)
|
||||||
goto iter;
|
goto iter;
|
||||||
Ic[0] = -beta * (Ir[0] + m13) / denom;
|
Ic[0] = -beta * (Ir[0] + m13) / denom;
|
||||||
// Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
|
#if 0
|
||||||
// Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
|
Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
|
||||||
|
Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
|
||||||
|
#endif
|
||||||
T = (Ic[0] - Ac[0]) / ABc[0];
|
T = (Ic[0] - Ac[0]) / ABc[0];
|
||||||
|
|
||||||
} else if (fabs(ABc[1]) > 1e-6) {
|
}
|
||||||
|
else if (fabs(ABc[1]) > 1.0e-6) {
|
||||||
alpha = ABc[2] / ABc[1];
|
alpha = ABc[2] / ABc[1];
|
||||||
beta = Ac[2] - alpha * Ac[1];
|
beta = Ac[2] - alpha * Ac[1];
|
||||||
denom = alpha * (Ir[1] + m23) + m22;
|
denom = alpha * (Ir[1] + m23) + m22;
|
||||||
if (fabs(denom) < 1e-6)
|
if (fabs(denom) < 1.0e-6)
|
||||||
goto iter;
|
goto iter;
|
||||||
Ic[1] = -beta * (Ir[1] + m23) / denom;
|
Ic[1] = -beta * (Ir[1] + m23) / denom;
|
||||||
// Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
|
#if 0
|
||||||
// Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
|
Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
|
||||||
|
Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
|
||||||
|
#endif
|
||||||
T = (Ic[1] - Ac[1]) / ABc[1];
|
T = (Ic[1] - Ac[1]) / ABc[1];
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
|
iter:
|
||||||
iter: bool x_coords, less_than;
|
bool x_coords, less_than;
|
||||||
if (fabs(Bi[0] - Ai[0]) > 1e-6) {
|
if (fabs(Bi[0] - Ai[0]) > 1.0e-6) {
|
||||||
x_coords = true;
|
x_coords = true;
|
||||||
less_than = Ai[0] < Bi[0];
|
less_than = Ai[0] < Bi[0];
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
x_coords = false;
|
x_coords = false;
|
||||||
less_than = Ai[1] < Bi[1];
|
less_than = Ai[1] < Bi[1];
|
||||||
}
|
}
|
||||||
Vec3r Pc, Pr, Pi;
|
Vec3r Pc, Pr, Pi;
|
||||||
real T_sta = 0.0;
|
real T_sta = 0.0;
|
||||||
real T_end = 1.0;
|
real T_end = 1.0;
|
||||||
real delta_x, delta_y, dist, dist_threshold = 1e-6;
|
real delta_x, delta_y, dist, dist_threshold = 1.0e-6;
|
||||||
int i, max_iters = 100;
|
int i, max_iters = 100;
|
||||||
for (i = 0; i < max_iters; i++) {
|
for (i = 0; i < max_iters; i++) {
|
||||||
T = T_sta + 0.5 * (T_end - T_sta);
|
T = T_sta + 0.5 * (T_end - T_sta);
|
||||||
@@ -235,15 +267,30 @@ iter: bool x_coords, less_than;
|
|||||||
break;
|
break;
|
||||||
if (x_coords) {
|
if (x_coords) {
|
||||||
if (less_than) {
|
if (less_than) {
|
||||||
if (Pi[0] < Ii[0]) { T_sta = T; } else { T_end = T; }
|
if (Pi[0] < Ii[0])
|
||||||
} else {
|
T_sta = T;
|
||||||
if (Pi[0] > Ii[0]) { T_sta = T; } else { T_end = T; }
|
else
|
||||||
|
T_end = T;
|
||||||
}
|
}
|
||||||
} else {
|
else {
|
||||||
|
if (Pi[0] > Ii[0])
|
||||||
|
T_sta = T;
|
||||||
|
else
|
||||||
|
T_end = T;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
if (less_than) {
|
if (less_than) {
|
||||||
if (Pi[1] < Ii[1]) { T_sta = T; } else { T_end = T; }
|
if (Pi[1] < Ii[1])
|
||||||
} else {
|
T_sta = T;
|
||||||
if (Pi[1] > Ii[1]) { T_sta = T; } else { T_end = T; }
|
else
|
||||||
|
T_end = T;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (Pi[1] > Ii[1])
|
||||||
|
T_sta = T;
|
||||||
|
else
|
||||||
|
T_end = T;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,15 +305,11 @@ iter: bool x_coords, less_than;
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r& M)
|
Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r& M)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
const real depth = _zfar - _znear;
|
const real depth = _zfar - _znear;
|
||||||
const real fac = (depth < 1e-6) ? 1.0 : 1.0 / depth;
|
const real fac = (depth < 1.0e-6) ? 1.0 : 1.0 / depth;
|
||||||
Vec3r newPoint;
|
Vec3r newPoint;
|
||||||
GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
|
GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
|
||||||
newPoint[2] = (-newPoint[2]-_znear) * fac; // normalize Z between 0 and 1
|
newPoint[2] = (-newPoint[2] - _znear) * fac; // normalize Z between 0 and 1
|
||||||
return newPoint;
|
return newPoint;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,46 @@
|
|||||||
//
|
/*
|
||||||
// Filename : SilhouetteGeomEngine.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Purpose : Class to perform all geometric operations dedicated
|
* This program is free software; you can redistribute it and/or
|
||||||
// to silhouette. That, for example, implies that
|
* modify it under the terms of the GNU General Public License
|
||||||
// this geom engine has as member data the viewpoint,
|
* as published by the Free Software Foundation; either version 2
|
||||||
// transformations, projections...
|
* of the License, or (at your option) any later version.
|
||||||
// Date of creation : 03/09/2002
|
*
|
||||||
//
|
* This program is distributed in the hope that it will be useful,
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
|
||||||
|
#define __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to perform all geometric operations dedicated to silhouette. That, for example, implies that
|
||||||
//
|
* this geom engine has as member data the viewpoint, transformations, projections...
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Stephane Grabli
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 03/09/2002
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef SILHOUETTEGEOMENGINE_H
|
#include <vector>
|
||||||
# define SILHOUETTEGEOMENGINE_H
|
|
||||||
|
|
||||||
# include <vector>
|
#include "../geometry/Geom.h"
|
||||||
# include "../system/FreestyleConfig.h"
|
|
||||||
# include "../geometry/Geom.h"
|
#include "../system/FreestyleConfig.h"
|
||||||
|
|
||||||
using namespace Geometry;
|
using namespace Geometry;
|
||||||
|
|
||||||
@@ -45,38 +50,47 @@ class FEdge;
|
|||||||
class LIB_VIEW_MAP_EXPORT SilhouetteGeomEngine
|
class LIB_VIEW_MAP_EXPORT SilhouetteGeomEngine
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static Vec3r _Viewpoint; // The viewpoint under which the silhouette has to be computed
|
// The viewpoint under which the silhouette has to be computed
|
||||||
|
static Vec3r _Viewpoint;
|
||||||
static real _translation[3];
|
static real _translation[3];
|
||||||
static real _modelViewMatrix[4][4]; // the model view matrix (_modelViewMatrix[i][j] means element of line i and column j)
|
// the model view matrix (_modelViewMatrix[i][j] means element of line i and column j)
|
||||||
static real _projectionMatrix[4][4]; // the projection matrix (_projectionMatrix[i][j] means element of line i and column j)
|
static real _modelViewMatrix[4][4];
|
||||||
static real _transform[4][4]; // the global transformation from world to screen (projection included) (_transform[i][j] means element of line i and column j)
|
// the projection matrix (_projectionMatrix[i][j] means element of line i and column j)
|
||||||
static int _viewport[4]; // the viewport
|
static real _projectionMatrix[4][4];
|
||||||
|
// the global transformation from world to screen (projection included)
|
||||||
|
// (_transform[i][j] means element of line i and column j)
|
||||||
|
static real _transform[4][4];
|
||||||
|
// the viewport
|
||||||
|
static int _viewport[4];
|
||||||
static real _Focal;
|
static real _Focal;
|
||||||
|
|
||||||
static real _znear;
|
static real _znear;
|
||||||
static real _zfar;
|
static real _zfar;
|
||||||
|
|
||||||
static real _glProjectionMatrix[4][4]; // GL style (column major) projection matrix
|
// GL style (column major) projection matrix
|
||||||
static real _glModelViewMatrix[4][4]; // GL style (column major) model view matrix
|
static real _glProjectionMatrix[4][4];
|
||||||
|
// GL style (column major) model view matrix
|
||||||
static bool _isOrthographicProjection;
|
static real _glModelViewMatrix[4][4];
|
||||||
|
|
||||||
|
static bool _isOrthographicProjection;
|
||||||
|
|
||||||
static SilhouetteGeomEngine *_pInstance;
|
static SilhouetteGeomEngine *_pInstance;
|
||||||
public:
|
|
||||||
|
|
||||||
|
public:
|
||||||
/*! retrieves an instance on the singleton */
|
/*! retrieves an instance on the singleton */
|
||||||
static SilhouetteGeomEngine * getInstance()
|
static SilhouetteGeomEngine *getInstance()
|
||||||
{
|
|
||||||
if(0 == _pInstance)
|
|
||||||
{
|
{
|
||||||
|
if(0 == _pInstance) {
|
||||||
_pInstance = new SilhouetteGeomEngine;
|
_pInstance = new SilhouetteGeomEngine;
|
||||||
}
|
}
|
||||||
return _pInstance;
|
return _pInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sets the current viewpoint */
|
/*! Sets the current viewpoint */
|
||||||
static inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;}
|
static inline void setViewpoint(const Vec3r& ivp)
|
||||||
|
{
|
||||||
|
_Viewpoint = ivp;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Sets the current transformation
|
/*! Sets the current transformation
|
||||||
* iModelViewMatrix
|
* iModelViewMatrix
|
||||||
@@ -88,11 +102,11 @@ public:
|
|||||||
* iFocal
|
* iFocal
|
||||||
* The focal length
|
* The focal length
|
||||||
*/
|
*/
|
||||||
static void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocal) ;
|
static void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
|
||||||
|
const int iViewport[4], real iFocal);
|
||||||
|
|
||||||
/*! Sets the current znear and zfar
|
/*! Sets the current znear and zfar */
|
||||||
*/
|
static void setFrustum(real iZNear, real iZFar);
|
||||||
static void setFrustum(real iZNear, real iZFar) ;
|
|
||||||
|
|
||||||
/* accessors */
|
/* accessors */
|
||||||
static void retrieveViewport(int viewport[4]);
|
static void retrieveViewport(int viewport[4]);
|
||||||
@@ -100,11 +114,10 @@ public:
|
|||||||
/*! Projects the silhouette in camera coordinates
|
/*! Projects the silhouette in camera coordinates
|
||||||
* This method modifies the ioEdges passed as argument.
|
* This method modifies the ioEdges passed as argument.
|
||||||
* ioVertices
|
* ioVertices
|
||||||
* The vertices to project. It is modified during the
|
* The vertices to project. It is modified during the operation.
|
||||||
* operation.
|
|
||||||
*/
|
*/
|
||||||
static void ProjectSilhouette(std::vector<SVertex*>& ioVertices);
|
static void ProjectSilhouette(std::vector<SVertex*>& ioVertices);
|
||||||
static void ProjectSilhouette(SVertex* ioVertex);
|
static void ProjectSilhouette(SVertex *ioVertex);
|
||||||
|
|
||||||
/*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain
|
/*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain
|
||||||
* the parameter giving the corresponding 3D intersection.
|
* the parameter giving the corresponding 3D intersection.
|
||||||
@@ -120,4 +133,4 @@ public:
|
|||||||
static Vec3r WorldToImage(const Vec3r& M);
|
static Vec3r WorldToImage(const Vec3r& M);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SILHOUETTEGEOMENGINE_H
|
#endif // __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
|
||||||
|
|||||||
@@ -1,37 +1,42 @@
|
|||||||
//
|
/*
|
||||||
// Filename : SphericalGrid.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2010-12-19
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/SphericalGrid.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2010-12-19
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
#include <algorithm>
|
||||||
//
|
#include <stdexcept>
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "SphericalGrid.h"
|
#include "SphericalGrid.h"
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Helper Classes
|
// Helper Classes
|
||||||
@@ -42,11 +47,12 @@ using namespace std;
|
|||||||
// Cell
|
// Cell
|
||||||
/////////
|
/////////
|
||||||
|
|
||||||
SphericalGrid::Cell::Cell () {}
|
SphericalGrid::Cell::Cell() {}
|
||||||
|
|
||||||
SphericalGrid::Cell::~Cell () {}
|
SphericalGrid::Cell::~Cell() {}
|
||||||
|
|
||||||
void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY) {
|
void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
|
||||||
|
{
|
||||||
const real epsilon = 1.0e-06;
|
const real epsilon = 1.0e-06;
|
||||||
boundary[0] = x - epsilon;
|
boundary[0] = x - epsilon;
|
||||||
boundary[1] = x + sizeX + epsilon;
|
boundary[1] = x + sizeX + epsilon;
|
||||||
@@ -54,11 +60,14 @@ void SphericalGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
|
|||||||
boundary[3] = y + sizeY + epsilon;
|
boundary[3] = y + sizeY + epsilon;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SphericalGrid::Cell::compareOccludersByShallowestPoint (const SphericalGrid::OccluderData* a, const SphericalGrid::OccluderData* b) {
|
bool SphericalGrid::Cell::compareOccludersByShallowestPoint(const SphericalGrid::OccluderData *a,
|
||||||
|
const SphericalGrid::OccluderData *b)
|
||||||
|
{
|
||||||
return a->shallowest < b->shallowest;
|
return a->shallowest < b->shallowest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalGrid::Cell::indexPolygons() {
|
void SphericalGrid::Cell::indexPolygons()
|
||||||
|
{
|
||||||
// Sort occluders by their shallowest points.
|
// Sort occluders by their shallowest points.
|
||||||
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
|
sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
|
||||||
}
|
}
|
||||||
@@ -66,13 +75,12 @@ void SphericalGrid::Cell::indexPolygons() {
|
|||||||
// Iterator
|
// Iterator
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
SphericalGrid::Iterator::Iterator (SphericalGrid& grid, Vec3r& center, real epsilon)
|
SphericalGrid::Iterator::Iterator(SphericalGrid& grid, Vec3r& center, real epsilon)
|
||||||
: _target(SphericalGrid::Transform::sphericalProjection(center)),
|
: _target(SphericalGrid::Transform::sphericalProjection(center)), _foundOccludee(false)
|
||||||
_foundOccludee(false)
|
|
||||||
{
|
{
|
||||||
// Find target cell
|
// Find target cell
|
||||||
_cell = grid.findCell(_target);
|
_cell = grid.findCell(_target);
|
||||||
#if sphericalgridlogging == 1
|
#if SPHERICAL_GRID_LOGGING
|
||||||
cout << "Searching for occluders of edge centered at " << _target << " in cell ["
|
cout << "Searching for occluders of edge centered at " << _target << " in cell ["
|
||||||
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
|
<< _cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2]
|
||||||
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
|
<< ", " << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
|
||||||
@@ -82,14 +90,14 @@ SphericalGrid::Iterator::Iterator (SphericalGrid& grid, Vec3r& center, real epsi
|
|||||||
_current = _cell->faces.begin();
|
_current = _cell->faces.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
SphericalGrid::Iterator::~Iterator () {}
|
SphericalGrid::Iterator::~Iterator() {}
|
||||||
|
|
||||||
// SphericalGrid
|
// SphericalGrid
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|
||||||
SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI)
|
SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
|
||||||
: _viewpoint(viewpoint),
|
Vec3r& viewpoint, bool enableQI)
|
||||||
_enableQI(enableQI)
|
: _viewpoint(viewpoint), _enableQI(enableQI)
|
||||||
{
|
{
|
||||||
cout << "Generate Cell structure" << endl;
|
cout << "Generate Cell structure" << endl;
|
||||||
// Generate Cell structure
|
// Generate Cell structure
|
||||||
@@ -103,10 +111,10 @@ SphericalGrid::SphericalGrid(OccluderSource& source, GridDensityProvider& densit
|
|||||||
cout << "Ready to use SphericalGrid" << endl;
|
cout << "Ready to use SphericalGrid" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
SphericalGrid::~SphericalGrid () {
|
SphericalGrid::~SphericalGrid() {}
|
||||||
}
|
|
||||||
|
|
||||||
void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap) {
|
void SphericalGrid::assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap)
|
||||||
|
{
|
||||||
_cellSize = density.cellSize();
|
_cellSize = density.cellSize();
|
||||||
_cellsX = density.cellsX();
|
_cellsX = density.cellsX();
|
||||||
_cellsY = density.cellsY();
|
_cellsY = density.cellsY();
|
||||||
@@ -115,20 +123,19 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
|
|||||||
|
|
||||||
// Now allocate the cell table and fill it with default (empty) cells
|
// Now allocate the cell table and fill it with default (empty) cells
|
||||||
_cells.resize(_cellsX * _cellsY);
|
_cells.resize(_cellsX * _cellsY);
|
||||||
for ( cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
|
for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
|
||||||
(*i) = NULL;
|
(*i) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identify cells that will be used, and set the dimensions for each
|
// Identify cells that will be used, and set the dimensions for each
|
||||||
ViewMap::fedges_container& fedges = viewMap->FEdges();
|
ViewMap::fedges_container& fedges = viewMap->FEdges();
|
||||||
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f ) {
|
for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) {
|
||||||
if ( (*f)->isInImage() ) {
|
if ((*f)->isInImage()) {
|
||||||
Vec3r point = SphericalGrid::Transform::sphericalProjection((*f)->center3d());
|
Vec3r point = SphericalGrid::Transform::sphericalProjection((*f)->center3d());
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
getCellCoordinates(point, i, j);
|
getCellCoordinates(point, i, j);
|
||||||
if ( _cells[i * _cellsY + j] == NULL ) {
|
if (_cells[i * _cellsY + j] == NULL) {
|
||||||
// This is an uninitialized cell
|
// This is an uninitialized cell
|
||||||
|
|
||||||
real x, y, width, height;
|
real x, y, width, height;
|
||||||
|
|
||||||
x = _cellOrigin[0] + _cellSize * i;
|
x = _cellOrigin[0] + _cellSize * i;
|
||||||
@@ -145,22 +152,23 @@ void SphericalGrid::assignCells (OccluderSource& source, GridDensityProvider& de
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalGrid::distributePolygons (OccluderSource& source) {
|
void SphericalGrid::distributePolygons(OccluderSource& source)
|
||||||
|
{
|
||||||
unsigned long nFaces = 0;
|
unsigned long nFaces = 0;
|
||||||
unsigned long nKeptFaces = 0;
|
unsigned long nKeptFaces = 0;
|
||||||
|
|
||||||
for ( source.begin(); source.isValid(); source.next() ) {
|
for (source.begin(); source.isValid(); source.next()) {
|
||||||
OccluderData* occluder = NULL;
|
OccluderData *occluder = NULL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( insertOccluder(source, occluder) ) {
|
if (insertOccluder(source, occluder)) {
|
||||||
_faces.push_back(occluder);
|
_faces.push_back(occluder);
|
||||||
++nKeptFaces;
|
++nKeptFaces;
|
||||||
}
|
}
|
||||||
} catch (...) {
|
}
|
||||||
// If an exception was thrown, _faces.push_back() cannot have succeeded.
|
catch (...) {
|
||||||
// occluder is not owned by anyone, and must be deleted.
|
// If an exception was thrown, _faces.push_back() cannot have succeeded. Occluder is not owned by anyone,
|
||||||
// If the exception was thrown before or during new OccluderData(), then
|
// and must be deleted. If the exception was thrown before or during new OccluderData(), then
|
||||||
// occluder is NULL, and this delete is harmless.
|
// occluder is NULL, and this delete is harmless.
|
||||||
delete occluder;
|
delete occluder;
|
||||||
throw;
|
throw;
|
||||||
@@ -170,46 +178,53 @@ void SphericalGrid::distributePolygons (OccluderSource& source) {
|
|||||||
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
|
cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalGrid::reorganizeCells () {
|
void SphericalGrid::reorganizeCells()
|
||||||
|
{
|
||||||
// Sort the occluders by shallowest point
|
// Sort the occluders by shallowest point
|
||||||
for ( vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i ) {
|
for (vector<Cell*>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
|
||||||
if ( *i != NULL ) {
|
if (*i != NULL) {
|
||||||
(*i)->indexPolygons();
|
(*i)->indexPolygons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y) {
|
void SphericalGrid::getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y)
|
||||||
|
{
|
||||||
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
|
x = min(_cellsX - 1, (unsigned) floor (max((double) 0.0f, point[0] - _cellOrigin[0]) / _cellSize));
|
||||||
y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
|
y = min(_cellsY - 1, (unsigned) floor (max((double) 0.0f, point[1] - _cellOrigin[1]) / _cellSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
SphericalGrid::Cell* SphericalGrid::findCell(const Vec3r& point) {
|
SphericalGrid::Cell *SphericalGrid::findCell(const Vec3r& point)
|
||||||
|
{
|
||||||
unsigned x, y;
|
unsigned x, y;
|
||||||
getCellCoordinates(point, x, y);
|
getCellCoordinates(point, x, y);
|
||||||
return _cells[x * _cellsY + y];
|
return _cells[x * _cellsY + y];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SphericalGrid::orthographicProjection () const {
|
bool SphericalGrid::orthographicProjection() const
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vec3r& SphericalGrid::viewpoint() const {
|
const Vec3r& SphericalGrid::viewpoint() const
|
||||||
|
{
|
||||||
return _viewpoint;
|
return _viewpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SphericalGrid::enableQI() const {
|
bool SphericalGrid::enableQI() const
|
||||||
|
{
|
||||||
return _enableQI;
|
return _enableQI;
|
||||||
}
|
}
|
||||||
|
|
||||||
SphericalGrid::Transform::Transform () : GridHelpers::Transform() {
|
SphericalGrid::Transform::Transform () : GridHelpers::Transform() {}
|
||||||
}
|
|
||||||
|
|
||||||
Vec3r SphericalGrid::Transform::operator() (const Vec3r& point) const {
|
Vec3r SphericalGrid::Transform::operator()(const Vec3r& point) const
|
||||||
|
{
|
||||||
return sphericalProjection(point);
|
return sphericalProjection(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) {
|
Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M)
|
||||||
|
{
|
||||||
Vec3r newPoint;
|
Vec3r newPoint;
|
||||||
|
|
||||||
newPoint[0] = ::atan(M[0] / M[2]);
|
newPoint[0] = ::atan(M[0] / M[2]);
|
||||||
@@ -218,4 +233,3 @@ Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r& M) {
|
|||||||
|
|
||||||
return newPoint;
|
return newPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,78 +1,86 @@
|
|||||||
//
|
/*
|
||||||
// Filename : SphericalGrid.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Alexander Beels
|
*
|
||||||
// Purpose : Class to define a cell grid surrounding
|
* This program is free software; you can redistribute it and/or
|
||||||
// the projected image of a scene
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 2010-12-19
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_SPHERICAL_GRID_H__
|
||||||
|
#define __FREESTYLE_SPHERICAL_GRID_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/SphericalGrid.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to define a cell grid surrounding the projected image of a scene
|
||||||
//
|
* \author Alexander Beels
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 2010-12-19
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef SPHERICALGRID_H
|
#define SPHERICAL_GRID_LOGGING FALSE
|
||||||
#define SPHERICALGRID_H
|
|
||||||
|
|
||||||
#define sphericalgridlogging 0
|
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector> separately results in
|
||||||
|
// redefinitions of identifiers. ViewMap.h already includes <vector> so it should be a safe fall-back.
|
||||||
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector>
|
|
||||||
// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
|
|
||||||
// so it should be a safe fall-back.
|
|
||||||
//#include <vector>
|
//#include <vector>
|
||||||
//#include <deque>
|
//#include <deque>
|
||||||
|
|
||||||
|
#include "GridDensityProvider.h"
|
||||||
|
#include "OccluderSource.h"
|
||||||
#include "ViewMap.h"
|
#include "ViewMap.h"
|
||||||
#include "../winged_edge/WEdge.h"
|
|
||||||
#include "../geometry/Polygon.h"
|
#include "../geometry/Polygon.h"
|
||||||
#include "../system/PointerSequence.h"
|
|
||||||
#include "../geometry/BBox.h"
|
#include "../geometry/BBox.h"
|
||||||
#include "../geometry/GridHelpers.h"
|
#include "../geometry/GridHelpers.h"
|
||||||
#include "OccluderSource.h"
|
|
||||||
#include "GridDensityProvider.h"
|
#include "../system/PointerSequence.h"
|
||||||
|
|
||||||
|
#include "../winged_edge/WEdge.h"
|
||||||
|
|
||||||
class SphericalGrid
|
class SphericalGrid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Helper classes
|
// Helper classes
|
||||||
struct OccluderData {
|
struct OccluderData
|
||||||
|
{
|
||||||
explicit OccluderData (OccluderSource& source, Polygon3r& p);
|
explicit OccluderData (OccluderSource& source, Polygon3r& p);
|
||||||
Polygon3r poly;
|
Polygon3r poly;
|
||||||
Polygon3r cameraSpacePolygon;
|
Polygon3r cameraSpacePolygon;
|
||||||
real shallowest, deepest;
|
real shallowest, deepest;
|
||||||
// N.B. We could, of course, store face in poly's userdata
|
// N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
|
||||||
// member, like the old ViewMapBuilder code does. However,
|
// However, code comments make it clear that userdata is deprecated, so we avoid the temptation to save
|
||||||
// code comments make it clear that userdata is deprecated,
|
// 4 or 8 bytes.
|
||||||
// so we avoid the temptation to save 4 or 8 bytes.
|
WFace *face;
|
||||||
WFace* face;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Cell {
|
struct Cell
|
||||||
|
{
|
||||||
// Can't store Cell in a vector without copy and assign
|
// Can't store Cell in a vector without copy and assign
|
||||||
//Cell(const Cell& other);
|
//Cell(const Cell& other);
|
||||||
//Cell& operator= (const Cell& other);
|
//Cell& operator=(const Cell& other);
|
||||||
|
|
||||||
explicit Cell ();
|
explicit Cell();
|
||||||
~Cell ();
|
~Cell();
|
||||||
|
|
||||||
static bool compareOccludersByShallowestPoint (const OccluderData* a, const OccluderData* b);
|
static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
|
||||||
|
|
||||||
void setDimensions(real x, real y, real sizeX, real sizeY);
|
void setDimensions(real x, real y, real sizeX, real sizeY);
|
||||||
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
|
void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
|
||||||
@@ -84,43 +92,37 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*****
|
/*! Iterator needs to allow the user to avoid full 3D comparison in two cases:
|
||||||
|
*
|
||||||
|
* (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
|
||||||
|
*
|
||||||
|
* (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
|
||||||
|
*
|
||||||
|
* In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an occludee
|
||||||
|
* candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder could
|
||||||
|
* possibly be a better occludee.
|
||||||
|
*/
|
||||||
|
|
||||||
Iterator needs to allow the user to avoid full 3D comparison in
|
class Iterator
|
||||||
two cases:
|
{
|
||||||
|
|
||||||
(1) Where (*current)->deepest < target[2], where the occluder is
|
|
||||||
unambiguously in front of the target point.
|
|
||||||
|
|
||||||
(2) Where (*current)->shallowest > target[2], where the occluder
|
|
||||||
is unambiguously in back of the target point.
|
|
||||||
|
|
||||||
In addition, when used by OptimizedFindOccludee, Iterator should
|
|
||||||
stop iterating as soon as it has an occludee candidate and
|
|
||||||
(*current)->shallowest > candidate[2], because at that point forward
|
|
||||||
no new occluder could possibly be a better occludee.
|
|
||||||
|
|
||||||
*****/
|
|
||||||
|
|
||||||
class Iterator {
|
|
||||||
public:
|
public:
|
||||||
// epsilon is not used in this class, but other grids with the same interface may need an epsilon
|
// epsilon is not used in this class, but other grids with the same interface may need an epsilon
|
||||||
explicit Iterator (SphericalGrid& grid, Vec3r& center, real epsilon=1e-06);
|
explicit Iterator(SphericalGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
|
||||||
~Iterator ();
|
~Iterator();
|
||||||
void initBeforeTarget ();
|
void initBeforeTarget();
|
||||||
void initAfterTarget ();
|
void initAfterTarget();
|
||||||
void nextOccluder ();
|
void nextOccluder();
|
||||||
void nextOccludee ();
|
void nextOccludee();
|
||||||
bool validBeforeTarget();
|
bool validBeforeTarget();
|
||||||
bool validAfterTarget();
|
bool validAfterTarget();
|
||||||
WFace* getWFace() const;
|
WFace *getWFace() const;
|
||||||
Polygon3r* getCameraSpacePolygon();
|
Polygon3r *getCameraSpacePolygon();
|
||||||
void reportDepth(Vec3r origin, Vec3r u, real t);
|
void reportDepth(Vec3r origin, Vec3r u, real t);
|
||||||
private:
|
private:
|
||||||
bool testOccluder(bool wantOccludee);
|
bool testOccluder(bool wantOccludee);
|
||||||
void markCurrentOccludeeCandidate(real depth);
|
void markCurrentOccludeeCandidate(real depth);
|
||||||
|
|
||||||
Cell* _cell;
|
Cell *_cell;
|
||||||
Vec3r _target;
|
Vec3r _target;
|
||||||
bool _foundOccludee;
|
bool _foundOccludee;
|
||||||
real _occludeeDepth;
|
real _occludeeDepth;
|
||||||
@@ -128,33 +130,35 @@ public:
|
|||||||
vector<OccluderData*>::iterator _current, _occludeeCandidate;
|
vector<OccluderData*>::iterator _current, _occludeeCandidate;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Transform : public GridHelpers::Transform {
|
class Transform : public GridHelpers::Transform
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
explicit Transform ();
|
explicit Transform();
|
||||||
explicit Transform (Transform& other);
|
explicit Transform(Transform& other);
|
||||||
Vec3r operator() (const Vec3r& point) const;
|
Vec3r operator()(const Vec3r& point) const;
|
||||||
static Vec3r sphericalProjection(const Vec3r& M);
|
static Vec3r sphericalProjection(const Vec3r& M);
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Prevent implicit copies and assignments.
|
// Prevent implicit copies and assignments.
|
||||||
SphericalGrid(const SphericalGrid& other);
|
SphericalGrid(const SphericalGrid& other);
|
||||||
SphericalGrid& operator= (const SphericalGrid& other);
|
SphericalGrid& operator=(const SphericalGrid& other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SphericalGrid (OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap, Vec3r& viewpoint, bool enableQI);
|
explicit SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
|
||||||
|
Vec3r& viewpoint, bool enableQI);
|
||||||
virtual ~SphericalGrid();
|
virtual ~SphericalGrid();
|
||||||
|
|
||||||
// Generate Cell structure
|
// Generate Cell structure
|
||||||
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
|
void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
|
||||||
// Fill Cells
|
// Fill Cells
|
||||||
void distributePolygons(OccluderSource& source);
|
void distributePolygons(OccluderSource& source);
|
||||||
// Insert one polygon into each matching cell,
|
// Insert one polygon into each matching cell, return true if any cell consumes the polygon
|
||||||
// return true if any cell consumes the polygon
|
|
||||||
bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
|
bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
|
||||||
// Sort occluders in each cell
|
// Sort occluders in each cell
|
||||||
void reorganizeCells();
|
void reorganizeCells();
|
||||||
|
|
||||||
Cell* findCell(const Vec3r& point);
|
Cell *findCell(const Vec3r& point);
|
||||||
|
|
||||||
// Accessors:
|
// Accessors:
|
||||||
bool orthographicProjection() const;
|
bool orthographicProjection() const;
|
||||||
@@ -176,51 +180,52 @@ private:
|
|||||||
bool _enableQI;
|
bool _enableQI;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void SphericalGrid::Iterator::initBeforeTarget () {
|
inline void SphericalGrid::Iterator::initBeforeTarget()
|
||||||
|
{
|
||||||
_current = _cell->faces.begin();
|
_current = _cell->faces.begin();
|
||||||
while ( _current != _cell->faces.end() && ! testOccluder(false) ) {
|
while (_current != _cell->faces.end() && !testOccluder(false)) {
|
||||||
++_current;
|
++_current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SphericalGrid::Iterator::initAfterTarget () {
|
inline void SphericalGrid::Iterator::initAfterTarget()
|
||||||
if ( _foundOccludee ) {
|
{
|
||||||
#if sphericalgridlogging == 1
|
if (_foundOccludee) {
|
||||||
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
|
std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth << std::endl;
|
||||||
#endif
|
#endif
|
||||||
_current = _occludeeCandidate;
|
_current = _occludeeCandidate;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if sphericalgridlogging == 1
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << "\tStarting occludee search from current position" << std::endl;
|
std::cout << "\tStarting occludee search from current position" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while ( _current != _cell->faces.end() && ! testOccluder(true) ) {
|
while (_current != _cell->faces.end() && !testOccluder(true)) {
|
||||||
++_current;
|
++_current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
|
inline bool SphericalGrid::Iterator::testOccluder(bool wantOccludee)
|
||||||
|
{
|
||||||
// End-of-list is not even a valid iterator position
|
// End-of-list is not even a valid iterator position
|
||||||
if ( _current == _cell->faces.end() ) {
|
if (_current == _cell->faces.end()) {
|
||||||
// Returning true seems strange, but it will break us out of whatever loop
|
// Returning true seems strange, but it will break us out of whatever loop is calling testOccluder, and
|
||||||
// is calling testOccluder, and _current=_cell->face.end() will make
|
// _current=_cell->face.end() will make the calling routine give up.
|
||||||
// the calling routine give up.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#if sphericalgridlogging == 1
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
|
std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
|
||||||
for ( unsigned i = 1; i < (*_current)->poly.getVertices().size(); ++i ) {
|
for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
|
||||||
std::cout << ", " << (*_current)->poly.getVertices()[i];
|
std::cout << ", " << (*_current)->poly.getVertices()[i];
|
||||||
}
|
}
|
||||||
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
|
std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// If we have an occluder candidate and we are unambiguously after it, abort
|
// If we have an occluder candidate and we are unambiguously after it, abort
|
||||||
if ( _foundOccludee && (*_current)->shallowest > _occludeeDepth ) {
|
if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
|
||||||
#if sphericalgridlogging == 1
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
|
std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
_current = _cell->faces.end();
|
_current = _cell->faces.end();
|
||||||
@@ -230,16 +235,17 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Specific continue or stop conditions when searching for each type
|
// Specific continue or stop conditions when searching for each type
|
||||||
if ( wantOccludee ) {
|
if (wantOccludee) {
|
||||||
if ( (*_current)->deepest < _target[2] ) {
|
if ((*_current)->deepest < _target[2]) {
|
||||||
#if sphericalgridlogging == 1
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
|
std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if ( (*_current)->shallowest > _target[2] ) {
|
else {
|
||||||
#if sphericalgridlogging == 1
|
if ((*_current)->shallowest > _target[2]) {
|
||||||
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
|
std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
@@ -251,70 +257,73 @@ inline bool SphericalGrid::Iterator::testOccluder (bool wantOccludee) {
|
|||||||
// Check to see if target is in the 2D bounding box
|
// Check to see if target is in the 2D bounding box
|
||||||
Vec3r bbMin, bbMax;
|
Vec3r bbMin, bbMax;
|
||||||
(*_current)->poly.getBBox(bbMin, bbMax);
|
(*_current)->poly.getBBox(bbMin, bbMax);
|
||||||
if ( _target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1] ) {
|
if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
|
||||||
#if sphericalgridlogging == 1
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
|
std::cout << "\t\tSkipping: bounding box violation" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've done all the corner cutting we can.
|
// We've done all the corner cutting we can. Let the caller work out whether or not the geometry is correct.
|
||||||
// Let the caller work out whether or not
|
|
||||||
// the geometry is correct.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SphericalGrid::Iterator::reportDepth (Vec3r origin, Vec3r u, real t) {
|
inline void SphericalGrid::Iterator::reportDepth(Vec3r origin, Vec3r u, real t)
|
||||||
// The reported depth is the length of a ray in camera space
|
{
|
||||||
// We need to convert it into the distance from viewpoint
|
// The reported depth is the length of a ray in camera space. We need to convert it into the distance from viewpoint
|
||||||
// If origin is the viewpoint, depth == t
|
// If origin is the viewpoint, depth == t. A future optimization could allow the caller to tell us if origin is
|
||||||
// A future optimization could allow the caller to tell us if origin is viewponit or target,
|
// viewponit or target, at the cost of changing the OptimizedGrid API.
|
||||||
// at the cost of changing the OptimizedGrid API.
|
|
||||||
real depth = (origin + u * t).norm();
|
real depth = (origin + u * t).norm();
|
||||||
#if sphericalgridlogging == 1
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
|
std::cout << "\t\tReporting depth of occluder/ee: " << depth;
|
||||||
#endif
|
#endif
|
||||||
if ( depth > _target[2] ) {
|
if (depth > _target[2]) {
|
||||||
#if sphericalgridlogging == 1
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << " is deeper than target" << std::endl;
|
std::cout << " is deeper than target" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
// If the current occluder is the best occludee so far, save it.
|
// If the current occluder is the best occludee so far, save it.
|
||||||
if ( ! _foundOccludee || _occludeeDepth > depth ) {
|
if (! _foundOccludee || _occludeeDepth > depth) {
|
||||||
markCurrentOccludeeCandidate(depth);
|
markCurrentOccludeeCandidate(depth);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
#if sphericalgridlogging == 1
|
else {
|
||||||
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SphericalGrid::Iterator::nextOccluder () {
|
inline void SphericalGrid::Iterator::nextOccluder()
|
||||||
if ( _current != _cell->faces.end() ) {
|
{
|
||||||
|
if (_current != _cell->faces.end()) {
|
||||||
do {
|
do {
|
||||||
++_current;
|
++_current;
|
||||||
} while ( _current != _cell->faces.end() && ! testOccluder(false) );
|
} while (_current != _cell->faces.end() && !testOccluder(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SphericalGrid::Iterator::nextOccludee () {
|
inline void SphericalGrid::Iterator::nextOccludee()
|
||||||
if ( _current != _cell->faces.end() ) {
|
{
|
||||||
|
if (_current != _cell->faces.end()) {
|
||||||
do {
|
do {
|
||||||
++_current;
|
++_current;
|
||||||
} while ( _current != _cell->faces.end() && ! testOccluder(true) );
|
} while (_current != _cell->faces.end() && !testOccluder(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SphericalGrid::Iterator::validBeforeTarget () {
|
inline bool SphericalGrid::Iterator::validBeforeTarget()
|
||||||
|
{
|
||||||
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
|
return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SphericalGrid::Iterator::validAfterTarget () {
|
inline bool SphericalGrid::Iterator::validAfterTarget()
|
||||||
|
{
|
||||||
return _current != _cell->faces.end();
|
return _current != _cell->faces.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
|
inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth)
|
||||||
#if sphericalgridlogging == 1
|
{
|
||||||
|
#if SPHERICAL_GRID_LOGGING
|
||||||
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
|
std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
|
||||||
#endif
|
#endif
|
||||||
_occludeeCandidate = _current;
|
_occludeeCandidate = _current;
|
||||||
@@ -322,18 +331,18 @@ inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth) {
|
|||||||
_foundOccludee = true;
|
_foundOccludee = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline WFace* SphericalGrid::Iterator::getWFace() const {
|
inline WFace *SphericalGrid::Iterator::getWFace() const
|
||||||
|
{
|
||||||
return (*_current)->face;
|
return (*_current)->face;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Polygon3r* SphericalGrid::Iterator::getCameraSpacePolygon() {
|
inline Polygon3r *SphericalGrid::Iterator::getCameraSpacePolygon()
|
||||||
|
{
|
||||||
return &((*_current)->cameraSpacePolygon);
|
return &((*_current)->cameraSpacePolygon);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
|
inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
|
||||||
: poly(p),
|
: poly(p), cameraSpacePolygon(source.getCameraSpacePolygon()), face(source.getWFace())
|
||||||
cameraSpacePolygon(source.getCameraSpacePolygon()),
|
|
||||||
face(source.getWFace())
|
|
||||||
{
|
{
|
||||||
const Vec3r viewpoint(0, 0, 0);
|
const Vec3r viewpoint(0, 0, 0);
|
||||||
// Get the point on the camera-space polygon that is closest to the viewpoint
|
// Get the point on the camera-space polygon that is closest to the viewpoint
|
||||||
@@ -343,17 +352,18 @@ inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygo
|
|||||||
// Get the point on the camera-space polygon that is furthest from the viewpoint
|
// Get the point on the camera-space polygon that is furthest from the viewpoint
|
||||||
// deepest is the distance from the viewpoint to that point
|
// deepest is the distance from the viewpoint to that point
|
||||||
deepest = cameraSpacePolygon.getVertices()[2].norm();
|
deepest = cameraSpacePolygon.getVertices()[2].norm();
|
||||||
for ( unsigned i = 0; i < 2; ++i ) {
|
for (unsigned int i = 0; i < 2; ++i) {
|
||||||
real t = cameraSpacePolygon.getVertices()[i].norm();
|
real t = cameraSpacePolygon.getVertices()[i].norm();
|
||||||
if ( t > deepest ) {
|
if (t > deepest) {
|
||||||
deepest = t;
|
deepest = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder) {
|
inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
|
||||||
if ( GridHelpers::insideProscenium (boundary, poly) ) {
|
{
|
||||||
if ( occluder == NULL) {
|
if (GridHelpers::insideProscenium (boundary, poly)) {
|
||||||
|
if (occluder == NULL) {
|
||||||
// Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
|
// Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
|
||||||
// or automatically by SphericalGrid::_faces;
|
// or automatically by SphericalGrid::_faces;
|
||||||
occluder = new OccluderData(source, poly);
|
occluder = new OccluderData(source, poly);
|
||||||
@@ -362,7 +372,8 @@ inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder) {
|
inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
|
||||||
|
{
|
||||||
Polygon3r& poly(source.getGridSpacePolygon());
|
Polygon3r& poly(source.getGridSpacePolygon());
|
||||||
occluder = NULL;
|
occluder = NULL;
|
||||||
|
|
||||||
@@ -373,9 +384,9 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
|
|||||||
getCellCoordinates(bbMin, startX, startY);
|
getCellCoordinates(bbMin, startX, startY);
|
||||||
getCellCoordinates(bbMax, endX, endY);
|
getCellCoordinates(bbMax, endX, endY);
|
||||||
|
|
||||||
for ( unsigned i = startX; i <= endX; ++i ) {
|
for (unsigned int i = startX; i <= endX; ++i) {
|
||||||
for ( unsigned j = startY; j <= endY; ++j ) {
|
for (unsigned int j = startY; j <= endY; ++j) {
|
||||||
if ( _cells[i * _cellsY + j] != NULL ) {
|
if (_cells[i * _cellsY + j] != NULL) {
|
||||||
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
|
_cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -384,5 +395,4 @@ inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*&
|
|||||||
return occluder != NULL;
|
return occluder != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SPHERICALGRID_H
|
#endif // __FREESTYLE_SPHERICAL_GRID_H__
|
||||||
|
|
||||||
|
|||||||
@@ -1,143 +1,168 @@
|
|||||||
//
|
/*
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// with this source distribution.
|
*
|
||||||
//
|
* This program is free software; you can redistribute it and/or
|
||||||
// This program is free software; you can redistribute it and/or
|
* modify it under the terms of the GNU General Public License
|
||||||
// modify it under the terms of the GNU General Public License
|
* as published by the Free Software Foundation; either version 2
|
||||||
// as published by the Free Software Foundation; either version 2
|
* of the License, or (at your option) any later version.
|
||||||
// of the License, or (at your option) any later version.
|
*
|
||||||
//
|
* This program is distributed in the hope that it will be useful,
|
||||||
// This program is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* GNU General Public License for more details.
|
||||||
// GNU General Public License for more details.
|
*
|
||||||
//
|
* You should have received a copy of the GNU General Public License
|
||||||
// You should have received a copy of the GNU General Public License
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
// along with this program; if not, write to the Free Software
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
*
|
||||||
//
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/view_map/SteerbaleViewMap.cpp
|
||||||
|
* \ingroup freestyle
|
||||||
|
* \brief Convenient access to the steerable ViewMap to which any element of the ViewMap belongs to.
|
||||||
|
* \author Stephane Grabli
|
||||||
|
* \date 01/07/2003
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
//soc #include <qimage.h>
|
||||||
|
//soc #include <qstring.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "Silhouette.h"
|
#include "Silhouette.h"
|
||||||
#include "SteerableViewMap.h"
|
#include "SteerableViewMap.h"
|
||||||
|
|
||||||
|
#include "../geometry/Geom.h"
|
||||||
|
|
||||||
#include "../image/ImagePyramid.h"
|
#include "../image/ImagePyramid.h"
|
||||||
#include "../image/Image.h"
|
#include "../image/Image.h"
|
||||||
#include <math.h>
|
|
||||||
#include "../geometry/Geom.h"
|
|
||||||
using namespace Geometry;
|
|
||||||
|
|
||||||
//soc #include <qstring.h>
|
|
||||||
//soc #include <qimage.h>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "IMB_imbuf.h"
|
#include "IMB_imbuf.h"
|
||||||
#include "IMB_imbuf_types.h"
|
#include "IMB_imbuf_types.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
SteerableViewMap::SteerableViewMap(unsigned int nbOrientations){
|
using namespace Geometry;
|
||||||
|
|
||||||
|
SteerableViewMap::SteerableViewMap(unsigned int nbOrientations)
|
||||||
|
{
|
||||||
_nbOrientations = nbOrientations;
|
_nbOrientations = nbOrientations;
|
||||||
_bound = cos(M_PI/(float)_nbOrientations);
|
_bound = cos(M_PI/(float)_nbOrientations);
|
||||||
for(unsigned i=0; i<_nbOrientations; ++i){
|
for (unsigned int i = 0; i < _nbOrientations; ++i) {
|
||||||
_directions.push_back(Vec2d(cos((float)i*M_PI/(float)_nbOrientations), sin((float)i*M_PI/(float)_nbOrientations)));
|
_directions.push_back(Vec2d(cos((float)i * M_PI / (float)_nbOrientations),
|
||||||
|
sin((float)i * M_PI / (float)_nbOrientations)));
|
||||||
}
|
}
|
||||||
Build();
|
Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SteerableViewMap::Build(){
|
void SteerableViewMap::Build()
|
||||||
_imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM
|
{
|
||||||
memset((_imagesPyramids),0,(_nbOrientations+1)*sizeof(ImagePyramid*));
|
_imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
|
||||||
|
memset((_imagesPyramids), 0, (_nbOrientations + 1) * sizeof(ImagePyramid *));
|
||||||
}
|
}
|
||||||
|
|
||||||
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){
|
SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother)
|
||||||
|
{
|
||||||
_nbOrientations = iBrother._nbOrientations;
|
_nbOrientations = iBrother._nbOrientations;
|
||||||
unsigned i;
|
unsigned int i;
|
||||||
_bound = iBrother._bound;
|
_bound = iBrother._bound;
|
||||||
_directions = iBrother._directions;
|
_directions = iBrother._directions;
|
||||||
_mapping = iBrother._mapping;
|
_mapping = iBrother._mapping;
|
||||||
_imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM
|
_imagesPyramids = new ImagePyramid * [_nbOrientations + 1]; // one more map to store the complete visible VM
|
||||||
for(i=0;i<_nbOrientations+1;++i)
|
for (i = 0; i < _nbOrientations + 1; ++i)
|
||||||
_imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
|
_imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
|
||||||
}
|
}
|
||||||
|
|
||||||
SteerableViewMap::~SteerableViewMap(){
|
SteerableViewMap::~SteerableViewMap()
|
||||||
|
{
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SteerableViewMap::Clear(){
|
void SteerableViewMap::Clear()
|
||||||
unsigned i;
|
{
|
||||||
if(_imagesPyramids){
|
unsigned int i;
|
||||||
for(i=0; i<=_nbOrientations; ++i){
|
if (_imagesPyramids) {
|
||||||
if(_imagesPyramids[i])
|
for (i = 0; i <= _nbOrientations; ++i) {
|
||||||
|
if (_imagesPyramids[i])
|
||||||
delete (_imagesPyramids)[i];
|
delete (_imagesPyramids)[i];
|
||||||
}
|
}
|
||||||
delete [] _imagesPyramids;
|
delete[] _imagesPyramids;
|
||||||
_imagesPyramids = 0;
|
_imagesPyramids = 0;
|
||||||
}
|
}
|
||||||
if(!_mapping.empty()){
|
if (!_mapping.empty()) {
|
||||||
for(map<unsigned int, double*>::iterator m=_mapping.begin(), mend=_mapping.end();
|
for (map<unsigned int, double*>::iterator m = _mapping.begin(), mend = _mapping.end(); m != mend; ++m) {
|
||||||
m!=mend;
|
delete[] (*m).second;
|
||||||
++m){
|
|
||||||
delete [] (*m).second;
|
|
||||||
}
|
}
|
||||||
_mapping.clear();
|
_mapping.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SteerableViewMap::Reset(){
|
void SteerableViewMap::Reset()
|
||||||
|
{
|
||||||
Clear();
|
Clear();
|
||||||
Build();
|
Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i){
|
double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i)
|
||||||
double dotp = fabs(dir*_directions[i]);
|
{
|
||||||
if(dotp < _bound)
|
double dotp = fabs(dir * _directions[i]);
|
||||||
return 0;
|
if (dotp < _bound)
|
||||||
if(dotp>1)
|
return 0.0;
|
||||||
dotp = 1;
|
if (dotp > 1.0)
|
||||||
|
dotp = 1.0;
|
||||||
|
|
||||||
return cos((float)_nbOrientations/2.0*acos(dotp));
|
return cos((float)_nbOrientations / 2.0 * acos(dotp));
|
||||||
}
|
}
|
||||||
|
|
||||||
double * SteerableViewMap::AddFEdge(FEdge *iFEdge){
|
double *SteerableViewMap::AddFEdge(FEdge *iFEdge)
|
||||||
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned id = iFEdge->getId().getFirst();
|
unsigned id = iFEdge->getId().getFirst();
|
||||||
map<unsigned int, double* >::iterator o = _mapping.find(id);
|
map<unsigned int, double* >::iterator o = _mapping.find(id);
|
||||||
if(o!=_mapping.end()){
|
if (o != _mapping.end()) {
|
||||||
return (*o).second;
|
return (*o).second;
|
||||||
}
|
}
|
||||||
double * res = new double[_nbOrientations];
|
double *res = new double[_nbOrientations];
|
||||||
for(i=0; i<_nbOrientations; ++i){
|
for (i = 0; i < _nbOrientations; ++i) {
|
||||||
res[i] = 0;
|
res[i] = 0.0;
|
||||||
}
|
}
|
||||||
Vec3r o2d3 = iFEdge->orientation2d();
|
Vec3r o2d3 = iFEdge->orientation2d();
|
||||||
Vec2r o2d2(o2d3.x(), o2d3.y());
|
Vec2r o2d2(o2d3.x(), o2d3.y());
|
||||||
real norm = o2d2.norm();
|
real norm = o2d2.norm();
|
||||||
if(norm < 1e-6){
|
if (norm < 1.0e-6) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
o2d2/=norm;
|
o2d2 /= norm;
|
||||||
|
|
||||||
for(i=0; i<_nbOrientations; ++i){
|
for (i = 0; i < _nbOrientations; ++i) {
|
||||||
res[i] = ComputeWeight(o2d2, i);
|
res[i] = ComputeWeight(o2d2, i);
|
||||||
}
|
}
|
||||||
_mapping[id] = res;
|
_mapping[id] = res;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){
|
unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient)
|
||||||
|
{
|
||||||
Vec2f dir(orient);
|
Vec2f dir(orient);
|
||||||
//soc unsigned res = 0;
|
//soc unsigned res = 0;
|
||||||
real norm = dir.norm();
|
real norm = dir.norm();
|
||||||
if(norm < 1e-6){
|
if (norm < 1.0e-6) {
|
||||||
return _nbOrientations+1;
|
return _nbOrientations + 1;
|
||||||
}
|
}
|
||||||
dir/=norm;
|
dir /= norm;
|
||||||
double maxw = 0.f;
|
double maxw = 0.0f;
|
||||||
unsigned winner = _nbOrientations+1;
|
unsigned winner = _nbOrientations + 1;
|
||||||
for(unsigned i=0; i<_nbOrientations; ++i){
|
for (unsigned int i = 0; i < _nbOrientations; ++i) {
|
||||||
double w = ComputeWeight(dir, i);
|
double w = ComputeWeight(dir, i);
|
||||||
if(w>maxw){
|
if (w > maxw) {
|
||||||
maxw = w;
|
maxw = w;
|
||||||
winner = i;
|
winner = i;
|
||||||
}
|
}
|
||||||
@@ -145,31 +170,32 @@ unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){
|
|||||||
return winner;
|
return winner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned SteerableViewMap::getSVMNumber(unsigned id)
|
||||||
unsigned SteerableViewMap::getSVMNumber(unsigned id){
|
{
|
||||||
map<unsigned int, double* >::iterator o = _mapping.find(id);
|
map<unsigned int, double* >::iterator o = _mapping.find(id);
|
||||||
if(o!=_mapping.end()){
|
if (o != _mapping.end()) {
|
||||||
double* wvalues= (*o).second;
|
double *wvalues = (*o).second;
|
||||||
double maxw = 0.f;
|
double maxw = 0.0;
|
||||||
unsigned winner = _nbOrientations+1;
|
unsigned winner = _nbOrientations + 1;
|
||||||
for(unsigned i=0; i<_nbOrientations; ++i){
|
for (unsigned i = 0; i < _nbOrientations; ++i) {
|
||||||
double w = wvalues[i];
|
double w = wvalues[i];
|
||||||
if(w>maxw){
|
if (w > maxw) {
|
||||||
maxw = w;
|
maxw = w;
|
||||||
winner = i;
|
winner = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return winner;
|
return winner;
|
||||||
}
|
}
|
||||||
return _nbOrientations+1;
|
return _nbOrientations + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma){
|
void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma)
|
||||||
for(unsigned i=0; i<=_nbOrientations; ++i){
|
{
|
||||||
ImagePyramid * svm = (_imagesPyramids)[i];
|
for (unsigned int i = 0; i <= _nbOrientations; ++i) {
|
||||||
if(svm)
|
ImagePyramid *svm = (_imagesPyramids)[i];
|
||||||
|
if (svm)
|
||||||
delete svm;
|
delete svm;
|
||||||
if(copy)
|
if (copy)
|
||||||
svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma);
|
svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma);
|
||||||
else
|
else
|
||||||
svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma);
|
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];
|
ImagePyramid *pyramid = _imagesPyramids[iOrientation];
|
||||||
if(pyramid==0){
|
if (pyramid == 0) {
|
||||||
cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
|
cout << "Warning: this steerable ViewMap level doesn't exist" << endl;
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
//float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)*255.f;
|
//float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) * 255.0f;
|
||||||
float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)/32.f; // we encode both the directionality and the lines counting on 8 bits
|
// We encode both the directionality and the lines counting on 8 bits (because of frame buffer). Thus, we allow
|
||||||
// (because of frame buffer). Thus, we allow until 8 lines to pass through
|
// until 8 lines to pass through the same pixel, so that we can discretize the Pi/_nbOrientations angle into
|
||||||
// the same pixel, so that we can discretize the Pi/_nbOrientations angle into
|
// 32 slices. Therefore, for example, in the vertical direction, a vertical line will have the value 32 on
|
||||||
// 32 slices. Therefore, for example, in the vertical direction, a vertical line
|
// each pixel it passes through.
|
||||||
// will have the value 32 on each pixel it passes through.
|
float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) / 32.0f;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y){
|
float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y)
|
||||||
return readSteerableViewMapPixel(_nbOrientations,iLevel,x,y);
|
{
|
||||||
|
return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int SteerableViewMap::getNumberOfPyramidLevels() const{
|
unsigned int SteerableViewMap::getNumberOfPyramidLevels() const
|
||||||
if(_imagesPyramids[0])
|
{
|
||||||
|
if (_imagesPyramids[0])
|
||||||
return _imagesPyramids[0]->getNumberOfLevels();
|
return _imagesPyramids[0]->getNumberOfLevels();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SteerableViewMap::saveSteerableViewMap() const {
|
void SteerableViewMap::saveSteerableViewMap() const
|
||||||
for(unsigned i=0; i<=_nbOrientations; ++i){
|
{
|
||||||
if(_imagesPyramids[i] == 0){
|
for (unsigned int i = 0; i <= _nbOrientations; ++i) {
|
||||||
cerr << "SteerableViewMap warning: orientation " << i <<" of steerable View Map whas not been computed yet" << endl;
|
if (_imagesPyramids[i] == 0) {
|
||||||
|
cerr << "SteerableViewMap warning: orientation " << i
|
||||||
|
<< " of steerable View Map whas not been computed yet" << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int ow = _imagesPyramids[i]->width(0);
|
int ow = _imagesPyramids[i]->width(0);
|
||||||
@@ -217,22 +248,22 @@ void SteerableViewMap::saveSteerableViewMap() const {
|
|||||||
string base("SteerableViewMap");
|
string base("SteerableViewMap");
|
||||||
stringstream filename;
|
stringstream filename;
|
||||||
|
|
||||||
for(int j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ //soc
|
for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc
|
||||||
float coeff = 1;//1/255.f; //100*255;//*pow(2,j);
|
float coeff = 1.0f; // 1 / 255.0f; // 100 * 255; // * pow(2, j);
|
||||||
//soc QImage qtmp(ow, oh, QImage::Format_RGB32);
|
//soc QImage qtmp(ow, oh, QImage::Format_RGB32);
|
||||||
ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
|
ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
|
||||||
int rowbytes = ow*4;
|
int rowbytes = ow * 4;
|
||||||
char *pix;
|
char *pix;
|
||||||
|
|
||||||
for(int y=0;y<oh;++y){ //soc
|
for (int y = 0; y < oh; ++y) { //soc
|
||||||
for(int x=0;x<ow;++x){ //soc
|
for (int x = 0; x < ow; ++x) { //soc
|
||||||
int c = (int)(coeff*_imagesPyramids[i]->pixel(x,y,j));
|
int c = (int)(coeff * _imagesPyramids[i]->pixel(x, y, j));
|
||||||
if(c>255)
|
if (c > 255)
|
||||||
c=255;
|
c = 255;
|
||||||
//int c = (int)(_imagesPyramids[i]->pixel(x,y,j));
|
//int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
|
||||||
|
|
||||||
//soc qtmp.setPixel(x,y,qRgb(c,c,c));
|
//soc qtmp.setPixel(x, y, qRgb(c, c, c));
|
||||||
pix = (char*)ibuf->rect + y*rowbytes + x*4;
|
pix = (char*)ibuf->rect + y * rowbytes + x * 4;
|
||||||
pix[0] = pix [1] = pix[2] = c;
|
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");
|
//soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
|
||||||
filename << base;
|
filename << base;
|
||||||
filename << i << "-" << j << ".png";
|
filename << i << "-" << j << ".png";
|
||||||
ibuf->ftype= PNG;
|
ibuf->ftype = PNG;
|
||||||
IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0);
|
IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
// QString base("SteerableViewMap");
|
#if 0
|
||||||
// for(unsigned j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){
|
QString base("SteerableViewMap");
|
||||||
// GrayImage * img = _imagesPyramids[i]->getLevel(j);
|
for (unsigned j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) {
|
||||||
// int ow = img->width();
|
GrayImage *img = _imagesPyramids[i]->getLevel(j);
|
||||||
// int oh = img->height();
|
int ow = img->width();
|
||||||
// float coeff = 1; //100*255;//*pow(2,j);
|
int oh = img->height();
|
||||||
// QImage qtmp(ow, oh, 32);
|
float coeff = 1.0f; // 100 * 255; // * pow(2, j);
|
||||||
// for(unsigned y=0;y<oh;++y){
|
QImage qtmp(ow, oh, 32);
|
||||||
// for(unsigned x=0;x<ow;++x){
|
for (unsigned int y = 0; y < oh; ++y) {
|
||||||
// int c = (int)(coeff*img->pixel(x,y));
|
for (unsigned int x = 0; x < ow; ++x) {
|
||||||
// if(c>255)
|
int c = (int)(coeff * img->pixel(x, y));
|
||||||
// c=255;
|
if (c > 255)
|
||||||
// //int c = (int)(_imagesPyramids[i]->pixel(x,y,j));
|
c = 255;
|
||||||
// qtmp.setPixel(x,y,qRgb(c,c,c));
|
//int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
|
||||||
// }
|
qtmp.setPixel(x, y, qRgb(c, c, c));
|
||||||
// }
|
}
|
||||||
// qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG");
|
}
|
||||||
// }
|
qtmp.save(base + QString::number(i) + "-" + QString::number(j) + ".png", "PNG");
|
||||||
//
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,46 @@
|
|||||||
//
|
/*
|
||||||
// Filename : SteerbaleViewMap.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Purpose : Convenient access to the steerable ViewMap
|
* This program is free software; you can redistribute it and/or
|
||||||
// to which any element of the ViewMap belongs to.
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 01/07/2003
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_STEERABLE_VIEW_MAP_H__
|
||||||
|
#define __FREESTYLE_STEERABLE_VIEW_MAP_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/SteerbaleViewMap.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Convenient access to the steerable ViewMap to which any element of the ViewMap belongs to.
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 01/07/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#ifndef STEERABLEVIEWMAP_H
|
|
||||||
# define STEERABLEVIEWMAP_H
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "../system/FreestyleConfig.h"
|
|
||||||
#include "../geometry/Geom.h"
|
#include "../geometry/Geom.h"
|
||||||
|
|
||||||
|
#include "../system/FreestyleConfig.h"
|
||||||
|
|
||||||
using namespace Geometry;
|
using namespace Geometry;
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -40,13 +48,16 @@ using namespace std;
|
|||||||
class FEdge;
|
class FEdge;
|
||||||
class ImagePyramid;
|
class ImagePyramid;
|
||||||
class GrayImage;
|
class GrayImage;
|
||||||
/*! This class checks for every FEdge in which steerable
|
|
||||||
* it belongs and stores the mapping allowing to retrieve
|
/*! This class checks for every FEdge in which steerable it belongs and stores the mapping allowing to retrieve
|
||||||
* this information from the FEdge Id
|
* this information from the FEdge Id.
|
||||||
*/
|
*/
|
||||||
class LIB_VIEW_MAP_EXPORT SteerableViewMap{
|
class LIB_VIEW_MAP_EXPORT SteerableViewMap
|
||||||
|
{
|
||||||
protected:
|
protected:
|
||||||
map<unsigned int, double* > _mapping; // for each vector the list of nbOrientations weigths corresponding to its contributions to the nbOrientations directional maps
|
// for each vector the list of nbOrientations weigths corresponding to its contributions
|
||||||
|
// to the nbOrientations directional maps
|
||||||
|
map<unsigned int, double*> _mapping;
|
||||||
unsigned _nbOrientations;
|
unsigned _nbOrientations;
|
||||||
ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM
|
ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM
|
||||||
|
|
||||||
@@ -63,45 +74,40 @@ public:
|
|||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
|
|
||||||
/*! Adds a FEdge to steerable VM.
|
/*! Adds a FEdge to steerable VM.
|
||||||
* Returns the nbOrientations weigths corresponding to
|
* Returns the nbOrientations weigths corresponding to the FEdge contributions to the nbOrientations
|
||||||
* the FEdge contributions to the nbOrientations directional maps.
|
* directional maps.
|
||||||
*/
|
*/
|
||||||
double* AddFEdge(FEdge *iFEdge);
|
double *AddFEdge(FEdge *iFEdge);
|
||||||
|
|
||||||
/*! Compute the weight of direction dir for orientation iNOrientation */
|
/*! Compute the weight of direction dir for orientation iNOrientation */
|
||||||
double ComputeWeight(const Vec2d& dir, unsigned iNOrientation);
|
double ComputeWeight(const Vec2d& dir, unsigned iNOrientation);
|
||||||
|
|
||||||
/*! Returns the number of the SVM to which a direction belongs
|
/*! Returns the number of the SVM to which a direction belongs to.
|
||||||
* to.
|
|
||||||
* \param dir
|
* \param dir
|
||||||
* The direction
|
* The direction
|
||||||
*/
|
*/
|
||||||
unsigned getSVMNumber(const Vec2f& dir);
|
unsigned getSVMNumber(const Vec2f& dir);
|
||||||
|
|
||||||
/*! Returns the number of the SVM to which a FEdge belongs
|
/*! Returns the number of the SVM to which a FEdge belongs most.
|
||||||
* most.
|
|
||||||
* \param id
|
* \param id
|
||||||
* The First element of the Id struct of the FEdge
|
* The First element of the Id struct of the FEdge we're intersted in.
|
||||||
* we're intersted in.
|
|
||||||
*/
|
*/
|
||||||
unsigned getSVMNumber(unsigned id);
|
unsigned getSVMNumber(unsigned id);
|
||||||
|
|
||||||
/*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images
|
/*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images of the steerable viewmap.
|
||||||
* of the steerable viewmap.
|
|
||||||
* \param steerableBases
|
* \param steerableBases
|
||||||
* The _nbOrientations+1 images constituing the basis for the steerable
|
* The _nbOrientations+1 images constituing the basis for the steerable pyramid.
|
||||||
* pyramid.
|
|
||||||
* \param copy
|
* \param copy
|
||||||
* If false, the data is not duplicated, and Canvas deals
|
* If false, the data is not duplicated, and Canvas deals with the memory management of these
|
||||||
* with the memory management of these _nbOrientations+1 images. If true, data
|
* _nbOrientations+1 images. If true, data is copied, and it's up to the caller to delete the images.
|
||||||
* is copied, and it's up to the caller to delete the images.
|
|
||||||
* \params iNbLevels
|
* \params iNbLevels
|
||||||
* The number of levels desired for each pyramid.
|
* The number of levels desired for each pyramid.
|
||||||
* If iNbLevels == 0, the complete pyramid is built.
|
* If iNbLevels == 0, the complete pyramid is built.
|
||||||
* \param iSigma
|
* \param iSigma
|
||||||
* The sigma that will be used for the gaussian blur
|
* The sigma that will be used for the gaussian blur
|
||||||
*/
|
*/
|
||||||
void buildImagesPyramids(GrayImage **steerableBases, bool copy = false, unsigned iNbLevels=4, float iSigma = 1.f);
|
void buildImagesPyramids(GrayImage **steerableBases, bool copy = false, unsigned iNbLevels = 4,
|
||||||
|
float iSigma = 1.0f);
|
||||||
|
|
||||||
/*! Reads a pixel value in one of the VewMap density steerable pyramids.
|
/*! Reads a pixel value in one of the VewMap density steerable pyramids.
|
||||||
* Returns a value between 0 and 1.
|
* Returns a value between 0 and 1.
|
||||||
@@ -116,19 +122,15 @@ public:
|
|||||||
* \param iLevel
|
* \param iLevel
|
||||||
* The level of the pyramid we want to read
|
* The level of the pyramid we want to read
|
||||||
* \param x
|
* \param x
|
||||||
* The abscissa of the desired pixel specified in level0 coordinate
|
* The abscissa of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
|
||||||
* system. The origin is the lower left corner.
|
|
||||||
* \param y
|
* \param y
|
||||||
* The ordinate of the desired pixel specified in level0 coordinate
|
* The ordinate of the desired pixel specified in level0 coordinate system. The origin is the lower left corner.
|
||||||
* system. The origin is the lower left corner.
|
|
||||||
*/
|
*/
|
||||||
float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y);
|
float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y);
|
||||||
|
|
||||||
/*! Reads a pixel in the one of the level of the
|
/*! Reads a pixel in the one of the level of the pyramid containing the images of the complete ViewMap.
|
||||||
* pyramid containing the images of the complete
|
|
||||||
* ViewMap.
|
|
||||||
* Returns a value between 0 and 1.
|
* Returns a value between 0 and 1.
|
||||||
* Equivalent to : readSteerableViewMapPixel(nbOrientations, x,y)
|
* Equivalent to : readSteerableViewMapPixel(nbOrientations, x, y)
|
||||||
*/
|
*/
|
||||||
float readCompleteViewMapPixel(int iLevel, int x, int y);
|
float readCompleteViewMapPixel(int iLevel, int x, int y);
|
||||||
|
|
||||||
@@ -136,18 +138,17 @@ public:
|
|||||||
unsigned int getNumberOfPyramidLevels() const;
|
unsigned int getNumberOfPyramidLevels() const;
|
||||||
|
|
||||||
/*! Returns the number of orientations */
|
/*! Returns the number of orientations */
|
||||||
unsigned int getNumberOfOrientations() const{
|
unsigned int getNumberOfOrientations() const
|
||||||
|
{
|
||||||
return _nbOrientations;
|
return _nbOrientations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! for debug purposes */
|
/*! for debug purposes */
|
||||||
void saveSteerableViewMap() const ;
|
void saveSteerableViewMap() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Clear();
|
void Clear();
|
||||||
void Build();
|
void Build();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STEERABLEVIEWMAP_H
|
#endif // __FREESTYLE_STEERABLE_VIEW_MAP_H__
|
||||||
|
|||||||
@@ -1,81 +1,92 @@
|
|||||||
//
|
/*
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// with this source distribution.
|
*
|
||||||
//
|
* This program is free software; you can redistribute it and/or
|
||||||
// This program is free software; you can redistribute it and/or
|
* modify it under the terms of the GNU General Public License
|
||||||
// modify it under the terms of the GNU General Public License
|
* as published by the Free Software Foundation; either version 2
|
||||||
// as published by the Free Software Foundation; either version 2
|
* of the License, or (at your option) any later version.
|
||||||
// of the License, or (at your option) any later version.
|
*
|
||||||
//
|
* This program is distributed in the hope that it will be useful,
|
||||||
// This program is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* GNU General Public License for more details.
|
||||||
// GNU General Public License for more details.
|
*
|
||||||
//
|
* You should have received a copy of the GNU General Public License
|
||||||
// You should have received a copy of the GNU General Public License
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
// along with this program; if not, write to the Free Software
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
*
|
||||||
//
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
|
||||||
|
* \ingroup freestyle
|
||||||
|
* \brief Class to build view edges and the underlying chains of feature edges...
|
||||||
|
* \author Stephane Grabli
|
||||||
|
* \date 27/10/2003
|
||||||
|
*/
|
||||||
|
|
||||||
#include "ViewMap.h"
|
|
||||||
#include "ViewEdgeXBuilder.h"
|
|
||||||
#include "../winged_edge/WXEdge.h"
|
|
||||||
#include "SilhouetteGeomEngine.h"
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#include "SilhouetteGeomEngine.h"
|
||||||
|
#include "ViewEdgeXBuilder.h"
|
||||||
|
#include "ViewMap.h"
|
||||||
|
|
||||||
|
#include "../winged_edge/WXEdge.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void ViewEdgeXBuilder::Init(ViewShape *oVShape){
|
void ViewEdgeXBuilder::Init(ViewShape *oVShape)
|
||||||
if(0 == oVShape)
|
{
|
||||||
|
if (0 == oVShape)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// for design conveniance, we store the current SShape.
|
// for design conveniance, we store the current SShape.
|
||||||
_pCurrentSShape = oVShape->sshape();
|
_pCurrentSShape = oVShape->sshape();
|
||||||
if(0 == _pCurrentSShape)
|
if (0 == _pCurrentSShape)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_pCurrentVShape = oVShape;
|
_pCurrentVShape = oVShape;
|
||||||
|
|
||||||
// Reset previous data
|
// Reset previous data
|
||||||
//--------------------
|
//--------------------
|
||||||
if(!_SVertexMap.empty())
|
if (!_SVertexMap.empty())
|
||||||
_SVertexMap.clear();
|
_SVertexMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewEdgeXBuilder::BuildViewEdges( WXShape *iWShape, ViewShape *oVShape,
|
void ViewEdgeXBuilder::BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, vector<ViewEdge*>& ioVEdges,
|
||||||
vector<ViewEdge*>& ioVEdges,
|
vector<ViewVertex*>& ioVVertices, vector<FEdge*>& ioFEdges,
|
||||||
vector<ViewVertex*>& ioVVertices,
|
vector<SVertex*>& ioSVertices)
|
||||||
vector<FEdge*>& ioFEdges,
|
{
|
||||||
vector<SVertex*>& ioSVertices){
|
|
||||||
// Reinit structures
|
// Reinit structures
|
||||||
Init(oVShape);
|
Init(oVShape);
|
||||||
|
|
||||||
ViewEdge *vedge ;
|
ViewEdge *vedge;
|
||||||
// Let us build the smooth stuff
|
// Let us build the smooth stuff
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
// We parse all faces to find the ones
|
// We parse all faces to find the ones that contain smooth edges
|
||||||
// that contain smooth edges
|
|
||||||
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
vector<WFace*>& wfaces = iWShape->GetFaceList();
|
||||||
vector<WFace*>::iterator wf, wfend;
|
vector<WFace*>::iterator wf, wfend;
|
||||||
WXFace *wxf;
|
WXFace *wxf;
|
||||||
for(wf=wfaces.begin(), wfend=wfaces.end();
|
for (wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; wf++) {
|
||||||
wf!=wfend;
|
|
||||||
wf++){
|
|
||||||
wxf = dynamic_cast<WXFace*>(*wf);
|
wxf = dynamic_cast<WXFace*>(*wf);
|
||||||
if(false == ((wxf))->hasSmoothEdges()) // does it contain at least one smooth edge ?
|
if (false == ((wxf))->hasSmoothEdges()) // does it contain at least one smooth edge ?
|
||||||
continue;
|
continue;
|
||||||
// parse all smooth layers:
|
// parse all smooth layers:
|
||||||
vector<WXFaceLayer*>& smoothLayers = wxf->getSmoothLayers();
|
vector<WXFaceLayer*>& smoothLayers = wxf->getSmoothLayers();
|
||||||
for(vector<WXFaceLayer*>::iterator sl = smoothLayers.begin(), slend=smoothLayers.end();
|
for (vector<WXFaceLayer*>::iterator sl = smoothLayers.begin(), slend = smoothLayers.end(); sl != slend; ++sl) {
|
||||||
sl!=slend;
|
if (!(*sl)->hasSmoothEdge())
|
||||||
++sl){
|
|
||||||
if(!(*sl)->hasSmoothEdge())
|
|
||||||
continue;
|
continue;
|
||||||
if(stopSmoothViewEdge((*sl))) // has it been parsed already ?
|
if (stopSmoothViewEdge((*sl))) // has it been parsed already ?
|
||||||
continue;
|
continue;
|
||||||
// here we know that we're dealing with a face layer that has not been
|
// here we know that we're dealing with a face layer that has not been processed yet and that contains
|
||||||
// processed yet and that contains a smooth edge.
|
// a smooth edge.
|
||||||
vedge = BuildSmoothViewEdge(OWXFaceLayer(*sl, true));
|
vedge = BuildSmoothViewEdge(OWXFaceLayer(*sl, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,22 +97,19 @@ void ViewEdgeXBuilder::BuildViewEdges( WXShape *iWShape, ViewShape *oVShape,
|
|||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
//iWShape->ResetUserData();
|
//iWShape->ResetUserData();
|
||||||
|
|
||||||
WXEdge * wxe;
|
WXEdge *wxe;
|
||||||
vector<WEdge*>& wedges = iWShape->getEdgeList();
|
vector<WEdge*>& wedges = iWShape->getEdgeList();
|
||||||
//
|
|
||||||
//------------------------------
|
//------------------------------
|
||||||
for(vector<WEdge*>::iterator we=wedges.begin(),weend=wedges.end();
|
for (vector<WEdge*>::iterator we = wedges.begin(), weend = wedges.end(); we != weend; we++) {
|
||||||
we!=weend;
|
|
||||||
we++){
|
|
||||||
wxe = dynamic_cast<WXEdge*>(*we);
|
wxe = dynamic_cast<WXEdge*>(*we);
|
||||||
if(Nature::NO_FEATURE == wxe->nature())
|
if (Nature::NO_FEATURE == wxe->nature())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(!stopSharpViewEdge(wxe)){
|
if (!stopSharpViewEdge(wxe)) {
|
||||||
bool b=true;
|
bool b = true;
|
||||||
if(wxe->order() == -1)
|
if (wxe->order() == -1)
|
||||||
b = false;
|
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());
|
ioSVertices.insert(ioSVertices.end(), newVertices.begin(), newVertices.end());
|
||||||
ioVVertices.insert(ioVVertices.end(), newVVertices.begin(), newVVertices.end());
|
ioVVertices.insert(ioVVertices.end(), newVVertices.begin(), newVVertices.end());
|
||||||
ioVEdges.insert(ioVEdges.end(), newVEdges.begin(), newVEdges.end());
|
ioVEdges.insert(ioVEdges.end(), newVEdges.begin(), newVEdges.end());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer){
|
ViewEdge *ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
|
||||||
|
{
|
||||||
// Find first edge:
|
// Find first edge:
|
||||||
OWXFaceLayer first = iFaceLayer;
|
OWXFaceLayer first = iFaceLayer;
|
||||||
OWXFaceLayer currentFace = first;
|
OWXFaceLayer currentFace = first;
|
||||||
@@ -133,51 +141,48 @@ ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
|
|||||||
// first direction
|
// first direction
|
||||||
list<OWXFaceLayer> facesChain;
|
list<OWXFaceLayer> facesChain;
|
||||||
unsigned size = 0;
|
unsigned size = 0;
|
||||||
while(!stopSmoothViewEdge(currentFace.fl)){
|
while (!stopSmoothViewEdge(currentFace.fl)) {
|
||||||
facesChain.push_back(currentFace);
|
facesChain.push_back(currentFace);
|
||||||
++size;
|
++size;
|
||||||
currentFace.fl->userdata = (void*)1; // processed
|
currentFace.fl->userdata = (void *)1; // processed
|
||||||
// Find the next edge!
|
// Find the next edge!
|
||||||
currentFace = FindNextFaceLayer(currentFace);
|
currentFace = FindNextFaceLayer(currentFace);
|
||||||
}
|
}
|
||||||
OWXFaceLayer end = facesChain.back();
|
OWXFaceLayer end = facesChain.back();
|
||||||
// second direction
|
// second direction
|
||||||
currentFace = FindPreviousFaceLayer(first);
|
currentFace = FindPreviousFaceLayer(first);
|
||||||
while(!stopSmoothViewEdge(currentFace.fl)){
|
while (!stopSmoothViewEdge(currentFace.fl)) {
|
||||||
facesChain.push_front(currentFace);
|
facesChain.push_front(currentFace);
|
||||||
++size;
|
++size;
|
||||||
currentFace.fl->userdata = (void*)1; // processed
|
currentFace.fl->userdata = (void *)1; // processed
|
||||||
// Find the previous edge!
|
// Find the previous edge!
|
||||||
currentFace = FindPreviousFaceLayer(currentFace);
|
currentFace = FindPreviousFaceLayer(currentFace);
|
||||||
}
|
}
|
||||||
first = facesChain.front();
|
first = facesChain.front();
|
||||||
|
|
||||||
if(iFaceLayer.fl->nature() & Nature::RIDGE){
|
if (iFaceLayer.fl->nature() & Nature::RIDGE) {
|
||||||
if(size<4){
|
if (size < 4) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a new chain edges
|
// Start a new chain edges
|
||||||
ViewEdge * newVEdge = new ViewEdge;
|
ViewEdge *newVEdge = new ViewEdge;
|
||||||
newVEdge->setId(_currentViewId);
|
newVEdge->setId(_currentViewId);
|
||||||
++_currentViewId;
|
++_currentViewId;
|
||||||
|
|
||||||
_pCurrentVShape->AddEdge(newVEdge);
|
_pCurrentVShape->AddEdge(newVEdge);
|
||||||
|
|
||||||
|
|
||||||
// build FEdges
|
// build FEdges
|
||||||
FEdge * feprevious = 0;
|
FEdge *feprevious = NULL;
|
||||||
FEdge * fefirst = 0;
|
FEdge *fefirst = NULL;
|
||||||
FEdge * fe = 0;
|
FEdge *fe = NULL;
|
||||||
for(list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend=facesChain.end();
|
for (list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend = facesChain.end(); fl != flend; ++fl) {
|
||||||
fl!=flend;
|
|
||||||
++fl){
|
|
||||||
fe = BuildSmoothFEdge(feprevious, (*fl));
|
fe = BuildSmoothFEdge(feprevious, (*fl));
|
||||||
if (feprevious && fe == feprevious)
|
if (feprevious && fe == feprevious)
|
||||||
continue;
|
continue;
|
||||||
fe->setViewEdge(newVEdge);
|
fe->setViewEdge(newVEdge);
|
||||||
if(!fefirst)
|
if (!fefirst)
|
||||||
fefirst = fe;
|
fefirst = fe;
|
||||||
feprevious = fe;
|
feprevious = fe;
|
||||||
}
|
}
|
||||||
@@ -188,12 +193,13 @@ ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
|
|||||||
newVEdge->setFEdgeB(fe);
|
newVEdge->setFEdgeB(fe);
|
||||||
|
|
||||||
// is it a closed loop ?
|
// is it a closed loop ?
|
||||||
if((first == end) && (size != 1)){
|
if ((first == end) && (size != 1)) {
|
||||||
fefirst->setPreviousEdge(fe);
|
fefirst->setPreviousEdge(fe);
|
||||||
fe->setNextEdge(fefirst);
|
fe->setNextEdge(fefirst);
|
||||||
newVEdge->setA(0);
|
newVEdge->setA(0);
|
||||||
newVEdge->setB(0);
|
newVEdge->setB(0);
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
|
ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
|
||||||
ViewVertex *vvb = MakeViewVertex(fe->vertexB());
|
ViewVertex *vvb = MakeViewVertex(fe->vertexB());
|
||||||
|
|
||||||
@@ -207,12 +213,13 @@ ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
|
|||||||
return newVEdge;
|
return newVEdge;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
|
ViewEdge *ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge)
|
||||||
|
{
|
||||||
// Start a new sharp chain edges
|
// Start a new sharp chain edges
|
||||||
ViewEdge * newVEdge = new ViewEdge;
|
ViewEdge *newVEdge = new ViewEdge;
|
||||||
newVEdge->setId(_currentViewId);
|
newVEdge->setId(_currentViewId);
|
||||||
++_currentViewId;
|
++_currentViewId;
|
||||||
unsigned size=0;
|
unsigned size = 0;
|
||||||
|
|
||||||
_pCurrentVShape->AddEdge(newVEdge);
|
_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. */
|
#if 0 /* TK 02-Sep-2012 Experimental fix for incorrect view edge visibility. */
|
||||||
// bidirectional chaining
|
// bidirectional chaining
|
||||||
// first direction:
|
// first direction:
|
||||||
while(!stopSharpViewEdge(currentWEdge.e)){
|
while (!stopSharpViewEdge(currentWEdge.e)) {
|
||||||
edgesChain.push_back(currentWEdge);
|
edgesChain.push_back(currentWEdge);
|
||||||
++size;
|
++size;
|
||||||
currentWEdge.e->userdata = (void*)1; // processed
|
currentWEdge.e->userdata = (void *)1; // processed
|
||||||
// Find the next edge!
|
// Find the next edge!
|
||||||
currentWEdge = FindNextWEdge(currentWEdge);
|
currentWEdge = FindNextWEdge(currentWEdge);
|
||||||
}
|
}
|
||||||
OWXEdge endWEdge = edgesChain.back();
|
OWXEdge endWEdge = edgesChain.back();
|
||||||
// second direction
|
// second direction
|
||||||
currentWEdge = FindPreviousWEdge(firstWEdge);
|
currentWEdge = FindPreviousWEdge(firstWEdge);
|
||||||
while(!stopSharpViewEdge(currentWEdge.e)){
|
while (!stopSharpViewEdge(currentWEdge.e)) {
|
||||||
edgesChain.push_front(currentWEdge);
|
edgesChain.push_front(currentWEdge);
|
||||||
++size;
|
++size;
|
||||||
currentWEdge.e->userdata = (void*)1; // processed
|
currentWEdge.e->userdata = (void *)1; // processed
|
||||||
// Find the previous edge!
|
// Find the previous edge!
|
||||||
currentWEdge = FindPreviousWEdge(currentWEdge);
|
currentWEdge = FindPreviousWEdge(currentWEdge);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
edgesChain.push_back(currentWEdge);
|
edgesChain.push_back(currentWEdge);
|
||||||
++size;
|
++size;
|
||||||
currentWEdge.e->userdata = (void*)1; // processed
|
currentWEdge.e->userdata = (void *)1; // processed
|
||||||
OWXEdge endWEdge = edgesChain.back();
|
OWXEdge endWEdge = edgesChain.back();
|
||||||
#endif
|
#endif
|
||||||
firstWEdge = edgesChain.front();
|
firstWEdge = edgesChain.front();
|
||||||
|
|
||||||
// build FEdges
|
// build FEdges
|
||||||
FEdge * feprevious = 0;
|
FEdge *feprevious = NULL;
|
||||||
FEdge * fefirst = 0;
|
FEdge *fefirst = NULL;
|
||||||
FEdge * fe = 0;
|
FEdge *fe = NULL;
|
||||||
for(list<OWXEdge>::iterator we = edgesChain.begin(), weend=edgesChain.end();
|
for (list<OWXEdge>::iterator we = edgesChain.begin(), weend = edgesChain.end(); we != weend; ++we) {
|
||||||
we!=weend;
|
|
||||||
++we){
|
|
||||||
fe = BuildSharpFEdge(feprevious, (*we));
|
fe = BuildSharpFEdge(feprevious, (*we));
|
||||||
fe->setViewEdge(newVEdge);
|
fe->setViewEdge(newVEdge);
|
||||||
if(!fefirst)
|
if (!fefirst)
|
||||||
fefirst = fe;
|
fefirst = fe;
|
||||||
feprevious = fe;
|
feprevious = fe;
|
||||||
}
|
}
|
||||||
@@ -269,12 +274,13 @@ ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
|
|||||||
newVEdge->setFEdgeB(fe);
|
newVEdge->setFEdgeB(fe);
|
||||||
|
|
||||||
// is it a closed loop ?
|
// is it a closed loop ?
|
||||||
if((firstWEdge == endWEdge) && (size!=1)){
|
if ((firstWEdge == endWEdge) && (size != 1)) {
|
||||||
fefirst->setPreviousEdge(fe);
|
fefirst->setPreviousEdge(fe);
|
||||||
fe->setNextEdge(fefirst);
|
fe->setNextEdge(fefirst);
|
||||||
newVEdge->setA(0);
|
newVEdge->setA(0);
|
||||||
newVEdge->setB(0);
|
newVEdge->setB(0);
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
|
ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
|
||||||
ViewVertex *vvb = MakeViewVertex(fe->vertexB());
|
ViewVertex *vvb = MakeViewVertex(fe->vertexB());
|
||||||
|
|
||||||
@@ -288,147 +294,152 @@ ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
|
|||||||
return newVEdge;
|
return newVEdge;
|
||||||
}
|
}
|
||||||
|
|
||||||
OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer){
|
OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer)
|
||||||
WXFace *nextFace = 0;
|
{
|
||||||
WOEdge * woeend;
|
WXFace *nextFace = NULL;
|
||||||
|
WOEdge *woeend;
|
||||||
real tend;
|
real tend;
|
||||||
if(iFaceLayer.order){
|
if (iFaceLayer.order) {
|
||||||
woeend = iFaceLayer.fl->getSmoothEdge()->woeb();
|
woeend = iFaceLayer.fl->getSmoothEdge()->woeb();
|
||||||
tend = iFaceLayer.fl->getSmoothEdge()->tb();
|
tend = iFaceLayer.fl->getSmoothEdge()->tb();
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
woeend = iFaceLayer.fl->getSmoothEdge()->woea();
|
woeend = iFaceLayer.fl->getSmoothEdge()->woea();
|
||||||
tend = iFaceLayer.fl->getSmoothEdge()->ta();
|
tend = iFaceLayer.fl->getSmoothEdge()->ta();
|
||||||
}
|
}
|
||||||
// special case of EDGE_VERTEX config:
|
// special case of EDGE_VERTEX config:
|
||||||
if((tend == 0.0) || (tend == 1.0)){
|
if ((tend == 0.0) || (tend == 1.0)) {
|
||||||
WVertex *nextVertex;
|
WVertex *nextVertex;
|
||||||
if(tend == 0.0)
|
if (tend == 0.0)
|
||||||
nextVertex = woeend->GetaVertex();
|
nextVertex = woeend->GetaVertex();
|
||||||
else
|
else
|
||||||
nextVertex = woeend->GetbVertex();
|
nextVertex = woeend->GetbVertex();
|
||||||
if(nextVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
|
if (nextVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(0, true);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
WVertex::face_iterator f=nextVertex->faces_begin();
|
WVertex::face_iterator f = nextVertex->faces_begin();
|
||||||
WVertex::face_iterator fend=nextVertex->faces_end();
|
WVertex::face_iterator fend = nextVertex->faces_end();
|
||||||
while((!found) && (f!=fend)){
|
while ((!found) && (f != fend)) {
|
||||||
nextFace = dynamic_cast<WXFace*>(*f);
|
nextFace = dynamic_cast<WXFace*>(*f);
|
||||||
if((0 != nextFace) && (nextFace!=iFaceLayer.fl->getFace())){
|
if ((0 != nextFace) && (nextFace != iFaceLayer.fl->getFace())) {
|
||||||
vector<WXFaceLayer*> sameNatureLayers;
|
vector<WXFaceLayer*> sameNatureLayers;
|
||||||
nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
||||||
if(sameNatureLayers.size() == 1) {// don't know
|
// don't know... Maybe should test whether this face has also a vertex_edge configuration.
|
||||||
// maybe should test whether this face has
|
if (sameNatureLayers.size() == 1) {
|
||||||
// also a vertex_edge configuration
|
WXFaceLayer *winner = sameNatureLayers[0];
|
||||||
WXFaceLayer * winner = sameNatureLayers[0];
|
|
||||||
// check face mark continuity
|
// check face mark continuity
|
||||||
if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(NULL, true);
|
||||||
if(woeend == winner->getSmoothEdge()->woea()->twin())
|
if (woeend == winner->getSmoothEdge()->woea()->twin())
|
||||||
return OWXFaceLayer(winner,true);
|
return OWXFaceLayer(winner, true);
|
||||||
else
|
else
|
||||||
return OWXFaceLayer(winner,false);
|
return OWXFaceLayer(winner, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++f;
|
++f;
|
||||||
}
|
}
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
nextFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woeend));
|
nextFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woeend));
|
||||||
if(0 == nextFace)
|
if (!nextFace)
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(NULL, true);
|
||||||
// if the next face layer has either no smooth edge or
|
// if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
|
||||||
// no smooth edge of same nature, no next face
|
if (!nextFace->hasSmoothEdges())
|
||||||
if(!nextFace->hasSmoothEdges())
|
return OWXFaceLayer(NULL,true);
|
||||||
return OWXFaceLayer(0,true);
|
|
||||||
vector<WXFaceLayer*> sameNatureLayers;
|
vector<WXFaceLayer*> sameNatureLayers;
|
||||||
nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
||||||
if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face
|
// don't know how to deal with several edges of same nature on a single face
|
||||||
return OWXFaceLayer(0,true);
|
if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
|
||||||
else{
|
return OWXFaceLayer(NULL, true);
|
||||||
WXFaceLayer * winner = sameNatureLayers[0];
|
}
|
||||||
|
else {
|
||||||
|
WXFaceLayer *winner = sameNatureLayers[0];
|
||||||
// check face mark continuity
|
// check face mark continuity
|
||||||
if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(NULL, true);
|
||||||
if(woeend == winner->getSmoothEdge()->woea()->twin())
|
if (woeend == winner->getSmoothEdge()->woea()->twin())
|
||||||
return OWXFaceLayer(winner,true);
|
return OWXFaceLayer(winner, true);
|
||||||
else
|
else
|
||||||
return OWXFaceLayer(winner,false);
|
return OWXFaceLayer(winner, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer) {
|
OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer)
|
||||||
WXFace *previousFace = 0;
|
{
|
||||||
WOEdge * woebegin;
|
WXFace *previousFace = NULL;
|
||||||
|
WOEdge *woebegin;
|
||||||
real tend;
|
real tend;
|
||||||
if(iFaceLayer.order){
|
if (iFaceLayer.order) {
|
||||||
woebegin = iFaceLayer.fl->getSmoothEdge()->woea();
|
woebegin = iFaceLayer.fl->getSmoothEdge()->woea();
|
||||||
tend = iFaceLayer.fl->getSmoothEdge()->ta();
|
tend = iFaceLayer.fl->getSmoothEdge()->ta();
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
woebegin = iFaceLayer.fl->getSmoothEdge()->woeb();
|
woebegin = iFaceLayer.fl->getSmoothEdge()->woeb();
|
||||||
tend = iFaceLayer.fl->getSmoothEdge()->tb();
|
tend = iFaceLayer.fl->getSmoothEdge()->tb();
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case of EDGE_VERTEX config:
|
// special case of EDGE_VERTEX config:
|
||||||
if((tend == 0.0) || (tend == 1.0)){
|
if ((tend == 0.0) || (tend == 1.0)) {
|
||||||
WVertex *previousVertex;
|
WVertex *previousVertex;
|
||||||
if(tend == 0.0)
|
if (tend == 0.0)
|
||||||
previousVertex = woebegin->GetaVertex();
|
previousVertex = woebegin->GetaVertex();
|
||||||
else
|
else
|
||||||
previousVertex = woebegin->GetbVertex();
|
previousVertex = woebegin->GetbVertex();
|
||||||
if(previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
|
if (previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(NULL, true);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
WVertex::face_iterator f=previousVertex->faces_begin();
|
WVertex::face_iterator f = previousVertex->faces_begin();
|
||||||
WVertex::face_iterator fend=previousVertex->faces_end();
|
WVertex::face_iterator fend = previousVertex->faces_end();
|
||||||
while((!found) && (f!=fend)){
|
for (; (!found) && (f != fend); ++f) {
|
||||||
previousFace = dynamic_cast<WXFace*>(*f);
|
previousFace = dynamic_cast<WXFace*>(*f);
|
||||||
if((0 != previousFace) && (previousFace!=iFaceLayer.fl->getFace())){
|
if ((0 != previousFace) && (previousFace!=iFaceLayer.fl->getFace())) {
|
||||||
vector<WXFaceLayer*> sameNatureLayers;
|
vector<WXFaceLayer*> sameNatureLayers;
|
||||||
previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
||||||
if(sameNatureLayers.size() == 1) {// don't know
|
// don't know... Maybe should test whether this face has also a vertex_edge configuration
|
||||||
// maybe should test whether this face has
|
if (sameNatureLayers.size() == 1) {
|
||||||
// also a vertex_edge configuration
|
WXFaceLayer *winner = sameNatureLayers[0];
|
||||||
WXFaceLayer * winner = sameNatureLayers[0];
|
|
||||||
// check face mark continuity
|
// check face mark continuity
|
||||||
if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(NULL, true);
|
||||||
if(woebegin == winner->getSmoothEdge()->woeb()->twin())
|
if (woebegin == winner->getSmoothEdge()->woeb()->twin())
|
||||||
return OWXFaceLayer(winner,true);
|
return OWXFaceLayer(winner, true);
|
||||||
else
|
else
|
||||||
return OWXFaceLayer(winner,false);
|
return OWXFaceLayer(winner, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++f;
|
|
||||||
}
|
}
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
previousFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin));
|
previousFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin));
|
||||||
if(0 == previousFace)
|
if (0 == previousFace)
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(NULL, true);
|
||||||
|
// if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
|
||||||
// if the next face layer has either no smooth edge or
|
if (!previousFace->hasSmoothEdges())
|
||||||
// no smooth edge of same nature, no next face
|
return OWXFaceLayer(NULL, true);
|
||||||
if(!previousFace->hasSmoothEdges())
|
|
||||||
return OWXFaceLayer(0,true);
|
|
||||||
vector<WXFaceLayer*> sameNatureLayers;
|
vector<WXFaceLayer*> sameNatureLayers;
|
||||||
previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
|
||||||
if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face
|
// don't know how to deal with several edges of same nature on a single face
|
||||||
return OWXFaceLayer(0,true);
|
if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
|
||||||
else{
|
return OWXFaceLayer(NULL, true);
|
||||||
WXFaceLayer * winner = sameNatureLayers[0];
|
}
|
||||||
|
else {
|
||||||
|
WXFaceLayer *winner = sameNatureLayers[0];
|
||||||
// check face mark continuity
|
// check face mark continuity
|
||||||
if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(NULL, true);
|
||||||
if(woebegin == winner->getSmoothEdge()->woeb()->twin())
|
if (woebegin == winner->getSmoothEdge()->woeb()->twin())
|
||||||
return OWXFaceLayer(winner,true);
|
return OWXFaceLayer(winner, true);
|
||||||
else
|
else
|
||||||
return OWXFaceLayer(winner,false);
|
return OWXFaceLayer(winner, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OWXFaceLayer(0,true);
|
return OWXFaceLayer(NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl){
|
FEdge *ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl)
|
||||||
|
{
|
||||||
WOEdge *woea, *woeb;
|
WOEdge *woea, *woeb;
|
||||||
real ta, tb;
|
real ta, tb;
|
||||||
SVertex *va, *vb;
|
SVertex *va, *vb;
|
||||||
@@ -441,7 +452,8 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
|
|||||||
woeb = se->woeb();
|
woeb = se->woeb();
|
||||||
ta = se->ta();
|
ta = se->ta();
|
||||||
tb = se->tb();
|
tb = se->tb();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
woea = se->woeb();
|
woea = se->woeb();
|
||||||
woeb = se->woea();
|
woeb = se->woea();
|
||||||
ta = se->tb();
|
ta = se->tb();
|
||||||
@@ -450,10 +462,10 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
|
|||||||
|
|
||||||
Vec3r normal;
|
Vec3r normal;
|
||||||
// Make the 2 Svertices
|
// 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 A1(woea->GetaVertex()->GetVertex());
|
||||||
Vec3r A2(woea->GetbVertex()->GetVertex());
|
Vec3r A2(woea->GetbVertex()->GetVertex());
|
||||||
Vec3r A(A1+ta*(A2-A1));
|
Vec3r A(A1 + ta * (A2 - A1));
|
||||||
|
|
||||||
va = MakeSVertex(A, false);
|
va = MakeSVertex(A, false);
|
||||||
// Set normal:
|
// Set normal:
|
||||||
@@ -465,20 +477,20 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
|
|||||||
normal = na;
|
normal = na;
|
||||||
|
|
||||||
// Set CurvatureInfo
|
// Set CurvatureInfo
|
||||||
CurvatureInfo* curvature_info_a = new CurvatureInfo(
|
CurvatureInfo *curvature_info_a =
|
||||||
*(dynamic_cast<WXVertex*>(woea->GetaVertex())->curvatures()),
|
new CurvatureInfo(*(dynamic_cast<WXVertex*>(woea->GetaVertex())->curvatures()),
|
||||||
*(dynamic_cast<WXVertex*>(woea->GetbVertex())->curvatures()),
|
*(dynamic_cast<WXVertex*>(woea->GetbVertex())->curvatures()), ta);
|
||||||
ta);
|
|
||||||
va->setCurvatureInfo(curvature_info_a);
|
va->setCurvatureInfo(curvature_info_a);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
va = feprevious->vertexB();
|
va = feprevious->vertexB();
|
||||||
|
}
|
||||||
|
|
||||||
Vec3r B1(woeb->GetaVertex()->GetVertex());
|
Vec3r B1(woeb->GetaVertex()->GetVertex());
|
||||||
Vec3r B2(woeb->GetbVertex()->GetVertex());
|
Vec3r B2(woeb->GetbVertex()->GetVertex());
|
||||||
Vec3r B(B1+tb*(B2-B1));
|
Vec3r B(B1 + tb * (B2 - B1));
|
||||||
|
|
||||||
if (feprevious && (B - va->point3D()).norm() < 1e-6)
|
if (feprevious && (B - va->point3D()).norm() < 1.0e-6)
|
||||||
return feprevious;
|
return feprevious;
|
||||||
|
|
||||||
vb = MakeSVertex(B, false);
|
vb = MakeSVertex(B, false);
|
||||||
@@ -491,10 +503,9 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
|
|||||||
vb->AddNormal(nb);
|
vb->AddNormal(nb);
|
||||||
|
|
||||||
// Set CurvatureInfo
|
// Set CurvatureInfo
|
||||||
CurvatureInfo* curvature_info_b = new CurvatureInfo(
|
CurvatureInfo *curvature_info_b =
|
||||||
*(dynamic_cast<WXVertex*>(woeb->GetaVertex())->curvatures()),
|
new CurvatureInfo(*(dynamic_cast<WXVertex*>(woeb->GetaVertex())->curvatures()),
|
||||||
*(dynamic_cast<WXVertex*>(woeb->GetbVertex())->curvatures()),
|
*(dynamic_cast<WXVertex*>(woeb->GetbVertex())->curvatures()), tb);
|
||||||
tb);
|
|
||||||
vb->setCurvatureInfo(curvature_info_b);
|
vb->setCurvatureInfo(curvature_info_b);
|
||||||
|
|
||||||
// Creates the corresponding feature edge
|
// Creates the corresponding feature edge
|
||||||
@@ -504,11 +515,11 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
|
|||||||
fe->setFrsMaterialIndex(ifl.fl->getFace()->frs_materialIndex());
|
fe->setFrsMaterialIndex(ifl.fl->getFace()->frs_materialIndex());
|
||||||
fe->setFace(ifl.fl->getFace());
|
fe->setFace(ifl.fl->getFace());
|
||||||
fe->setFaceMark(ifl.fl->getFace()->GetMark());
|
fe->setFaceMark(ifl.fl->getFace()->GetMark());
|
||||||
if(feprevious == 0)
|
if (feprevious == 0)
|
||||||
normal.normalize();
|
normal.normalize();
|
||||||
fe->setNormal(normal);
|
fe->setNormal(normal);
|
||||||
fe->setPreviousEdge(feprevious);
|
fe->setPreviousEdge(feprevious);
|
||||||
if(feprevious)
|
if (feprevious)
|
||||||
feprevious->setNextEdge(fe);
|
feprevious->setNextEdge(fe);
|
||||||
_pCurrentSShape->AddEdge(fe);
|
_pCurrentSShape->AddEdge(fe);
|
||||||
va->AddFEdge(fe);
|
va->AddFEdge(fe);
|
||||||
@@ -519,10 +530,11 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer
|
|||||||
return fe;
|
return fe;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer){
|
bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer)
|
||||||
if(0 == iFaceLayer)
|
{
|
||||||
|
if (0 == iFaceLayer)
|
||||||
return true;
|
return true;
|
||||||
if(iFaceLayer->userdata == 0)
|
if (iFaceLayer->userdata == 0)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -539,100 +551,100 @@ int ViewEdgeXBuilder::retrieveFaceMarks(WXEdge *iEdge)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge){
|
OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge)
|
||||||
if(Nature::NO_FEATURE == iEdge.e->nature())
|
{
|
||||||
return OWXEdge(0, true);
|
if (Nature::NO_FEATURE == iEdge.e->nature())
|
||||||
|
return OWXEdge(NULL, true);
|
||||||
|
|
||||||
WVertex *v;
|
WVertex *v;
|
||||||
if(true == iEdge.order)
|
if (true == iEdge.order)
|
||||||
v = iEdge.e->GetbVertex();
|
v = iEdge.e->GetbVertex();
|
||||||
else
|
else
|
||||||
v = iEdge.e->GetaVertex();
|
v = iEdge.e->GetaVertex();
|
||||||
|
|
||||||
if(((WXVertex*)v)->isFeature())
|
if (((WXVertex*)v)->isFeature())
|
||||||
return 0;
|
return 0; /* XXX eeek? NULL? OWXEdge(NULL, true/false)?*/
|
||||||
|
|
||||||
|
|
||||||
int faceMarks = retrieveFaceMarks(iEdge.e);
|
int faceMarks = retrieveFaceMarks(iEdge.e);
|
||||||
vector<WEdge*>& vEdges = (v)->GetEdges();
|
vector<WEdge*>& vEdges = (v)->GetEdges();
|
||||||
for(vector<WEdge*>::iterator ve=vEdges.begin(),veend=vEdges.end();
|
for (vector<WEdge*>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
|
||||||
ve!=veend;
|
|
||||||
ve++){
|
|
||||||
WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
|
WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
|
||||||
if(wxe == iEdge.e)
|
if (wxe == iEdge.e)
|
||||||
continue; // same edge as the one processed
|
continue; // same edge as the one processed
|
||||||
|
|
||||||
if(wxe->nature() != iEdge.e->nature())
|
if (wxe->nature() != iEdge.e->nature())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// check face mark continuity
|
// check face mark continuity
|
||||||
if(retrieveFaceMarks(wxe) != faceMarks)
|
if (retrieveFaceMarks(wxe) != faceMarks)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(wxe->GetaVertex() == v){
|
if (wxe->GetaVertex() == v) {
|
||||||
// That means that the face necesarily lies on the edge left.
|
// That means that the face necesarily lies on the edge left.
|
||||||
// So the vertex order is OK.
|
// So the vertex order is OK.
|
||||||
return OWXEdge(wxe, true);
|
return OWXEdge(wxe, true);
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
// That means that the face necesarily lies on the edge left.
|
// That means that the face necesarily lies on the edge left.
|
||||||
// So the vertex order is OK.
|
// So the vertex order is OK.
|
||||||
return OWXEdge(wxe, false);
|
return OWXEdge(wxe, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// we did not find:
|
// we did not find:
|
||||||
return OWXEdge(0, true);
|
return OWXEdge(NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge){
|
OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge)
|
||||||
if(Nature::NO_FEATURE == iEdge.e->nature())
|
{
|
||||||
return OWXEdge(0, true);
|
if (Nature::NO_FEATURE == iEdge.e->nature())
|
||||||
|
return OWXEdge(NULL, true);
|
||||||
|
|
||||||
WVertex *v;
|
WVertex *v;
|
||||||
if(true == iEdge.order)
|
if (true == iEdge.order)
|
||||||
v = iEdge.e->GetaVertex();
|
v = iEdge.e->GetaVertex();
|
||||||
else
|
else
|
||||||
v = iEdge.e->GetbVertex();
|
v = iEdge.e->GetbVertex();
|
||||||
|
|
||||||
if(((WXVertex*)v)->isFeature())
|
if (((WXVertex*)v)->isFeature())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
int faceMarks = retrieveFaceMarks(iEdge.e);
|
int faceMarks = retrieveFaceMarks(iEdge.e);
|
||||||
vector<WEdge*>& vEdges = (v)->GetEdges();
|
vector<WEdge*>& vEdges = (v)->GetEdges();
|
||||||
for(vector<WEdge*>::iterator ve=vEdges.begin(),veend=vEdges.end();
|
for (vector<WEdge*>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
|
||||||
ve!=veend;
|
|
||||||
ve++){
|
|
||||||
WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
|
WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
|
||||||
if(wxe == iEdge.e)
|
if (wxe == iEdge.e)
|
||||||
continue; // same edge as the one processed
|
continue; // same edge as the one processed
|
||||||
|
|
||||||
if(wxe->nature() != iEdge.e->nature())
|
if (wxe->nature() != iEdge.e->nature())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// check face mark continuity
|
// check face mark continuity
|
||||||
if(retrieveFaceMarks(wxe) != faceMarks)
|
if (retrieveFaceMarks(wxe) != faceMarks)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(wxe->GetbVertex() == v){
|
if (wxe->GetbVertex() == v) {
|
||||||
return OWXEdge(wxe, true);
|
return OWXEdge(wxe, true);
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
return OWXEdge(wxe, false);
|
return OWXEdge(wxe, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// we did not find:
|
// we did not find:
|
||||||
return OWXEdge(0, true);
|
return OWXEdge(NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe){
|
FEdge *ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
|
||||||
|
{
|
||||||
SVertex *va, *vb;
|
SVertex *va, *vb;
|
||||||
FEdgeSharp *fe;
|
FEdgeSharp *fe;
|
||||||
WXVertex *wxVA, *wxVB;
|
WXVertex *wxVA, *wxVB;
|
||||||
if(iwe.order){
|
if (iwe.order) {
|
||||||
wxVA = (WXVertex*)iwe.e->GetaVertex();
|
wxVA = (WXVertex *)iwe.e->GetaVertex();
|
||||||
wxVB = (WXVertex*)iwe.e->GetbVertex();
|
wxVB = (WXVertex *)iwe.e->GetbVertex();
|
||||||
}else{
|
}
|
||||||
wxVA = (WXVertex*)iwe.e->GetbVertex();
|
else {
|
||||||
wxVB = (WXVertex*)iwe.e->GetaVertex();
|
wxVA = (WXVertex *)iwe.e->GetbVertex();
|
||||||
|
wxVB = (WXVertex *)iwe.e->GetaVertex();
|
||||||
}
|
}
|
||||||
// Make the 2 SVertex
|
// Make the 2 SVertex
|
||||||
va = MakeSVertex(wxVA->GetVertex(), true);
|
va = MakeSVertex(wxVA->GetVertex(), true);
|
||||||
@@ -642,27 +654,27 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
|
|||||||
Vec3r normalA, normalB;
|
Vec3r normalA, normalB;
|
||||||
unsigned matA(0), matB(0);
|
unsigned matA(0), matB(0);
|
||||||
bool faceMarkA = false, faceMarkB = false;
|
bool faceMarkA = false, faceMarkB = false;
|
||||||
if(iwe.order){
|
if (iwe.order) {
|
||||||
normalB = (iwe.e->GetbFace()->GetNormal());
|
normalB = (iwe.e->GetbFace()->GetNormal());
|
||||||
matB = (iwe.e->GetbFace()->frs_materialIndex());
|
matB = (iwe.e->GetbFace()->frs_materialIndex());
|
||||||
faceMarkB = (iwe.e->GetbFace()->GetMark());
|
faceMarkB = (iwe.e->GetbFace()->GetMark());
|
||||||
if(!(iwe.e->nature() & Nature::BORDER)) {
|
if (!(iwe.e->nature() & Nature::BORDER)) {
|
||||||
normalA = (iwe.e->GetaFace()->GetNormal());
|
normalA = (iwe.e->GetaFace()->GetNormal());
|
||||||
matA = (iwe.e->GetaFace()->frs_materialIndex());
|
matA = (iwe.e->GetaFace()->frs_materialIndex());
|
||||||
faceMarkA = (iwe.e->GetaFace()->GetMark());
|
faceMarkA = (iwe.e->GetaFace()->GetMark());
|
||||||
}
|
}
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
normalA = (iwe.e->GetbFace()->GetNormal());
|
normalA = (iwe.e->GetbFace()->GetNormal());
|
||||||
matA = (iwe.e->GetbFace()->frs_materialIndex());
|
matA = (iwe.e->GetbFace()->frs_materialIndex());
|
||||||
faceMarkA = (iwe.e->GetbFace()->GetMark());
|
faceMarkA = (iwe.e->GetbFace()->GetMark());
|
||||||
if(!(iwe.e->nature() & Nature::BORDER)) {
|
if (!(iwe.e->nature() & Nature::BORDER)) {
|
||||||
normalB = (iwe.e->GetaFace()->GetNormal());
|
normalB = (iwe.e->GetaFace()->GetNormal());
|
||||||
matB = (iwe.e->GetaFace()->frs_materialIndex());
|
matB = (iwe.e->GetaFace()->frs_materialIndex());
|
||||||
faceMarkB = (iwe.e->GetaFace()->GetMark());
|
faceMarkB = (iwe.e->GetaFace()->GetMark());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Creates the corresponding feature edge
|
// Creates the corresponding feature edge
|
||||||
// Creates the corresponding feature edge
|
|
||||||
fe = new FEdgeSharp(va, vb);
|
fe = new FEdgeSharp(va, vb);
|
||||||
fe->setNature(iwe.e->nature());
|
fe->setNature(iwe.e->nature());
|
||||||
fe->setId(_currentFId);
|
fe->setId(_currentFId);
|
||||||
@@ -673,7 +685,7 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
|
|||||||
fe->setNormalA(normalA);
|
fe->setNormalA(normalA);
|
||||||
fe->setNormalB(normalB);
|
fe->setNormalB(normalB);
|
||||||
fe->setPreviousEdge(feprevious);
|
fe->setPreviousEdge(feprevious);
|
||||||
if(feprevious)
|
if (feprevious)
|
||||||
feprevious->setNextEdge(fe);
|
feprevious->setNextEdge(fe);
|
||||||
_pCurrentSShape->AddEdge(fe);
|
_pCurrentSShape->AddEdge(fe);
|
||||||
va->AddFEdge(fe);
|
va->AddFEdge(fe);
|
||||||
@@ -689,15 +701,17 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe)
|
|||||||
return fe;
|
return fe;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge){
|
bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge)
|
||||||
if(0 == iEdge)
|
{
|
||||||
|
if (0 == iEdge)
|
||||||
return true;
|
return true;
|
||||||
if(iEdge->userdata == 0)
|
if (iEdge->userdata == 0)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint){
|
SVertex *ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint)
|
||||||
|
{
|
||||||
SVertex *va = new SVertex(iPoint, _currentSVertexId);
|
SVertex *va = new SVertex(iPoint, _currentSVertexId);
|
||||||
SilhouetteGeomEngine::ProjectSilhouette(va);
|
SilhouetteGeomEngine::ProjectSilhouette(va);
|
||||||
++_currentSVertexId;
|
++_currentSVertexId;
|
||||||
@@ -706,16 +720,19 @@ SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint){
|
|||||||
return va;
|
return va;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint, bool shared){
|
SVertex *ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint, bool shared)
|
||||||
|
{
|
||||||
SVertex *va;
|
SVertex *va;
|
||||||
if (!shared) {
|
if (!shared) {
|
||||||
va = MakeSVertex(iPoint);
|
va = MakeSVertex(iPoint);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// Check whether the iPoint is already in the table
|
// Check whether the iPoint is already in the table
|
||||||
SVertexMap::const_iterator found = _SVertexMap.find(iPoint);
|
SVertexMap::const_iterator found = _SVertexMap.find(iPoint);
|
||||||
if (shared && found != _SVertexMap.end()) {
|
if (shared && found != _SVertexMap.end()) {
|
||||||
va = (*found).second;
|
va = (*found).second;
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
va = MakeSVertex(iPoint);
|
va = MakeSVertex(iPoint);
|
||||||
// Add the svertex into the table using iPoint as the key
|
// Add the svertex into the table using iPoint as the key
|
||||||
_SVertexMap[iPoint] = va;
|
_SVertexMap[iPoint] = va;
|
||||||
@@ -724,13 +741,13 @@ SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint, bool shared){
|
|||||||
return va;
|
return va;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewVertex * ViewEdgeXBuilder::MakeViewVertex(SVertex *iSVertex){
|
ViewVertex *ViewEdgeXBuilder::MakeViewVertex(SVertex *iSVertex)
|
||||||
|
{
|
||||||
ViewVertex *vva = iSVertex->viewvertex();
|
ViewVertex *vva = iSVertex->viewvertex();
|
||||||
if(vva != 0)
|
if (vva)
|
||||||
return vva;
|
return vva;
|
||||||
vva = new NonTVertex(iSVertex);
|
vva = new NonTVertex(iSVertex);
|
||||||
// Add the view vertex to the ViewShape svertex list:
|
// Add the view vertex to the ViewShape svertex list:
|
||||||
_pCurrentVShape->AddVertex(vva);
|
_pCurrentVShape->AddVertex(vva);
|
||||||
return vva;
|
return vva;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,72 +1,86 @@
|
|||||||
//
|
/*
|
||||||
// Filename : ViewEdgeXBuilder.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Purpose : Class to build view edges and the underlying chains
|
* This program is free software; you can redistribute it and/or
|
||||||
// of feature edges...
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 27/10/2003
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
|
||||||
|
#define __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to build view edges and the underlying chains of feature edges...
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 27/10/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef VIEWEDGEXBUILDER_H
|
#include <map>
|
||||||
# define VIEWEDGEXBUILDER_H
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
# include <map>
|
#if 0 // soc
|
||||||
# include <utility>
|
#if defined(__GNUC__) && (__GNUC__ >= 3)
|
||||||
# include <vector>
|
//hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
|
||||||
|
# include <hash_map.h>
|
||||||
|
#else
|
||||||
|
# include <hash_map>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// soc
|
#include "Interface1D.h"
|
||||||
// # if defined(__GNUC__) && (__GNUC__ >= 3)
|
|
||||||
// //hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility
|
|
||||||
// # include <hash_map.h>
|
|
||||||
// # else
|
|
||||||
// # include <hash_map>
|
|
||||||
// # endif
|
|
||||||
|
|
||||||
# include "../system/FreestyleConfig.h"
|
#include "../geometry/Geom.h"
|
||||||
# include "../geometry/Geom.h"
|
|
||||||
# include "Interface1D.h"
|
#include "../system/FreestyleConfig.h"
|
||||||
|
|
||||||
using namespace Geometry;
|
using namespace Geometry;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class SVertex;
|
class SVertex;
|
||||||
|
|
||||||
/*! Defines a hash table used for searching the SVertex */
|
/*! Defines a hash table used for searching the SVertex */
|
||||||
struct SVertexHasher {
|
struct SVertexHasher
|
||||||
|
{
|
||||||
#define _MUL 950706376UL
|
#define _MUL 950706376UL
|
||||||
#define _MOD 2147483647UL
|
#define _MOD 2147483647UL
|
||||||
inline size_t operator() (const Vec3r& p) const {
|
inline size_t operator()(const Vec3r& p) const
|
||||||
size_t res = ((unsigned long) (p[0] * _MUL)) % _MOD;
|
{
|
||||||
res = ((res + (unsigned long) (p[1]) * _MUL)) % _MOD;
|
size_t res = ((unsigned long)(p[0] * _MUL)) % _MOD;
|
||||||
return ((res +(unsigned long) (p[2]) * _MUL)) % _MOD;
|
res = ((res + (unsigned long)(p[1]) * _MUL)) % _MOD;
|
||||||
|
return ((res +(unsigned long)(p[2]) * _MUL)) % _MOD;
|
||||||
}
|
}
|
||||||
|
#undef _MUL
|
||||||
|
#undef _MOD
|
||||||
};
|
};
|
||||||
|
|
||||||
// Key_compare predicate for hash_map. In particular, return false if equal.
|
// Key_compare predicate for hash_map. In particular, return false if equal.
|
||||||
struct epsilonEquals{
|
struct epsilonEquals
|
||||||
bool operator()(const Vec3r& v1, const Vec3r& v2) const{
|
{
|
||||||
real norm = (v1-v2).norm();
|
bool operator()(const Vec3r& v1, const Vec3r& v2) const
|
||||||
return (norm<1e-06);
|
{
|
||||||
|
real norm = (v1 - v2).norm();
|
||||||
|
return (norm < 1.0e-06);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,46 +89,80 @@ struct epsilonEquals{
|
|||||||
typedef map<Vec3r , SVertex*> SVertexMap;
|
typedef map<Vec3r , SVertex*> SVertexMap;
|
||||||
|
|
||||||
class WXFaceLayer;
|
class WXFaceLayer;
|
||||||
|
|
||||||
/*! class to describe an oriented smooth edge */
|
/*! class to describe an oriented smooth edge */
|
||||||
class OWXFaceLayer{
|
class OWXFaceLayer
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
WXFaceLayer * fl;
|
WXFaceLayer *fl;
|
||||||
bool order;
|
bool order;
|
||||||
|
|
||||||
OWXFaceLayer() {fl=0;order=true;}
|
OWXFaceLayer()
|
||||||
OWXFaceLayer(WXFaceLayer *ifl, bool iOrder=true){fl = ifl;order=iOrder;}
|
{
|
||||||
OWXFaceLayer& operator=(const OWXFaceLayer& iBrother){
|
fl = NULL;
|
||||||
|
order = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
OWXFaceLayer(WXFaceLayer *ifl, bool iOrder = true)
|
||||||
|
{
|
||||||
|
fl = ifl;
|
||||||
|
order = iOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
OWXFaceLayer& operator=(const OWXFaceLayer& iBrother)
|
||||||
|
{
|
||||||
fl = iBrother.fl;
|
fl = iBrother.fl;
|
||||||
order = iBrother.order;
|
order = iBrother.order;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
bool operator==(const OWXFaceLayer& b){
|
|
||||||
|
bool operator==(const OWXFaceLayer& b)
|
||||||
|
{
|
||||||
return ((fl == b.fl) && (order == b.order));
|
return ((fl == b.fl) && (order == b.order));
|
||||||
}
|
}
|
||||||
bool operator!=(const OWXFaceLayer& b){
|
|
||||||
return !(*this==b);
|
bool operator!=(const OWXFaceLayer& b)
|
||||||
|
{
|
||||||
|
return !(*this == b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class WXEdge;
|
class WXEdge;
|
||||||
|
|
||||||
/*! class to describe an oriented sharp edge */
|
/*! class to describe an oriented sharp edge */
|
||||||
class OWXEdge{
|
class OWXEdge
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
WXEdge * e;
|
WXEdge *e;
|
||||||
bool order;
|
bool order;
|
||||||
|
|
||||||
OWXEdge() {e=0;order=true;}
|
OWXEdge()
|
||||||
OWXEdge(WXEdge *ie, bool iOrder=true){e = ie;order=iOrder;}
|
{
|
||||||
OWXEdge& operator=(const OWXEdge& iBrother){
|
e = NULL;
|
||||||
|
order = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
OWXEdge(WXEdge *ie, bool iOrder = true)
|
||||||
|
{
|
||||||
|
e = ie;
|
||||||
|
order = iOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
OWXEdge& operator=(const OWXEdge& iBrother)
|
||||||
|
{
|
||||||
e = iBrother.e;
|
e = iBrother.e;
|
||||||
order = iBrother.order;
|
order = iBrother.order;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
bool operator==(const OWXEdge& b){
|
|
||||||
|
bool operator==(const OWXEdge& b)
|
||||||
|
{
|
||||||
return ((e == b.e) && (order == b.order));
|
return ((e == b.e) && (order == b.order));
|
||||||
}
|
}
|
||||||
bool operator!=(const OWXEdge& b){
|
|
||||||
return !(*this==b);
|
bool operator!=(const OWXEdge& b)
|
||||||
|
{
|
||||||
|
return !(*this == b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,24 +174,28 @@ class FEdge;
|
|||||||
class ViewVertex;
|
class ViewVertex;
|
||||||
class ViewEdge;
|
class ViewEdge;
|
||||||
class ViewShape;
|
class ViewShape;
|
||||||
|
|
||||||
class LIB_VIEW_MAP_EXPORT ViewEdgeXBuilder
|
class LIB_VIEW_MAP_EXPORT ViewEdgeXBuilder
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
int _currentViewId; // Id for view edges
|
int _currentViewId; // Id for view edges
|
||||||
int _currentFId; // Id for FEdges
|
int _currentFId; // Id for FEdges
|
||||||
int _currentSVertexId; // Id for SVertex
|
int _currentSVertexId; // Id for SVertex
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline ViewEdgeXBuilder()
|
inline ViewEdgeXBuilder()
|
||||||
{_currentViewId = 1;_currentFId=0;_currentSVertexId=0;}
|
{
|
||||||
virtual ~ViewEdgeXBuilder(){}
|
_currentViewId = 1;
|
||||||
|
_currentFId = 0;
|
||||||
|
_currentSVertexId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Builds a view shape from a WXShape in which the feature edges
|
virtual ~ViewEdgeXBuilder() {}
|
||||||
* are flagged
|
|
||||||
|
/*! Builds a view shape from a WXShape in which the feature edges are flagged
|
||||||
* Builds chains of feature edges (so ViewEdges) from a WXShape
|
* Builds chains of feature edges (so ViewEdges) from a WXShape
|
||||||
* iWShape
|
* iWShape
|
||||||
* The Winged Edge structure in which all silhouette edges
|
* The Winged Edge structure in which all silhouette edges and vertices are flagged.
|
||||||
* and vertices are flagged.
|
|
||||||
* oViewShape
|
* oViewShape
|
||||||
* The Silhouette Shape in which the chains must be added.
|
* The Silhouette Shape in which the chains must be added.
|
||||||
* ioVEdges
|
* ioVEdges
|
||||||
@@ -155,40 +207,59 @@ public:
|
|||||||
* ioSVertices
|
* ioSVertices
|
||||||
* A list of SVertex where all created SVertex are added.
|
* A list of SVertex where all created SVertex are added.
|
||||||
*/
|
*/
|
||||||
virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape,
|
virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, std::vector<ViewEdge*>& ioVEdges,
|
||||||
std::vector<ViewEdge*>& ioVEdges,
|
std::vector<ViewVertex*>& ioVVertices, std::vector<FEdge*>& ioFEdges,
|
||||||
std::vector<ViewVertex*>& ioVVertices,
|
std::vector<SVertex*>& ioSVertices);
|
||||||
std::vector<FEdge*>& ioFEdges,
|
|
||||||
std::vector<SVertex*>& ioSVertices) ;
|
|
||||||
|
|
||||||
/*! Builds a smooth view edge, starting the face iFace.*/
|
/*! Builds a smooth view edge, starting the face iFace. */
|
||||||
ViewEdge * BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer);
|
ViewEdge *BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer);
|
||||||
|
|
||||||
/*! Makes a sharp viewedge
|
|
||||||
*/
|
|
||||||
ViewEdge * BuildSharpViewEdge(const OWXEdge& iWEdge) ;
|
|
||||||
|
|
||||||
|
/*! Makes a sharp viewedge */
|
||||||
|
ViewEdge *BuildSharpViewEdge(const OWXEdge& iWEdge);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! accessors */
|
/*! accessors */
|
||||||
inline int currentViewId() const { return _currentViewId; }
|
inline int currentViewId() const
|
||||||
inline int currentFId() const { return _currentFId; }
|
{
|
||||||
inline int currentSVertexId() const { return _currentSVertexId; }
|
return _currentViewId;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int currentFId() const
|
||||||
|
{
|
||||||
|
return _currentFId;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int currentSVertexId() const
|
||||||
|
{
|
||||||
|
return _currentSVertexId;
|
||||||
|
}
|
||||||
|
|
||||||
/*! modifiers */
|
/*! modifiers */
|
||||||
inline void setCurrentViewId(int id) { _currentViewId = id; }
|
inline void setCurrentViewId(int id)
|
||||||
inline void setCurrentFId(int id) { _currentFId = id; }
|
{
|
||||||
inline void setCurrentSVertexId(int id) { _currentSVertexId = id; }
|
_currentViewId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setCurrentFId(int id)
|
||||||
|
{
|
||||||
|
_currentFId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setCurrentSVertexId(int id)
|
||||||
|
{
|
||||||
|
_currentSVertexId = id;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*! Init the view edges building */
|
/*! Init the view edges building */
|
||||||
virtual void Init(ViewShape *oVShape) ;
|
virtual void Init(ViewShape *oVShape);
|
||||||
|
|
||||||
// SMOOTH //
|
// SMOOTH //
|
||||||
/*! checks whether a face has already been processed or not */
|
/*! checks whether a face has already been processed or not */
|
||||||
bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer);
|
bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer);
|
||||||
OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer& iFaceLayer);
|
OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer& iFaceLayer);
|
||||||
OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer);
|
OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer);
|
||||||
FEdge * BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl);
|
FEdge *BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl);
|
||||||
|
|
||||||
// SHARP //
|
// SHARP //
|
||||||
/*! checks whether a WEdge has already been processed or not */
|
/*! checks whether a WEdge has already been processed or not */
|
||||||
@@ -196,23 +267,22 @@ protected:
|
|||||||
int retrieveFaceMarks(WXEdge *iEdge);
|
int retrieveFaceMarks(WXEdge *iEdge);
|
||||||
OWXEdge FindNextWEdge(const OWXEdge& iEdge);
|
OWXEdge FindNextWEdge(const OWXEdge& iEdge);
|
||||||
OWXEdge FindPreviousWEdge(const OWXEdge& iEdge);
|
OWXEdge FindPreviousWEdge(const OWXEdge& iEdge);
|
||||||
FEdge * BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe);
|
FEdge *BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe);
|
||||||
|
|
||||||
// GENERAL //
|
// GENERAL //
|
||||||
/*! Instanciate a SVertex */
|
/*! Instanciate a SVertex */
|
||||||
SVertex * MakeSVertex(Vec3r& iPoint);
|
SVertex *MakeSVertex(Vec3r& iPoint);
|
||||||
/*! Instanciate a SVertex if it hasn't been already created */
|
/*! Instanciate a SVertex if it hasn't been already created */
|
||||||
SVertex * MakeSVertex(Vec3r& iPoint, bool shared);
|
SVertex *MakeSVertex(Vec3r& iPoint, bool shared);
|
||||||
/*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */
|
/*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */
|
||||||
ViewVertex * MakeViewVertex(SVertex *iSVertex);
|
ViewVertex *MakeViewVertex(SVertex *iSVertex);
|
||||||
|
|
||||||
//oldtmp values
|
//oldtmp values
|
||||||
// IdHashTable _hashtable;
|
//IdHashTable _hashtable;
|
||||||
// VVIdHashTable _multivertexHashTable;
|
//VVIdHashTable _multivertexHashTable;
|
||||||
SVertexMap _SVertexMap;
|
SVertexMap _SVertexMap;
|
||||||
SShape *_pCurrentSShape;
|
SShape *_pCurrentSShape;
|
||||||
ViewShape * _pCurrentVShape;
|
ViewShape *_pCurrentVShape;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,83 +1,88 @@
|
|||||||
//
|
/*
|
||||||
// Filename : ViewMapBuilder.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Purpose : Class to build silhouette edges from a
|
* This program is free software; you can redistribute it and/or
|
||||||
// Winged-Edge structure
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 25/03/2002
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_VIEW_MAP_BUILDER_H__
|
||||||
|
#define __FREESTYLE_VIEW_MAP_BUILDER_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/ViewMapBuilder.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to build silhouette edges from a Winged-Edge structure
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 25/03/2002
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef VIEWMAPBUILDER_H
|
#include <vector>
|
||||||
# define VIEWMAPBUILDER_H
|
|
||||||
|
|
||||||
# include "Silhouette.h"
|
#include "GridDensityProvider.h"
|
||||||
# include <vector>
|
#include "Silhouette.h"
|
||||||
# include "../system/FreestyleConfig.h"
|
#include "SilhouetteGeomEngine.h"
|
||||||
# include "../geometry/Geom.h"
|
#include "ViewEdgeXBuilder.h"
|
||||||
# include "../scene_graph/NodeGroup.h"
|
#include "ViewMap.h"
|
||||||
# include "../winged_edge/WXEdge.h"
|
|
||||||
# include "../geometry/GeomUtils.h"
|
#include "../geometry/Geom.h"
|
||||||
# include "../geometry/Grid.h"
|
#include "../geometry/GeomUtils.h"
|
||||||
# include "../system/ProgressBar.h"
|
#include "../geometry/Grid.h"
|
||||||
# include "../system/RenderMonitor.h"
|
#include "../geometry/SweepLine.h"
|
||||||
# include "../geometry/SweepLine.h"
|
|
||||||
# include "ViewMap.h"
|
#include "../scene_graph/NodeGroup.h"
|
||||||
# include "SilhouetteGeomEngine.h"
|
#include "../scene_graph/TriangleRep.h"
|
||||||
# include "../scene_graph/TriangleRep.h"
|
|
||||||
# include "../winged_edge/WEdge.h"
|
#include "../system/FreestyleConfig.h"
|
||||||
# include "ViewEdgeXBuilder.h"
|
#include "../system/ProgressBar.h"
|
||||||
# include "../system/TimeUtils.h"
|
#include "../system/RenderMonitor.h"
|
||||||
# include "GridDensityProvider.h"
|
#include "../system/TimeUtils.h"
|
||||||
|
|
||||||
|
#include "../winged_edge/WEdge.h"
|
||||||
|
#include "../winged_edge/WXEdge.h"
|
||||||
|
|
||||||
using namespace Geometry;
|
using namespace Geometry;
|
||||||
|
|
||||||
class LIB_VIEW_MAP_EXPORT ViewMapBuilder
|
class LIB_VIEW_MAP_EXPORT ViewMapBuilder
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
ViewMap *_ViewMap; // result
|
||||||
ViewMap * _ViewMap; // result
|
|
||||||
//SilhouetteGeomEngine _GeomEngine;
|
//SilhouetteGeomEngine _GeomEngine;
|
||||||
ProgressBar *_pProgressBar;
|
ProgressBar *_pProgressBar;
|
||||||
RenderMonitor *_pRenderMonitor;
|
RenderMonitor *_pRenderMonitor;
|
||||||
Vec3r _viewpoint;
|
Vec3r _viewpoint;
|
||||||
bool _orthographicProjection;
|
bool _orthographicProjection;
|
||||||
Grid* _Grid;
|
Grid *_Grid;
|
||||||
ViewEdgeXBuilder *_pViewEdgeBuilder;
|
ViewEdgeXBuilder *_pViewEdgeBuilder;
|
||||||
bool _EnableQI;
|
bool _EnableQI;
|
||||||
double _epsilon;
|
double _epsilon;
|
||||||
|
|
||||||
|
|
||||||
// tmp values:
|
// tmp values:
|
||||||
int _currentId;
|
int _currentId;
|
||||||
int _currentFId;
|
int _currentFId;
|
||||||
int _currentSVertexId;
|
int _currentSVertexId;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
sweep_line
|
sweep_line,
|
||||||
} intersection_algo;
|
} intersection_algo;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -87,14 +92,14 @@ public:
|
|||||||
ray_casting_culled_adaptive_traditional,
|
ray_casting_culled_adaptive_traditional,
|
||||||
ray_casting_adaptive_traditional,
|
ray_casting_adaptive_traditional,
|
||||||
ray_casting_culled_adaptive_cumulative,
|
ray_casting_culled_adaptive_cumulative,
|
||||||
ray_casting_adaptive_cumulative
|
ray_casting_adaptive_cumulative,
|
||||||
} visibility_algo;
|
} visibility_algo;
|
||||||
|
|
||||||
inline ViewMapBuilder()
|
inline ViewMapBuilder()
|
||||||
{
|
{
|
||||||
_pProgressBar = 0;
|
_pProgressBar = NULL;
|
||||||
_pRenderMonitor = 0;
|
_pRenderMonitor = NULL;
|
||||||
_Grid = 0;
|
_Grid = NULL;
|
||||||
_currentId = 1;
|
_currentId = 1;
|
||||||
_currentFId = 0;
|
_currentFId = 0;
|
||||||
_currentSVertexId = 0;
|
_currentSVertexId = 0;
|
||||||
@@ -104,9 +109,9 @@ public:
|
|||||||
|
|
||||||
inline ~ViewMapBuilder()
|
inline ~ViewMapBuilder()
|
||||||
{
|
{
|
||||||
if(_pViewEdgeBuilder){
|
if (_pViewEdgeBuilder) {
|
||||||
delete _pViewEdgeBuilder;
|
delete _pViewEdgeBuilder;
|
||||||
_pViewEdgeBuilder = 0;
|
_pViewEdgeBuilder = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,15 +124,18 @@ public:
|
|||||||
|
|
||||||
/*! Compute Cusps */
|
/*! Compute Cusps */
|
||||||
void computeCusps(ViewMap *ioViewMap);
|
void computeCusps(ViewMap *ioViewMap);
|
||||||
/*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of
|
|
||||||
* each cusp SVertex
|
/*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of each cusp SVertex
|
||||||
* We use a hysteresis approach to avoid noise.
|
* We use a hysteresis approach to avoid noise.
|
||||||
*/
|
*/
|
||||||
void DetectCusps(ViewEdge *ioEdge);
|
void DetectCusps(ViewEdge *ioEdge);
|
||||||
|
|
||||||
|
|
||||||
/*! Sets the current viewpoint */
|
/*! Sets the current viewpoint */
|
||||||
inline void setViewpoint(const Vec3r& ivp) {_viewpoint = ivp; SilhouetteGeomEngine::setViewpoint(ivp);}
|
inline void setViewpoint(const Vec3r& ivp)
|
||||||
|
{
|
||||||
|
_viewpoint = ivp;
|
||||||
|
SilhouetteGeomEngine::setViewpoint(ivp);
|
||||||
|
}
|
||||||
|
|
||||||
/*! Sets the current transformation
|
/*! Sets the current transformation
|
||||||
* iModelViewMatrix
|
* iModelViewMatrix
|
||||||
@@ -137,86 +145,91 @@ public:
|
|||||||
* iViewport
|
* iViewport
|
||||||
* The viewport. 4 real array: origin.x, origin.y, width, length
|
* The viewport. 4 real array: origin.x, origin.y, width, length
|
||||||
*/
|
*/
|
||||||
inline void setTransform(const real iModelViewMatrix[4][4],
|
inline void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
|
||||||
const real iProjectionMatrix[4][4],
|
const int iViewport[4], real iFocalLength, real iAspect, real iFovy)
|
||||||
const int iViewport[4],
|
{
|
||||||
real iFocalLength,
|
|
||||||
real iAspect,
|
|
||||||
real iFovy) {
|
|
||||||
_orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
|
_orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
|
||||||
SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
|
SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setFrustum(real iZnear, real iZfar) {
|
inline void setFrustum(real iZnear, real iZfar)
|
||||||
|
{
|
||||||
SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
|
SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Builds the scene view map
|
/*! Builds the scene view map returns the list the view map
|
||||||
* returns the list the view map
|
|
||||||
* it is up to the caller to delete this ViewMap
|
* it is up to the caller to delete this ViewMap
|
||||||
* iWRoot
|
* iWRoot
|
||||||
* The root group node containing the WEdge structured scene
|
* The root group node containing the WEdge structured scene
|
||||||
*/
|
*/
|
||||||
|
ViewMap *BuildViewMap(WingedEdge& we, visibility_algo iAlgo, real epsilon, const BBox<Vec3r>& bbox,
|
||||||
|
unsigned int sceneNumFaces);
|
||||||
|
|
||||||
ViewMap* BuildViewMap(WingedEdge& we, visibility_algo iAlgo, real epsilon,
|
void CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4],
|
||||||
const BBox<Vec3r>& bbox, unsigned int sceneNumFaces);
|
bool extensiveFEdgeSearch = true);
|
||||||
void CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4], bool extensiveFEdgeSearch = true);
|
|
||||||
/*! computes the intersection between all 2D
|
/*! computes the intersection between all 2D feature edges of the scene.
|
||||||
* feature edges of the scene.
|
|
||||||
* ioViewMap
|
* ioViewMap
|
||||||
* The view map. It is modified by the method.
|
* The view map. It is modified by the method.
|
||||||
* The list of all features edges of the scene.
|
* The list of all features edges of the scene.
|
||||||
* Each time an intersection is found, the 2 intersecting
|
* Each time an intersection is found, the 2 intersecting edges are splitted (creating 2 new vertices)
|
||||||
* edges are splitted (creating 2 new vertices)
|
* At the end, this list is updated with the adding of all new created edges (resulting from splitting).
|
||||||
* At the end, this list is updated with the adding
|
|
||||||
* of all new created edges (resulting from splitting).
|
|
||||||
* iAlgo
|
* iAlgo
|
||||||
* The algo to use for computing the intersections
|
* The algo to use for computing the intersections
|
||||||
*/
|
*/
|
||||||
void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon=1e-06);
|
void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon = 1.0e-06);
|
||||||
|
|
||||||
/*! Computes the 2D scene silhouette edges visibility
|
/*! Computes the 2D scene silhouette edges visibility
|
||||||
* iGrid
|
* iGrid
|
||||||
* For the Ray Casting algorithm.
|
* For the Ray Casting algorithm.
|
||||||
*/
|
*/
|
||||||
void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces,
|
void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces,
|
||||||
visibility_algo iAlgo= ray_casting, real epsilon=1e-6);
|
visibility_algo iAlgo = ray_casting, real epsilon = 1.0e-6);
|
||||||
|
|
||||||
void setGrid(Grid *iGrid) {_Grid = iGrid;}
|
void setGrid(Grid *iGrid)
|
||||||
|
{
|
||||||
|
_Grid = iGrid;
|
||||||
|
}
|
||||||
|
|
||||||
/*! accessors */
|
/*! accessors */
|
||||||
|
|
||||||
/*! Modifiers */
|
/*! Modifiers */
|
||||||
inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;}
|
inline void setProgressBar(ProgressBar *iProgressBar)
|
||||||
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;}
|
{
|
||||||
inline void setEnableQI(bool iBool) {_EnableQI = iBool;}
|
_pProgressBar = iProgressBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
|
||||||
|
{
|
||||||
|
_pRenderMonitor = iRenderMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setEnableQI(bool iBool)
|
||||||
|
{
|
||||||
|
_EnableQI = iBool;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/*! Computes intersections on all edges of the scene using a sweep line algorithm */
|
||||||
|
void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1.0e-6);
|
||||||
|
|
||||||
/*! Computes intersections on all edges of the scene using a sweep line
|
/*! Computes the 2D scene silhouette edges visibility using a ray casting. On each edge, a ray is cast
|
||||||
* algorithm*/
|
* to check its quantitative invisibility. The list of occluders are each time stored in the tested edge.
|
||||||
void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1e-6);
|
|
||||||
|
|
||||||
/*! Computes the 2D scene silhouette edges visibility
|
|
||||||
* using a ray casting. On each edge, a ray is cast
|
|
||||||
* to check its quantitative invisibility. The list
|
|
||||||
* of occluders are each time stored in the tested edge.
|
|
||||||
* ioViewMap
|
* ioViewMap
|
||||||
* The view map.
|
* The view map.
|
||||||
* The 2D scene silhouette edges as FEdges.
|
* The 2D scene silhouette edges as FEdges.
|
||||||
* These edges have already been splitted at their intersections points.
|
* These edges have already been splitted at their intersections points.
|
||||||
* Thus, these edges do not intersect anymore.
|
* Thus, these edges do not intersect anymore.
|
||||||
* The visibility corresponding to each edge of ioScene is set is this
|
* The visibility corresponding to each edge of ioScene is set is this edge.
|
||||||
* edge.
|
|
||||||
*/
|
*/
|
||||||
void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
|
void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
|
||||||
void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
|
void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
|
||||||
void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1e-6);
|
void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
|
||||||
|
|
||||||
void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we,
|
void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
|
||||||
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory);
|
bool cull, GridDensityProviderFactory& factory);
|
||||||
void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we,
|
void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
|
||||||
const BBox<Vec3r>& bbox, real epsilon, bool cull, GridDensityProviderFactory& factory);
|
bool cull, GridDensityProviderFactory& factory);
|
||||||
|
|
||||||
/*! Compute the visibility for the FEdge fe.
|
/*! Compute the visibility for the FEdge fe.
|
||||||
* The occluders are added to fe occluders list.
|
* The occluders are added to fe occluders list.
|
||||||
@@ -228,21 +241,17 @@ void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we,
|
|||||||
* The epsilon used for computation
|
* The epsilon used for computation
|
||||||
* oShapeId
|
* oShapeId
|
||||||
* fe is the border (in 2D) between 2 2D spaces.
|
* fe is the border (in 2D) between 2 2D spaces.
|
||||||
* if fe is a silhouette,
|
* if fe is a silhouette, One of these 2D spaces is occupied by the shape to which fe belongs (on its left)
|
||||||
* One of these 2D spaces is occupied by the shape
|
* and the other one is either occupied by another shape or empty or occupied by the same shape.
|
||||||
* to which fe belongs (on its left) and the other one is either occupied
|
* We use this ray csating operation to determine which shape lies on fe's right.
|
||||||
* by another shape or empty or occupied by the same shape.
|
|
||||||
* We use this ray csating operation to determine which shape
|
|
||||||
* lies on fe's right.
|
|
||||||
* The result is the shape id stored in oShapeId
|
* The result is the shape id stored in oShapeId
|
||||||
*/
|
*/
|
||||||
int ComputeRayCastingVisibility(FEdge *fe, Grid* iGrid, real epsilon, set<ViewShape*>& oOccluders,
|
int ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
|
||||||
Polygon3r** oaPolygon, unsigned timestamp);
|
Polygon3r **oaPolygon, unsigned timestamp);
|
||||||
// FIXME
|
// 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);
|
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
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Emmanuel Turquin
|
*
|
||||||
// Purpose : Functions to manage I/O for the view map
|
* This program is free software; you can redistribute it and/or
|
||||||
// Date of creation : 09/01/2003
|
* modify it under the terms of the GNU General Public License
|
||||||
//
|
* as published by the Free Software Foundation; either version 2
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_VIEW_MAP_IO_H__
|
||||||
|
#define __FREESTYLE_VIEW_MAP_IO_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/ViewMapIO.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Functions to manage I/O for the view map
|
||||||
//
|
* \author Emmanuel Turquin
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 09/01/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef VIEWMAPIO_H
|
#include <fstream>
|
||||||
# define VIEWMAPIO_H
|
#include <string>
|
||||||
|
|
||||||
# include "ViewMap.h"
|
#include "ViewMap.h"
|
||||||
# include <fstream>
|
|
||||||
# include <string>
|
#include "../system/FreestyleConfig.h"
|
||||||
# include "../system/FreestyleConfig.h"
|
#include "../system/ProgressBar.h"
|
||||||
# include "../system/ProgressBar.h"
|
|
||||||
|
|
||||||
namespace ViewMapIO {
|
namespace ViewMapIO {
|
||||||
|
|
||||||
static const unsigned ZERO = UINT_MAX;
|
static const unsigned ZERO = UINT_MAX;
|
||||||
|
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
int load(istream& in, ViewMap* vm, ProgressBar* pb = NULL);
|
int load(istream& in, ViewMap *vm, ProgressBar *pb = NULL);
|
||||||
|
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
int save(ostream& out, ViewMap* vm, ProgressBar* pb = NULL);
|
int save(ostream& out, ViewMap *vm, ProgressBar *pb = NULL);
|
||||||
|
|
||||||
namespace Options {
|
namespace Options {
|
||||||
|
|
||||||
static const unsigned char FLOAT_VECTORS = 1;
|
static const unsigned char FLOAT_VECTORS = 1;
|
||||||
static const unsigned char NO_OCCLUDERS = 2;
|
static const unsigned char NO_OCCLUDERS = 2;
|
||||||
|
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void setFlags(const unsigned char flags);
|
void setFlags(const unsigned char flags);
|
||||||
|
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void addFlags(const unsigned char flags);
|
void addFlags(const unsigned char flags);
|
||||||
|
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void rmFlags(const unsigned char flags);
|
void rmFlags(const unsigned char flags);
|
||||||
|
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
unsigned char getFlags();
|
unsigned char getFlags();
|
||||||
|
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
void setModelsPath(const string& path);
|
void setModelsPath(const string& path);
|
||||||
|
|
||||||
LIB_VIEW_MAP_EXPORT
|
LIB_VIEW_MAP_EXPORT
|
||||||
string getModelsPath();
|
string getModelsPath();
|
||||||
|
|
||||||
}; // End of namepace Options
|
}; // End of namepace Options
|
||||||
|
|
||||||
# ifdef IRIX
|
#ifdef IRIX
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
template <unsigned S>
|
template <unsigned S>
|
||||||
ostream& write(ostream& out, const char* str) {
|
ostream& write(ostream& out, const char *str)
|
||||||
|
{
|
||||||
out.put(str[S - 1]);
|
out.put(str[S - 1]);
|
||||||
return write<S - 1>(out, str);
|
return write<S - 1>(out, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
ostream& write<1>(ostream& out, const char* str) {
|
ostream& write<1>(ostream& out, const char *str)
|
||||||
|
{
|
||||||
return out.put(str[0]);
|
return out.put(str[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
ostream& write<0>(ostream& out, const char*) {
|
ostream& write<0>(ostream& out, const char*)
|
||||||
|
{
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <unsigned S>
|
template <unsigned S>
|
||||||
istream& read(istream& in, char* str) {
|
istream& read(istream& in, char *str)
|
||||||
|
{
|
||||||
in.get(str[S - 1]);
|
in.get(str[S - 1]);
|
||||||
return read<S - 1>(in, str);
|
return read<S - 1>(in, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
istream& read<1>(istream& in, char* str) {
|
istream& read<1>(istream& in, char *str)
|
||||||
|
{
|
||||||
return in.get(str[0]);
|
return in.get(str[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
istream& read<0>(istream& in, char*) {
|
istream& read<0>(istream& in, char*)
|
||||||
|
{
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Internal
|
} // End of namespace Internal
|
||||||
|
|
||||||
# endif // IRIX
|
#endif // IRIX
|
||||||
|
|
||||||
} // End of namespace ViewMapIO
|
} // End of namespace ViewMapIO
|
||||||
|
|
||||||
#endif // VIEWMAPIO_H
|
#endif // __FREESTYLE_VIEW_MAP_IO_H__
|
||||||
|
|||||||
@@ -1,67 +1,71 @@
|
|||||||
//
|
/*
|
||||||
// Filename : ViewMapIterators.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Purpose : Iterators used to iterate over the various elements
|
* This program is free software; you can redistribute it and/or
|
||||||
// of the ViewMap
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 01/07/2003
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_VIEW_MAP_ITERATORS_H__
|
||||||
|
#define __FREESTYLE_VIEW_MAP_ITERATORS_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/ViewMapIterators.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Iterators used to iterate over the various elements of the ViewMap
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 01/07/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef VIEWMAPITERATORS_H
|
|
||||||
# define VIEWMAPITERATORS_H
|
|
||||||
|
|
||||||
#include "ViewMap.h"
|
#include "ViewMap.h"
|
||||||
|
|
||||||
#include "../system/Iterator.h" //soc
|
#include "../system/Iterator.h" //soc
|
||||||
|
|
||||||
|
|
||||||
/**********************************/
|
/**********************************/
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* ViewMap */
|
/* ViewMap */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
|
||||||
/**********************************/
|
/**********************************/
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* ViewVertex */
|
/* ViewVertex */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
|
||||||
namespace ViewVertexInternal{
|
namespace ViewVertexInternal {
|
||||||
|
|
||||||
/*! Class representing an iterator over oriented ViewEdges
|
/*! Class representing an iterator over oriented ViewEdges around a ViewVertex. This iterator allows a CCW iteration
|
||||||
* around a ViewVertex. This iterator allows a CCW iteration
|
|
||||||
* (in the image plane).
|
* (in the image plane).
|
||||||
* An instance of an orientedViewEdgeIterator can only
|
* An instance of an orientedViewEdgeIterator can only be obtained from a ViewVertex by calling edgesBegin()
|
||||||
* be obtained from a ViewVertex by calling edgesBegin() or edgesEnd().
|
* or edgesEnd().
|
||||||
*/
|
*/
|
||||||
class orientedViewEdgeIterator : public Iterator
|
class orientedViewEdgeIterator : public Iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
friend class ViewVertex;
|
friend class ViewVertex;
|
||||||
friend class TVertex;
|
friend class TVertex;
|
||||||
friend class NonTVertex;
|
friend class NonTVertex;
|
||||||
@@ -70,8 +74,8 @@ namespace ViewVertexInternal{
|
|||||||
// FIXME
|
// FIXME
|
||||||
typedef ::TVertex::edge_pointers_container edge_pointers_container;
|
typedef ::TVertex::edge_pointers_container edge_pointers_container;
|
||||||
typedef ::NonTVertex::edges_container edges_container;
|
typedef ::NonTVertex::edges_container edges_container;
|
||||||
protected:
|
|
||||||
|
|
||||||
|
protected:
|
||||||
Nature::VertexNature _Nature; // the nature of the underlying vertex
|
Nature::VertexNature _Nature; // the nature of the underlying vertex
|
||||||
// T vertex attributes
|
// T vertex attributes
|
||||||
edge_pointers_container::iterator _tbegin;
|
edge_pointers_container::iterator _tbegin;
|
||||||
@@ -83,33 +87,35 @@ namespace ViewVertexInternal{
|
|||||||
edges_container::iterator _end;
|
edges_container::iterator _end;
|
||||||
edges_container::iterator _nontvertex_iter;
|
edges_container::iterator _nontvertex_iter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! Default constructor */
|
/*! Default constructor */
|
||||||
inline orientedViewEdgeIterator() {}
|
inline orientedViewEdgeIterator() {}
|
||||||
|
|
||||||
inline orientedViewEdgeIterator(Nature::VertexNature iNature)
|
inline orientedViewEdgeIterator(Nature::VertexNature iNature)
|
||||||
{_Nature = iNature;}
|
{
|
||||||
|
_Nature = iNature;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Copy constructor */
|
/*! Copy constructor */
|
||||||
orientedViewEdgeIterator(const orientedViewEdgeIterator& iBrother)
|
orientedViewEdgeIterator(const orientedViewEdgeIterator& iBrother)
|
||||||
{
|
{
|
||||||
_Nature = iBrother._Nature;
|
_Nature = iBrother._Nature;
|
||||||
if(_Nature & Nature::T_VERTEX)
|
if (_Nature & Nature::T_VERTEX) {
|
||||||
{
|
|
||||||
_tbegin = iBrother._tbegin;
|
_tbegin = iBrother._tbegin;
|
||||||
_tend = iBrother._tend;
|
_tend = iBrother._tend;
|
||||||
_tvertex_iter = iBrother._tvertex_iter;
|
_tvertex_iter = iBrother._tvertex_iter;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
_begin = iBrother._begin;
|
_begin = iBrother._begin;
|
||||||
_end = iBrother._end;
|
_end = iBrother._end;
|
||||||
_nontvertex_iter = iBrother._nontvertex_iter;
|
_nontvertex_iter = iBrother._nontvertex_iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~orientedViewEdgeIterator() {}
|
virtual ~orientedViewEdgeIterator() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline orientedViewEdgeIterator(edge_pointers_container::iterator begin,
|
inline orientedViewEdgeIterator(edge_pointers_container::iterator begin, edge_pointers_container::iterator end,
|
||||||
edge_pointers_container::iterator end,
|
|
||||||
edge_pointers_container::iterator iter)
|
edge_pointers_container::iterator iter)
|
||||||
{
|
{
|
||||||
_Nature = Nature::T_VERTEX;
|
_Nature = Nature::T_VERTEX;
|
||||||
@@ -117,8 +123,8 @@ namespace ViewVertexInternal{
|
|||||||
_tend = end;
|
_tend = end;
|
||||||
_tvertex_iter = iter;
|
_tvertex_iter = iter;
|
||||||
}
|
}
|
||||||
inline orientedViewEdgeIterator(edges_container::iterator begin,
|
|
||||||
edges_container::iterator end,
|
inline orientedViewEdgeIterator(edges_container::iterator begin, edges_container::iterator end,
|
||||||
edges_container::iterator iter)
|
edges_container::iterator iter)
|
||||||
{
|
{
|
||||||
_Nature = Nature::NON_T_VERTEX;
|
_Nature = Nature::NON_T_VERTEX;
|
||||||
@@ -127,48 +133,40 @@ namespace ViewVertexInternal{
|
|||||||
_nontvertex_iter = iter;
|
_nontvertex_iter = iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/*! Tells whether the ViewEdge pointed by this iterator is the first one of the iteration list or not. */
|
||||||
|
|
||||||
/*! Tells whether the ViewEdge pointed
|
|
||||||
* by this iterator is the first one of the
|
|
||||||
* iteration list or not.
|
|
||||||
*/
|
|
||||||
virtual bool isBegin() const
|
virtual bool isBegin() const
|
||||||
{
|
{
|
||||||
if(_Nature & Nature::T_VERTEX)
|
if (_Nature & Nature::T_VERTEX)
|
||||||
return (_tvertex_iter == _tbegin);
|
return (_tvertex_iter == _tbegin);
|
||||||
else
|
else
|
||||||
return (_nontvertex_iter == _begin);
|
return (_nontvertex_iter == _begin);
|
||||||
}
|
}
|
||||||
/*! Tells whether the ViewEdge pointed
|
|
||||||
* by this iterator is after the last one of the
|
/*! Tells whether the ViewEdge pointed by this iterator is after the last one of the iteration list or not. */
|
||||||
* iteration list or not.
|
|
||||||
*/
|
|
||||||
virtual bool isEnd() const
|
virtual bool isEnd() const
|
||||||
{
|
{
|
||||||
if(_Nature & Nature::T_VERTEX)
|
if (_Nature & Nature::T_VERTEX)
|
||||||
return (_tvertex_iter == _tend);
|
return (_tvertex_iter == _tend);
|
||||||
else
|
else
|
||||||
return (_nontvertex_iter == _end);
|
return (_nontvertex_iter == _end);
|
||||||
}
|
}
|
||||||
|
|
||||||
// operators
|
// operators
|
||||||
/*! Increments.In the scripting language, call
|
/*! Increments. In the scripting language, call "increment()". */
|
||||||
* "increment()".
|
// operator corresponding to ++i
|
||||||
*/
|
virtual orientedViewEdgeIterator& operator++()
|
||||||
virtual orientedViewEdgeIterator& operator++() // operator corresponding to ++i
|
|
||||||
{
|
{
|
||||||
increment();
|
increment();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
/*! Increments.In the scripting language, call
|
|
||||||
* "increment()".
|
// operator corresponding to i++, i.e. which returns the value *and then* increments.
|
||||||
*/
|
// That's why we store the value in a temp.
|
||||||
virtual orientedViewEdgeIterator operator++(int) // opérateur correspondant à i++
|
virtual orientedViewEdgeIterator operator++(int)
|
||||||
{ // c.a.d qui renvoie la valeur *puis* incrémente.
|
{
|
||||||
orientedViewEdgeIterator tmp = *this; // C'est pour cela qu'on stocke la valeur
|
orientedViewEdgeIterator tmp = *this;
|
||||||
increment(); // dans un temporaire.
|
increment();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +174,7 @@ namespace ViewVertexInternal{
|
|||||||
/*! operator != */
|
/*! operator != */
|
||||||
virtual bool operator!=(const orientedViewEdgeIterator& b) const
|
virtual bool operator!=(const orientedViewEdgeIterator& b) const
|
||||||
{
|
{
|
||||||
if(_Nature & Nature::T_VERTEX)
|
if (_Nature & Nature::T_VERTEX)
|
||||||
return (_tvertex_iter != b._tvertex_iter);
|
return (_tvertex_iter != b._tvertex_iter);
|
||||||
else
|
else
|
||||||
return (_nontvertex_iter != b._nontvertex_iter);
|
return (_nontvertex_iter != b._nontvertex_iter);
|
||||||
@@ -184,16 +182,17 @@ namespace ViewVertexInternal{
|
|||||||
|
|
||||||
/*! operator == */
|
/*! operator == */
|
||||||
virtual bool operator==(const orientedViewEdgeIterator& b) const
|
virtual bool operator==(const orientedViewEdgeIterator& b) const
|
||||||
{return !(*this != b);}
|
{
|
||||||
|
return !(*this != b);
|
||||||
|
}
|
||||||
|
|
||||||
// dereferencing
|
// dereferencing
|
||||||
/*! Returns a reference to the pointed orientedViewEdge.
|
/*! Returns a reference to the pointed orientedViewEdge.
|
||||||
* In the scripting language, you must call
|
* In the scripting language, you must call "getObject()" instead.
|
||||||
* "getObject()"instead.
|
|
||||||
*/
|
*/
|
||||||
virtual ::ViewVertex::directedViewEdge& operator*() const
|
virtual ::ViewVertex::directedViewEdge& operator*() const
|
||||||
{
|
{
|
||||||
if(_Nature & Nature::T_VERTEX)
|
if (_Nature & Nature::T_VERTEX)
|
||||||
//return _tvertex_iter;
|
//return _tvertex_iter;
|
||||||
return **_tvertex_iter;
|
return **_tvertex_iter;
|
||||||
else
|
else
|
||||||
@@ -202,49 +201,54 @@ namespace ViewVertexInternal{
|
|||||||
/*! Returns a pointer to the pointed orientedViewEdge.
|
/*! Returns a pointer to the pointed orientedViewEdge.
|
||||||
* Can't be called in the scripting language.
|
* Can't be called in the scripting language.
|
||||||
*/
|
*/
|
||||||
virtual ::ViewVertex::directedViewEdge* operator->() const { return &(operator*());}
|
virtual ::ViewVertex::directedViewEdge *operator->() const
|
||||||
|
{
|
||||||
|
return &(operator*());
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! increments.*/
|
/*! increments.*/
|
||||||
virtual inline int increment()
|
virtual inline int increment()
|
||||||
{
|
{
|
||||||
if(_Nature & Nature::T_VERTEX)
|
if (_Nature & Nature::T_VERTEX) {
|
||||||
{
|
|
||||||
::ViewVertex::directedViewEdge tmp = (**_tvertex_iter);
|
::ViewVertex::directedViewEdge tmp = (**_tvertex_iter);
|
||||||
++_tvertex_iter;
|
++_tvertex_iter;
|
||||||
if(_tvertex_iter != _tend){
|
if (_tvertex_iter != _tend) {
|
||||||
// FIXME : pquoi deja ?
|
// FIXME : pquoi deja ?
|
||||||
::ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter);
|
::ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter);
|
||||||
if(tmp2.first == tmp.first)
|
if (tmp2.first == tmp.first)
|
||||||
++_tvertex_iter;
|
++_tvertex_iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
++_nontvertex_iter;
|
++_nontvertex_iter;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // ViewVertexInternal namespace
|
||||||
/**********************************/
|
|
||||||
/* */
|
/**********************************/
|
||||||
/* */
|
/* */
|
||||||
/* ViewEdge */
|
/* */
|
||||||
/* */
|
/* ViewEdge */
|
||||||
/* */
|
/* */
|
||||||
/**********************************/
|
/* */
|
||||||
|
/**********************************/
|
||||||
|
|
||||||
namespace ViewEdgeInternal {
|
namespace ViewEdgeInternal {
|
||||||
|
|
||||||
//
|
//
|
||||||
// SVertexIterator
|
// SVertexIterator
|
||||||
//
|
//
|
||||||
/////////////////////////////////////////////////
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
class SVertexIterator : public Interface0DIteratorNested
|
class SVertexIterator : public Interface0DIteratorNested
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SVertexIterator()
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
SVertexIterator() {
|
|
||||||
_vertex = NULL;
|
_vertex = NULL;
|
||||||
_begin = NULL;
|
_begin = NULL;
|
||||||
_previous_edge = NULL;
|
_previous_edge = NULL;
|
||||||
@@ -252,7 +256,8 @@ namespace ViewEdgeInternal {
|
|||||||
_t = 0;
|
_t = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVertexIterator(const SVertexIterator& vi) {
|
SVertexIterator(const SVertexIterator& vi)
|
||||||
|
{
|
||||||
_vertex = vi._vertex;
|
_vertex = vi._vertex;
|
||||||
_begin = vi._begin;
|
_begin = vi._begin;
|
||||||
_previous_edge = vi._previous_edge;
|
_previous_edge = vi._previous_edge;
|
||||||
@@ -260,7 +265,8 @@ namespace ViewEdgeInternal {
|
|||||||
_t = vi._t;
|
_t = vi._t;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVertexIterator(SVertex* v, SVertex* begin, FEdge* prev, FEdge* next, float t) {
|
SVertexIterator(SVertex *v, SVertex *begin, FEdge *prev, FEdge *next, float t)
|
||||||
|
{
|
||||||
_vertex = v;
|
_vertex = v;
|
||||||
_begin = begin;
|
_begin = begin;
|
||||||
_previous_edge = prev;
|
_previous_edge = prev;
|
||||||
@@ -268,7 +274,8 @@ namespace ViewEdgeInternal {
|
|||||||
_t = t;
|
_t = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVertexIterator& operator=(const SVertexIterator& vi) {
|
SVertexIterator& operator=(const SVertexIterator& vi)
|
||||||
|
{
|
||||||
_vertex = vi._vertex;
|
_vertex = vi._vertex;
|
||||||
_begin = vi._begin;
|
_begin = vi._begin;
|
||||||
_previous_edge = vi._previous_edge;
|
_previous_edge = vi._previous_edge;
|
||||||
@@ -279,43 +286,51 @@ namespace ViewEdgeInternal {
|
|||||||
|
|
||||||
virtual ~SVertexIterator() {}
|
virtual ~SVertexIterator() {}
|
||||||
|
|
||||||
virtual string getExactTypeName() const {
|
virtual string getExactTypeName() const
|
||||||
|
{
|
||||||
return "SVertexIterator";
|
return "SVertexIterator";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SVertex& operator*() {
|
virtual SVertex& operator*()
|
||||||
|
{
|
||||||
return *_vertex;
|
return *_vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SVertex* operator->() {
|
virtual SVertex *operator->()
|
||||||
|
{
|
||||||
return &(operator*());
|
return &(operator*());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SVertexIterator& operator++() {
|
virtual SVertexIterator& operator++()
|
||||||
|
{
|
||||||
increment();
|
increment();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SVertexIterator operator++(int) {
|
virtual SVertexIterator operator++(int)
|
||||||
|
{
|
||||||
SVertexIterator ret(*this);
|
SVertexIterator ret(*this);
|
||||||
increment();
|
increment();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SVertexIterator& operator--() {
|
virtual SVertexIterator& operator--()
|
||||||
|
{
|
||||||
decrement();
|
decrement();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SVertexIterator operator--(int) {
|
virtual SVertexIterator operator--(int)
|
||||||
|
{
|
||||||
SVertexIterator ret(*this);
|
SVertexIterator ret(*this);
|
||||||
decrement();
|
decrement();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int increment(){
|
virtual int increment()
|
||||||
|
{
|
||||||
if (!_next_edge) {
|
if (!_next_edge) {
|
||||||
_vertex = 0;
|
_vertex = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_t += (float)_next_edge->getLength2D();
|
_t += (float)_next_edge->getLength2D();
|
||||||
@@ -323,14 +338,15 @@ namespace ViewEdgeInternal {
|
|||||||
_previous_edge = _next_edge;
|
_previous_edge = _next_edge;
|
||||||
_next_edge = _next_edge->nextEdge();
|
_next_edge = _next_edge->nextEdge();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual int decrement(){
|
|
||||||
|
virtual int decrement()
|
||||||
|
{
|
||||||
if (!_previous_edge) {
|
if (!_previous_edge) {
|
||||||
_vertex = 0;
|
_vertex = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if((!_next_edge) && (!_vertex)){
|
if ((!_next_edge) && (!_vertex)) {
|
||||||
_vertex = _previous_edge->vertexB();
|
_vertex = _previous_edge->vertexB();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -341,41 +357,46 @@ namespace ViewEdgeInternal {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isBegin() const {
|
virtual bool isBegin() const
|
||||||
|
{
|
||||||
return _vertex == _begin;
|
return _vertex == _begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isEnd() const {
|
virtual bool isEnd() const
|
||||||
|
{
|
||||||
return (!_vertex) || (_vertex == _begin && _previous_edge);
|
return (!_vertex) || (_vertex == _begin && _previous_edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual float t() const {
|
virtual float t() const
|
||||||
|
{
|
||||||
return _t;
|
return _t;
|
||||||
}
|
}
|
||||||
virtual float u() const {
|
|
||||||
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 {
|
virtual bool operator==(const Interface0DIteratorNested& it) const
|
||||||
const SVertexIterator* it_exact = dynamic_cast<const SVertexIterator*>(&it);
|
{
|
||||||
|
const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator*>(&it);
|
||||||
if (!it_exact)
|
if (!it_exact)
|
||||||
return false;
|
return false;
|
||||||
return (_vertex == it_exact->_vertex);
|
return (_vertex == it_exact->_vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SVertexIterator* copy() const {
|
virtual SVertexIterator *copy() const
|
||||||
|
{
|
||||||
return new SVertexIterator(*this);
|
return new SVertexIterator(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
SVertex *_vertex;
|
||||||
SVertex* _vertex;
|
SVertex *_begin;
|
||||||
SVertex* _begin;
|
FEdge *_previous_edge;
|
||||||
FEdge* _previous_edge;
|
FEdge *_next_edge;
|
||||||
FEdge* _next_edge;
|
|
||||||
float _t; // curvilinear abscissa
|
float _t; // curvilinear abscissa
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -383,34 +404,31 @@ namespace ViewEdgeInternal {
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*! Base class for iterators over ViewEdges of the ViewMap Graph.
|
/*! Base class for iterators over ViewEdges of the ViewMap Graph.
|
||||||
* Basically the "increment()" operator of this class should
|
* Basically the "increment()" operator of this class should be able to take the decision of "where" (on which
|
||||||
* be able to take the decision of "where" (on which ViewEdge) to go
|
* ViewEdge) to go when pointing on a given ViewEdge.
|
||||||
* when pointing on a given ViewEdge.
|
* ::Caution::: the dereferencing operator returns a *pointer* to the pointed ViewEdge.
|
||||||
* ::Caution::: the dereferencing operator returns a *pointer* to
|
|
||||||
* the pointed ViewEdge.
|
|
||||||
*/
|
*/
|
||||||
class ViewEdgeIterator : public Iterator
|
class ViewEdgeIterator : public Iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation.
|
/*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation.
|
||||||
* \param begin
|
* \param begin
|
||||||
* The ViewEdge from where to start the iteration.
|
* The ViewEdge from where to start the iteration.
|
||||||
* \param orientation
|
* \param orientation
|
||||||
* If true, we'll look for the next ViewEdge among the
|
* If true, we'll look for the next ViewEdge among the ViewEdges that surround the ending ViewVertex of begin.
|
||||||
* ViewEdges that surround the ending ViewVertex of begin.
|
* If false, we'll search over the ViewEdges surrounding the ending ViewVertex of begin.
|
||||||
* If false, we'll search over the ViewEdges surrounding
|
|
||||||
* the ending ViewVertex of begin.
|
|
||||||
*/
|
*/
|
||||||
ViewEdgeIterator(ViewEdge* begin = 0, bool orientation = true) {
|
ViewEdgeIterator(ViewEdge *begin = NULL, bool orientation = true)
|
||||||
|
{
|
||||||
_orientation = orientation;
|
_orientation = orientation;
|
||||||
_edge = begin;
|
_edge = begin;
|
||||||
_begin = begin;
|
_begin = begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Copy constructor */
|
/*! Copy constructor */
|
||||||
ViewEdgeIterator(const ViewEdgeIterator& it) {
|
ViewEdgeIterator(const ViewEdgeIterator& it)
|
||||||
|
{
|
||||||
_orientation = it._orientation;
|
_orientation = it._orientation;
|
||||||
_edge = it._edge;
|
_edge = it._edge;
|
||||||
_begin = it._begin;
|
_begin = it._begin;
|
||||||
@@ -419,131 +437,138 @@ public:
|
|||||||
virtual ~ViewEdgeIterator() {}
|
virtual ~ViewEdgeIterator() {}
|
||||||
|
|
||||||
/*! Returns the string "ViewEdgeIterator" */
|
/*! Returns the string "ViewEdgeIterator" */
|
||||||
virtual string getExactTypeName() const {
|
virtual string getExactTypeName() const
|
||||||
|
{
|
||||||
return "ViewEdgeIterator";
|
return "ViewEdgeIterator";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the current pointed ViewEdge. */
|
/*! Returns the current pointed ViewEdge. */
|
||||||
ViewEdge* getCurrentEdge() {
|
ViewEdge *getCurrentEdge()
|
||||||
|
{
|
||||||
return _edge;
|
return _edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sets the current pointed ViewEdge. */
|
/*! Sets the current pointed ViewEdge. */
|
||||||
void setCurrentEdge(ViewEdge* edge) {
|
void setCurrentEdge(ViewEdge *edge)
|
||||||
|
{
|
||||||
_edge = edge;
|
_edge = edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns the first ViewEdge used for the iteration. */
|
/*! Returns the first ViewEdge used for the iteration. */
|
||||||
ViewEdge* getBegin() {
|
ViewEdge *getBegin()
|
||||||
|
{
|
||||||
return _begin;
|
return _begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sets the first ViewEdge used for the iteration. */
|
/*! Sets the first ViewEdge used for the iteration. */
|
||||||
void setBegin(ViewEdge* begin) {
|
void setBegin(ViewEdge *begin)
|
||||||
|
{
|
||||||
_begin = begin;
|
_begin = begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Gets the orientation of the pointed ViewEdge in the iteration. */
|
/*! Gets the orientation of the pointed ViewEdge in the iteration. */
|
||||||
bool getOrientation() const {
|
bool getOrientation() const
|
||||||
|
{
|
||||||
return _orientation;
|
return _orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sets the orientation of the pointed ViewEdge in the iteration. */
|
/*! Sets the orientation of the pointed ViewEdge in the iteration. */
|
||||||
void setOrientation(bool orientation) {
|
void setOrientation(bool orientation)
|
||||||
|
{
|
||||||
_orientation = orientation;
|
_orientation = orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Changes the current orientation. */
|
/*! Changes the current orientation. */
|
||||||
void changeOrientation() {
|
void changeOrientation()
|
||||||
|
{
|
||||||
_orientation = !_orientation;
|
_orientation = !_orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns a *pointer* to the pointed ViewEdge. */
|
/*! Returns a *pointer* to the pointed ViewEdge. */
|
||||||
virtual ViewEdge* operator*() {
|
virtual ViewEdge *operator*()
|
||||||
|
{
|
||||||
return _edge;
|
return _edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ViewEdge* operator->() {
|
virtual ViewEdge *operator->()
|
||||||
|
{
|
||||||
return operator*();
|
return operator*();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Increments. In the scripting language, call
|
/*! Increments. In the scripting language, call "increment()". */
|
||||||
* "increment()".
|
virtual ViewEdgeIterator& operator++()
|
||||||
*/
|
{
|
||||||
virtual ViewEdgeIterator& operator++() {
|
|
||||||
increment();
|
increment();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Increments. In the scripting language, call
|
/*! Increments. In the scripting language, call "increment()". */
|
||||||
* "increment()".
|
virtual ViewEdgeIterator operator++(int)
|
||||||
*/
|
{
|
||||||
virtual ViewEdgeIterator operator++(int) {
|
|
||||||
ViewEdgeIterator tmp(*this);
|
ViewEdgeIterator tmp(*this);
|
||||||
increment();
|
increment();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! increments. */
|
/*! increments. */
|
||||||
virtual int increment() {
|
virtual int increment()
|
||||||
|
{
|
||||||
cerr << "Warning: method increment() not implemented" << endl;
|
cerr << "Warning: method increment() not implemented" << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Decrements. In the scripting language, call
|
/*! Decrements. In the scripting language, call "decrement()". */
|
||||||
* "decrement()".
|
virtual ViewEdgeIterator& operator--()
|
||||||
*/
|
{
|
||||||
virtual ViewEdgeIterator& operator--() {
|
|
||||||
decrement();
|
decrement();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Decrements. In the scripting language, call
|
/*! Decrements. In the scripting language, call "decrement()". */
|
||||||
* "decrement()".
|
virtual ViewEdgeIterator operator--(int)
|
||||||
*/
|
{
|
||||||
virtual ViewEdgeIterator operator--(int) {
|
|
||||||
ViewEdgeIterator tmp(*this);
|
ViewEdgeIterator tmp(*this);
|
||||||
decrement();
|
decrement();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! decrements. */
|
/*! decrements. */
|
||||||
virtual int decrement(){
|
virtual int decrement()
|
||||||
|
{
|
||||||
cerr << "Warning: method decrement() not implemented" << endl;
|
cerr << "Warning: method decrement() not implemented" << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns true if the pointed ViewEdge is the
|
/*! Returns true if the pointed ViewEdge is the first one used for the iteration. */
|
||||||
* first one used for the iteration.
|
virtual bool isBegin() const
|
||||||
*/
|
{
|
||||||
virtual bool isBegin() const {
|
|
||||||
return _edge == _begin;
|
return _edge == _begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns true if the pointed ViewEdge* equals 0.
|
/*! Returns true if the pointed ViewEdge* equals 0. */
|
||||||
*/
|
virtual bool isEnd() const
|
||||||
virtual bool isEnd() const {
|
{
|
||||||
return !_edge;
|
return !_edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! operator == */
|
/*! operator == */
|
||||||
virtual bool operator==(ViewEdgeIterator& it) const {
|
virtual bool operator==(ViewEdgeIterator& it) const
|
||||||
|
{
|
||||||
return _edge == it._edge;
|
return _edge == it._edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! operator != */
|
/*! operator != */
|
||||||
virtual bool operator!=(ViewEdgeIterator& it) const {
|
virtual bool operator!=(ViewEdgeIterator& it) const
|
||||||
|
{
|
||||||
return !(*this == it);
|
return !(*this == it);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool _orientation;
|
bool _orientation;
|
||||||
ViewEdge* _edge;
|
ViewEdge *_edge;
|
||||||
ViewEdge* _begin;
|
ViewEdge *_begin;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace ViewEdgeInternal
|
} // 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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/ViewMapTesselator.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 26/03/2002
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "ViewMapTesselator.h"
|
#include "ViewMapTesselator.h"
|
||||||
|
|
||||||
NodeGroup* ViewMapTesselator::Tesselate(ViewMap *iViewMap)
|
NodeGroup *ViewMapTesselator::Tesselate(ViewMap *iViewMap)
|
||||||
{
|
{
|
||||||
if(0 == iViewMap->ViewEdges().size())
|
if (0 == iViewMap->ViewEdges().size())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const vector<ViewEdge*>& viewedges = iViewMap->ViewEdges();
|
const vector<ViewEdge*>& viewedges = iViewMap->ViewEdges();
|
||||||
return Tesselate(viewedges.begin(), viewedges.end());
|
return Tesselate(viewedges.begin(), viewedges.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeGroup* ViewMapTesselator::Tesselate(WShape *)
|
NodeGroup *ViewMapTesselator::Tesselate(WShape *)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,50 @@
|
|||||||
//
|
/*
|
||||||
// Filename : ViewMapTesselator.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Purpose : Class to build a Node Tree designed to be displayed
|
* This program is free software; you can redistribute it and/or
|
||||||
// from a Silhouette View Map structure.
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 26/03/2002
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_VIEW_MAP_TESSELATOR_H__
|
||||||
|
#define __FREESTYLE_VIEW_MAP_TESSELATOR_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/view_map/ViewMapTesselator.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 26/03/2002
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef VIEWMAPTESSELATOR_H
|
#include "Silhouette.h"
|
||||||
# define VIEWMAPTESSELATOR_H
|
#include "ViewMap.h"
|
||||||
|
|
||||||
# include "Silhouette.h"
|
#include "../scene_graph/LineRep.h"
|
||||||
# include "ViewMap.h"
|
#include "../scene_graph/NodeShape.h"
|
||||||
# include "../scene_graph/NodeShape.h"
|
#include "../scene_graph/NodeGroup.h"
|
||||||
# include "../winged_edge/WEdge.h"
|
#include "../scene_graph/OrientedLineRep.h"
|
||||||
# include "../scene_graph/NodeGroup.h"
|
#include "../scene_graph/VertexRep.h"
|
||||||
# include "../scene_graph/LineRep.h"
|
|
||||||
# include "../scene_graph/OrientedLineRep.h"
|
#include "../winged_edge/WEdge.h"
|
||||||
# include "../scene_graph/VertexRep.h"
|
|
||||||
|
|
||||||
class NodeShape;
|
class NodeShape;
|
||||||
class NodeGroup;
|
class NodeGroup;
|
||||||
@@ -48,32 +54,47 @@ class WShape;
|
|||||||
class LIB_VIEW_MAP_EXPORT ViewMapTesselator
|
class LIB_VIEW_MAP_EXPORT ViewMapTesselator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
inline ViewMapTesselator()
|
||||||
|
{
|
||||||
|
_nature = Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE;
|
||||||
|
_FrsMaterial.setDiffuse(0, 0, 0, 1);
|
||||||
|
_overloadFrsMaterial = false;
|
||||||
|
}
|
||||||
|
|
||||||
inline ViewMapTesselator() {_nature = Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE;_FrsMaterial.setDiffuse(0,0,0,1);_overloadFrsMaterial=false;}
|
|
||||||
virtual ~ViewMapTesselator() {}
|
virtual ~ViewMapTesselator() {}
|
||||||
|
|
||||||
/*! Builds a set of lines rep contained under a
|
/*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a ViewMap */
|
||||||
* a NodeShape, itself contained under a NodeGroup from a ViewMap
|
NodeGroup *Tesselate(ViewMap *iViewMap);
|
||||||
*/
|
|
||||||
NodeGroup* Tesselate(ViewMap* iViewMap) ;
|
|
||||||
|
|
||||||
/*! Builds a set of lines rep contained under a
|
/*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup from a set of
|
||||||
* a NodeShape, itself contained under a NodeGroup from a
|
* view edges
|
||||||
* set of view edges
|
|
||||||
*/
|
*/
|
||||||
template<class ViewEdgesIterator>
|
template<class ViewEdgesIterator>
|
||||||
NodeGroup* Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end) ;
|
NodeGroup *Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end);
|
||||||
|
|
||||||
/*! Builds a set of lines rep contained among a
|
/*! Builds a set of lines rep contained among a NodeShape, from a WShape */
|
||||||
* a NodeShape, from a WShape
|
NodeGroup *Tesselate(WShape *iWShape);
|
||||||
*/
|
|
||||||
NodeGroup* Tesselate(WShape* iWShape);
|
|
||||||
|
|
||||||
|
inline void setNature(Nature::EdgeNature iNature)
|
||||||
|
{
|
||||||
|
_nature = iNature;
|
||||||
|
}
|
||||||
|
|
||||||
inline void setNature(Nature::EdgeNature iNature) {_nature = iNature;}
|
inline void setFrsMaterial(const FrsMaterial& iMaterial)
|
||||||
inline void setFrsMaterial(const FrsMaterial& iMaterial) {_FrsMaterial=iMaterial;_overloadFrsMaterial=true;}
|
{
|
||||||
inline Nature::EdgeNature nature() {return _nature;}
|
_FrsMaterial = iMaterial;
|
||||||
inline const FrsMaterial& frs_material() const {return _FrsMaterial;}
|
_overloadFrsMaterial = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Nature::EdgeNature nature()
|
||||||
|
{
|
||||||
|
return _nature;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const FrsMaterial& frs_material() const
|
||||||
|
{
|
||||||
|
return _FrsMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
|
virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0;
|
||||||
@@ -118,70 +139,64 @@ protected:
|
|||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
template<class ViewEdgesIterator>
|
template<class ViewEdgesIterator>
|
||||||
NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
|
NodeGroup *ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end)
|
||||||
{
|
{
|
||||||
NodeGroup *group = new NodeGroup;
|
NodeGroup *group = new NodeGroup;
|
||||||
NodeShape *tshape = new NodeShape;
|
NodeShape *tshape = new NodeShape;
|
||||||
group->AddChild(tshape);
|
group->AddChild(tshape);
|
||||||
//tshape->frs_material().setDiffuse(0.f, 0.f, 0.f, 1.f);
|
//tshape->frs_material().setDiffuse(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
tshape->setFrsMaterial(_FrsMaterial);
|
tshape->setFrsMaterial(_FrsMaterial);
|
||||||
|
|
||||||
LineRep* line;
|
LineRep *line;
|
||||||
|
|
||||||
|
|
||||||
FEdge *firstEdge;
|
FEdge *firstEdge;
|
||||||
FEdge *nextFEdge, *currentEdge;
|
FEdge *nextFEdge, *currentEdge;
|
||||||
|
|
||||||
int id=0;
|
int id = 0;
|
||||||
// for(vector<ViewEdge*>::const_iterator c=viewedges.begin(),cend=viewedges.end();
|
//for (vector<ViewEdge*>::const_iterator c = viewedges.begin(), cend = viewedges.end(); c != cend; c++)
|
||||||
// c!=cend;
|
for (ViewEdgesIterator c = begin, cend = end; c != cend; c++) {
|
||||||
// c++)
|
#if 0
|
||||||
for(ViewEdgesIterator c=begin, cend=end;
|
if ((*c)->qi() > 0) {
|
||||||
c!=cend;
|
continue;
|
||||||
c++)
|
}
|
||||||
{
|
if (!((*c)->nature() & (_nature))) {
|
||||||
// if((*c)->qi() > 0){
|
continue;
|
||||||
// continue;
|
}
|
||||||
// }
|
#endif
|
||||||
// if(!((*c)->nature() & (_nature)))
|
|
||||||
// continue;
|
|
||||||
//
|
|
||||||
firstEdge = (*c)->fedgeA();
|
firstEdge = (*c)->fedgeA();
|
||||||
|
|
||||||
// if(firstEdge->invisibility() > 0)
|
#if 0
|
||||||
// continue;
|
if (firstEdge->invisibility() > 0)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
line = new OrientedLineRep();
|
line = new OrientedLineRep();
|
||||||
if(_overloadFrsMaterial)
|
if (_overloadFrsMaterial)
|
||||||
line->setFrsMaterial(_FrsMaterial);
|
line->setFrsMaterial(_FrsMaterial);
|
||||||
|
|
||||||
// there might be chains containing a single element
|
// there might be chains containing a single element
|
||||||
if(0 == (firstEdge)->nextEdge())
|
if (0 == (firstEdge)->nextEdge()) {
|
||||||
{
|
|
||||||
line->setStyle(LineRep::LINES);
|
line->setStyle(LineRep::LINES);
|
||||||
// line->AddVertex((*c)->vertexA()->point3D());
|
//line->AddVertex((*c)->vertexA()->point3D());
|
||||||
// line->AddVertex((*c)->vertexB()->point3D());
|
//line->AddVertex((*c)->vertexB()->point3D());
|
||||||
AddVertexToLine(line, firstEdge->vertexA());
|
AddVertexToLine(line, firstEdge->vertexA());
|
||||||
AddVertexToLine(line, firstEdge->vertexB());
|
AddVertexToLine(line, firstEdge->vertexB());
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
line->setStyle(LineRep::LINE_STRIP);
|
line->setStyle(LineRep::LINE_STRIP);
|
||||||
|
|
||||||
//firstEdge = (*c);
|
//firstEdge = (*c);
|
||||||
nextFEdge = firstEdge;
|
nextFEdge = firstEdge;
|
||||||
currentEdge = firstEdge;
|
currentEdge = firstEdge;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
//line->AddVertex(nextFEdge->vertexA()->point3D());
|
//line->AddVertex(nextFEdge->vertexA()->point3D());
|
||||||
AddVertexToLine(line, nextFEdge->vertexA());
|
AddVertexToLine(line, nextFEdge->vertexA());
|
||||||
currentEdge = nextFEdge;
|
currentEdge = nextFEdge;
|
||||||
nextFEdge = nextFEdge->nextEdge();
|
nextFEdge = nextFEdge->nextEdge();
|
||||||
}while((nextFEdge != NULL) && (nextFEdge != firstEdge));
|
} while ((nextFEdge != NULL) && (nextFEdge != firstEdge));
|
||||||
// Add the last vertex
|
// Add the last vertex
|
||||||
//line->AddVertex(currentEdge->vertexB()->point3D());
|
//line->AddVertex(currentEdge->vertexB()->point3D());
|
||||||
AddVertexToLine(line, currentEdge->vertexB());
|
AddVertexToLine(line, currentEdge->vertexB());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
line->setId((*c)->getId().getFirst());
|
line->setId((*c)->getId().getFirst());
|
||||||
@@ -193,4 +208,4 @@ NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesItera
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // VIEWMAPTESSELATOR_H
|
#endif // __FREESTYLE_VIEW_MAP_TESSELATOR_H__
|
||||||
|
|||||||
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU General Public License
|
||||||
* License as published by the Free Software Foundation; either
|
* as published by the Free Software Foundation; either version 2
|
||||||
* version 2 of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Library General Public
|
* You should have received a copy of the GNU General Public License
|
||||||
* License along with this library; if not, write to the
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
* Boston, MA 02111-1307, USA.
|
*
|
||||||
|
* This Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is:
|
||||||
|
* GTS - Library for the manipulation of triangulated surfaces
|
||||||
|
* Copyright (C) 1999 Stephane Popinet
|
||||||
|
* and:
|
||||||
|
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
|
||||||
|
* Copyright (C) 2000-2003 Bruno Levy
|
||||||
|
* Contact: Bruno Levy levy@loria.fr
|
||||||
|
* ISA Project
|
||||||
|
* LORIA, INRIA Lorraine,
|
||||||
|
* Campus Scientifique, BP 239
|
||||||
|
* 54506 VANDOEUVRE LES NANCY CEDEX
|
||||||
|
* FRANCE
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/winged_edge/Curvature.cpp
|
||||||
|
* \ingroup freestyle
|
||||||
|
* \brief GTS - Library for the manipulation of triangulated surfaces
|
||||||
|
* \author Stephane Popinet
|
||||||
|
* \date 1999
|
||||||
|
* \brief OGF/Graphite: Geometry and Graphics Programming Library + Utilities
|
||||||
|
* \author Bruno Levy
|
||||||
|
* \date 2000-2003
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstdlib> // for malloc and free
|
|
||||||
#include "Curvature.h"
|
|
||||||
#include <math.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "WEdge.h"
|
#include <cstdlib> // for malloc and free
|
||||||
#include "../system/FreestyleConfig.h"
|
#include <math.h>
|
||||||
#include "../geometry/normal_cycle.h"
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
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;
|
WOEdge *e;
|
||||||
f->getOppositeEdge (v, e);
|
f->getOppositeEdge(v, e);
|
||||||
|
|
||||||
Vec3r vec1(e->GetaVertex()->GetVertex()-v->GetVertex());
|
Vec3r vec1(e->GetaVertex()->GetVertex()-v->GetVertex());
|
||||||
Vec3r vec2(e->GetbVertex()->GetVertex()-v->GetVertex());
|
Vec3r vec2(e->GetbVertex()->GetVertex()-v->GetVertex());
|
||||||
@@ -39,52 +71,49 @@ static bool angle_obtuse (WVertex * v, WFace * f)
|
|||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
// WVvertex is useless but kept for history reasons
|
// 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;
|
bool b = false;
|
||||||
for (int i=0; i<3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
b = b ||
|
b = b || ((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i + 1) % 3]->GetVec()) < 0);
|
||||||
((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i+1)%3]->GetVec()) < 0);
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
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] */
|
/* cf. Appendix B of [Meyer et al 2002] */
|
||||||
real udotv, denom;
|
real udotv, denom;
|
||||||
|
|
||||||
Vec3r u(v1->GetVertex()- vo->GetVertex());
|
Vec3r u(v1->GetVertex() - vo->GetVertex());
|
||||||
Vec3r v(v2->GetVertex()- vo->GetVertex());
|
Vec3r v(v2->GetVertex() - vo->GetVertex());
|
||||||
|
|
||||||
udotv = u * v;
|
udotv = u * v;
|
||||||
denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
|
denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
|
||||||
|
|
||||||
/* denom can be zero if u==v. Returning 0 is acceptable, based on
|
/* denom can be zero if u==v. Returning 0 is acceptable, based on the callers of this function below. */
|
||||||
* the callers of this function below. */
|
if (denom == 0.0)
|
||||||
if (denom == 0.0) return (0.0);
|
return 0.0;
|
||||||
|
|
||||||
return (udotv / denom);
|
return (udotv / denom);
|
||||||
}
|
}
|
||||||
|
|
||||||
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] */
|
/* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */
|
||||||
real udotv, denom;
|
real udotv, denom;
|
||||||
|
|
||||||
Vec3r u (v1->GetVertex()-vo->GetVertex());
|
Vec3r u (v1->GetVertex() - vo->GetVertex());
|
||||||
Vec3r v(v2->GetVertex()-vo->GetVertex());
|
Vec3r v(v2->GetVertex() - vo->GetVertex());
|
||||||
|
|
||||||
udotv = u * v;
|
udotv = u * v;
|
||||||
denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
|
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) */
|
/* 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.
|
* @v: a #WVertex.
|
||||||
* @s: a #GtsSurface.
|
* @s: a #GtsSurface.
|
||||||
* @Kh: the Mean Curvature Normal at @v.
|
* @Kh: the Mean Curvature Normal at @v.
|
||||||
@@ -92,10 +121,9 @@ static real angle_from_cotan (WVertex * vo, WVertex * v1, WVertex * v2)
|
|||||||
* Computes the Discrete Mean Curvature Normal approximation at @v.
|
* Computes the Discrete Mean Curvature Normal approximation at @v.
|
||||||
* The mean curvature at @v is half the magnitude of the vector @Kh.
|
* The mean curvature at @v is half the magnitude of the vector @Kh.
|
||||||
*
|
*
|
||||||
* Note: the normal computed is not unit length, and may point either
|
* Note: the normal computed is not unit length, and may point either into or out of the surface, depending on
|
||||||
* into or out of the surface, depending on the curvature at @v. It
|
* the curvature at @v. It is the responsibility of the caller of the function to use the mean curvature normal
|
||||||
* is the responsibility of the caller of the function to use the mean
|
* appropriately.
|
||||||
* curvature normal appropriately.
|
|
||||||
*
|
*
|
||||||
* This approximation is from the paper:
|
* This approximation is from the paper:
|
||||||
* Discrete Differential-Geometry Operators for Triangulated 2-Manifolds
|
* Discrete Differential-Geometry Operators for Triangulated 2-Manifolds
|
||||||
@@ -103,56 +131,56 @@ static real angle_from_cotan (WVertex * vo, WVertex * v1, WVertex * v2)
|
|||||||
* VisMath '02, Berlin (Germany)
|
* VisMath '02, Berlin (Germany)
|
||||||
* http://www-grail.usc.edu/pubs.html
|
* http://www-grail.usc.edu/pubs.html
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the operator could be evaluated, %FALSE if the
|
* Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is
|
||||||
* evaluation failed for some reason (@v is boundary or is the
|
* boundary or is the endpoint of a non-manifold edge.)
|
||||||
* endpoint of a non-manifold edge.)
|
|
||||||
*/
|
*/
|
||||||
bool gts_vertex_mean_curvature_normal (WVertex * v, Vec3r &Kh)
|
bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh)
|
||||||
{
|
{
|
||||||
real area = 0.0;
|
real area = 0.0;
|
||||||
|
|
||||||
if (!v) return false;
|
if (!v)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* this operator is not defined for boundary edges */
|
/* this operator is not defined for boundary edges */
|
||||||
if (v->isBoundary()) return false;
|
if (v->isBoundary())
|
||||||
|
return false;
|
||||||
|
|
||||||
WVertex::incoming_edge_iterator itE;
|
WVertex::incoming_edge_iterator itE;
|
||||||
|
|
||||||
for (itE=v->incoming_edges_begin();
|
for (itE=v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
|
||||||
itE!=v->incoming_edges_end(); itE++)
|
area += (*itE)->GetaFace()->getArea();
|
||||||
area+=(*itE)->GetaFace()->getArea();
|
|
||||||
|
|
||||||
Kh=Vec3r(0.0, 0.0, 0.0);
|
Kh = Vec3r(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
for (itE=v->incoming_edges_begin();
|
for (itE=v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
|
||||||
itE!=v->incoming_edges_end(); itE++)
|
WOEdge *e = (*itE)->getPrevOnFace();
|
||||||
{
|
#if 0
|
||||||
WOEdge * e = (*itE)->getPrevOnFace();
|
if ((e->GetaVertex() == v) || (e->GetbVertex() == v))
|
||||||
//if ((e->GetaVertex()==v) || (e->GetbVertex()==v)) cerr<< "BUG ";
|
cerr<< "BUG ";
|
||||||
|
#endif
|
||||||
WVertex * v1 = e->GetaVertex();
|
WVertex *v1 = e->GetaVertex();
|
||||||
WVertex * v2 = e->GetbVertex();
|
WVertex *v2 = e->GetbVertex();
|
||||||
real temp;
|
real temp;
|
||||||
|
|
||||||
temp = cotan (v1, v, v2);
|
temp = cotan(v1, v, v2);
|
||||||
Kh = Vec3r(Kh+temp*(v2->GetVertex()-v->GetVertex()));
|
Kh = Vec3r(Kh + temp * (v2->GetVertex() - v->GetVertex()));
|
||||||
|
|
||||||
temp = cotan (v2, v, v1);
|
temp = cotan(v2, v, v1);
|
||||||
Kh = Vec3r(Kh+temp*(v1->GetVertex()-v->GetVertex()));
|
Kh = Vec3r(Kh + temp * (v1->GetVertex() - v->GetVertex()));
|
||||||
}
|
}
|
||||||
if (area > 0.0)
|
if (area > 0.0) {
|
||||||
{
|
Kh[0] /= 2 * area;
|
||||||
Kh[0] /= 2*area;
|
Kh[1] /= 2 * area;
|
||||||
Kh[1] /= 2*area;
|
Kh[2] /= 2 * area;
|
||||||
Kh[2] /= 2*area;
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*! gts_vertex_gaussian_curvature:
|
||||||
* gts_vertex_gaussian_curvature:
|
|
||||||
* @v: a #WVertex.
|
* @v: a #WVertex.
|
||||||
* @s: a #GtsSurface.
|
* @s: a #GtsSurface.
|
||||||
* @Kg: the Discrete Gaussian Curvature approximation at @v.
|
* @Kg: the Discrete Gaussian Curvature approximation at @v.
|
||||||
@@ -165,97 +193,92 @@ bool gts_vertex_mean_curvature_normal (WVertex * v, Vec3r &Kh)
|
|||||||
* VisMath '02, Berlin (Germany)
|
* VisMath '02, Berlin (Germany)
|
||||||
* http://www-grail.usc.edu/pubs.html
|
* http://www-grail.usc.edu/pubs.html
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the operator could be evaluated, %FALSE if the
|
* Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is
|
||||||
* evaluation failed for some reason (@v is boundary or is the
|
* boundary or is the endpoint of a non-manifold edge.)
|
||||||
* endpoint of a non-manifold edge.)
|
|
||||||
*/
|
*/
|
||||||
bool gts_vertex_gaussian_curvature (WVertex * v, real * Kg)
|
bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg)
|
||||||
{
|
{
|
||||||
real area = 0.0;
|
real area = 0.0;
|
||||||
real angle_sum = 0.0;
|
real angle_sum = 0.0;
|
||||||
|
|
||||||
if (!v) return false;
|
if (!v)
|
||||||
if (!Kg) return false;
|
return false;
|
||||||
|
if (!Kg)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* this operator is not defined for boundary edges */
|
/* this operator is not defined for boundary edges */
|
||||||
if (v->isBoundary()) {*Kg=0.0 ;return false;}
|
if (v->isBoundary()) {
|
||||||
|
*Kg = 0.0;
|
||||||
WVertex::incoming_edge_iterator itE;
|
return false;
|
||||||
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;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*! gts_vertex_principal_curvatures:
|
||||||
* gts_vertex_principal_curvatures:
|
|
||||||
* @Kh: mean curvature.
|
* @Kh: mean curvature.
|
||||||
* @Kg: Gaussian curvature.
|
* @Kg: Gaussian curvature.
|
||||||
* @K1: first principal curvature.
|
* @K1: first principal curvature.
|
||||||
* @K2: second principal curvature.
|
* @K2: second principal curvature.
|
||||||
*
|
*
|
||||||
* Computes the principal curvatures at a point given the mean and
|
* Computes the principal curvatures at a point given the mean and Gaussian curvatures at that point.
|
||||||
* Gaussian curvatures at that point.
|
|
||||||
*
|
*
|
||||||
* The mean curvature can be computed as one-half the magnitude of the
|
* The mean curvature can be computed as one-half the magnitude of the vector computed by
|
||||||
* vector computed by gts_vertex_mean_curvature_normal().
|
* gts_vertex_mean_curvature_normal().
|
||||||
*
|
*
|
||||||
* The Gaussian curvature can be computed with
|
* The Gaussian curvature can be computed with gts_vertex_gaussian_curvature().
|
||||||
* gts_vertex_gaussian_curvature().
|
|
||||||
*/
|
*/
|
||||||
void gts_vertex_principal_curvatures (real Kh, real Kg,
|
void gts_vertex_principal_curvatures (real Kh, real Kg, real *K1, real *K2)
|
||||||
real * K1, real * K2)
|
|
||||||
{
|
{
|
||||||
real temp = Kh*Kh - Kg;
|
real temp = Kh * Kh - Kg;
|
||||||
|
|
||||||
if (!K1) return;
|
if (!K1 || !K2)
|
||||||
if (!K1) return;
|
return;
|
||||||
|
|
||||||
if (temp < 0.0) temp = 0.0;
|
if (temp < 0.0)
|
||||||
|
temp = 0.0;
|
||||||
temp = sqrt (temp);
|
temp = sqrt (temp);
|
||||||
*K1 = Kh + temp;
|
*K1 = Kh + temp;
|
||||||
*K2 = Kh - temp;
|
*K2 = Kh - temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* from Maple */
|
/* from Maple */
|
||||||
static void linsolve (real m11, real m12, real b1,
|
static void linsolve(real m11, real m12, real b1, real m21, real m22, real b2, real *x1, real *x2)
|
||||||
real m21, real m22, real b2,
|
|
||||||
real * x1, real * x2)
|
|
||||||
{
|
{
|
||||||
real temp;
|
real temp;
|
||||||
|
|
||||||
temp = 1.0 / (m21*m12 - m11*m22);
|
temp = 1.0 / (m21 * m12 - m11 * m22);
|
||||||
*x1 = (m12*b2 - m22*b1)*temp;
|
*x1 = (m12 * b2 - m22 * b1) * temp;
|
||||||
*x2 = (m11*b2 - m21*b1)*temp;
|
*x2 = (m11 * b2 - m21 * b1) * temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* from Maple - largest eigenvector of [a b; b c] */
|
/* from Maple - largest eigenvector of [a b; b c] */
|
||||||
static void eigenvector (real a, real b, real c,
|
static void eigenvector(real a, real b, real c, Vec3r e)
|
||||||
Vec3r e)
|
|
||||||
{
|
{
|
||||||
if (b == 0.0) {
|
if (b == 0.0) {
|
||||||
e[0] = 0.0;
|
e[0] = 0.0;
|
||||||
} else {
|
}
|
||||||
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[1] = 1.0;
|
||||||
e[2] = 0.0;
|
e[2] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*! gts_vertex_principal_directions:
|
||||||
* gts_vertex_principal_directions:
|
|
||||||
* @v: a #WVertex.
|
* @v: a #WVertex.
|
||||||
* @s: a #GtsSurface.
|
* @s: a #GtsSurface.
|
||||||
* @Kh: mean curvature normal (a #Vec3r).
|
* @Kh: mean curvature normal (a #Vec3r).
|
||||||
@@ -263,18 +286,14 @@ static void eigenvector (real a, real b, real c,
|
|||||||
* @e1: first principal curvature direction (direction of largest curvature).
|
* @e1: first principal curvature direction (direction of largest curvature).
|
||||||
* @e2: second principal curvature direction.
|
* @e2: second principal curvature direction.
|
||||||
*
|
*
|
||||||
* Computes the principal curvature directions at a point given @Kh
|
* Computes the principal curvature directions at a point given @Kh and @Kg, the mean curvature normal and
|
||||||
* and @Kg, the mean curvature normal and Gaussian curvatures at that
|
* Gaussian curvatures at that point, computed with gts_vertex_mean_curvature_normal() and
|
||||||
* point, computed with gts_vertex_mean_curvature_normal() and
|
|
||||||
* gts_vertex_gaussian_curvature(), respectively.
|
* gts_vertex_gaussian_curvature(), respectively.
|
||||||
*
|
*
|
||||||
* Note that this computation is very approximate and tends to be
|
* Note that this computation is very approximate and tends to be unstable. Smoothing of the surface or the principal
|
||||||
* unstable. Smoothing of the surface or the principal directions may
|
* directions may be necessary to achieve reasonable results.
|
||||||
* be necessary to achieve reasonable results.
|
|
||||||
*/
|
*/
|
||||||
void gts_vertex_principal_directions (WVertex * v,
|
void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2)
|
||||||
Vec3r Kh, real Kg,
|
|
||||||
Vec3r &e1, Vec3r &e2)
|
|
||||||
{
|
{
|
||||||
Vec3r N;
|
Vec3r N;
|
||||||
real normKh;
|
real normKh;
|
||||||
@@ -296,22 +315,21 @@ void gts_vertex_principal_directions (WVertex * v,
|
|||||||
|
|
||||||
if (normKh > 0.0) {
|
if (normKh > 0.0) {
|
||||||
Kh.normalize();
|
Kh.normalize();
|
||||||
} else {
|
}
|
||||||
/* This vertex is a point of zero mean curvature (flat or saddle
|
else {
|
||||||
* point). Compute a normal by averaging the adjacent triangles
|
/* This vertex is a point of zero mean curvature (flat or saddle point). Compute a normal by averaging
|
||||||
|
* the adjacent triangles
|
||||||
*/
|
*/
|
||||||
N[0] = N[1] = N[2] = 0.0;
|
N[0] = N[1] = N[2] = 0.0;
|
||||||
|
|
||||||
for (itE=v->incoming_edges_begin();
|
for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
|
||||||
itE!=v->incoming_edges_end(); itE++)
|
N = Vec3r(N + (*itE)->GetaFace()->GetNormal());
|
||||||
N=Vec3r(N+(*itE)->GetaFace()->GetNormal());
|
|
||||||
real normN = N.norm();
|
real normN = N.norm();
|
||||||
if (normN <= 0.0)
|
if (normN <= 0.0)
|
||||||
return;
|
return;
|
||||||
N.normalize();
|
N.normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* construct a basis from N: */
|
/* construct a basis from N: */
|
||||||
/* set basis1 to any component not the largest of N */
|
/* set basis1 to any component not the largest of N */
|
||||||
basis1[0] = basis1[1] = basis1[2] = 0.0;
|
basis1[0] = basis1[1] = basis1[2] = 0.0;
|
||||||
@@ -332,90 +350,79 @@ void gts_vertex_principal_directions (WVertex * v,
|
|||||||
aterm_db = bterm_db = cterm_db = const_db = 0.0;
|
aterm_db = bterm_db = cterm_db = const_db = 0.0;
|
||||||
int nb_edges=v->GetEdges().size();
|
int nb_edges=v->GetEdges().size();
|
||||||
|
|
||||||
weights = (real *) malloc (sizeof (real)*nb_edges);
|
weights = (real *)malloc(sizeof (real) * nb_edges);
|
||||||
kappas = (real*) malloc (sizeof (real)*nb_edges);
|
kappas = (real *)malloc(sizeof (real) * nb_edges);
|
||||||
d1s = (real*) malloc (sizeof (real)*nb_edges);
|
d1s = (real *)malloc(sizeof (real) * nb_edges);
|
||||||
d2s = (real*) malloc (sizeof (real)*nb_edges);
|
d2s = (real *)malloc(sizeof (real) * nb_edges);
|
||||||
edge_count = 0;
|
edge_count = 0;
|
||||||
|
|
||||||
for (itE=v->incoming_edges_begin();
|
for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
|
||||||
itE!=v->incoming_edges_end(); itE++)
|
WOEdge *e;
|
||||||
{
|
WFace *f1, *f2;
|
||||||
WOEdge * e;
|
|
||||||
WFace * f1, * f2;
|
|
||||||
real weight, kappa, d1, d2;
|
real weight, kappa, d1, d2;
|
||||||
Vec3r vec_edge;
|
Vec3r vec_edge;
|
||||||
if (! *itE) continue;
|
if (!*itE)
|
||||||
|
continue;
|
||||||
e = *itE;
|
e = *itE;
|
||||||
|
|
||||||
/* since this vertex passed the tests in
|
/* since this vertex passed the tests in gts_vertex_mean_curvature_normal(), this should be true. */
|
||||||
* gts_vertex_mean_curvature_normal(), this should be true. */
|
//g_assert(gts_edge_face_number (e, s) == 2);
|
||||||
//g_assert (gts_edge_face_number (e, s) == 2);
|
|
||||||
|
|
||||||
/* identify the two triangles bordering e in s */
|
/* identify the two triangles bordering e in s */
|
||||||
f1=e->GetaFace();
|
f1 = e->GetaFace();
|
||||||
f2=e->GetbFace();
|
f2 = e->GetbFace();
|
||||||
|
|
||||||
/* We are solving for the values of the curvature tensor
|
/* We are solving for the values of the curvature tensor
|
||||||
* B = [ a b ; b c ].
|
* B = [ a b ; b c ].
|
||||||
* The computations here are from section 5 of [Meyer et al 2002].
|
* The computations here are from section 5 of [Meyer et al 2002].
|
||||||
*
|
*
|
||||||
* The first step is to calculate the linear equations governing
|
* The first step is to calculate the linear equations governing the values of (a,b,c). These can be computed
|
||||||
* the values of (a,b,c). These can be computed by setting the
|
* by setting the derivatives of the error E to zero (section 5.3).
|
||||||
* derivatives of the error E to zero (section 5.3).
|
|
||||||
*
|
*
|
||||||
* Since a + c = norm(Kh), we only compute the linear equations
|
* Since a + c = norm(Kh), we only compute the linear equations for dE/da and dE/db. (NB: [Meyer et al 2002]
|
||||||
* for dE/da and dE/db. (NB: [Meyer et al 2002] has the
|
* has the equation a + b = norm(Kh), but I'm almost positive this is incorrect).
|
||||||
* equation a + b = norm(Kh), but I'm almost positive this is
|
|
||||||
* incorrect.)
|
|
||||||
*
|
*
|
||||||
* Note that the w_ij (defined in section 5.2) are all scaled by
|
* Note that the w_ij (defined in section 5.2) are all scaled by (1/8*A_mixed). We drop this uniform scale
|
||||||
* (1/8*A_mixed). We drop this uniform scale factor because the
|
* factor because the solution of the linear equations doesn't rely on it.
|
||||||
* solution of the linear equations doesn't rely on it.
|
|
||||||
*
|
*
|
||||||
* The terms of the linear equations are xterm_dy with x in
|
* The terms of the linear equations are xterm_dy with x in {a,b,c} and y in {a,b}. There are also const_dy
|
||||||
* {a,b,c} and y in {a,b}. There are also const_dy terms that are
|
* terms that are the constant factors in the equations.
|
||||||
* the constant factors in the equations.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* find the vector from v along edge e */
|
/* find the vector from v along edge e */
|
||||||
vec_edge=Vec3r(-1*e->GetVec());
|
vec_edge = Vec3r(-1 * e->GetVec());
|
||||||
|
|
||||||
ve2 = vec_edge.squareNorm();
|
ve2 = vec_edge.squareNorm();
|
||||||
vdotN = vec_edge * N;
|
vdotN = vec_edge * N;
|
||||||
|
|
||||||
/* section 5.2 - There is a typo in the computation of kappa. The
|
/* section 5.2 - There is a typo in the computation of kappa. The edges should be x_j-x_i. */
|
||||||
* edges should be x_j-x_i.
|
|
||||||
*/
|
|
||||||
kappa = 2.0 * vdotN / ve2;
|
kappa = 2.0 * vdotN / ve2;
|
||||||
|
|
||||||
/* section 5.2 */
|
/* section 5.2 */
|
||||||
|
|
||||||
/* I don't like performing a minimization where some of the
|
/* I don't like performing a minimization where some of the weights can be negative (as can be the case
|
||||||
* weights can be negative (as can be the case if f1 or f2 are
|
* if f1 or f2 are obtuse). To ensure all-positive weights, we check for obtuseness. */
|
||||||
* obtuse). To ensure all-positive weights, we check for
|
|
||||||
* obtuseness. */
|
|
||||||
weight = 0.0;
|
weight = 0.0;
|
||||||
if (! triangle_obtuse(v, f1)) {
|
if (!triangle_obtuse(v, f1)) {
|
||||||
weight += ve2 *
|
weight += ve2 * cotan(f1->GetNextOEdge(e->twin())->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
|
||||||
cotan (f1->GetNextOEdge(e->twin())->GetbVertex(),
|
}
|
||||||
e->GetaVertex(), e->GetbVertex()) / 8.0;
|
else {
|
||||||
} else {
|
if (angle_obtuse(v, f1)) {
|
||||||
if (angle_obtuse (v, f1)) {
|
|
||||||
weight += ve2 * f1->getArea() / 4.0;
|
weight += ve2 * f1->getArea() / 4.0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
weight += ve2 * f1->getArea() / 8.0;
|
weight += ve2 * f1->getArea() / 8.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! triangle_obtuse(v, f2)) {
|
if (!triangle_obtuse(v, f2)) {
|
||||||
weight += ve2 *
|
weight += ve2 * cotan (f2->GetNextOEdge(e)->GetbVertex(), e->GetaVertex(), e->GetbVertex()) / 8.0;
|
||||||
cotan (f2->GetNextOEdge(e)->GetbVertex(),
|
}
|
||||||
e->GetaVertex(), e->GetbVertex()) / 8.0;
|
else {
|
||||||
} else {
|
if (angle_obtuse(v, f2)) {
|
||||||
if (angle_obtuse (v, f2)) {
|
|
||||||
weight += ve2 * f1->getArea() / 4.0;
|
weight += ve2 * f1->getArea() / 4.0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
weight += ve2 * f1->getArea() / 8.0;
|
weight += ve2 * f1->getArea() / 8.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -441,13 +448,12 @@ void gts_vertex_principal_directions (WVertex * v,
|
|||||||
aterm_da += weight * d1 * d1 * d1 * d1;
|
aterm_da += weight * d1 * d1 * d1 * d1;
|
||||||
bterm_da += weight * d1 * d1 * 2 * d1 * d2;
|
bterm_da += weight * d1 * d1 * 2 * d1 * d2;
|
||||||
cterm_da += weight * d1 * d1 * d2 * 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;
|
aterm_db += weight * d1 * d2 * d1 * d1;
|
||||||
bterm_db += weight * d1 * d2 * 2 * d1 * d2;
|
bterm_db += weight * d1 * d2 * 2 * d1 * d2;
|
||||||
cterm_db += weight * d1 * d2 * d2 * d2;
|
cterm_db += weight * d1 * d2 * d2 * d2;
|
||||||
const_db += weight * d1 * d2 * (- kappa);
|
const_db += weight * d1 * d2 * (-kappa);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */
|
/* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */
|
||||||
@@ -458,33 +464,28 @@ void gts_vertex_principal_directions (WVertex * v,
|
|||||||
const_db += cterm_db * normKh;
|
const_db += cterm_db * normKh;
|
||||||
|
|
||||||
/* check for solvability of the linear system */
|
/* check for solvability of the linear system */
|
||||||
if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) &&
|
if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) && ((const_da != 0.0) || (const_db != 0.0))) {
|
||||||
((const_da != 0.0) || (const_db != 0.0))) {
|
linsolve(aterm_da, bterm_da, -const_da, aterm_db, bterm_db, -const_db, &a, &b);
|
||||||
linsolve (aterm_da, bterm_da, -const_da,
|
|
||||||
aterm_db, bterm_db, -const_db,
|
|
||||||
&a, &b);
|
|
||||||
|
|
||||||
c = normKh - a;
|
c = normKh - a;
|
||||||
|
|
||||||
eigenvector (a, b, c, eig);
|
eigenvector(a, b, c, eig);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
/* region of v is planar */
|
/* region of v is planar */
|
||||||
eig[0] = 1.0;
|
eig[0] = 1.0;
|
||||||
eig[1] = 0.0;
|
eig[1] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Although the eigenvectors of B are good estimates of the
|
/* Although the eigenvectors of B are good estimates of the principal directions, it seems that which one is
|
||||||
* principal directions, it seems that which one is attached to
|
* attached to which curvature direction is a bit arbitrary. This may be a bug in my implementation, or just
|
||||||
* which curvature direction is a bit arbitrary. This may be a bug
|
* a side-effect of the inaccuracy of B due to the discrete nature of the sampling.
|
||||||
* in my implementation, or just a side-effect of the inaccuracy of
|
|
||||||
* B due to the discrete nature of the sampling.
|
|
||||||
*
|
*
|
||||||
* To overcome this behavior, we'll evaluate which assignment best
|
* To overcome this behavior, we'll evaluate which assignment best matches the given eigenvectors by comparing
|
||||||
* matches the given eigenvectors by comparing the curvature
|
* the curvature estimates computed above and the curvatures calculated from the discrete differential operators.
|
||||||
* estimates computed above and the curvatures calculated from the
|
*/
|
||||||
* discrete differential operators. */
|
|
||||||
|
|
||||||
gts_vertex_principal_curvatures (0.5 * normKh, Kg, &K1, &K2);
|
gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2);
|
||||||
|
|
||||||
err_e1 = err_e2 = 0.0;
|
err_e1 = err_e2 = 0.0;
|
||||||
/* loop through the values previously saved */
|
/* loop through the values previously saved */
|
||||||
@@ -535,112 +536,107 @@ void gts_vertex_principal_directions (WVertex * v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace OGF {
|
namespace OGF {
|
||||||
inline static real angle(WOEdge * h) {
|
|
||||||
|
inline static real angle(WOEdge *h)
|
||||||
|
{
|
||||||
const Vec3r& n1 = h->GetbFace()->GetNormal();
|
const Vec3r& n1 = h->GetbFace()->GetNormal();
|
||||||
const Vec3r& n2 = h->GetaFace()->GetNormal();
|
const Vec3r& n2 = h->GetaFace()->GetNormal();
|
||||||
const Vec3r v = h->getVec3r();
|
const Vec3r v = h->getVec3r();
|
||||||
real sine = (n1 ^ n2) * v / v.norm() ;
|
real sine = (n1 ^ n2) * v / v.norm();
|
||||||
if(sine >= 1.0) {
|
if (sine >= 1.0) {
|
||||||
return M_PI / 2.0 ;
|
return M_PI / 2.0;
|
||||||
}
|
}
|
||||||
if(sine <= -1.0) {
|
if (sine <= -1.0) {
|
||||||
return -M_PI / 2.0 ;
|
return -M_PI / 2.0;
|
||||||
}
|
|
||||||
return ::asin(sine) ;
|
|
||||||
}
|
}
|
||||||
|
return ::asin(sine);
|
||||||
|
}
|
||||||
|
|
||||||
// precondition1: P is inside the sphere
|
// precondition1: P is inside the sphere
|
||||||
// precondition2: P,V points to the outside of
|
// precondition2: P,V points to the outside of the sphere (i.e. OP.V > 0)
|
||||||
// the sphere (i.e. OP.V > 0)
|
static bool sphere_clip_vector(const Vec3r& O, real r, const Vec3r& P, Vec3r& V)
|
||||||
static bool sphere_clip_vector(
|
{
|
||||||
const Vec3r& O, real r,
|
Vec3r W = P - O;
|
||||||
const Vec3r& P, Vec3r& V
|
real a = V.squareNorm();
|
||||||
) {
|
real b = 2.0 * V * W;
|
||||||
|
real c = W.squareNorm() - r * r;
|
||||||
Vec3r W = P - O ;
|
real delta = b * b - 4 * a * c;
|
||||||
real a = V.squareNorm() ;
|
if (delta < 0) {
|
||||||
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)
|
// Should not happen, but happens sometimes (numerical precision)
|
||||||
return true ;
|
return true;
|
||||||
}
|
}
|
||||||
real t = - b + ::sqrt(delta) / (2.0 * a) ;
|
real t = - b + ::sqrt(delta) / (2.0 * a);
|
||||||
if(t < 0.0) {
|
if (t < 0.0) {
|
||||||
// Should not happen, but happens sometimes (numerical precision)
|
// Should not happen, but happens sometimes (numerical precision)
|
||||||
return true ;
|
return true;
|
||||||
}
|
}
|
||||||
if(t >= 1.0) {
|
if (t >= 1.0) {
|
||||||
// Inside the sphere
|
// Inside the sphere
|
||||||
return false ;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
V[0] = (t * V.x()) ;
|
V[0] = (t * V.x());
|
||||||
V[1] = (t * V.y()) ;
|
V[1] = (t * V.y());
|
||||||
V[2] = (t * V.z()) ;
|
V[2] = (t * V.z());
|
||||||
|
|
||||||
return true ;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check optimizations:
|
// TODO: check optimizations:
|
||||||
// use marking ? (measure *timings* ...)
|
// use marking ? (measure *timings* ...)
|
||||||
void compute_curvature_tensor(
|
void compute_curvature_tensor(WVertex *start, real radius, NormalCycle& nc)
|
||||||
WVertex* start, real radius, NormalCycle& nc
|
{
|
||||||
) {
|
|
||||||
// in case we have a non-manifold vertex, skip it...
|
// in case we have a non-manifold vertex, skip it...
|
||||||
if(start->isBoundary())
|
if(start->isBoundary())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::set<WVertex*> vertices ;
|
std::set<WVertex*> vertices;
|
||||||
const Vec3r& O = start->GetVertex() ;
|
const Vec3r& O = start->GetVertex();
|
||||||
std::stack<WVertex*> S ;
|
std::stack<WVertex*> S;
|
||||||
S.push(start) ;
|
S.push(start);
|
||||||
vertices.insert(start) ;
|
vertices.insert(start);
|
||||||
while(!S.empty()) {
|
while (!S.empty()) {
|
||||||
WVertex* v = S.top() ;
|
WVertex *v = S.top();
|
||||||
S.pop() ;
|
S.pop();
|
||||||
if(v->isBoundary())
|
if (v->isBoundary())
|
||||||
continue;
|
continue;
|
||||||
const Vec3r& P = v->GetVertex() ;
|
const Vec3r& P = v->GetVertex();
|
||||||
WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin();
|
WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin();
|
||||||
WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end();
|
WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end();
|
||||||
for(;woeit!=woeitend; ++woeit){
|
for (; woeit != woeitend; ++woeit) {
|
||||||
WOEdge *h = *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());
|
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
|
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) {
|
if (!isect) {
|
||||||
WVertex* w = h->GetaVertex() ;
|
WVertex *w = h->GetaVertex();
|
||||||
if(vertices.find(w) == vertices.end()) {
|
if (vertices.find(w) == vertices.end()) {
|
||||||
vertices.insert(w) ;
|
vertices.insert(w);
|
||||||
S.push(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...
|
// in case we have a non-manifold vertex, skip it...
|
||||||
if(start->isBoundary())
|
if (start->isBoundary())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WVertex::incoming_edge_iterator woeit = start->incoming_edges_begin();
|
WVertex::incoming_edge_iterator woeit = start->incoming_edges_begin();
|
||||||
WVertex::incoming_edge_iterator woeitend = start->incoming_edges_end();
|
WVertex::incoming_edge_iterator woeitend = start->incoming_edges_end();
|
||||||
for(;woeit!=woeitend; ++woeit){
|
for (; woeit != woeitend; ++woeit) {
|
||||||
WOEdge *h = (*woeit)->twin();
|
WOEdge *h = (*woeit)->twin();
|
||||||
nc.accumulate_dihedral_angle(h->GetVec(), h->GetAngle()) ;
|
nc.accumulate_dihedral_angle(h->GetVec(), h->GetAngle());
|
||||||
WOEdge *hprev = h->getPrevOnFace();
|
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
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
* Copyright (C) 1999 Stéphane Popinet
|
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU General Public License
|
||||||
* License as published by the Free Software Foundation; either
|
* as published by the Free Software Foundation; either version 2
|
||||||
* version 2 of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Library General Public
|
* You should have received a copy of the GNU General Public License
|
||||||
* License along with this library; if not, write to the
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
* Boston, MA 02111-1307, USA.
|
*
|
||||||
|
* This Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is:
|
||||||
|
* GTS - Library for the manipulation of triangulated surfaces
|
||||||
|
* Copyright (C) 1999 Stephane Popinet
|
||||||
|
* and:
|
||||||
|
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
|
||||||
|
* Copyright (C) 2000-2003 Bruno Levy
|
||||||
|
* Contact: Bruno Levy levy@loria.fr
|
||||||
|
* ISA Project
|
||||||
|
* LORIA, INRIA Lorraine,
|
||||||
|
* Campus Scientifique, BP 239
|
||||||
|
* 54506 VANDOEUVRE LES NANCY CEDEX
|
||||||
|
* FRANCE
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CURVATURE_H__
|
#ifndef __FREESTYLE_CURVATURE_H__
|
||||||
#define __CURVATURE_H__
|
#define __FREESTYLE_CURVATURE_H__
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/winged_edge/Curvature.h
|
||||||
|
* \ingroup freestyle
|
||||||
|
* \brief GTS - Library for the manipulation of triangulated surfaces
|
||||||
|
* \author Stephane Popinet
|
||||||
|
* \date 1999
|
||||||
|
* \brief OGF/Graphite: Geometry and Graphics Programming Library + Utilities
|
||||||
|
* \author Bruno Levy
|
||||||
|
* \date 2000-2003
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../geometry/Geom.h"
|
||||||
|
|
||||||
|
#include "../system/FreestyleConfig.h"
|
||||||
|
#include "../system/Precision.h"
|
||||||
|
|
||||||
# include "../system/FreestyleConfig.h"
|
|
||||||
# include "../system/Precision.h"
|
|
||||||
# include "../geometry/Geom.h"
|
|
||||||
using namespace Geometry;
|
using namespace Geometry;
|
||||||
|
|
||||||
class WVertex;
|
class WVertex;
|
||||||
@@ -31,19 +61,19 @@ class WVertex;
|
|||||||
class LIB_WINGED_EDGE_EXPORT CurvatureInfo
|
class LIB_WINGED_EDGE_EXPORT CurvatureInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CurvatureInfo()
|
CurvatureInfo()
|
||||||
{
|
{
|
||||||
K1 = 0.0;
|
K1 = 0.0;
|
||||||
K2 = 0.0;
|
K2 = 0.0;
|
||||||
e1 = Vec3r(0.0,0.0,0.0);
|
e1 = Vec3r(0.0, 0.0, 0.0);
|
||||||
e2 = Vec3r(0.0,0.0,0.0);
|
e2 = Vec3r(0.0, 0.0, 0.0);
|
||||||
Kr = 0.0;
|
Kr = 0.0;
|
||||||
dKr = 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;
|
K1 = iBrother.K1;
|
||||||
K2 = iBrother.K2;
|
K2 = iBrother.K2;
|
||||||
e1 = iBrother.e1;
|
e1 = iBrother.e1;
|
||||||
@@ -53,7 +83,8 @@ public:
|
|||||||
er = iBrother.er;
|
er = iBrother.er;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t) {
|
CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t)
|
||||||
|
{
|
||||||
K1 = ca.K1 + t * (cb.K1 - ca.K1);
|
K1 = ca.K1 + t * (cb.K1 - ca.K1);
|
||||||
K2 = ca.K2 + t * (cb.K2 - ca.K2);
|
K2 = ca.K2 + t * (cb.K2 - ca.K2);
|
||||||
e1 = ca.e1 + t * (cb.e1 - ca.e1);
|
e1 = ca.e1 + t * (cb.e1 - ca.e1);
|
||||||
@@ -72,85 +103,41 @@ public:
|
|||||||
Vec3r er; // radial curvature direction
|
Vec3r er; // radial curvature direction
|
||||||
};
|
};
|
||||||
|
|
||||||
class Face_Curvature_Info{
|
class Face_Curvature_Info
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
Face_Curvature_Info() {}
|
Face_Curvature_Info() {}
|
||||||
~Face_Curvature_Info(){
|
|
||||||
for(vector<CurvatureInfo*>::iterator ci=vec_curvature_info.begin(), ciend=vec_curvature_info.end();
|
~Face_Curvature_Info()
|
||||||
ci!=ciend;
|
{
|
||||||
++ci){
|
for (vector<CurvatureInfo*>::iterator ci = vec_curvature_info.begin(), ciend = vec_curvature_info.end();
|
||||||
|
ci != ciend;
|
||||||
|
++ci)
|
||||||
|
{
|
||||||
delete (*ci);
|
delete (*ci);
|
||||||
}
|
}
|
||||||
vec_curvature_info.clear();
|
vec_curvature_info.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<CurvatureInfo *> vec_curvature_info;
|
vector<CurvatureInfo *> vec_curvature_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal (WVertex * v,
|
bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &n);
|
||||||
Vec3r &n);
|
|
||||||
|
|
||||||
bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature (WVertex * v,
|
bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature(WVertex *v, real *Kg);
|
||||||
real * Kg);
|
|
||||||
|
|
||||||
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures (real Kh,
|
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2);
|
||||||
real Kg,
|
|
||||||
real * K1,
|
|
||||||
real * K2);
|
|
||||||
|
|
||||||
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions (WVertex * v,
|
void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2);
|
||||||
Vec3r Kh,
|
|
||||||
real Kg,
|
|
||||||
Vec3r &e1,
|
|
||||||
Vec3r &e2);
|
|
||||||
|
|
||||||
/*
|
namespace OGF {
|
||||||
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
|
|
||||||
* Copyright (C) 2000-2003 Bruno Levy
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
* If you modify this software, you should include a notice giving the
|
|
||||||
* name of the person performing the modification, the date of modification,
|
|
||||||
* and the reason for such modification.
|
|
||||||
*
|
|
||||||
* Contact: Bruno Levy
|
|
||||||
*
|
|
||||||
* levy@loria.fr
|
|
||||||
*
|
|
||||||
* ISA Project
|
|
||||||
* LORIA, INRIA Lorraine,
|
|
||||||
* Campus Scientifique, BP 239
|
|
||||||
* 54506 VANDOEUVRE LES NANCY CEDEX
|
|
||||||
* FRANCE
|
|
||||||
*
|
|
||||||
* Note that the GNU General Public License does not permit incorporating
|
|
||||||
* the Software into proprietary programs.
|
|
||||||
*/
|
|
||||||
namespace OGF {
|
|
||||||
|
|
||||||
class NormalCycle ;
|
class NormalCycle ;
|
||||||
|
|
||||||
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor(
|
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( WVertex *start, double radius, NormalCycle& nc);
|
||||||
WVertex* start, double radius, NormalCycle& nc
|
|
||||||
) ;
|
|
||||||
|
|
||||||
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(
|
void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc);
|
||||||
WVertex* start, NormalCycle& nc
|
|
||||||
) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} // OGF namespace
|
||||||
|
|
||||||
#endif /* __CURVATURE_H__ */
|
#endif /* __FREESTYLE_CURVATURE_H__ */
|
||||||
|
|
||||||
|
|||||||
@@ -1,79 +1,79 @@
|
|||||||
//
|
/*
|
||||||
// Filename : Nature.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Emmanuel Turquin
|
*
|
||||||
// Purpose : Different natures for both vertices and edges
|
* This program is free software; you can redistribute it and/or
|
||||||
// Date of creation : 01/07/2003
|
* modify it under the terms of the GNU General Public License
|
||||||
//
|
* as published by the Free Software Foundation; either version 2
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
//
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// with this source distribution.
|
* GNU General Public License for more details.
|
||||||
//
|
*
|
||||||
// This program is free software; you can redistribute it and/or
|
* You should have received a copy of the GNU General Public License
|
||||||
// modify it under the terms of the GNU General Public License
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
// as published by the Free Software Foundation; either version 2
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
// of the License, or (at your option) any later version.
|
*
|
||||||
//
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
// This program is distributed in the hope that it will be useful,
|
* All rights reserved.
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
*
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* The Original Code is: all of this file.
|
||||||
// GNU General Public License for more details.
|
*
|
||||||
//
|
* Contributor(s): none yet.
|
||||||
// You should have received a copy of the GNU General Public License
|
*
|
||||||
// along with this program; if not, write to the Free Software
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef NATURE_H
|
|
||||||
# define NATURE_H
|
|
||||||
|
|
||||||
/*! \file Nature.h
|
|
||||||
* Definitions of Natures of the ViewMap's elements
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! Namespace gathering the different possible
|
#ifndef __FREESTYLE_NATURE_H__
|
||||||
* natures of 0D and 1D elements of the ViewMap
|
#define __FREESTYLE_NATURE_H__
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/winged_edge/Nature.h
|
||||||
|
* \ingroup freestyle
|
||||||
|
* \brief Different natures for both vertices and edges
|
||||||
|
* \author Emmanuel Turquin
|
||||||
|
* \date 01/07/2003
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*! Namespace gathering the different possible natures of 0D and 1D elements of the ViewMap */
|
||||||
namespace Nature {
|
namespace Nature {
|
||||||
|
|
||||||
typedef unsigned short VertexNature;
|
/* XXX Why not using enums??? */
|
||||||
|
|
||||||
/*! true for any 0D element */
|
typedef unsigned short VertexNature;
|
||||||
static const VertexNature POINT = 0; // 0
|
/*! true for any 0D element */
|
||||||
/*! true for SVertex */
|
static const VertexNature POINT = 0; // 0
|
||||||
static const VertexNature S_VERTEX = (1 << 0); // 1
|
/*! true for SVertex */
|
||||||
/*! true for ViewVertex */
|
static const VertexNature S_VERTEX = (1 << 0); // 1
|
||||||
static const VertexNature VIEW_VERTEX = (1 << 1); // 2
|
/*! true for ViewVertex */
|
||||||
/*! true for NonTVertex */
|
static const VertexNature VIEW_VERTEX = (1 << 1); // 2
|
||||||
static const VertexNature NON_T_VERTEX = (1 << 2); // 4
|
/*! true for NonTVertex */
|
||||||
/*! true for TVertex */
|
static const VertexNature NON_T_VERTEX = (1 << 2); // 4
|
||||||
static const VertexNature T_VERTEX = (1 << 3); // 8
|
/*! true for TVertex */
|
||||||
/*! true for CUSP */
|
static const VertexNature T_VERTEX = (1 << 3); // 8
|
||||||
static const VertexNature CUSP = (1 << 4); // 16
|
/*! true for CUSP */
|
||||||
|
static const VertexNature CUSP = (1 << 4); // 16
|
||||||
|
|
||||||
typedef unsigned short EdgeNature;
|
typedef unsigned short EdgeNature;
|
||||||
/*! true for non feature edges (always false for 1D elements of the ViewMap) */
|
/*! true for non feature edges (always false for 1D elements of the ViewMap) */
|
||||||
static const EdgeNature NO_FEATURE = 0; // 0
|
static const EdgeNature NO_FEATURE = 0; // 0
|
||||||
/*! true for silhouettes */
|
/*! true for silhouettes */
|
||||||
static const EdgeNature SILHOUETTE = (1 << 0); // 1
|
static const EdgeNature SILHOUETTE = (1 << 0); // 1
|
||||||
/*! true for borders */
|
/*! true for borders */
|
||||||
static const EdgeNature BORDER = (1 << 1); // 2
|
static const EdgeNature BORDER = (1 << 1); // 2
|
||||||
/*! true for creases */
|
/*! true for creases */
|
||||||
static const EdgeNature CREASE = (1 << 2); // 4
|
static const EdgeNature CREASE = (1 << 2); // 4
|
||||||
/*! true for ridges */
|
/*! true for ridges */
|
||||||
static const EdgeNature RIDGE = (1 << 3); // 8
|
static const EdgeNature RIDGE = (1 << 3); // 8
|
||||||
/*! true for valleys */
|
/*! true for valleys */
|
||||||
static const EdgeNature VALLEY = (1 << 4); // 16
|
static const EdgeNature VALLEY = (1 << 4); // 16
|
||||||
/*! true for suggestive contours */
|
/*! true for suggestive contours */
|
||||||
static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32
|
static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32
|
||||||
/*! true for material boundaries */
|
/*! true for material boundaries */
|
||||||
static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64
|
static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64
|
||||||
/*! true for user-defined edge marks */
|
/*! true for user-defined edge marks */
|
||||||
static const EdgeNature EDGE_MARK = (1 << 7); // 128
|
static const EdgeNature EDGE_MARK = (1 << 7); // 128
|
||||||
|
|
||||||
} // end of namespace Nature
|
} // 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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/winged_edge/WEdge.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Classes to define a Winged Edge data structure.
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 18/02/2002
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "WEdge.h"
|
#include "WEdge.h"
|
||||||
|
|
||||||
/*! Temporary structures */
|
/*! Temporary structures */
|
||||||
@@ -48,13 +62,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**********************************/
|
/**********************************
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/* WVertex */
|
* WVertex *
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/**********************************/
|
**********************************/
|
||||||
|
|
||||||
WVertex::WVertex(WVertex& iBrother)
|
WVertex::WVertex(WVertex& iBrother)
|
||||||
{
|
{
|
||||||
@@ -67,106 +81,119 @@ WVertex::WVertex(WVertex& iBrother)
|
|||||||
_Border = iBrother._Border;
|
_Border = iBrother._Border;
|
||||||
userdata = NULL;
|
userdata = NULL;
|
||||||
iBrother.userdata = new vertexdata;
|
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);
|
WVertex *clone = new WVertex(*this);
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WOEdge *WVertex::incoming_edge_iterator::operator*()
|
||||||
WOEdge* WVertex::incoming_edge_iterator::operator*()
|
|
||||||
|
|
||||||
{
|
{
|
||||||
return _current;
|
return _current;
|
||||||
}
|
}
|
||||||
void WVertex::incoming_edge_iterator::increment(){
|
|
||||||
|
void WVertex::incoming_edge_iterator::increment()
|
||||||
|
{
|
||||||
WOEdge *twin = _current->twin();
|
WOEdge *twin = _current->twin();
|
||||||
if(!twin){
|
if (!twin) {
|
||||||
// we reached a hole
|
// we reached a hole
|
||||||
_current = 0;
|
_current = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WOEdge *next = twin->getPrevOnFace();
|
WOEdge *next = twin->getPrevOnFace();
|
||||||
if(next == _begin){
|
if (next == _begin) {
|
||||||
next = 0;
|
next = NULL;
|
||||||
}
|
}
|
||||||
_current = next;
|
_current = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
WFace* WVertex::face_iterator::operator*(){
|
WFace *WVertex::face_iterator::operator*()
|
||||||
WOEdge * woedge = *_edge_it;
|
{
|
||||||
if(woedge == 0)
|
WOEdge *woedge = *_edge_it;
|
||||||
return 0;
|
if (!woedge)
|
||||||
|
return NULL;
|
||||||
return (woedge)->GetbFace();
|
return (woedge)->GetbFace();
|
||||||
}
|
}
|
||||||
|
|
||||||
//bool WVertex::isBoundary () const{
|
#if 0
|
||||||
// return _Border;
|
bool WVertex::isBoundary () const
|
||||||
//}
|
{
|
||||||
|
return _Border;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
bool WVertex::isBoundary ()
|
bool WVertex::isBoundary ()
|
||||||
{
|
{
|
||||||
if(_Border == 1)
|
if (_Border == 1)
|
||||||
return true;
|
return true;
|
||||||
else if(_Border == 0)
|
else if (_Border == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
vector<WEdge *>::const_iterator it;
|
vector<WEdge *>::const_iterator it;
|
||||||
for(it=_EdgeList.begin(); it!=_EdgeList.end(); it++){
|
for (it = _EdgeList.begin(); it != _EdgeList.end(); it++) {
|
||||||
if((*it)->GetNumberOfOEdges() == 1){
|
if ((*it)->GetNumberOfOEdges() == 1) {
|
||||||
_Border = 1;
|
_Border = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (!(*it)->GetaOEdge()->GetaFace()) return true;
|
#if 0
|
||||||
|
if (!(*it)->GetaOEdge()->GetaFace())
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
_Border = 0;
|
_Border = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WVertex::AddEdge(WEdge *iEdge) {
|
void WVertex::AddEdge(WEdge *iEdge)
|
||||||
|
{
|
||||||
_EdgeList.push_back(iEdge);
|
_EdgeList.push_back(iEdge);
|
||||||
}
|
}
|
||||||
|
|
||||||
WVertex::incoming_edge_iterator WVertex::incoming_edges_begin(){
|
WVertex::incoming_edge_iterator WVertex::incoming_edges_begin()
|
||||||
|
{
|
||||||
WOEdge *begin;
|
WOEdge *begin;
|
||||||
WEdge * wedge = _EdgeList.front();
|
WEdge *wedge = _EdgeList.front();
|
||||||
WOEdge* aOEdge = wedge->GetaOEdge();
|
WOEdge *aOEdge = wedge->GetaOEdge();
|
||||||
if(aOEdge->GetbVertex() == this)
|
if (aOEdge->GetbVertex() == this)
|
||||||
begin = aOEdge;
|
begin = aOEdge;
|
||||||
else
|
else
|
||||||
begin = _EdgeList.front()->GetbOEdge();
|
begin = _EdgeList.front()->GetbOEdge();
|
||||||
return incoming_edge_iterator(this, begin, begin);
|
return incoming_edge_iterator(this, begin, begin);
|
||||||
}
|
}
|
||||||
WVertex::incoming_edge_iterator WVertex::incoming_edges_end(){
|
|
||||||
|
WVertex::incoming_edge_iterator WVertex::incoming_edges_end()
|
||||||
|
{
|
||||||
WOEdge *begin;
|
WOEdge *begin;
|
||||||
WOEdge* aOEdge = _EdgeList.front()->GetaOEdge();
|
WOEdge *aOEdge = _EdgeList.front()->GetaOEdge();
|
||||||
if(aOEdge->GetbVertex() == this)
|
if (aOEdge->GetbVertex() == this)
|
||||||
begin = aOEdge;
|
begin = aOEdge;
|
||||||
else
|
else
|
||||||
begin = _EdgeList.front()->GetbOEdge();
|
begin = _EdgeList.front()->GetbOEdge();
|
||||||
return incoming_edge_iterator(this, begin, 0);
|
return incoming_edge_iterator(this, begin, 0);
|
||||||
}
|
}
|
||||||
//WOEdge** WVertex::incoming_edge_iterator::operator->()
|
#if 0
|
||||||
//{
|
WOEdge **WVertex::incoming_edge_iterator::operator->()
|
||||||
// WOEdge ** ppaOEdge = (*_iter)->GetaOEdge();
|
{
|
||||||
// if(aOEdge->GetbVertex() == _vertex)
|
WOEdge **ppaOEdge = (*_iter)->GetaOEdge();
|
||||||
// return ppaOEdge;
|
if (aOEdge->GetbVertex() == _vertex) {
|
||||||
// else
|
return ppaOEdge;
|
||||||
// {
|
}
|
||||||
// WOEdge *bOEdge = (*_iter)->GetbOEdge();
|
else {
|
||||||
// return &bOEdge;
|
WOEdge *bOEdge = (*_iter)->GetbOEdge();
|
||||||
// }
|
return &bOEdge;
|
||||||
//
|
}
|
||||||
//}
|
}
|
||||||
/**********************************/
|
#endif
|
||||||
/* */
|
|
||||||
/* */
|
/**********************************
|
||||||
/* WOEdge */
|
* *
|
||||||
/* */
|
* *
|
||||||
/* */
|
* WOEdge *
|
||||||
/**********************************/
|
* *
|
||||||
|
* *
|
||||||
|
**********************************/
|
||||||
|
|
||||||
WOEdge::WOEdge(WOEdge& iBrother)
|
WOEdge::WOEdge(WOEdge& iBrother)
|
||||||
{
|
{
|
||||||
@@ -177,42 +204,40 @@ WOEdge::WOEdge(WOEdge& iBrother)
|
|||||||
_pOwner = iBrother.GetOwner();
|
_pOwner = iBrother.GetOwner();
|
||||||
userdata = NULL;
|
userdata = NULL;
|
||||||
iBrother.userdata = new oedgedata;
|
iBrother.userdata = new oedgedata;
|
||||||
((oedgedata*)(iBrother.userdata))->_copy = this;
|
((oedgedata *)(iBrother.userdata))->_copy = this;
|
||||||
|
|
||||||
_vec = iBrother._vec;
|
_vec = iBrother._vec;
|
||||||
_angle = iBrother._angle;
|
_angle = iBrother._angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
WOEdge * WOEdge::duplicate()
|
WOEdge *WOEdge::duplicate()
|
||||||
{
|
{
|
||||||
WOEdge *clone = new WOEdge(*this);
|
WOEdge *clone = new WOEdge(*this);
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3r
|
Vec3r WOEdge::getVec3r ()
|
||||||
WOEdge::getVec3r ()
|
|
||||||
{
|
{
|
||||||
return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex());
|
return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex());
|
||||||
}
|
}
|
||||||
|
|
||||||
WOEdge * WOEdge::twin ()
|
WOEdge *WOEdge::twin ()
|
||||||
{
|
{
|
||||||
return GetOwner()->GetOtherOEdge(this);
|
return GetOwner()->GetOtherOEdge(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
WOEdge *
|
WOEdge *WOEdge::getPrevOnFace()
|
||||||
WOEdge::getPrevOnFace()
|
|
||||||
{
|
{
|
||||||
return _pbFace->GetPrevOEdge(this);
|
return _pbFace->GetPrevOEdge(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************/
|
/**********************************
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/* WEdge */
|
* WEdge *
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/**********************************/
|
**********************************/
|
||||||
|
|
||||||
WEdge::WEdge(WEdge& iBrother)
|
WEdge::WEdge(WEdge& iBrother)
|
||||||
{
|
{
|
||||||
@@ -222,33 +247,32 @@ WEdge::WEdge(WEdge& iBrother)
|
|||||||
WOEdge *boedge = iBrother.GetbOEdge();
|
WOEdge *boedge = iBrother.GetbOEdge();
|
||||||
userdata = NULL;
|
userdata = NULL;
|
||||||
|
|
||||||
if(NULL != aoedge)
|
if (aoedge)
|
||||||
//_paOEdge = new WOEdge(*aoedge);
|
//_paOEdge = new WOEdge(*aoedge);
|
||||||
_paOEdge = aoedge->duplicate();
|
_paOEdge = aoedge->duplicate();
|
||||||
if(NULL != boedge)
|
if (boedge)
|
||||||
//_pbOEdge = new WOEdge(*boedge);
|
//_pbOEdge = new WOEdge(*boedge);
|
||||||
_pbOEdge = boedge->duplicate();
|
_pbOEdge = boedge->duplicate();
|
||||||
|
|
||||||
_nOEdges = iBrother.GetNumberOfOEdges();
|
_nOEdges = iBrother.GetNumberOfOEdges();
|
||||||
_Id = iBrother.GetId();
|
_Id = iBrother.GetId();
|
||||||
iBrother.userdata = new edgedata;
|
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);
|
WEdge *clone = new WEdge(*this);
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************/
|
/**********************************
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/* WFace */
|
* WFace *
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/**********************************/
|
**********************************/
|
||||||
|
|
||||||
|
|
||||||
WFace::WFace(WFace& iBrother)
|
WFace::WFace(WFace& iBrother)
|
||||||
{
|
{
|
||||||
@@ -261,36 +285,30 @@ WFace::WFace(WFace& iBrother)
|
|||||||
_Mark = iBrother._Mark;
|
_Mark = iBrother._Mark;
|
||||||
userdata = NULL;
|
userdata = NULL;
|
||||||
iBrother.userdata = new facedata;
|
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;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FrsMaterial& WFace::frs_material() {
|
const FrsMaterial& WFace::frs_material()
|
||||||
|
{
|
||||||
return getShape()->frs_material(_FrsMaterialIndex);
|
return getShape()->frs_material(_FrsMaterialIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
WOEdge *WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
||||||
{
|
{
|
||||||
// First check whether the same oriented edge already exists
|
// First check whether the same oriented edge already exists or not:
|
||||||
// or not:
|
|
||||||
vector<WEdge *>& v1Edges = v1->GetEdges();
|
vector<WEdge *>& v1Edges = v1->GetEdges();
|
||||||
for(vector<WEdge*>::iterator it1=v1Edges.begin(), end=v1Edges.end();
|
for (vector<WEdge*>::iterator it1 = v1Edges.begin(), end = v1Edges.end(); it1 != end; it1++) {
|
||||||
it1!=end;
|
WEdge *we = (*it1);
|
||||||
it1++)
|
|
||||||
{
|
|
||||||
|
|
||||||
WEdge *we=(*it1);
|
|
||||||
|
|
||||||
WOEdge *woea = we->GetaOEdge();
|
WOEdge *woea = we->GetaOEdge();
|
||||||
|
|
||||||
if((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2))
|
//if ((*it1)->GetbVertex() == v2) {
|
||||||
//if((*it1)->GetbVertex() == v2)
|
if ((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) {
|
||||||
{
|
|
||||||
// The oriented edge already exists
|
// The oriented edge already exists
|
||||||
cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
|
cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
|
||||||
// Adds the edge to the face
|
// Adds the edge to the face
|
||||||
@@ -305,11 +323,8 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
WOEdge *woeb = we->GetbOEdge();
|
WOEdge *woeb = we->GetbOEdge();
|
||||||
if((woeb != 0) && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2))
|
//if ((*it1)->GetbVertex() == v2)
|
||||||
|
if (woeb && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2)) {
|
||||||
//if((*it1)->GetbVertex() == v2)
|
|
||||||
|
|
||||||
{
|
|
||||||
// The oriented edge already exists
|
// The oriented edge already exists
|
||||||
cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
|
cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
|
||||||
// Adds the edge to the face
|
// Adds the edge to the face
|
||||||
@@ -326,20 +341,17 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
|||||||
|
|
||||||
// the oriented edge we're about to build
|
// the oriented edge we're about to build
|
||||||
WOEdge *pOEdge = new WOEdge;
|
WOEdge *pOEdge = new WOEdge;
|
||||||
|
// The edge containing the oriented edge.
|
||||||
WEdge * edge; // The edge containing the oriented edge.
|
WEdge *edge;
|
||||||
|
|
||||||
// checks whether this edge already exists or not
|
// checks whether this edge already exists or not
|
||||||
// If it exists, it points outward v2
|
// If it exists, it points outward v2
|
||||||
|
|
||||||
bool exist = false;
|
bool exist = false;
|
||||||
WOEdge *pInvertEdge = NULL; // The inverted edge if it exists
|
WOEdge *pInvertEdge = NULL; // The inverted edge if it exists
|
||||||
vector<WEdge *>& v2Edges = v2->GetEdges();
|
vector<WEdge *>& v2Edges = v2->GetEdges();
|
||||||
vector<WEdge *>::iterator it;
|
vector<WEdge *>::iterator it;
|
||||||
for(it=v2Edges.begin(); it!=v2Edges.end(); it++)
|
for (it = v2Edges.begin(); it != v2Edges.end(); it++) {
|
||||||
{
|
if ((*it)->GetbVertex() == v1) {
|
||||||
if((*it)->GetbVertex() == v1)
|
|
||||||
{
|
|
||||||
// The invert edge already exists
|
// The invert edge already exists
|
||||||
exist = true;
|
exist = true;
|
||||||
pInvertEdge = (*it)->GetaOEdge();
|
pInvertEdge = (*it)->GetaOEdge();
|
||||||
@@ -348,10 +360,7 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//DEBUG:
|
//DEBUG:
|
||||||
|
if (true == exist) { // The invert edge already exists
|
||||||
|
|
||||||
if(true == exist) // The invert edge already exists
|
|
||||||
{
|
|
||||||
// Retrieves the corresponding edge
|
// Retrieves the corresponding edge
|
||||||
edge = pInvertEdge->GetOwner();
|
edge = pInvertEdge->GetOwner();
|
||||||
|
|
||||||
@@ -361,8 +370,7 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
|||||||
// Updates the invert edge:
|
// Updates the invert edge:
|
||||||
pInvertEdge->setaFace(this);
|
pInvertEdge->setaFace(this);
|
||||||
}
|
}
|
||||||
else // The invert edge does not exist yet
|
else { // The invert edge does not exist yet
|
||||||
{
|
|
||||||
// we must create a new edge
|
// we must create a new edge
|
||||||
//edge = new WEdge;
|
//edge = new WEdge;
|
||||||
edge = instanciateEdge();
|
edge = instanciateEdge();
|
||||||
@@ -370,7 +378,6 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
|||||||
// updates the a,b vertex edges list:
|
// updates the a,b vertex edges list:
|
||||||
v1->AddEdge(edge);
|
v1->AddEdge(edge);
|
||||||
v2->AddEdge(edge);
|
v2->AddEdge(edge);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pOEdge->setOwner(edge);
|
pOEdge->setOwner(edge);
|
||||||
@@ -379,11 +386,11 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
|||||||
pOEdge->setbVertex(v2);
|
pOEdge->setbVertex(v2);
|
||||||
|
|
||||||
// Debug:
|
// Debug:
|
||||||
if(v1->GetId() == v2->GetId())
|
if (v1->GetId() == v2->GetId())
|
||||||
cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl;
|
cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl;
|
||||||
|
|
||||||
edge->AddOEdge(pOEdge);
|
edge->AddOEdge(pOEdge);
|
||||||
//edge->setNumberOfOEdges(edge->GetNumberOfOEdges()+1);
|
//edge->setNumberOfOEdges(edge->GetNumberOfOEdges() + 1);
|
||||||
|
|
||||||
// Add this face (the b face)
|
// Add this face (the b face)
|
||||||
pOEdge->setbFace(this);
|
pOEdge->setbFace(this);
|
||||||
@@ -395,82 +402,83 @@ WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool WFace::getOppositeEdge (const WVertex *v, WOEdge *&e)
|
||||||
WFace::getOppositeEdge (const WVertex *v, WOEdge* &e)
|
|
||||||
{
|
{
|
||||||
if (_OEdgeList.size()!=3) return false;
|
if (_OEdgeList.size() != 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
vector<WOEdge *>::iterator it;
|
vector<WOEdge *>::iterator it;
|
||||||
e=NULL;
|
e = NULL;
|
||||||
for(it=_OEdgeList.begin(); it!=_OEdgeList.end(); it++)
|
for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) {
|
||||||
if ((*it)->GetaVertex()==v) e=*it;
|
if ((*it)->GetaVertex() == v)
|
||||||
if (!e) return false;
|
e = *it;
|
||||||
e=NULL;
|
}
|
||||||
for(it=_OEdgeList.begin(); it!=_OEdgeList.end(); it++)
|
if (!e)
|
||||||
if (((*it)->GetaVertex()!=v) && ((*it)->GetbVertex()!=v)) e=*it;
|
return false;
|
||||||
if (!e) return false;
|
e = NULL;
|
||||||
else return true;
|
for (it = _OEdgeList.begin(); it != _OEdgeList.end(); it++) {
|
||||||
|
if (((*it)->GetaVertex() != v) && ((*it)->GetbVertex() != v))
|
||||||
|
e = *it;
|
||||||
|
}
|
||||||
|
if (!e)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
real
|
real WFace::getArea ()
|
||||||
WFace::getArea ()
|
|
||||||
{
|
{
|
||||||
vector<WOEdge *>::iterator it;
|
vector<WOEdge *>::iterator it;
|
||||||
Vec3r origin=(*(_OEdgeList.begin()))->GetaVertex()->GetVertex();
|
Vec3r origin = (*(_OEdgeList.begin()))->GetaVertex()->GetVertex();
|
||||||
it=_OEdgeList.begin();
|
it = _OEdgeList.begin();
|
||||||
real a=0;
|
real a = 0;
|
||||||
for (it=it++; it!=_OEdgeList.end(); it++) {
|
for (it = it++; it != _OEdgeList.end(); it++) {
|
||||||
Vec3r v1=Vec3r((*it)->GetaVertex()->GetVertex() - origin);
|
Vec3r v1 = Vec3r((*it)->GetaVertex()->GetVertex() - origin);
|
||||||
Vec3r v2=Vec3r((*it)->GetbVertex()->GetVertex() - origin);
|
Vec3r v2 = Vec3r((*it)->GetbVertex()->GetVertex() - origin);
|
||||||
a += (v1 ^ v2).norm() / 2.0;
|
a += (v1 ^ v2).norm() / 2.0;
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WOEdge*
|
WOEdge *WFace::GetPrevOEdge(WOEdge* iOEdge)
|
||||||
WFace::GetPrevOEdge(WOEdge* iOEdge)
|
{
|
||||||
{
|
vector<WOEdge *>::iterator woe, woend, woefirst;
|
||||||
vector<WOEdge*>::iterator woe,woend, woefirst;
|
|
||||||
woefirst = _OEdgeList.begin();
|
woefirst = _OEdgeList.begin();
|
||||||
woend=_OEdgeList.end();
|
woend = _OEdgeList.end();
|
||||||
WOEdge *prev =*woefirst;
|
WOEdge *prev = *woefirst;
|
||||||
woe=woefirst;
|
woe = woefirst;
|
||||||
woe++;
|
++woe;
|
||||||
for(;
|
for (; woe != woend; woe++) {
|
||||||
woe!=woend;
|
if ((*woe) == iOEdge)
|
||||||
woe++)
|
|
||||||
{
|
|
||||||
if((*woe) == iOEdge)
|
|
||||||
return prev;
|
return prev;
|
||||||
prev= *woe;
|
prev = *woe;
|
||||||
}
|
}
|
||||||
// We left the loop. That means that the first
|
// We left the loop. That means that the first OEdge was the good one:
|
||||||
// OEdge was the good one:
|
if ((*woefirst) == iOEdge)
|
||||||
if((*woefirst)==iOEdge)
|
|
||||||
return prev;
|
return prev;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
WShape * WFace::getShape()
|
WShape *WFace::getShape()
|
||||||
{
|
{
|
||||||
return GetVertex(0)->shape();
|
return GetVertex(0)->shape();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************/
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* WShape */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/**********************************/
|
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
* WShape *
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
**********************************/
|
||||||
|
|
||||||
LIB_WINGED_EDGE_EXPORT
|
LIB_WINGED_EDGE_EXPORT
|
||||||
unsigned WShape::_SceneCurrentId = 0;
|
unsigned WShape::_SceneCurrentId = 0;
|
||||||
|
|
||||||
WShape * WShape::duplicate()
|
WShape *WShape::duplicate()
|
||||||
{
|
{
|
||||||
WShape *clone = new WShape(*this);
|
WShape *clone = new WShape(*this);
|
||||||
return clone;
|
return clone;
|
||||||
@@ -483,12 +491,9 @@ WShape::WShape(WShape& iBrother)
|
|||||||
_FrsMaterials = iBrother._FrsMaterials;
|
_FrsMaterials = iBrother._FrsMaterials;
|
||||||
_meanEdgeSize = iBrother._meanEdgeSize;
|
_meanEdgeSize = iBrother._meanEdgeSize;
|
||||||
iBrother.bbox(_min, _max);
|
iBrother.bbox(_min, _max);
|
||||||
vector<WVertex*>& vertexList = iBrother.getVertexList();
|
vector<WVertex *>& vertexList = iBrother.getVertexList();
|
||||||
vector<WVertex*>::iterator v=vertexList.begin(), vend=vertexList.end();
|
vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end();
|
||||||
for(;
|
for (; v != vend; ++v) {
|
||||||
v!=vend;
|
|
||||||
v++)
|
|
||||||
{
|
|
||||||
//WVertex *newVertex = new WVertex(*(*v));
|
//WVertex *newVertex = new WVertex(*(*v));
|
||||||
WVertex *newVertex = (*v)->duplicate();
|
WVertex *newVertex = (*v)->duplicate();
|
||||||
|
|
||||||
@@ -496,90 +501,72 @@ WShape::WShape(WShape& iBrother)
|
|||||||
AddVertex(newVertex);
|
AddVertex(newVertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<WEdge*>& edgeList = iBrother.getEdgeList();
|
vector<WEdge *>& edgeList = iBrother.getEdgeList();
|
||||||
vector<WEdge*>::iterator e=edgeList.begin(), eend=edgeList.end();
|
vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end();
|
||||||
for(;
|
for (; e != eend; ++e) {
|
||||||
e!=eend;
|
|
||||||
e++)
|
|
||||||
{
|
|
||||||
//WEdge *newEdge = new WEdge(*(*e));
|
//WEdge *newEdge = new WEdge(*(*e));
|
||||||
WEdge *newEdge = (*e)->duplicate();
|
WEdge *newEdge = (*e)->duplicate();
|
||||||
AddEdge(newEdge);
|
AddEdge(newEdge);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<WFace*>& faceList = iBrother.GetFaceList();
|
vector<WFace *>& faceList = iBrother.GetFaceList();
|
||||||
vector<WFace*>::iterator f=faceList.begin(), fend=faceList.end();
|
vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end();
|
||||||
for(;
|
for (; f != fend; ++f) {
|
||||||
f!=fend;
|
|
||||||
f++)
|
|
||||||
{
|
|
||||||
//WFace *newFace = new WFace(*(*f));
|
//WFace *newFace = new WFace(*(*f));
|
||||||
WFace *newFace = (*f)->duplicate();
|
WFace *newFace = (*f)->duplicate();
|
||||||
AddFace(newFace);
|
AddFace(newFace);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update all pointed addresses thanks to the newly created objects:
|
// update all pointed addresses thanks to the newly created objects:
|
||||||
vend=_VertexList.end();
|
vend = _VertexList.end();
|
||||||
for(v=_VertexList.begin();
|
for (v = _VertexList.begin(); v != vend; ++v) {
|
||||||
v!=vend;
|
const vector<WEdge *>& vedgeList = (*v)->GetEdges();
|
||||||
v++)
|
vector<WEdge *> newvedgelist;
|
||||||
{
|
|
||||||
const vector<WEdge*>& vedgeList = (*v)->GetEdges();
|
|
||||||
vector<WEdge*> newvedgelist;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for(i=0; i<vedgeList.size(); i++)
|
for (i = 0; i < vedgeList.size(); i++) {
|
||||||
{
|
|
||||||
WEdge *current = vedgeList[i];
|
WEdge *current = vedgeList[i];
|
||||||
edgedata * currentvedata = (edgedata*)current->userdata;
|
edgedata *currentvedata = (edgedata *)current->userdata;
|
||||||
newvedgelist.push_back(currentvedata->_copy);
|
newvedgelist.push_back(currentvedata->_copy);
|
||||||
}
|
}
|
||||||
(*v)->setEdges(newvedgelist);
|
(*v)->setEdges(newvedgelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
eend = _EdgeList.end();
|
eend = _EdgeList.end();
|
||||||
for(e=_EdgeList.begin();
|
for (e = _EdgeList.begin(); e != eend; ++e) {
|
||||||
e!=eend;
|
|
||||||
e++)
|
|
||||||
{
|
|
||||||
// update aOedge:
|
// update aOedge:
|
||||||
WOEdge *aoEdge = (*e)->GetaOEdge();
|
WOEdge *aoEdge = (*e)->GetaOEdge();
|
||||||
aoEdge->setaVertex(((vertexdata*)(aoEdge->GetaVertex()->userdata))->_copy);
|
aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy);
|
||||||
aoEdge->setbVertex(((vertexdata*)(aoEdge->GetbVertex()->userdata))->_copy);
|
aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy);
|
||||||
if(NULL != aoEdge->GetaFace())
|
if (aoEdge->GetaFace())
|
||||||
aoEdge->setaFace(((facedata*)(aoEdge->GetaFace()->userdata))->_copy);
|
aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy);
|
||||||
aoEdge->setbFace(((facedata*)(aoEdge->GetbFace()->userdata))->_copy);
|
aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy);
|
||||||
aoEdge->setOwner(((edgedata*)(aoEdge->GetOwner()->userdata))->_copy);
|
aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy);
|
||||||
// update bOedge:
|
|
||||||
|
|
||||||
|
// update bOedge:
|
||||||
WOEdge *boEdge = (*e)->GetbOEdge();
|
WOEdge *boEdge = (*e)->GetbOEdge();
|
||||||
if(boEdge != 0)
|
if (boEdge) {
|
||||||
{
|
boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy);
|
||||||
boEdge->setaVertex(((vertexdata*)(boEdge->GetaVertex()->userdata))->_copy);
|
boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy);
|
||||||
boEdge->setbVertex(((vertexdata*)(boEdge->GetbVertex()->userdata))->_copy);
|
if (boEdge->GetaFace())
|
||||||
if(NULL != boEdge->GetaFace())
|
boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy);
|
||||||
boEdge->setaFace(((facedata*)(boEdge->GetaFace()->userdata))->_copy);
|
boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy);
|
||||||
boEdge->setbFace(((facedata*)(boEdge->GetbFace()->userdata))->_copy);
|
boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy);
|
||||||
boEdge->setOwner(((edgedata*)(boEdge->GetOwner()->userdata))->_copy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fend = _FaceList.end();
|
fend = _FaceList.end();
|
||||||
for(f=_FaceList.begin();
|
for (f = _FaceList.begin(); f != fend; ++f) {
|
||||||
f!=fend;
|
unsigned int i;
|
||||||
f++)
|
const vector<WOEdge *>& oedgeList = (*f)->getEdgeList();
|
||||||
{
|
vector<WOEdge *> newoedgelist;
|
||||||
unsigned i;
|
|
||||||
const vector<WOEdge*>& oedgeList = (*f)->getEdgeList();
|
|
||||||
vector<WOEdge*> newoedgelist;
|
|
||||||
|
|
||||||
unsigned n = oedgeList.size();
|
unsigned int n = oedgeList.size();
|
||||||
for(i=0; i<n; i++)
|
for (i = 0; i < n; i++) {
|
||||||
{
|
|
||||||
WOEdge *current = oedgeList[i];
|
WOEdge *current = oedgeList[i];
|
||||||
oedgedata * currentoedata = (oedgedata*)current->userdata;
|
oedgedata *currentoedata = (oedgedata *)current->userdata;
|
||||||
newoedgelist.push_back(currentoedata->_copy);
|
newoedgelist.push_back(currentoedata->_copy);
|
||||||
//oedgeList[i] = currentoedata->_copy;
|
//oedgeList[i] = currentoedata->_copy;
|
||||||
//oedgeList[i] = ((oedgedata*)(oedgeList[i]->userdata))->_copy;
|
//oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy;
|
||||||
}
|
}
|
||||||
(*f)->setEdgeList(newoedgelist);
|
(*f)->setEdgeList(newoedgelist);
|
||||||
}
|
}
|
||||||
@@ -587,65 +574,54 @@ WShape::WShape(WShape& iBrother)
|
|||||||
// Free all memory (arghh!)
|
// Free all memory (arghh!)
|
||||||
// Vertex
|
// Vertex
|
||||||
vend = iBrother.getVertexList().end();
|
vend = iBrother.getVertexList().end();
|
||||||
for(v=iBrother.getVertexList().begin();
|
for (v = iBrother.getVertexList().begin(); v != vend; ++v) {
|
||||||
v!=vend;
|
delete (vertexdata *)((*v)->userdata);
|
||||||
v++)
|
|
||||||
{
|
|
||||||
delete (vertexdata*)((*v)->userdata);
|
|
||||||
(*v)->userdata = NULL;
|
(*v)->userdata = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edges and OEdges:
|
// Edges and OEdges:
|
||||||
eend = iBrother.getEdgeList().end();
|
eend = iBrother.getEdgeList().end();
|
||||||
for(e=iBrother.getEdgeList().begin();
|
for (e = iBrother.getEdgeList().begin(); e != eend; ++e) {
|
||||||
e!=eend;
|
delete (edgedata *)((*e)->userdata);
|
||||||
e++)
|
|
||||||
{
|
|
||||||
delete (edgedata*)((*e)->userdata);
|
|
||||||
(*e)->userdata = NULL;
|
(*e)->userdata = NULL;
|
||||||
// OEdge a :
|
// OEdge a:
|
||||||
delete (oedgedata*)((*e)->GetaOEdge()->userdata);
|
delete (oedgedata *)((*e)->GetaOEdge()->userdata);
|
||||||
(*e)->GetaOEdge()->userdata = NULL;
|
(*e)->GetaOEdge()->userdata = NULL;
|
||||||
// OEdge b:
|
// OEdge b:
|
||||||
WOEdge* oedgeb = (*e)->GetbOEdge();
|
WOEdge *oedgeb = (*e)->GetbOEdge();
|
||||||
if(NULL != oedgeb)
|
if (oedgeb) {
|
||||||
{
|
delete (oedgedata *)(oedgeb->userdata);
|
||||||
delete (oedgedata*)(oedgeb->userdata);
|
|
||||||
oedgeb->userdata = NULL;
|
oedgeb->userdata = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Faces
|
// Faces
|
||||||
fend = iBrother.GetFaceList().end();
|
fend = iBrother.GetFaceList().end();
|
||||||
for(f=iBrother.GetFaceList().begin();
|
for (f = iBrother.GetFaceList().begin(); f != fend; ++f) {
|
||||||
f!=fend;
|
delete (facedata *)((*f)->userdata);
|
||||||
f++)
|
|
||||||
{
|
|
||||||
delete (facedata*)((*f)->userdata);
|
|
||||||
(*f)->userdata = NULL;
|
(*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
|
// allocate the new face
|
||||||
WFace *face = instanciateFace();
|
WFace *face = instanciateFace();
|
||||||
|
|
||||||
WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face);
|
WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face);
|
||||||
if (0 == result) {
|
if (!result)
|
||||||
delete face;
|
delete face;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
|
WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
|
||||||
|
vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
|
||||||
{
|
{
|
||||||
// allocate the new face
|
// allocate the new face
|
||||||
WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial);
|
WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial);
|
||||||
|
|
||||||
if(0 == face)
|
if (!face)
|
||||||
|
return NULL;
|
||||||
return 0;
|
|
||||||
|
|
||||||
// set the list of per-vertex normals
|
// set the list of per-vertex normals
|
||||||
face->setNormalList(iNormalsList);
|
face->setNormalList(iNormalsList);
|
||||||
@@ -655,9 +631,9 @@ WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsL
|
|||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial, WFace *face)
|
WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial,
|
||||||
|
WFace *face)
|
||||||
{
|
{
|
||||||
|
|
||||||
int id = _FaceList.size();
|
int id = _FaceList.size();
|
||||||
|
|
||||||
face->setFrsMaterialIndex(iMaterial);
|
face->setFrsMaterialIndex(iMaterial);
|
||||||
@@ -666,26 +642,16 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
|
|||||||
|
|
||||||
// LET'S HACK IT FOR THE TRIANGLE CASE:
|
// LET'S HACK IT FOR THE TRIANGLE CASE:
|
||||||
|
|
||||||
if(3 == iVertexList.size())
|
if (3 == iVertexList.size()) {
|
||||||
|
if ((iVertexList[0] == iVertexList[1]) ||
|
||||||
{
|
(iVertexList[0] == iVertexList[2]) ||
|
||||||
|
(iVertexList[2] == iVertexList[1])) {
|
||||||
if((iVertexList[0] == iVertexList[1])
|
|
||||||
|
|
||||||
|| (iVertexList[0] == iVertexList[2])
|
|
||||||
|
|
||||||
|| (iVertexList[2] == iVertexList[1]))
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
cerr << "Warning: degenerated triangle detected, correcting" << endl;
|
cerr << "Warning: degenerated triangle detected, correcting" << endl;
|
||||||
return 0;
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
vector<WVertex *>::iterator it;
|
||||||
|
|
||||||
vector<WVertex*>::iterator it;
|
|
||||||
|
|
||||||
// compute the face normal (v1v2 ^ v1v3)
|
// compute the face normal (v1v2 ^ v1v3)
|
||||||
WVertex *v1, *v2, *v3;
|
WVertex *v1, *v2, *v3;
|
||||||
@@ -696,8 +662,8 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
|
|||||||
it++;
|
it++;
|
||||||
v3 = *it;
|
v3 = *it;
|
||||||
|
|
||||||
Vec3r vector1(v2->GetVertex()-v1->GetVertex());
|
Vec3r vector1(v2->GetVertex() - v1->GetVertex());
|
||||||
Vec3r vector2(v3->GetVertex()-v1->GetVertex());
|
Vec3r vector2(v3->GetVertex() - v1->GetVertex());
|
||||||
|
|
||||||
Vec3r normal(vector1 ^ vector2);
|
Vec3r normal(vector1 ^ vector2);
|
||||||
normal.normalize();
|
normal.normalize();
|
||||||
@@ -708,32 +674,27 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
|
|||||||
mit++;
|
mit++;
|
||||||
|
|
||||||
// vertex pointers used to build each edge
|
// vertex pointers used to build each edge
|
||||||
vector<WVertex*>::iterator va, vb;
|
vector<WVertex *>::iterator va, vb;
|
||||||
|
|
||||||
va = iVertexList.begin();
|
va = iVertexList.begin();
|
||||||
vb = va;
|
vb = va;
|
||||||
for(; va != iVertexList.end(); va = vb)
|
for (; va != iVertexList.end(); va = vb) {
|
||||||
{
|
++vb;
|
||||||
vb++;
|
|
||||||
// Adds va to the vertex list:
|
// Adds va to the vertex list:
|
||||||
//face->AddVertex(*va);
|
//face->AddVertex(*va);
|
||||||
|
|
||||||
WOEdge * oedge;
|
WOEdge *oedge;
|
||||||
if(*va == iVertexList.back())
|
if (*va == iVertexList.back())
|
||||||
oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge
|
oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge
|
||||||
else
|
else
|
||||||
oedge = face->MakeEdge(*va, *vb);
|
oedge = face->MakeEdge(*va, *vb);
|
||||||
|
|
||||||
|
if (!oedge)
|
||||||
if(oedge == 0)
|
return NULL;
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
|
||||||
WEdge *edge = oedge->GetOwner();
|
WEdge *edge = oedge->GetOwner();
|
||||||
if(1 == edge->GetNumberOfOEdges())
|
if (1 == edge->GetNumberOfOEdges()) {
|
||||||
{
|
// means that we just created a new edge and that we must add it to the shape's edges list
|
||||||
// means that we just created a new edge and that we must add it to the
|
|
||||||
// shape's edges list
|
|
||||||
edge->setId(_EdgeList.size());
|
edge->setId(_EdgeList.size());
|
||||||
AddEdge(edge);
|
AddEdge(edge);
|
||||||
// compute the mean edge value:
|
// compute the mean edge value:
|
||||||
@@ -741,7 +702,7 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
edge->setMark(*mit);
|
edge->setMark(*mit);
|
||||||
mit++;
|
++mit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the face to the shape's faces list:
|
// Add the face to the shape's faces list:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/winged_edge/WFillGrid.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
|
||||||
//
|
* \author Emmanuel Turquin
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Stephane Grabli
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 03/05/2003
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "WEdge.h"
|
#include "WEdge.h"
|
||||||
#include "WFillGrid.h"
|
#include "WFillGrid.h"
|
||||||
|
|
||||||
void WFillGrid::fillGrid() {
|
void WFillGrid::fillGrid()
|
||||||
|
{
|
||||||
if (!_winged_edge || !_grid)
|
if (!_winged_edge || !_grid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vector<WShape*> wshapes = _winged_edge->getWShapes();
|
vector<WShape *> wshapes = _winged_edge->getWShapes();
|
||||||
vector<WVertex*> fvertices;
|
vector<WVertex *> fvertices;
|
||||||
vector<Vec3r> vectors;
|
vector<Vec3r> vectors;
|
||||||
vector<WFace*> faces;
|
vector<WFace *> faces;
|
||||||
|
|
||||||
for (vector<WShape*>::const_iterator it = wshapes.begin();
|
for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) {
|
||||||
it != wshapes.end();
|
|
||||||
it++) {
|
|
||||||
faces = (*it)->GetFaceList();
|
faces = (*it)->GetFaceList();
|
||||||
|
|
||||||
for (vector<WFace*>::const_iterator f = faces.begin();
|
for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) {
|
||||||
f != faces.end();
|
|
||||||
f++) {
|
|
||||||
(*f)->RetrieveVertexList(fvertices);
|
(*f)->RetrieveVertexList(fvertices);
|
||||||
|
|
||||||
for (vector<WVertex*>::const_iterator wv = fvertices.begin();
|
for (vector<WVertex*>::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv)
|
||||||
wv != fvertices.end();
|
|
||||||
wv++)
|
|
||||||
vectors.push_back(Vec3r((*wv)->GetVertex()));
|
vectors.push_back(Vec3r((*wv)->GetVertex()));
|
||||||
|
|
||||||
// occluder will be deleted by the grid
|
// occluder will be deleted by the grid
|
||||||
Polygon3r *occluder =
|
Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal());
|
||||||
new Polygon3r(vectors, (*f)->GetNormal());
|
|
||||||
occluder->setId(_polygon_id++);
|
occluder->setId(_polygon_id++);
|
||||||
occluder->userdata = (void*)(*f);
|
occluder->userdata = (void *)(*f);
|
||||||
_grid->insertOccluder(occluder);
|
_grid->insertOccluder(occluder);
|
||||||
vectors.clear();
|
vectors.clear();
|
||||||
fvertices.clear();
|
fvertices.clear();
|
||||||
|
|||||||
@@ -1,46 +1,51 @@
|
|||||||
//
|
/*
|
||||||
// Filename : WFillGrid.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Emmanuel Turquin
|
* This program is free software; you can redistribute it and/or
|
||||||
// Purpose : Class to fill in a grid from a SceneGraph
|
* modify it under the terms of the GNU General Public License
|
||||||
// (uses only the WingedEdge structures)
|
* as published by the Free Software Foundation; either version 2
|
||||||
// Date of creation : 03/05/2003
|
* of the License, or (at your option) any later version.
|
||||||
//
|
*
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_W_FILL_GRID_H__
|
||||||
|
#define __FREESTYLE_W_FILL_GRID_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/winged_edge/WFillGrid.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
|
||||||
//
|
* \author Emmanuel Turquin
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Stephane Grabli
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 03/05/2003
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef W_FILL_GRID_H
|
#include "WEdge.h"
|
||||||
# define W_FILL_GRID_H
|
|
||||||
|
|
||||||
# include "../geometry/Grid.h"
|
#include "../geometry/Grid.h"
|
||||||
# include "../geometry/Polygon.h"
|
#include "../geometry/Polygon.h"
|
||||||
# include "WEdge.h"
|
|
||||||
|
|
||||||
class LIB_WINGED_EDGE_EXPORT WFillGrid
|
class LIB_WINGED_EDGE_EXPORT WFillGrid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
inline WFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
|
||||||
inline WFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) {
|
{
|
||||||
_winged_edge = winged_edge;
|
_winged_edge = winged_edge;
|
||||||
_grid = grid;
|
_grid = grid;
|
||||||
_polygon_id = 0;
|
_polygon_id = 0;
|
||||||
@@ -51,30 +56,33 @@ public:
|
|||||||
void fillGrid();
|
void fillGrid();
|
||||||
|
|
||||||
/*! Accessors */
|
/*! Accessors */
|
||||||
WingedEdge* getWingedEdge() {
|
WingedEdge *getWingedEdge()
|
||||||
|
{
|
||||||
return _winged_edge;
|
return _winged_edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid* getGrid() {
|
Grid *getGrid()
|
||||||
|
{
|
||||||
return _grid;
|
return _grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Modifiers */
|
/*! Modifiers */
|
||||||
void setWingedEdge(WingedEdge* winged_edge) {
|
void setWingedEdge(WingedEdge *winged_edge)
|
||||||
|
{
|
||||||
if (winged_edge)
|
if (winged_edge)
|
||||||
_winged_edge = winged_edge;
|
_winged_edge = winged_edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGrid(Grid* grid) {
|
void setGrid(Grid *grid)
|
||||||
|
{
|
||||||
if (grid)
|
if (grid)
|
||||||
_grid = grid;
|
_grid = grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Grid *_grid;
|
||||||
Grid* _grid;
|
WingedEdge *_winged_edge;
|
||||||
WingedEdge* _winged_edge;
|
|
||||||
unsigned _polygon_id;
|
unsigned _polygon_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WS_FILL_GRID_H
|
#endif // __FREESTYLE_W_FILL_GRID_H__
|
||||||
@@ -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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/winged_edge/WSFillGrid.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 03/05/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "WEdge.h"
|
#include "WEdge.h"
|
||||||
#include "WSFillGrid.h"
|
#include "WSFillGrid.h"
|
||||||
|
|
||||||
void WSFillGrid::fillGrid() {
|
void WSFillGrid::fillGrid()
|
||||||
|
{
|
||||||
if (!_winged_edge || !_grid)
|
if (!_winged_edge || !_grid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vector<WShape*> wshapes = _winged_edge->getWShapes();
|
vector<WShape *> wshapes = _winged_edge->getWShapes();
|
||||||
vector<WVertex*> fvertices;
|
vector<WVertex *> fvertices;
|
||||||
vector<Vec3r> vectors;
|
vector<Vec3r> vectors;
|
||||||
vector<WFace*> faces;
|
vector<WFace *> faces;
|
||||||
|
|
||||||
for (vector<WShape*>::const_iterator it = wshapes.begin();
|
for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); ++it) {
|
||||||
it != wshapes.end();
|
|
||||||
it++) {
|
|
||||||
faces = (*it)->GetFaceList();
|
faces = (*it)->GetFaceList();
|
||||||
|
|
||||||
for (vector<WFace*>::const_iterator f = faces.begin();
|
for (vector<WFace *>::const_iterator f = faces.begin(); f != faces.end(); ++f) {
|
||||||
f != faces.end();
|
|
||||||
f++) {
|
|
||||||
(*f)->RetrieveVertexList(fvertices);
|
(*f)->RetrieveVertexList(fvertices);
|
||||||
|
|
||||||
for (vector<WVertex*>::const_iterator wv = fvertices.begin();
|
for (vector<WVertex*>::const_iterator wv = fvertices.begin(); wv != fvertices.end(); ++wv)
|
||||||
wv != fvertices.end();
|
|
||||||
wv++)
|
|
||||||
vectors.push_back(Vec3r((*wv)->GetVertex()));
|
vectors.push_back(Vec3r((*wv)->GetVertex()));
|
||||||
|
|
||||||
// occluder will be deleted by the grid
|
// occluder will be deleted by the grid
|
||||||
Polygon3r *occluder =
|
Polygon3r *occluder = new Polygon3r(vectors, (*f)->GetNormal());
|
||||||
new Polygon3r(vectors, (*f)->GetNormal());
|
|
||||||
occluder->setId(_polygon_id++);
|
occluder->setId(_polygon_id++);
|
||||||
occluder->userdata = (void*)(*f);
|
occluder->userdata = (void *)(*f);
|
||||||
_grid->insertOccluder(occluder);
|
_grid->insertOccluder(occluder);
|
||||||
vectors.clear();
|
vectors.clear();
|
||||||
fvertices.clear();
|
fvertices.clear();
|
||||||
|
|||||||
@@ -1,45 +1,50 @@
|
|||||||
//
|
/*
|
||||||
// Filename : WSFillGrid.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Purpose : Class to fill in a grid from a SceneGraph
|
* This program is free software; you can redistribute it and/or
|
||||||
// (uses only the WingedEdge structures)
|
* modify it under the terms of the GNU General Public License
|
||||||
// Date of creation : 03/05/2003
|
* as published by the Free Software Foundation; either version 2
|
||||||
//
|
* of the License, or (at your option) any later version.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_WS_FILL_GRID_H__
|
||||||
|
#define __FREESTYLE_WS_FILL_GRID_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/winged_edge/WSFillGrid.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
|
||||||
//
|
* \author Stephane Grabli
|
||||||
// This program is free software; you can redistribute it and/or
|
* \date 03/05/2003
|
||||||
// modify it under the terms of the GNU General Public License
|
*/
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef WS_FILL_GRID_H
|
#include "WEdge.h"
|
||||||
# define WS_FILL_GRID_H
|
|
||||||
|
|
||||||
# include "../geometry/Grid.h"
|
#include "../geometry/Grid.h"
|
||||||
# include "../geometry/Polygon.h"
|
#include "../geometry/Polygon.h"
|
||||||
# include "WEdge.h"
|
|
||||||
|
|
||||||
class LIB_WINGED_EDGE_EXPORT WSFillGrid
|
class LIB_WINGED_EDGE_EXPORT WSFillGrid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
inline WSFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
|
||||||
inline WSFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) {
|
{
|
||||||
_winged_edge = winged_edge;
|
_winged_edge = winged_edge;
|
||||||
_grid = grid;
|
_grid = grid;
|
||||||
_polygon_id = 0;
|
_polygon_id = 0;
|
||||||
@@ -50,30 +55,33 @@ public:
|
|||||||
void fillGrid();
|
void fillGrid();
|
||||||
|
|
||||||
/*! Accessors */
|
/*! Accessors */
|
||||||
WingedEdge* getWingedEdge() {
|
WingedEdge *getWingedEdge()
|
||||||
|
{
|
||||||
return _winged_edge;
|
return _winged_edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid* getGrid() {
|
Grid *getGrid()
|
||||||
|
{
|
||||||
return _grid;
|
return _grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Modifiers */
|
/*! Modifiers */
|
||||||
void setWingedEdge(WingedEdge* winged_edge) {
|
void setWingedEdge(WingedEdge *winged_edge)
|
||||||
|
{
|
||||||
if (winged_edge)
|
if (winged_edge)
|
||||||
_winged_edge = winged_edge;
|
_winged_edge = winged_edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGrid(Grid* grid) {
|
void setGrid(Grid *grid)
|
||||||
|
{
|
||||||
if (grid)
|
if (grid)
|
||||||
_grid = grid;
|
_grid = grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Grid *_grid;
|
||||||
Grid* _grid;
|
WingedEdge *_winged_edge;
|
||||||
WingedEdge* _winged_edge;
|
|
||||||
unsigned _polygon_id;
|
unsigned _polygon_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WS_FILL_GRID_H
|
#endif // __FREESTYLE_WS_FILL_GRID_H__
|
||||||
@@ -1,69 +1,86 @@
|
|||||||
//
|
/*
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// with this source distribution.
|
*
|
||||||
//
|
* This program is free software; you can redistribute it and/or
|
||||||
// This program is free software; you can redistribute it and/or
|
* modify it under the terms of the GNU General Public License
|
||||||
// modify it under the terms of the GNU General Public License
|
* as published by the Free Software Foundation; either version 2
|
||||||
// as published by the Free Software Foundation; either version 2
|
* of the License, or (at your option) any later version.
|
||||||
// of the License, or (at your option) any later version.
|
*
|
||||||
//
|
* This program is distributed in the hope that it will be useful,
|
||||||
// This program is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* GNU General Public License for more details.
|
||||||
// GNU General Public License for more details.
|
*
|
||||||
//
|
* You should have received a copy of the GNU General Public License
|
||||||
// You should have received a copy of the GNU General Public License
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
// along with this program; if not, write to the Free Software
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
*
|
||||||
//
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/winged_edge/WXEdge.cpp
|
||||||
|
* \ingroup freestyle
|
||||||
|
* \brief Classes to define an Extended Winged Edge data structure.
|
||||||
|
* \author Stephane Grabli
|
||||||
|
* \date 26/10/2003
|
||||||
|
*/
|
||||||
|
|
||||||
#include "WXEdge.h"
|
#include "WXEdge.h"
|
||||||
|
|
||||||
/**********************************/
|
/**********************************
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/* WXFace */
|
* WXFace *
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/**********************************/
|
**********************************/
|
||||||
|
|
||||||
unsigned int WXFaceLayer::Get0VertexIndex() const {
|
unsigned int WXFaceLayer::Get0VertexIndex() const
|
||||||
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int nEdges = _pWXFace->numberOfEdges();
|
int nEdges = _pWXFace->numberOfEdges();
|
||||||
for(i=0; i<nEdges; ++i){
|
for (i = 0; i < nEdges; ++i) {
|
||||||
if(_DotP[i] == 0){
|
if (_DotP[i] == 0) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{
|
unsigned int WXFaceLayer::GetSmoothEdgeIndex() const
|
||||||
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int nEdges = _pWXFace->numberOfEdges();
|
int nEdges = _pWXFace->numberOfEdges();
|
||||||
for(i=0; i<nEdges; ++i){
|
for (i = 0; i < nEdges; ++i) {
|
||||||
if((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)){
|
if ((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){
|
void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges)
|
||||||
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int nEdges = _pWXFace->numberOfEdges();
|
int nEdges = _pWXFace->numberOfEdges();
|
||||||
for(i=0; i<nEdges; ++i){
|
for (i = 0; i < nEdges; ++i) {
|
||||||
if(_DotP[i]*_DotP[(i+1)%nEdges] < 0){
|
if (_DotP[i] * _DotP[(i + 1) % nEdges] < 0) {
|
||||||
// we got one
|
// we got one
|
||||||
oCuspEdges.push_back(i);
|
oCuspEdges.push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
|
WXSmoothEdge *WXFaceLayer::BuildSmoothEdge()
|
||||||
// if the smooth edge has already been
|
{
|
||||||
// built: exit
|
// if the smooth edge has already been built: exit
|
||||||
if(0 != _pSmoothEdge)
|
if (_pSmoothEdge)
|
||||||
return _pSmoothEdge;
|
return _pSmoothEdge;
|
||||||
real ta, tb;
|
real ta, tb;
|
||||||
WOEdge *woea(0), *woeb(0);
|
WOEdge *woea(0), *woeb(0);
|
||||||
@@ -71,33 +88,30 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
|
|||||||
vector<int> cuspEdgesIndices;
|
vector<int> cuspEdgesIndices;
|
||||||
int indexStart, indexEnd;
|
int indexStart, indexEnd;
|
||||||
unsigned nedges = _pWXFace->numberOfEdges();
|
unsigned nedges = _pWXFace->numberOfEdges();
|
||||||
if(_nNullDotP == nedges){
|
if (_nNullDotP == nedges) {
|
||||||
_pSmoothEdge = 0;
|
_pSmoothEdge = NULL;
|
||||||
return _pSmoothEdge;
|
return _pSmoothEdge;
|
||||||
}
|
}
|
||||||
if((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)){
|
if ((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)) {
|
||||||
// that means that we have a smooth edge that starts from
|
// that means that we have a smooth edge that starts from an edge and ends at an edge
|
||||||
// an edge and ends at an edge
|
|
||||||
//-----------------------------
|
//-----------------------------
|
||||||
// We retrieve the 2 edges for which we have
|
// We retrieve the 2 edges for which we have opposite signs for each extremity
|
||||||
// opposite signs for each extremity
|
|
||||||
RetrieveCuspEdgesIndices(cuspEdgesIndices);
|
RetrieveCuspEdgesIndices(cuspEdgesIndices);
|
||||||
if(cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges
|
if (cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// let us determine which cusp edge corresponds to the starting:
|
// let us determine which cusp edge corresponds to the starting:
|
||||||
// We can do that because we defined that
|
// We can do that because we defined that a silhouette edge had the back facing part on its right.
|
||||||
// a silhouette edge had the back facing part on its right.
|
// So if the WOEdge woea is such that woea[0].dotp > 0 and woea[1].dotp < 0, it is the starting edge.
|
||||||
// So if the WOEdge woea is such that woea[0].dotp > 0 and
|
|
||||||
// woea[1].dotp < 0, it is the starting edge.
|
|
||||||
//-------------------------------------------
|
//-------------------------------------------
|
||||||
|
|
||||||
if(_DotP[cuspEdgesIndices[0]] > 0){
|
if (_DotP[cuspEdgesIndices[0]] > 0) {
|
||||||
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
||||||
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
|
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
|
||||||
indexStart = cuspEdgesIndices[0];
|
indexStart = cuspEdgesIndices[0];
|
||||||
indexEnd = cuspEdgesIndices[1];
|
indexEnd = cuspEdgesIndices[1];
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
|
woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
|
||||||
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
||||||
indexStart = cuspEdgesIndices[1];
|
indexStart = cuspEdgesIndices[1];
|
||||||
@@ -105,70 +119,73 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute the interpolation:
|
// Compute the interpolation:
|
||||||
ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]);
|
ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
|
||||||
tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]);
|
tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
|
||||||
ok = true;
|
ok = true;
|
||||||
}else if(_nNullDotP == 1){
|
}
|
||||||
// that means that we have exactly one of the
|
else if (_nNullDotP == 1) {
|
||||||
// 2 extremities of our silhouette edge is
|
// that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex of the mesh
|
||||||
// a vertex of the mesh
|
if ((_nPosDotP == 2) || (_nPosDotP == 0)) {
|
||||||
if((_nPosDotP == 2) || (_nPosDotP == 0)){
|
_pSmoothEdge = NULL;
|
||||||
_pSmoothEdge = 0;
|
|
||||||
return _pSmoothEdge;
|
return _pSmoothEdge;
|
||||||
}
|
}
|
||||||
RetrieveCuspEdgesIndices(cuspEdgesIndices);
|
RetrieveCuspEdgesIndices(cuspEdgesIndices);
|
||||||
// We should have only one EdgeCusp:
|
// We should have only one EdgeCusp:
|
||||||
if(cuspEdgesIndices.size() != 1){
|
if (cuspEdgesIndices.size() != 1) {
|
||||||
cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl;
|
cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl;
|
||||||
_pSmoothEdge = 0;
|
_pSmoothEdge = NULL;
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
|
unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
|
||||||
unsigned nedges = _pWXFace->numberOfEdges();
|
unsigned nedges = _pWXFace->numberOfEdges();
|
||||||
if(_DotP[cuspEdgesIndices[0]] > 0){
|
if (_DotP[cuspEdgesIndices[0]] > 0) {
|
||||||
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
||||||
woeb = _pWXFace->GetOEdge(index0);
|
woeb = _pWXFace->GetOEdge(index0);
|
||||||
indexStart = cuspEdgesIndices[0];
|
indexStart = cuspEdgesIndices[0];
|
||||||
ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]);
|
ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
|
||||||
tb = 0.0;
|
tb = 0.0;
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
woea = _pWXFace->GetOEdge(index0);
|
woea = _pWXFace->GetOEdge(index0);
|
||||||
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
|
||||||
indexEnd = cuspEdgesIndices[0];
|
indexEnd = cuspEdgesIndices[0];
|
||||||
ta = 0.0;
|
ta = 0.0;
|
||||||
tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]);
|
tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
|
||||||
}
|
}
|
||||||
ok = true;
|
ok = true;
|
||||||
}else if(_nNullDotP == 2){
|
}
|
||||||
// that means that the silhouette edge
|
else if (_nNullDotP == 2) {
|
||||||
// is an edge of the mesh
|
// that means that the silhouette edge is an edge of the mesh
|
||||||
int index = GetSmoothEdgeIndex();
|
int index = GetSmoothEdgeIndex();
|
||||||
if(!_pWXFace->front()) {// is it in the right order ?
|
if (!_pWXFace->front()) { // is it in the right order ?
|
||||||
// the order of the WOEdge index is wrong
|
// the order of the WOEdge index is wrong
|
||||||
woea = _pWXFace->GetOEdge((index+1)%nedges);
|
woea = _pWXFace->GetOEdge((index + 1) % nedges);
|
||||||
woeb = _pWXFace->GetOEdge((index-1)%nedges);
|
woeb = _pWXFace->GetOEdge((index - 1) % nedges);
|
||||||
ta = 0;
|
ta = 0;
|
||||||
tb = 1;
|
tb = 1;
|
||||||
ok = true;
|
ok = true;
|
||||||
}else{
|
}
|
||||||
|
else {
|
||||||
// here it's not good, our edge is a single point -> skip that face
|
// here it's not good, our edge is a single point -> skip that face
|
||||||
ok = false;
|
ok = false;
|
||||||
|
#if 0
|
||||||
// the order of the WOEdge index is good
|
// the order of the WOEdge index is good
|
||||||
// woea = _pWXFace->GetOEdge((index-1)%nedges);
|
woea = _pWXFace->GetOEdge((index - 1) % nedges);
|
||||||
// woeb = _pWXFace->GetOEdge((index+1)%nedges);
|
woeb = _pWXFace->GetOEdge((index + 1) % nedges);
|
||||||
// ta = 1;
|
ta = 1;
|
||||||
// tb = 0;
|
tb = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ok){
|
if (ok) {
|
||||||
_pSmoothEdge = new WXSmoothEdge;
|
_pSmoothEdge = new WXSmoothEdge;
|
||||||
_pSmoothEdge->setWOeA(woea);
|
_pSmoothEdge->setWOeA(woea);
|
||||||
_pSmoothEdge->setWOeB(woeb);
|
_pSmoothEdge->setWOeB(woeb);
|
||||||
_pSmoothEdge->setTa(ta);
|
_pSmoothEdge->setTa(ta);
|
||||||
_pSmoothEdge->setTb(tb);
|
_pSmoothEdge->setTb(tb);
|
||||||
if(_Nature & Nature::SILHOUETTE){
|
if (_Nature & Nature::SILHOUETTE) {
|
||||||
if(_nNullDotP != 2){
|
if (_nNullDotP != 2) {
|
||||||
if(_DotP[_ClosestPointIndex] + 0.01 > 0)
|
if (_DotP[_ClosestPointIndex] + 0.01 > 0)
|
||||||
_pSmoothEdge->setFront(true);
|
_pSmoothEdge->setFront(true);
|
||||||
else
|
else
|
||||||
_pSmoothEdge->setFront(false);
|
_pSmoothEdge->setFront(false);
|
||||||
@@ -176,121 +193,106 @@ WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check bording edges to see if they have different dotp values
|
#if 0
|
||||||
// in bording faces.
|
// check bording edges to see if they have different dotp values in bording faces.
|
||||||
// for(int i=0; i<numberOfEdges(); i++)
|
for (int i = 0; i < numberOfEdges(); i++) {
|
||||||
// {
|
WSFace *bface = (WSFace *)GetBordingFace(i);
|
||||||
// WSFace * bface = (WSFace*)GetBordingFace(i);
|
if (bface) {
|
||||||
// if(bface != 0)
|
if ((front()) ^ (bface->front())) { // fA->front XOR fB->front (true if one is 0 and the other is 1)
|
||||||
// {
|
// that means that the edge i of the face is a silhouette edge
|
||||||
// if((front())^(bface->front())) // fA->front XOR fB->front (true if one is 0 and the other is 1)
|
// CHECK FIRST WHETHER THE EXACTSILHOUETTEEDGE HAS NOT YET BEEN BUILT ON THE OTHER FACE (1 is enough).
|
||||||
// {
|
if (((WSExactFace *)bface)->exactSilhouetteEdge()) {
|
||||||
// // that means that the edge i of the face is
|
// that means that this silhouette edge has already been built
|
||||||
// // a silhouette edge
|
return ((WSExactFace *)bface)->exactSilhouetteEdge();
|
||||||
// // TESTER D'ABORD SI LE EXACTSILHOUETTEEDGE N'A PAS
|
}
|
||||||
// // ETE CONSTRUIT SUR L'AUTRE FACE.(1 suffit)
|
// Else we must build it
|
||||||
// if(0 != ((WSExactFace*)bface)->exactSilhouetteEdge())
|
WOEdge *woea, *woeb;
|
||||||
// {
|
real ta, tb;
|
||||||
// // that means that this silhouette edge has already been built
|
if (!front()) { // is it in the right order ?
|
||||||
// return ((WSExactFace*)bface)->exactSilhouetteEdge();
|
// the order of the WOEdge index is wrong
|
||||||
// }
|
woea = _OEdgeList[(i + 1) % numberOfEdges()];
|
||||||
// // Else we must build it
|
if (0 == i)
|
||||||
// WOEdge *woea, *woeb;
|
woeb = _OEdgeList[numberOfEdges() - 1];
|
||||||
// real ta, tb;
|
else
|
||||||
// if(!front()) // is it in the right order ?
|
woeb = _OEdgeList[(i - 1)];
|
||||||
// {
|
ta = 0;
|
||||||
// // the order of the WOEdge index is wrong
|
tb = 1;
|
||||||
// woea = _OEdgeList[(i+1)%numberOfEdges()];
|
}
|
||||||
// if(0 == i)
|
else {
|
||||||
// woeb = _OEdgeList[numberOfEdges()-1];
|
// the order of the WOEdge index is good
|
||||||
// else
|
if (0 == i)
|
||||||
// woeb = _OEdgeList[(i-1)];
|
woea = _OEdgeList[numberOfEdges() - 1];
|
||||||
// ta = 0;
|
else
|
||||||
// tb = 1;
|
woea = _OEdgeList[(i - 1)];
|
||||||
// }
|
woeb = _OEdgeList[(i + 1) % numberOfEdges()];
|
||||||
// else
|
ta = 1;
|
||||||
// {
|
tb = 0;
|
||||||
// // the order of the WOEdge index is good
|
}
|
||||||
// if(0 == i)
|
|
||||||
// woea = _OEdgeList[numberOfEdges()-1];
|
_pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
|
||||||
// else
|
_pSmoothEdge->setWOeA(woea);
|
||||||
// woea = _OEdgeList[(i-1)];
|
_pSmoothEdge->setWOeA(woeb);
|
||||||
// woeb = _OEdgeList[(i+1)%numberOfEdges()];
|
_pSmoothEdge->setTa(ta);
|
||||||
// ta = 1;
|
_pSmoothEdge->setTb(tb);
|
||||||
// tb = 0;
|
|
||||||
// }
|
return _pSmoothEdge;
|
||||||
//
|
}
|
||||||
// _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
|
}
|
||||||
// _pSmoothEdge->setWOeA(woea);
|
}
|
||||||
// _pSmoothEdge->setWOeA(woeb);
|
#endif
|
||||||
// _pSmoothEdge->setTa(ta);
|
|
||||||
// _pSmoothEdge->setTb(tb);
|
|
||||||
//
|
|
||||||
// return _pSmoothEdge;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
return _pSmoothEdge;
|
return _pSmoothEdge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WXFace::ComputeCenter()
|
void WXFace::ComputeCenter()
|
||||||
{
|
{
|
||||||
vector<WVertex*> iVertexList;
|
vector<WVertex *> iVertexList;
|
||||||
RetrieveVertexList(iVertexList);
|
RetrieveVertexList(iVertexList);
|
||||||
Vec3r center;
|
Vec3r center;
|
||||||
for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
|
for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
|
||||||
wv!=wvend;
|
|
||||||
wv++)
|
|
||||||
{
|
|
||||||
center += (*wv)->GetVertex();
|
center += (*wv)->GetVertex();
|
||||||
}
|
}
|
||||||
center /= (real)iVertexList.size();
|
center /= (real)iVertexList.size();
|
||||||
setCenter(center);
|
setCenter(center);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************/
|
/**********************************
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/* WXShape */
|
* WXShape *
|
||||||
/* */
|
* *
|
||||||
/* */
|
* *
|
||||||
/**********************************/
|
**********************************/
|
||||||
|
|
||||||
|
WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
|
||||||
WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
|
|
||||||
{
|
{
|
||||||
WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
|
WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
|
||||||
if(0 == face)
|
if (!face)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
Vec3r center;
|
Vec3r center;
|
||||||
for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
|
for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
|
||||||
wv!=wvend;
|
|
||||||
wv++)
|
|
||||||
{
|
|
||||||
center += (*wv)->GetVertex();
|
center += (*wv)->GetVertex();
|
||||||
}
|
}
|
||||||
center /= (real)iVertexList.size();
|
center /= (real)iVertexList.size();
|
||||||
((WXFace*)face)->setCenter(center);
|
((WXFace *)face)->setCenter(center);
|
||||||
|
|
||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
|
WFace *WXShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
|
||||||
|
vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex)
|
||||||
{
|
{
|
||||||
WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
|
WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
|
||||||
|
|
||||||
// Vec3r center;
|
#if 0
|
||||||
// for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end();
|
Vec3r center;
|
||||||
// wv!=wvend;
|
for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end(); wv != wvend; ++wv) {
|
||||||
// wv++)
|
center += (*wv)->GetVertex();
|
||||||
// {
|
}
|
||||||
// center += (*wv)->GetVertex();
|
center /= (real)iVertexList.size();
|
||||||
// }
|
((WSFace *)face)->setCenter(center);
|
||||||
// center /= (real)iVertexList.size();
|
#endif
|
||||||
// ((WSFace*)face)->setCenter(center);
|
|
||||||
|
|
||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,25 +1,40 @@
|
|||||||
//
|
/*
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// with this source distribution.
|
*
|
||||||
//
|
* This program is free software; you can redistribute it and/or
|
||||||
// This program is free software; you can redistribute it and/or
|
* modify it under the terms of the GNU General Public License
|
||||||
// modify it under the terms of the GNU General Public License
|
* as published by the Free Software Foundation; either version 2
|
||||||
// as published by the Free Software Foundation; either version 2
|
* of the License, or (at your option) any later version.
|
||||||
// of the License, or (at your option) any later version.
|
*
|
||||||
//
|
* This program is distributed in the hope that it will be useful,
|
||||||
// This program is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* GNU General Public License for more details.
|
||||||
// GNU General Public License for more details.
|
*
|
||||||
//
|
* You should have received a copy of the GNU General Public License
|
||||||
// You should have received a copy of the GNU General Public License
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
// along with this program; if not, write to the Free Software
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
*
|
||||||
//
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/winged_edge/WSBuilder.cpp
|
||||||
|
* \ingroup freestyle
|
||||||
|
* \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info
|
||||||
|
* (silhouette etc...)) structure from a polygonal model
|
||||||
|
* \author Stephane Grabli
|
||||||
|
* \date 28/05/2003
|
||||||
|
*/
|
||||||
|
|
||||||
#include "WXEdgeBuilder.h"
|
|
||||||
#include "WXEdge.h"
|
#include "WXEdge.h"
|
||||||
|
#include "WXEdgeBuilder.h"
|
||||||
|
|
||||||
void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
|
void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
|
||||||
{
|
{
|
||||||
@@ -32,14 +47,11 @@ void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
|
|||||||
//ifs.setId(shape->GetId());
|
//ifs.setId(shape->GetId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WXEdgeBuilder::buildWVertices(WShape& shape,
|
void WXEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize)
|
||||||
const real *vertices,
|
{
|
||||||
unsigned vsize) {
|
|
||||||
WXVertex *vertex;
|
WXVertex *vertex;
|
||||||
for (unsigned i = 0; i < vsize; i += 3) {
|
for (unsigned int i = 0; i < vsize; i += 3) {
|
||||||
vertex = new WXVertex(Vec3r(vertices[i],
|
vertex = new WXVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
|
||||||
vertices[i + 1],
|
|
||||||
vertices[i + 2]));
|
|
||||||
vertex->setId(i / 3);
|
vertex->setId(i / 3);
|
||||||
shape.AddVertex(vertex);
|
shape.AddVertex(vertex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
#ifndef __FREESTYLE_WX_EDGE_BUILDER_H__
|
||||||
// Filename : WSBuilder.h
|
#define __FREESTYLE_WX_EDGE_BUILDER_H__
|
||||||
// Author(s) : Stephane Grabli
|
|
||||||
// Purpose : Class inherited from WingedEdgeBuilder and
|
|
||||||
// designed to build a WX (WingedEdge + extended info(silhouette etc...))
|
|
||||||
// structure from a polygonal model
|
|
||||||
// Date of creation : 28/05/03
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
/** \file blender/freestyle/intern/winged_edge/WSBuilder.h
|
||||||
|
* \ingroup freestyle
|
||||||
|
* \brief Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info
|
||||||
|
* (silhouette etc...)) structure from a polygonal model
|
||||||
|
* \author Stephane Grabli
|
||||||
|
* \date 28/05/2003
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
#include "WingedEdgeBuilder.h"
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
|
||||||
// with this source distribution.
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
# include "WingedEdgeBuilder.h"
|
#include "../scene_graph/IndexedFaceSet.h"
|
||||||
# include "../scene_graph/IndexedFaceSet.h"
|
|
||||||
|
|
||||||
class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder
|
class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder
|
||||||
{
|
{
|
||||||
@@ -43,9 +48,7 @@ public:
|
|||||||
VISIT_DECL(IndexedFaceSet)
|
VISIT_DECL(IndexedFaceSet)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void buildWVertices(WShape& shape,
|
virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
|
||||||
const real *vertices,
|
|
||||||
unsigned vsize);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WXEDGEBUILDER_H
|
#endif // __FREESTYLE_WX_EDGE_BUILDER_H__
|
||||||
@@ -1,31 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes
|
||||||
//
|
* of a scene graph
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Stephane Grabli
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 28/05/2003
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
#include <set>
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
#include "WingedEdgeBuilder.h"
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "../geometry/GeomUtils.h"
|
#include "../geometry/GeomUtils.h"
|
||||||
|
|
||||||
#include "../scene_graph/NodeShape.h"
|
#include "../scene_graph/NodeShape.h"
|
||||||
#include "WingedEdgeBuilder.h"
|
|
||||||
#include <set>
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) {
|
void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
|
||||||
|
{
|
||||||
if (_pRenderMonitor && _pRenderMonitor->testBreak())
|
if (_pRenderMonitor && _pRenderMonitor->testBreak())
|
||||||
return;
|
return;
|
||||||
WShape *shape = new WShape;
|
WShape *shape = new WShape;
|
||||||
@@ -34,13 +53,15 @@ void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) {
|
|||||||
//ifs.setId(shape->GetId());
|
//ifs.setId(shape->GetId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) {
|
void WingedEdgeBuilder::visitNodeShape(NodeShape& ns)
|
||||||
|
{
|
||||||
//Sets the current material to iShapeode->material:
|
//Sets the current material to iShapeode->material:
|
||||||
_current_frs_material = &(ns.frs_material());
|
_current_frs_material = &(ns.frs_material());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) {
|
void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn)
|
||||||
if(!_current_matrix) {
|
{
|
||||||
|
if (!_current_matrix) {
|
||||||
_current_matrix = new Matrix44r(tn.matrix());
|
_current_matrix = new Matrix44r(tn.matrix());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -50,11 +71,12 @@ void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) {
|
|||||||
_current_matrix = new_matrix;
|
_current_matrix = new_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) {
|
void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&)
|
||||||
if(_current_matrix)
|
{
|
||||||
|
if (_current_matrix)
|
||||||
delete _current_matrix;
|
delete _current_matrix;
|
||||||
|
|
||||||
if(_matrices_stack.empty()) {
|
if (_matrices_stack.empty()) {
|
||||||
_current_matrix = NULL;
|
_current_matrix = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -63,23 +85,24 @@ void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) {
|
|||||||
_matrices_stack.pop_back();
|
_matrices_stack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
|
void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs)
|
||||||
unsigned vsize = ifs.vsize();
|
{
|
||||||
unsigned nsize = ifs.nsize();
|
unsigned int vsize = ifs.vsize();
|
||||||
|
unsigned int nsize = ifs.nsize();
|
||||||
//soc unused - unsigned tsize = ifs.tsize();
|
//soc unused - unsigned tsize = ifs.tsize();
|
||||||
|
|
||||||
const real* vertices = ifs.vertices();
|
const real *vertices = ifs.vertices();
|
||||||
const real* normals = ifs.normals();
|
const real *normals = ifs.normals();
|
||||||
const real* texCoords = ifs.texCoords();
|
const real *texCoords = ifs.texCoords();
|
||||||
|
|
||||||
real* new_vertices;
|
real *new_vertices;
|
||||||
real* new_normals;
|
real *new_normals;
|
||||||
|
|
||||||
new_vertices = new real[vsize];
|
new_vertices = new real[vsize];
|
||||||
new_normals = new real[nsize];
|
new_normals = new real[nsize];
|
||||||
|
|
||||||
// transform coordinates from local to world system
|
// transform coordinates from local to world system
|
||||||
if(_current_matrix) {
|
if (_current_matrix) {
|
||||||
transformVertices(vertices, vsize, *_current_matrix, new_vertices);
|
transformVertices(vertices, vsize, *_current_matrix, new_vertices);
|
||||||
transformNormals(normals, nsize, *_current_matrix, new_normals);
|
transformNormals(normals, nsize, *_current_matrix, new_normals);
|
||||||
}
|
}
|
||||||
@@ -88,22 +111,23 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
|
|||||||
memcpy(new_normals, normals, nsize * sizeof(*new_normals));
|
memcpy(new_normals, normals, nsize * sizeof(*new_normals));
|
||||||
}
|
}
|
||||||
|
|
||||||
const IndexedFaceSet::TRIANGLES_STYLE* faceStyle = ifs.trianglesStyle();
|
const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle();
|
||||||
|
|
||||||
vector<FrsMaterial> frs_materials;
|
vector<FrsMaterial> frs_materials;
|
||||||
if(ifs.msize()){
|
if (ifs.msize()) {
|
||||||
const FrsMaterial*const* mats = ifs.frs_materials();
|
const FrsMaterial *const *mats = ifs.frs_materials();
|
||||||
for(unsigned i=0; i<ifs.msize(); ++i)
|
for (unsigned i = 0; i < ifs.msize(); ++i)
|
||||||
frs_materials.push_back(*(mats[i]));
|
frs_materials.push_back(*(mats[i]));
|
||||||
shape.setFrsMaterials(frs_materials);
|
shape.setFrsMaterials(frs_materials);
|
||||||
}
|
}
|
||||||
|
|
||||||
// const FrsMaterial * mat = (ifs.frs_material());
|
#if 0
|
||||||
// if (mat)
|
const FrsMaterial *mat = (ifs.frs_material());
|
||||||
// shape.setFrsMaterial(*mat);
|
if (mat)
|
||||||
// else if(_current_frs_material)
|
shape.setFrsMaterial(*mat);
|
||||||
// shape.setFrsMaterial(*_current_frs_material);
|
else if (_current_frs_material)
|
||||||
|
shape.setFrsMaterial(*_current_frs_material);
|
||||||
|
#endif
|
||||||
const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();
|
const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();
|
||||||
|
|
||||||
// sets the current WShape to shape
|
// sets the current WShape to shape
|
||||||
@@ -112,63 +136,39 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
|
|||||||
// create a WVertex for each vertex
|
// create a WVertex for each vertex
|
||||||
buildWVertices(shape, new_vertices, vsize);
|
buildWVertices(shape, new_vertices, vsize);
|
||||||
|
|
||||||
const unsigned* vindices = ifs.vindices();
|
const unsigned int *vindices = ifs.vindices();
|
||||||
const unsigned* nindices = ifs.nindices();
|
const unsigned int *nindices = ifs.nindices();
|
||||||
const unsigned* tindices = 0;
|
const unsigned int *tindices = NULL;
|
||||||
if(ifs.tsize()){
|
if (ifs.tsize()) {
|
||||||
tindices = ifs.tindices();
|
tindices = ifs.tindices();
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned *mindices = 0;
|
const unsigned int *mindices = NULL;
|
||||||
if(ifs.msize())
|
if (ifs.msize())
|
||||||
mindices = ifs.mindices();
|
mindices = ifs.mindices();
|
||||||
const unsigned* numVertexPerFace = ifs.numVertexPerFaces();
|
const unsigned int *numVertexPerFace = ifs.numVertexPerFaces();
|
||||||
const unsigned numfaces = ifs.numFaces();
|
const unsigned int numfaces = ifs.numFaces();
|
||||||
|
|
||||||
for (unsigned index = 0; index < numfaces; index++) {
|
for (unsigned int index = 0; index < numfaces; index++) {
|
||||||
switch(faceStyle[index]) {
|
switch (faceStyle[index]) {
|
||||||
case IndexedFaceSet::TRIANGLE_STRIP:
|
case IndexedFaceSet::TRIANGLE_STRIP:
|
||||||
buildTriangleStrip(new_vertices,
|
buildTriangleStrip(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
|
||||||
new_normals,
|
nindices, mindices, tindices, numVertexPerFace[index]);
|
||||||
frs_materials,
|
|
||||||
texCoords,
|
|
||||||
faceEdgeMarks,
|
|
||||||
vindices,
|
|
||||||
nindices,
|
|
||||||
mindices,
|
|
||||||
tindices,
|
|
||||||
numVertexPerFace[index]);
|
|
||||||
break;
|
break;
|
||||||
case IndexedFaceSet::TRIANGLE_FAN:
|
case IndexedFaceSet::TRIANGLE_FAN:
|
||||||
buildTriangleFan(new_vertices,
|
buildTriangleFan(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
|
||||||
new_normals,
|
nindices, mindices, tindices, numVertexPerFace[index]);
|
||||||
frs_materials,
|
|
||||||
texCoords,
|
|
||||||
faceEdgeMarks,
|
|
||||||
vindices,
|
|
||||||
nindices,
|
|
||||||
mindices,
|
|
||||||
tindices,
|
|
||||||
numVertexPerFace[index]);
|
|
||||||
break;
|
break;
|
||||||
case IndexedFaceSet::TRIANGLES:
|
case IndexedFaceSet::TRIANGLES:
|
||||||
buildTriangles(new_vertices,
|
buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
|
||||||
new_normals,
|
nindices, mindices, tindices, numVertexPerFace[index]);
|
||||||
frs_materials,
|
|
||||||
texCoords,
|
|
||||||
faceEdgeMarks,
|
|
||||||
vindices,
|
|
||||||
nindices,
|
|
||||||
mindices,
|
|
||||||
tindices,
|
|
||||||
numVertexPerFace[index]);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vindices += numVertexPerFace[index];
|
vindices += numVertexPerFace[index];
|
||||||
nindices += numVertexPerFace[index];
|
nindices += numVertexPerFace[index];
|
||||||
if(mindices)
|
if (mindices)
|
||||||
mindices += numVertexPerFace[index];
|
mindices += numVertexPerFace[index];
|
||||||
if(tindices)
|
if (tindices)
|
||||||
tindices += numVertexPerFace[index];
|
tindices += numVertexPerFace[index];
|
||||||
faceEdgeMarks++;
|
faceEdgeMarks++;
|
||||||
}
|
}
|
||||||
@@ -183,26 +183,23 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
|
|||||||
|
|
||||||
// Parse the built winged-edge shape to update post-flags
|
// Parse the built winged-edge shape to update post-flags
|
||||||
set<Vec3r> normalsSet;
|
set<Vec3r> normalsSet;
|
||||||
vector<WVertex*>& wvertices = shape.getVertexList();
|
vector<WVertex *>& wvertices = shape.getVertexList();
|
||||||
for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end();
|
for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
|
||||||
wv!=wvend;
|
if ((*wv)->isBoundary())
|
||||||
++wv){
|
|
||||||
if((*wv)->isBoundary())
|
|
||||||
continue;
|
continue;
|
||||||
if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
|
if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
|
||||||
continue;
|
continue;
|
||||||
normalsSet.clear();
|
normalsSet.clear();
|
||||||
WVertex::face_iterator fit = (*wv)->faces_begin();
|
WVertex::face_iterator fit = (*wv)->faces_begin();
|
||||||
WVertex::face_iterator fitend = (*wv)->faces_end();
|
WVertex::face_iterator fitend = (*wv)->faces_end();
|
||||||
while(fit!=fitend){
|
for (; fit != fitend; ++fit) {
|
||||||
WFace *face = *fit;
|
WFace *face = *fit;
|
||||||
normalsSet.insert(face->GetVertexNormal(*wv));
|
normalsSet.insert(face->GetVertexNormal(*wv));
|
||||||
if(normalsSet.size()!=1){
|
if (normalsSet.size() != 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++fit;
|
|
||||||
}
|
}
|
||||||
if(normalsSet.size()!=1){
|
if (normalsSet.size() !=1 ) {
|
||||||
(*wv)->setSmooth(false);
|
(*wv)->setSmooth(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,133 +207,127 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
|
|||||||
_winged_edge->addWShape(&shape);
|
_winged_edge->addWShape(&shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::buildWVertices(WShape& shape,
|
void WingedEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize)
|
||||||
const real *vertices,
|
{
|
||||||
unsigned vsize) {
|
|
||||||
WVertex *vertex;
|
WVertex *vertex;
|
||||||
for (unsigned i = 0; i < vsize; i += 3) {
|
for (unsigned int i = 0; i < vsize; i += 3) {
|
||||||
vertex = new WVertex(Vec3r(vertices[i],
|
vertex = new WVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
|
||||||
vertices[i + 1],
|
|
||||||
vertices[i + 2]));
|
|
||||||
vertex->setId(i / 3);
|
vertex->setId(i / 3);
|
||||||
shape.AddVertex(vertex);
|
shape.AddVertex(vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::buildTriangleStrip( const real *vertices,
|
void WingedEdgeBuilder::buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
|
||||||
const real *normals,
|
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
||||||
vector<FrsMaterial>& iMaterials,
|
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
|
||||||
const real *texCoords,
|
const unsigned *tindices, const unsigned nvertices)
|
||||||
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
{
|
||||||
const unsigned *vindices,
|
|
||||||
const unsigned *nindices,
|
|
||||||
const unsigned *mindices,
|
|
||||||
const unsigned *tindices,
|
|
||||||
const unsigned nvertices) {
|
|
||||||
unsigned nDoneVertices = 2; // number of vertices already treated
|
unsigned nDoneVertices = 2; // number of vertices already treated
|
||||||
unsigned nTriangle = 0; // number of the triangle currently being treated
|
unsigned nTriangle = 0; // number of the triangle currently being treated
|
||||||
//int nVertex = 0; // vertex number
|
//int nVertex = 0; // vertex number
|
||||||
|
|
||||||
WShape* currentShape = _current_wshape; // the current shape being built
|
WShape *currentShape = _current_wshape; // the current shape being built
|
||||||
vector<WVertex *> triangleVertices;
|
vector<WVertex *> triangleVertices;
|
||||||
vector<Vec3r> triangleNormals;
|
vector<Vec3r> triangleNormals;
|
||||||
vector<Vec2r> triangleTexCoords;
|
vector<Vec2r> triangleTexCoords;
|
||||||
vector<bool> triangleFaceEdgeMarks;
|
vector<bool> triangleFaceEdgeMarks;
|
||||||
|
|
||||||
while(nDoneVertices < nvertices)
|
while (nDoneVertices < nvertices) {
|
||||||
{
|
|
||||||
//clear the vertices list:
|
//clear the vertices list:
|
||||||
triangleVertices.clear();
|
triangleVertices.clear();
|
||||||
//Then rebuild it:
|
//Then rebuild it:
|
||||||
if(0 == nTriangle%2) // if nTriangle is even
|
if (0 == nTriangle % 2) { // if nTriangle is even
|
||||||
{
|
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
|
||||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]);
|
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
|
||||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+1]/3]);
|
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
|
||||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]);
|
|
||||||
|
|
||||||
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2]));
|
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
|
||||||
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]],normals[nindices[nTriangle+1]+1],normals[nindices[nTriangle+1]+2]));
|
normals[nindices[nTriangle] + 2]));
|
||||||
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]], normals[nindices[nTriangle+2]+1], normals[nindices[nTriangle+2]+2]));
|
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
|
||||||
|
normals[nindices[nTriangle + 1] + 2]));
|
||||||
|
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
|
||||||
|
normals[nindices[nTriangle + 2] + 2]));
|
||||||
|
|
||||||
if(texCoords){
|
if (texCoords) {
|
||||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1]));
|
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
|
||||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]],texCoords[tindices[nTriangle+1]+1]));
|
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
|
||||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]], texCoords[tindices[nTriangle+2]+1]));
|
texCoords[tindices[nTriangle + 1] + 1]));
|
||||||
|
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
|
||||||
|
texCoords[tindices[nTriangle + 2] + 1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // if nTriangle is odd
|
else { // if nTriangle is odd
|
||||||
{
|
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
|
||||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]);
|
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
|
||||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]);
|
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
|
||||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+1]/3]);
|
|
||||||
|
|
||||||
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2]));
|
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
|
||||||
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]],normals[nindices[nTriangle+2]+1],normals[nindices[nTriangle+2]+2]));
|
normals[nindices[nTriangle] + 2]));
|
||||||
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]], normals[nindices[nTriangle+1]+1], normals[nindices[nTriangle+1]+2]));
|
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
|
||||||
|
normals[nindices[nTriangle + 2] + 2]));
|
||||||
|
triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
|
||||||
|
normals[nindices[nTriangle + 1] + 2]));
|
||||||
|
|
||||||
if(texCoords){
|
if (texCoords) {
|
||||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1]));
|
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
|
||||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]],texCoords[tindices[nTriangle+2]+1]));
|
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
|
||||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]], texCoords[tindices[nTriangle+1]+1]));
|
texCoords[tindices[nTriangle + 2] + 1]));
|
||||||
|
triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
|
||||||
|
texCoords[tindices[nTriangle + 1] + 1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::FACE_MARK) != 0);
|
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != 0);
|
||||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
|
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
|
||||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
|
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
|
||||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
|
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
|
||||||
if(mindices)
|
if (mindices) {
|
||||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[nTriangle/3]);
|
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
|
||||||
else
|
mindices[nTriangle / 3]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
|
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
|
||||||
|
}
|
||||||
nDoneVertices++; // with a strip, each triangle is one vertex more
|
nDoneVertices++; // with a strip, each triangle is one vertex more
|
||||||
nTriangle++;
|
nTriangle++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::buildTriangleFan( const real *vertices,
|
void WingedEdgeBuilder::buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
|
||||||
const real *normals,
|
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
||||||
vector<FrsMaterial>& iMaterials,
|
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
|
||||||
const real *texCoords,
|
const unsigned *tindices, const unsigned nvertices)
|
||||||
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
{
|
||||||
const unsigned *vindices,
|
|
||||||
const unsigned *nindices,
|
|
||||||
const unsigned *mindices,
|
|
||||||
const unsigned *tindices,
|
|
||||||
const unsigned nvertices) {
|
|
||||||
// Nothing to be done
|
// Nothing to be done
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::buildTriangles(const real *vertices,
|
void WingedEdgeBuilder::buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
|
||||||
const real *normals,
|
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
||||||
vector<FrsMaterial>& iMaterials,
|
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
|
||||||
const real *texCoords,
|
const unsigned *tindices, const unsigned nvertices)
|
||||||
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
{
|
||||||
const unsigned *vindices,
|
WShape *currentShape = _current_wshape; // the current shape begin built
|
||||||
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<WVertex *> triangleVertices;
|
||||||
vector<Vec3r> triangleNormals;
|
vector<Vec3r> triangleNormals;
|
||||||
vector<Vec2r> triangleTexCoords;
|
vector<Vec2r> triangleTexCoords;
|
||||||
vector<bool> triangleFaceEdgeMarks;
|
vector<bool> triangleFaceEdgeMarks;
|
||||||
|
|
||||||
// Each triplet of vertices is considered as an independent triangle
|
// Each triplet of vertices is considered as an independent triangle
|
||||||
for(unsigned i = 0; i < nvertices / 3; i++)
|
for (unsigned int i = 0; i < nvertices / 3; i++) {
|
||||||
{
|
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]);
|
||||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i]/3]);
|
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]);
|
||||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+1]/3]);
|
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]);
|
||||||
triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+2]/3]);
|
|
||||||
|
|
||||||
triangleNormals.push_back(Vec3r(normals[nindices[3*i]],normals[nindices[3*i]+1], normals[nindices[3*i]+2]));
|
triangleNormals.push_back(Vec3r(normals[nindices[3 * i]], normals[nindices[3 * i] + 1],
|
||||||
triangleNormals.push_back(Vec3r(normals[nindices[3*i+1]],normals[nindices[3*i+1]+1],normals[nindices[3*i+1]+2]));
|
normals[nindices[3 * i] + 2]));
|
||||||
triangleNormals.push_back(Vec3r(normals[nindices[3*i+2]], normals[nindices[3*i+2]+1], normals[nindices[3*i+2]+2]));
|
triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 1]], normals[nindices[3 * i + 1] + 1],
|
||||||
|
normals[nindices[3 * i + 1] + 2]));
|
||||||
|
triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 2]], normals[nindices[3 * i + 2] + 1],
|
||||||
|
normals[nindices[3 * i + 2] + 2]));
|
||||||
|
|
||||||
if(texCoords){
|
if (texCoords) {
|
||||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i]],texCoords[tindices[3*i]+1]));
|
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1]));
|
||||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+1]],texCoords[tindices[3*i+1]+1]));
|
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1]));
|
||||||
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+2]], texCoords[tindices[3*i+2]+1]));
|
triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 2]], texCoords[tindices[3 * i + 2] + 1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
|
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
|
||||||
@@ -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_V2V3) != 0);
|
||||||
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
|
triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
|
||||||
}
|
}
|
||||||
if(mindices)
|
if (mindices)
|
||||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]);
|
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
|
||||||
|
mindices[0]);
|
||||||
else
|
else
|
||||||
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
|
currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::transformVertices(const real *vertices,
|
void WingedEdgeBuilder::transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res)
|
||||||
unsigned vsize,
|
{
|
||||||
const Matrix44r& transform,
|
|
||||||
real *res) {
|
|
||||||
const real *v = vertices;
|
const real *v = vertices;
|
||||||
real *pv = res;
|
real *pv = res;
|
||||||
|
|
||||||
for (unsigned i = 0; i < vsize / 3; i++) {
|
for (unsigned int i = 0; i < vsize / 3; i++) {
|
||||||
HVec3r hv_tmp(v[0], v[1], v[2]);
|
HVec3r hv_tmp(v[0], v[1], v[2]);
|
||||||
HVec3r hv(transform * hv_tmp);
|
HVec3r hv(transform * hv_tmp);
|
||||||
for (unsigned j = 0; j < 3; j++)
|
for (unsigned int j = 0; j < 3; j++)
|
||||||
pv[j] = hv[j] / hv[3];
|
pv[j] = hv[j] / hv[3];
|
||||||
v += 3;
|
v += 3;
|
||||||
pv += 3;
|
pv += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingedEdgeBuilder::transformNormals(const real *normals,
|
void WingedEdgeBuilder::transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res)
|
||||||
unsigned nsize,
|
{
|
||||||
const Matrix44r& transform,
|
|
||||||
real* res) {
|
|
||||||
const real *n = normals;
|
const real *n = normals;
|
||||||
real *pn = res;
|
real *pn = res;
|
||||||
|
|
||||||
for (unsigned i = 0; i < nsize / 3; i++) {
|
for (unsigned int i = 0; i < nsize / 3; i++) {
|
||||||
Vec3r hn(n[0], n[1], n[2]);
|
Vec3r hn(n[0], n[1], n[2]);
|
||||||
hn = GeomUtils::rotateVector(transform, hn);
|
hn = GeomUtils::rotateVector(transform, hn);
|
||||||
for (unsigned j = 0; j < 3; j++)
|
for (unsigned int j = 0; j < 3; j++)
|
||||||
pn[j] = hn[j];
|
pn[j] = hn[j];
|
||||||
n += 3;
|
n += 3;
|
||||||
pn += 3;
|
pn += 3;
|
||||||
|
|||||||
@@ -1,49 +1,55 @@
|
|||||||
//
|
/*
|
||||||
// Filename : WingedEdgeBuilder.h
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
// Author(s) : Stephane Grabli
|
*
|
||||||
// Purpose : Class to render a WingedEdge data structure
|
* This program is free software; you can redistribute it and/or
|
||||||
// from a polyhedral data structure organized in
|
* modify it under the terms of the GNU General Public License
|
||||||
// nodes of a scene graph
|
* as published by the Free Software Foundation; either version 2
|
||||||
// Date of creation : 28/05/03
|
* of the License, or (at your option) any later version.
|
||||||
//
|
*
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FREESTYLE_WINGED_EDGE_BUILDER_H__
|
||||||
|
#define __FREESTYLE_WINGED_EDGE_BUILDER_H__
|
||||||
|
|
||||||
//
|
/** \file blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
|
||||||
// Copyright (C) : Please refer to the COPYRIGHT file distributed
|
* \ingroup freestyle
|
||||||
// with this source distribution.
|
* \brief Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes
|
||||||
//
|
* of a scene graph
|
||||||
// This program is free software; you can redistribute it and/or
|
* \author Stephane Grabli
|
||||||
// modify it under the terms of the GNU General Public License
|
* \date 28/05/2003
|
||||||
// as published by the Free Software Foundation; either version 2
|
*/
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef WINGED_EDGE_BUILDER_H
|
#include "WEdge.h"
|
||||||
# define WINGED_EDGE_BUILDER_H
|
|
||||||
|
|
||||||
# include "../system/FreestyleConfig.h"
|
#include "../scene_graph/IndexedFaceSet.h"
|
||||||
# include "../system/RenderMonitor.h"
|
#include "../scene_graph/NodeTransform.h"
|
||||||
# include "../scene_graph/SceneVisitor.h"
|
#include "../scene_graph/SceneVisitor.h"
|
||||||
# include "WEdge.h"
|
|
||||||
# include "../scene_graph/IndexedFaceSet.h"
|
#include "../system/FreestyleConfig.h"
|
||||||
# include "../scene_graph/NodeTransform.h"
|
#include "../system/RenderMonitor.h"
|
||||||
|
|
||||||
class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
|
class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
inline WingedEdgeBuilder() : SceneVisitor()
|
||||||
inline WingedEdgeBuilder() : SceneVisitor() {
|
{
|
||||||
_current_wshape = NULL;
|
_current_wshape = NULL;
|
||||||
_current_frs_material = NULL;
|
_current_frs_material = NULL;
|
||||||
_current_matrix = NULL;
|
_current_matrix = NULL;
|
||||||
@@ -51,10 +57,9 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
|
|||||||
_pRenderMonitor = NULL;
|
_pRenderMonitor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~WingedEdgeBuilder() {
|
virtual ~WingedEdgeBuilder()
|
||||||
for (vector<Matrix44r*>::iterator it = _matrices_stack.begin();
|
{
|
||||||
it != _matrices_stack.end();
|
for (vector<Matrix44r*>::iterator it = _matrices_stack.begin(); it != _matrices_stack.end(); ++it)
|
||||||
it++)
|
|
||||||
delete *it;
|
delete *it;
|
||||||
_matrices_stack.clear();
|
_matrices_stack.clear();
|
||||||
}
|
}
|
||||||
@@ -70,19 +75,23 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
|
|||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
inline WingedEdge* getWingedEdge() {
|
inline WingedEdge *getWingedEdge()
|
||||||
|
{
|
||||||
return _winged_edge;
|
return _winged_edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline WShape* getCurrentWShape() {
|
inline WShape *getCurrentWShape()
|
||||||
|
{
|
||||||
return _current_wshape;
|
return _current_wshape;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline FrsMaterial* getCurrentFrsMaterial() {
|
inline FrsMaterial *getCurrentFrsMaterial()
|
||||||
|
{
|
||||||
return _current_frs_material;
|
return _current_frs_material;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Matrix44r* getCurrentMatrix() {
|
inline Matrix44r *getCurrentMatrix()
|
||||||
|
{
|
||||||
return _current_matrix;
|
return _current_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,81 +100,58 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
|
|||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
inline void setCurrentWShape(WShape* wshape) {
|
inline void setCurrentWShape(WShape *wshape)
|
||||||
|
{
|
||||||
_current_wshape = wshape;
|
_current_wshape = wshape;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setCurrentFrsMaterial(FrsMaterial* mat) {
|
inline void setCurrentFrsMaterial(FrsMaterial *mat)
|
||||||
|
{
|
||||||
_current_frs_material = mat;
|
_current_frs_material = mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// inline void setCurrentMatrix(Matrix44r* matrix) {
|
#if 0
|
||||||
// _current_matrix = matrix;
|
inline void setCurrentMatrix(Matrix44r *matrix)
|
||||||
// }
|
{
|
||||||
|
_current_matrix = matrix;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {
|
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {
|
||||||
_pRenderMonitor = iRenderMonitor;
|
_pRenderMonitor = iRenderMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs);
|
virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs);
|
||||||
virtual void buildWVertices(WShape& shape,
|
virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
|
||||||
const real *vertices,
|
|
||||||
unsigned vsize);
|
|
||||||
|
|
||||||
RenderMonitor *_pRenderMonitor;
|
RenderMonitor *_pRenderMonitor;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
|
||||||
|
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
||||||
|
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
|
||||||
|
const unsigned *tindices, const unsigned nvertices);
|
||||||
|
|
||||||
void buildTriangleStrip(const real *vertices,
|
void buildTriangleFan(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
|
||||||
const real *normals,
|
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
||||||
vector<FrsMaterial>& iMaterials,
|
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
|
||||||
const real *texCoords,
|
const unsigned *tindices, const unsigned nvertices);
|
||||||
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
|
||||||
const unsigned *vindices,
|
|
||||||
const unsigned *nindices,
|
|
||||||
const unsigned *mindices,
|
|
||||||
const unsigned *tindices,
|
|
||||||
const unsigned nvertices);
|
|
||||||
|
|
||||||
void buildTriangleFan(const real *vertices,
|
void buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
|
||||||
const real *normals,
|
const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
||||||
vector<FrsMaterial>& iMaterials,
|
const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
|
||||||
const real *texCoords,
|
const unsigned *tindices, const unsigned nvertices);
|
||||||
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
|
||||||
const unsigned *vindices,
|
|
||||||
const unsigned *nindices,
|
|
||||||
const unsigned *mindices,
|
|
||||||
const unsigned *tindices,
|
|
||||||
const unsigned nvertices);
|
|
||||||
|
|
||||||
void buildTriangles(const real *vertices,
|
void transformVertices(const real *vertices, unsigned vsize, const Matrix44r& transform, real *res);
|
||||||
const real *normals,
|
|
||||||
vector<FrsMaterial>& iMaterials,
|
|
||||||
const real *texCoords,
|
|
||||||
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
|
|
||||||
const unsigned *vindices,
|
|
||||||
const unsigned *nindices,
|
|
||||||
const unsigned *mindices,
|
|
||||||
const unsigned *tindices,
|
|
||||||
const unsigned nvertices);
|
|
||||||
|
|
||||||
void transformVertices(const real *vertices,
|
void transformNormals(const real *normals, unsigned nsize, const Matrix44r& transform, real *res);
|
||||||
unsigned vsize,
|
|
||||||
const Matrix44r& transform,
|
|
||||||
real *res);
|
|
||||||
|
|
||||||
void transformNormals(const real *normals,
|
WShape *_current_wshape;
|
||||||
unsigned nsize,
|
FrsMaterial *_current_frs_material;
|
||||||
const Matrix44r& transform,
|
WingedEdge *_winged_edge;
|
||||||
real *res);
|
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