Files
test/source/blender/freestyle/intern/view_map/ViewMapBuilder.h

263 lines
8.6 KiB
C
Raw Normal View History

/*
* ***** 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.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __FREESTYLE_VIEW_MAP_BUILDER_H__
#define __FREESTYLE_VIEW_MAP_BUILDER_H__
/** \file blender/freestyle/intern/view_map/ViewMapBuilder.h
* \ingroup freestyle
* \brief Class to build silhouette edges from a Winged-Edge structure
* \author Stephane Grabli
* \date 25/03/2002
*/
#include <vector>
#include "GridDensityProvider.h"
#include "Silhouette.h"
#include "SilhouetteGeomEngine.h"
#include "ViewEdgeXBuilder.h"
#include "ViewMap.h"
#include "../geometry/Geom.h"
#include "../geometry/GeomUtils.h"
#include "../geometry/Grid.h"
#include "../geometry/SweepLine.h"
#include "../scene_graph/NodeGroup.h"
#include "../scene_graph/TriangleRep.h"
#include "../system/FreestyleConfig.h"
#include "../system/ProgressBar.h"
#include "../system/RenderMonitor.h"
#include "../system/TimeUtils.h"
#include "../winged_edge/WEdge.h"
#include "../winged_edge/WXEdge.h"
2008-04-30 15:41:54 +00:00
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
Attempt to fix a potential name conflict between Freestyle and the compositor. A crash in the Freestyle renderer was reported by Ton on IRC with a stack trace below. Note that #2 is in Freestyle, whereas #1 is in the compositor. The problem was observed in a debug build on OS X 10.7 (gcc 4.2, openmp disabled, no llvm). ---------------------------------------------------------------------- Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: 13 at address: 0x0000000000000000 [Switching to process 72386 thread 0xf303] 0x0000000100c129f3 in NodeBase::~NodeBase (this=0x10e501c80) at COM_NodeBase.cpp:43 43 delete (this->m_outputsockets.back()); Current language: auto; currently c++ (gdb) where #0 0x0000000100c129f3 in NodeBase::~NodeBase (this=0x10e501c80) at COM_NodeBase.cpp:43 #1 0x0000000100c29066 in Node::~Node (this=0x10e501c80) at COM_Node.h:49 #2 0x000000010089c273 in NodeShape::~NodeShape (this=0x10e501c80) at NodeShape.cpp:43 #3 0x000000010089910b in NodeGroup::destroy (this=0x10e501da0) at NodeGroup.cpp:61 #4 0x00000001008990cd in NodeGroup::destroy (this=0x10e5014b0) at NodeGroup.cpp:59 #5 0x00000001008990cd in NodeGroup::destroy (this=0x114e18da0) at NodeGroup.cpp:59 #6 0x00000001007e6602 in Controller::ClearRootNode (this=0x114e19640) at Controller.cpp:329 #7 0x00000001007ea52e in Controller::LoadMesh (this=0x114e19640, re=0x10aba4638, srl=0x1140f5258) at Controller.cpp:302 #8 0x00000001008030ad in prepare (re=0x10aba4638, srl=0x1140f5258) at FRS_freestyle.cpp:302 #9 0x000000010080457a in FRS_do_stroke_rendering (re=0x10aba4638, srl=0x1140f5258) at FRS_freestyle.cpp:600 #10 0x00000001006aeb9d in add_freestyle (re=0x10aba4638) at pipeline.c:1584 #11 0x00000001006aceb7 in do_render_3d (re=0x10aba4638) at pipeline.c:1094 #12 0x00000001006ae061 in do_render_fields_blur_3d (re=0x10aba4638) at pipeline.c:1367 #13 0x00000001006afa16 in do_render_composite_fields_blur_3d (re=0x10aba4638) at pipeline.c:1815 #14 0x00000001006b04e4 in do_render_all_options (re=0x10aba4638) at pipeline.c:2021 ---------------------------------------------------------------------- Apparently a name conflict between the two Blender modules is taking place. The present commit hence intends to address it by putting all the Freestyle C++ classes in the namespace 'Freestyle'. This revision will also prevent potential name conflicts with other Blender modules in the future. Special thanks to Lukas Toenne for the help with C++ namespace.
2013-04-09 00:46:49 +00:00
namespace Freestyle {
2008-04-30 15:41:54 +00:00
using namespace Geometry;
class ViewMapBuilder
2008-04-30 15:41:54 +00:00
{
private:
ViewMap *_ViewMap; // result
//SilhouetteGeomEngine _GeomEngine;
ProgressBar *_pProgressBar;
RenderMonitor *_pRenderMonitor;
Vec3r _viewpoint;
bool _orthographicProjection;
Grid *_Grid;
ViewEdgeXBuilder *_pViewEdgeBuilder;
bool _EnableQI;
double _epsilon;
// tmp values:
int _currentId;
int _currentFId;
int _currentSVertexId;
2008-04-30 15:41:54 +00:00
public:
typedef enum {
sweep_line,
} intersection_algo;
2008-04-30 15:41:54 +00:00
typedef enum {
ray_casting,
ray_casting_fast,
ray_casting_very_fast,
ray_casting_culled_adaptive_traditional,
ray_casting_adaptive_traditional,
ray_casting_culled_adaptive_cumulative,
ray_casting_adaptive_cumulative,
} visibility_algo;
Optimized view map calculation by Alexander Beels. * View map calculation has been intensively optimized for speed by means of: 1) new spatial grid data structures (SphericalGrid for perspective cameras and BoxGrid for orthographic cameras; automatically switched based on the camera type); 2) a heuristic grid density calculation algorithm; and 3) new line visibility computation algorithms: A "traditional" algorithm for emulating old visibility algorithms, and a "cumulative" algorithm for improved, more consistent line visibility, both exploiting the new spatial grid data structures for fast ray casting. A new option "Raycasting Algorithm" was added to allow users to choose a ray casting (line visibility) algorithm. Available choices are: - Normal Ray Casting - Fast Ray Casting - Very Fast Ray Casting - Culled Traditional Visibility Detection - Unculled Traditional Visibility Detection - Culled Cumulative Visibility Detection - Unculled Cumulative Visibility Detection The first three algorithms are those available in the original Freestyle (the "normal" ray casting was used unconditionally, though). The "fast" and "very fast" ray casting algorithms achieve a faster calculation at the cost of less visibility accuracy. The last four are newly introduced optimized options. The culled versions of the new algorithms will exclude from visibility calculation those faces that lay outside the camera, which leads to a faster view map construction. The unculled counterparts will take all faces into account. The unculled visibility algorithms are useful when culling affects stroke chaining. The recommended options for users are the culled/unculled cumulative visibility algorithms. These options are meant to replace the old algorithms in the future. Performance improvements over the old algorithms depend on the scenes to be rendered. * Silhouette detection has also been considerably optimized for speed. Performance gains by this optimization do not depend on scenes. * Improper handling of error conditions in the view map construction was fixed.
2011-03-14 00:36:27 +00:00
inline ViewMapBuilder()
{
_pProgressBar = NULL;
_pRenderMonitor = NULL;
_Grid = NULL;
_currentId = 1;
_currentFId = 0;
_currentSVertexId = 0;
_pViewEdgeBuilder = new ViewEdgeXBuilder;
_EnableQI = true;
}
2008-04-30 15:41:54 +00:00
inline ~ViewMapBuilder()
{
if (_pViewEdgeBuilder) {
delete _pViewEdgeBuilder;
_pViewEdgeBuilder = NULL;
}
}
/* Build Grid for ray casting */
/*! Build non-culled Grid in camera space for ray casting */
void BuildGrid(WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces);
/*! Compute Shapes from a WingedEdge containing a list of WShapes */
void computeInitialViewEdges(WingedEdge&);
/*! Compute Cusps */
void computeCusps(ViewMap *ioViewMap);
2008-04-30 15:41:54 +00:00
/*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of each cusp SVertex
* We use a hysteresis approach to avoid noise.
*/
void DetectCusps(ViewEdge *ioEdge);
/*! Sets the current viewpoint */
inline void setViewpoint(const Vec3r& ivp)
{
_viewpoint = ivp;
SilhouetteGeomEngine::setViewpoint(ivp);
}
/*! Sets the current transformation
* iModelViewMatrix
* The 4x4 model view matrix, in column major order (openGL like).
* iProjection matrix
* The 4x4 projection matrix, in column major order (openGL like).
* iViewport
* The viewport. 4 real array: origin.x, origin.y, width, length
*/
inline void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4],
const int iViewport[4], real iFocalLength, real /*iAspect*/, real /*iFovy*/)
{
_orthographicProjection = (iProjectionMatrix[3][3] != 0.0);
SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength);
}
inline void setFrustum(real iZnear, real iZfar)
{
SilhouetteGeomEngine::setFrustum(iZnear, iZfar);
}
/*! Builds the scene view map returns the list the view map
* it is up to the caller to delete this ViewMap
* iWRoot
2018-06-17 17:05:14 +02:00
* 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);
void CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4],
bool extensiveFEdgeSearch = true);
/*! computes the intersection between all 2D feature edges of the scene.
* ioViewMap
* The view map. It is modified by the method.
* The list of all features edges of the scene.
* Each time an intersection is found, the 2 intersecting edges are splitted (creating 2 new vertices)
* At the end, this list is updated with the adding of all new created edges (resulting from splitting).
* iAlgo
* The algo to use for computing the intersections
*/
void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon = 1.0e-06);
/*! Computes the 2D scene silhouette edges visibility
* iGrid
2018-06-17 17:05:14 +02:00
* For the Ray Casting algorithm.
*/
void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, unsigned int sceneNumFaces,
visibility_algo iAlgo = ray_casting, real epsilon = 1.0e-6);
void setGrid(Grid *iGrid)
{
_Grid = iGrid;
}
/*! accessors */
/*! Modifiers */
inline void setProgressBar(ProgressBar *iProgressBar)
{
_pProgressBar = iProgressBar;
}
inline void setRenderMonitor(RenderMonitor *iRenderMonitor)
{
_pRenderMonitor = iRenderMonitor;
}
inline void setEnableQI(bool iBool)
{
_EnableQI = iBool;
}
2008-04-30 15:41:54 +00:00
protected:
/*! Computes intersections on all edges of the scene using a sweep line algorithm */
void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1.0e-6);
/*! Computes the 2D scene silhouette edges visibility using a ray casting. On each edge, a ray is cast
* to check its quantitative invisibility. The list of occluders are each time stored in the tested edge.
* ioViewMap
* The view map.
* The 2D scene silhouette edges as FEdges.
* These edges have already been splitted at their intersections points.
* Thus, these edges do not intersect anymore.
* The visibility corresponding to each edge of ioScene is set is this edge.
*/
void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon = 1.0e-6);
2008-04-30 15:41:54 +00:00
void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
bool cull, GridDensityProviderFactory& factory);
void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox, real epsilon,
bool cull, GridDensityProviderFactory& factory);
2008-04-30 15:41:54 +00:00
/*! Compute the visibility for the FEdge fe.
* The occluders are added to fe occluders list.
* fe
* The FEdge
* iGrid
* The grid used to compute the ray casting visibility
* epsilon
* The epsilon used for computation
* oShapeId
* fe is the border (in 2D) between 2 2D spaces.
* if fe is a silhouette, One of these 2D spaces is occupied by the shape to which fe belongs (on its left)
* and the other one is either occupied by another shape or empty or occupied by the same shape.
* We use this ray csating operation to determine which shape lies on fe's right.
* The result is the shape id stored in oShapeId
*/
int ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
Polygon3r **oaPolygon, unsigned timestamp);
// FIXME
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapBuilder")
#endif
2008-04-30 15:41:54 +00:00
};
Attempt to fix a potential name conflict between Freestyle and the compositor. A crash in the Freestyle renderer was reported by Ton on IRC with a stack trace below. Note that #2 is in Freestyle, whereas #1 is in the compositor. The problem was observed in a debug build on OS X 10.7 (gcc 4.2, openmp disabled, no llvm). ---------------------------------------------------------------------- Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: 13 at address: 0x0000000000000000 [Switching to process 72386 thread 0xf303] 0x0000000100c129f3 in NodeBase::~NodeBase (this=0x10e501c80) at COM_NodeBase.cpp:43 43 delete (this->m_outputsockets.back()); Current language: auto; currently c++ (gdb) where #0 0x0000000100c129f3 in NodeBase::~NodeBase (this=0x10e501c80) at COM_NodeBase.cpp:43 #1 0x0000000100c29066 in Node::~Node (this=0x10e501c80) at COM_Node.h:49 #2 0x000000010089c273 in NodeShape::~NodeShape (this=0x10e501c80) at NodeShape.cpp:43 #3 0x000000010089910b in NodeGroup::destroy (this=0x10e501da0) at NodeGroup.cpp:61 #4 0x00000001008990cd in NodeGroup::destroy (this=0x10e5014b0) at NodeGroup.cpp:59 #5 0x00000001008990cd in NodeGroup::destroy (this=0x114e18da0) at NodeGroup.cpp:59 #6 0x00000001007e6602 in Controller::ClearRootNode (this=0x114e19640) at Controller.cpp:329 #7 0x00000001007ea52e in Controller::LoadMesh (this=0x114e19640, re=0x10aba4638, srl=0x1140f5258) at Controller.cpp:302 #8 0x00000001008030ad in prepare (re=0x10aba4638, srl=0x1140f5258) at FRS_freestyle.cpp:302 #9 0x000000010080457a in FRS_do_stroke_rendering (re=0x10aba4638, srl=0x1140f5258) at FRS_freestyle.cpp:600 #10 0x00000001006aeb9d in add_freestyle (re=0x10aba4638) at pipeline.c:1584 #11 0x00000001006aceb7 in do_render_3d (re=0x10aba4638) at pipeline.c:1094 #12 0x00000001006ae061 in do_render_fields_blur_3d (re=0x10aba4638) at pipeline.c:1367 #13 0x00000001006afa16 in do_render_composite_fields_blur_3d (re=0x10aba4638) at pipeline.c:1815 #14 0x00000001006b04e4 in do_render_all_options (re=0x10aba4638) at pipeline.c:2021 ---------------------------------------------------------------------- Apparently a name conflict between the two Blender modules is taking place. The present commit hence intends to address it by putting all the Freestyle C++ classes in the namespace 'Freestyle'. This revision will also prevent potential name conflicts with other Blender modules in the future. Special thanks to Lukas Toenne for the help with C++ namespace.
2013-04-09 00:46:49 +00:00
} /* namespace Freestyle */
#endif // __FREESTYLE_VIEW_MAP_BUILDER_H__