This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp

976 lines
32 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 *****
*/
/** \file blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
* \ingroup freestyle
*/
#include "BlenderStrokeRenderer.h"
#include "../application/AppConfig.h"
#include "../stroke/Canvas.h"
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
extern "C" {
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_types.h"
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
#include "DNA_camera_types.h"
#include "DNA_listBase.h"
#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
#include "BKE_collection.h"
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_library.h" /* free_libblock */
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math_color.h"
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
#include "RE_pipeline.h"
#include "render_types.h"
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
}
#include <limits.h>
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 {
const char *BlenderStrokeRenderer::uvNames[] = {"along_stroke", "along_stroke_tips"};
BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : StrokeRenderer()
{
freestyle_bmain = re->freestyle_bmain;
// for stroke mesh generation
_width = re->winx;
_height = re->winy;
old_scene = re->scene;
char name[MAX_ID_NAME - 2];
BLI_snprintf(name, sizeof(name), "FRS%d_%s", render_count, re->scene->id.name + 2);
freestyle_scene = BKE_scene_add(freestyle_bmain, name);
freestyle_scene->r.cfra = old_scene->r.cfra;
freestyle_scene->r.mode = old_scene->r.mode &
~(R_EDGE_FRS | R_SHADOW | R_SSS | R_PANORAMA | R_ENVMAP | R_MBLUR | R_BORDER);
freestyle_scene->r.xsch = re->rectx; // old_scene->r.xsch
freestyle_scene->r.ysch = re->recty; // old_scene->r.ysch
freestyle_scene->r.xasp = 1.0f; // old_scene->r.xasp;
freestyle_scene->r.yasp = 1.0f; // old_scene->r.yasp;
freestyle_scene->r.tilex = old_scene->r.tilex;
freestyle_scene->r.tiley = old_scene->r.tiley;
freestyle_scene->r.size = 100; // old_scene->r.size
//freestyle_scene->r.maximsize = old_scene->r.maximsize; /* DEPRECATED */
freestyle_scene->r.ocres = old_scene->r.ocres;
freestyle_scene->r.color_mgt_flag = 0; // old_scene->r.color_mgt_flag;
freestyle_scene->r.scemode = old_scene->r.scemode & ~(R_SINGLE_LAYER | R_NO_FRAME_UPDATE | R_MULTIVIEW);
freestyle_scene->r.flag = old_scene->r.flag;
freestyle_scene->r.threads = old_scene->r.threads;
freestyle_scene->r.border.xmin = old_scene->r.border.xmin;
freestyle_scene->r.border.ymin = old_scene->r.border.ymin;
freestyle_scene->r.border.xmax = old_scene->r.border.xmax;
freestyle_scene->r.border.ymax = old_scene->r.border.ymax;
strcpy(freestyle_scene->r.pic, old_scene->r.pic);
freestyle_scene->r.safety.xmin = old_scene->r.safety.xmin;
freestyle_scene->r.safety.ymin = old_scene->r.safety.ymin;
freestyle_scene->r.safety.xmax = old_scene->r.safety.xmax;
freestyle_scene->r.safety.ymax = old_scene->r.safety.ymax;
freestyle_scene->r.osa = old_scene->r.osa;
freestyle_scene->r.filtertype = old_scene->r.filtertype;
freestyle_scene->r.gauss = old_scene->r.gauss;
freestyle_scene->r.dither_intensity = old_scene->r.dither_intensity;
BKE_viewrender_copy(&freestyle_scene->view_render, &old_scene->view_render);
freestyle_scene->r.im_format.planes = R_IMF_PLANES_RGBA;
freestyle_scene->r.im_format.imtype = R_IMF_IMTYPE_PNG;
if (G.debug & G_DEBUG_FREESTYLE) {
printf("%s: %d thread(s)\n", __func__, BKE_render_num_threads(&freestyle_scene->r));
}
// Render layer
SceneRenderLayer *srl = (SceneRenderLayer *)freestyle_scene->r.layers.first;
srl->layflag = SCE_LAY_SOLID | SCE_LAY_ZTRA;
BKE_scene_set_background(freestyle_bmain, freestyle_scene);
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
// Camera
Render Layers and Collections (merge from render-layers) Design Documents ---------------- * https://wiki.blender.org/index.php/Dev:2.8/Source/Layers * https://wiki.blender.org/index.php/Dev:2.8/Source/DataDesignRevised User Commit Log --------------- * New Layer and Collection system to replace render layers and viewport layers. * A layer is a set of collections of objects (and their drawing options) required for specific tasks. * A collection is a set of objects, equivalent of the old layers in Blender. A collection can be shared across multiple layers. * All Scenes have a master collection that all other collections are children of. * New collection "context" tab (in Properties Editor) * New temporary viewport "collections" panel to control per-collection visibility Missing User Features --------------------- * Collection "Filter" Option to add objects based on their names * Collection Manager operators The existing buttons are placeholders * Collection Manager drawing The editor main region is empty * Collection Override * Per-Collection engine settings This will come as a separate commit, as part of the clay-engine branch Dev Commit Log -------------- * New DNA file (DNA_layer_types.h) with the new structs We are replacing Base by a new extended Base while keeping it backward compatible with some legacy settings (i.e., lay, flag_legacy). Renamed all Base to BaseLegacy to make it clear the areas of code that still need to be converted Note: manual changes were required on - deg_builder_nodes.h, rna_object.c, KX_Light.cpp * Unittesting for main syncronization requirements - read, write, add/copy/remove objects, copy scene, collection link/unlinking, context) * New Editor: Collection Manager Based on patch by Julian Eisel This is extracted from the layer-manager branch. With the following changes: - Renamed references of layer manager to collections manager - I doesn't include the editors/space_collections/ draw and util files - The drawing code itself will be implemented separately by Julian * Base / Object: A little note about them. Original Blender code would try to keep them in sync through the code, juggling flags back and forth. This will now be handled by Depsgraph, keeping Object and Bases more separated throughout the non-rendering code. Scene.base is being cleared in doversion, and the old viewport drawing code was poorly converted to use the new bases while the new viewport code doesn't get merged and replace the old one. Python API Changes ------------------ ``` - scene.layers + # no longer exists - scene.objects + scene.scene_layers.active.objects - scene.objects.active + scene.render_layers.active.objects.active - bpy.context.scene.objects.link() + bpy.context.scene_collection.objects.link() - bpy_extras.object_utils.object_data_add(context, obdata, operator=None, use_active_layer=True, name=None) + bpy_extras.object_utils.object_data_add(context, obdata, operator=None, name=None) - bpy.context.object.select + bpy.context.object.select = True + bpy.context.object.select = False + bpy.context.object.select_get() + bpy.context.object.select_set(action='SELECT') + bpy.context.object.select_set(action='DESELECT') -AddObjectHelper.layers + # no longer exists ```
2017-02-07 10:18:38 +01:00
Object *object_camera = BKE_object_add(freestyle_bmain, freestyle_scene, (SceneLayer *)freestyle_scene->render_layers.first, OB_CAMERA, NULL);
DEG_relations_tag_update(freestyle_bmain);
Camera *camera = (Camera *)object_camera->data;
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
camera->type = CAM_ORTHO;
camera->ortho_scale = max(re->rectx, re->recty);
camera->clipsta = 0.1f;
camera->clipend = 100.0f;
_z_delta = 0.00001f;
_z = camera->clipsta + _z_delta;
object_camera->loc[0] = re->disprect.xmin + 0.5f * re->rectx;
object_camera->loc[1] = re->disprect.ymin + 0.5f * re->recty;
object_camera->loc[2] = 1.0f;
freestyle_scene->camera = object_camera;
// Reset serial mesh ID (used for BlenderStrokeRenderer::NewMesh())
_mesh_id = 0xffffffff;
// Check if the rendering engine uses new shading nodes
_use_shading_nodes = BKE_scene_use_new_shading_nodes(freestyle_scene);
// Create a bNodeTree-to-Material hash table
if (_use_shading_nodes)
_nodetree_hash = BLI_ghash_ptr_new("BlenderStrokeRenderer::_nodetree_hash");
else
_nodetree_hash = NULL;
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
}
BlenderStrokeRenderer::~BlenderStrokeRenderer()
{
2010-06-26 16:35:56 +00:00
// The freestyle_scene object is not released here. Instead,
// the scene is released in free_all_freestyle_renders() in
// source/blender/render/intern/source/pipeline.c, after the
// compositor has finished.
// release objects and data blocks
SceneLayer *scene_layer = (SceneLayer *)freestyle_scene->render_layers.first;
for (Base *b = (Base *)scene_layer->object_bases.first; b; b = b->next) {
Object *ob = b->object;
void *data = ob->data;
char *name = ob->id.name;
#if 0
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "removing " << name[0] << name[1] << ":" << (name+2) << endl;
}
#endif
switch (ob->type) {
case OB_MESH:
BKE_libblock_free(freestyle_bmain, ob);
BKE_libblock_free(freestyle_bmain, data);
break;
case OB_CAMERA:
BKE_libblock_free(freestyle_bmain, ob);
BKE_libblock_free(freestyle_bmain, data);
freestyle_scene->camera = NULL;
break;
default:
cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":" << (name + 2) << endl;
}
}
// Make sure we don't have any bases which might reference freed objects.
FOREACH_SCENE_COLLECTION(freestyle_scene, sc)
{
BLI_freelistN(&sc->objects);
}
FOREACH_SCENE_COLLECTION_END
BLI_freelistN(&scene_layer->object_bases);
BLI_freelistN(&freestyle_scene->base);
// release materials
Link *lnk = (Link *)freestyle_bmain->mat.first;
while (lnk)
{
Material *ma = (Material*)lnk;
// We want to retain the linestyle mtexs, so let's detach them first
for (int a = 0; a < MAX_MTEX; a++) {
if (ma->mtex[a]) {
ma->mtex[a] = NULL;
}
else {
break; // Textures are ordered, no empty slots between two textures
}
}
lnk = lnk->next;
BKE_libblock_free(freestyle_bmain, ma);
}
if (_use_shading_nodes)
BLI_ghash_free(_nodetree_hash, NULL, NULL);
FreeStrokeGroups();
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
}
float BlenderStrokeRenderer::get_stroke_vertex_z(void) const
{
float z = _z;
BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this);
if (!(_z < _z_delta * 100000.0f))
self->_z_delta *= 10.0f;
self->_z += _z_delta;
return -z;
}
unsigned int BlenderStrokeRenderer::get_stroke_mesh_id(void) const
{
unsigned mesh_id = _mesh_id;
BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this);
self->_mesh_id--;
return mesh_id;
}
Material* BlenderStrokeRenderer::GetStrokeShader(Main *bmain, bNodeTree *iNodeTree, bool do_id_user)
{
Material *ma = BKE_material_add(bmain, "stroke_shader");
bNodeTree *ntree;
bNode *output_linestyle = NULL;
bNodeSocket *fromsock, *tosock;
PointerRNA fromptr, toptr;
NodeShaderAttribute *storage;
id_us_min(&ma->id);
if (iNodeTree) {
// make a copy of linestyle->nodetree
ntree = ntreeCopyTree_ex(iNodeTree, bmain, do_id_user);
// find the active Output Line Style node
for (bNode *node = (bNode *)ntree->nodes.first; node; node = node->next) {
if (node->type == SH_NODE_OUTPUT_LINESTYLE && (node->flag & NODE_DO_OUTPUT)) {
output_linestyle = node;
break;
}
}
}
else {
ntree = ntreeAddTree(NULL, "stroke_shader", "ShaderNodeTree");
}
ma->nodetree = ntree;
ma->use_nodes = 1;
bNode *input_attr_color = nodeAddStaticNode(NULL, ntree, SH_NODE_ATTRIBUTE);
input_attr_color->locx = 0.0f;
input_attr_color->locy = -200.0f;
storage = (NodeShaderAttribute *)input_attr_color->storage;
BLI_strncpy(storage->name, "Color", sizeof(storage->name));
bNode *mix_rgb_color = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_RGB);
mix_rgb_color->custom1 = MA_RAMP_BLEND; // Mix
mix_rgb_color->locx = 200.0f;
mix_rgb_color->locy = -200.0f;
tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 0); // Fac
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
RNA_float_set(&toptr, "default_value", 0.0f);
bNode *input_attr_alpha = nodeAddStaticNode(NULL, ntree, SH_NODE_ATTRIBUTE);
input_attr_alpha->locx = 400.0f;
input_attr_alpha->locy = 300.0f;
storage = (NodeShaderAttribute *)input_attr_alpha->storage;
BLI_strncpy(storage->name, "Alpha", sizeof(storage->name));
bNode *mix_rgb_alpha = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_RGB);
mix_rgb_alpha->custom1 = MA_RAMP_BLEND; // Mix
mix_rgb_alpha->locx = 600.0f;
mix_rgb_alpha->locy = 300.0f;
tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 0); // Fac
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
RNA_float_set(&toptr, "default_value", 0.0f);
bNode *shader_emission = nodeAddStaticNode(NULL, ntree, SH_NODE_EMISSION);
shader_emission->locx = 400.0f;
shader_emission->locy = -200.0f;
bNode *input_light_path = nodeAddStaticNode(NULL, ntree, SH_NODE_LIGHT_PATH);
input_light_path->locx = 400.0f;
input_light_path->locy = 100.0f;
bNode *mix_shader_color = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_SHADER);
mix_shader_color->locx = 600.0f;
mix_shader_color->locy = -100.0f;
bNode *shader_transparent = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_TRANSPARENT);
shader_transparent->locx = 600.0f;
shader_transparent->locy = 100.0f;
bNode *mix_shader_alpha = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_SHADER);
mix_shader_alpha->locx = 800.0f;
mix_shader_alpha->locy = 100.0f;
bNode *output_material = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
output_material->locx = 1000.0f;
output_material->locy = 100.0f;
fromsock = (bNodeSocket *)BLI_findlink(&input_attr_color->outputs, 0); // Color
tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 1); // Color1
nodeAddLink(ntree, input_attr_color, fromsock, mix_rgb_color, tosock);
fromsock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->outputs, 0); // Color
tosock = (bNodeSocket *)BLI_findlink(&shader_emission->inputs, 0); // Color
nodeAddLink(ntree, mix_rgb_color, fromsock, shader_emission, tosock);
fromsock = (bNodeSocket *)BLI_findlink(&shader_emission->outputs, 0); // Emission
tosock = (bNodeSocket *)BLI_findlink(&mix_shader_color->inputs, 2); // Shader (second)
nodeAddLink(ntree, shader_emission, fromsock, mix_shader_color, tosock);
fromsock = (bNodeSocket *)BLI_findlink(&input_light_path->outputs, 0); // In Camera Ray
tosock = (bNodeSocket *)BLI_findlink(&mix_shader_color->inputs, 0); // Fac
nodeAddLink(ntree, input_light_path, fromsock, mix_shader_color, tosock);
fromsock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->outputs, 0); // Color
tosock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->inputs, 0); // Fac
nodeAddLink(ntree, mix_rgb_alpha, fromsock, mix_shader_alpha, tosock);
fromsock = (bNodeSocket *)BLI_findlink(&input_attr_alpha->outputs, 0); // Color
tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 1); // Color1
nodeAddLink(ntree, input_attr_alpha, fromsock, mix_rgb_alpha, tosock);
fromsock = (bNodeSocket *)BLI_findlink(&shader_transparent->outputs, 0); // BSDF
tosock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->inputs, 1); // Shader (first)
nodeAddLink(ntree, shader_transparent, fromsock, mix_shader_alpha, tosock);
fromsock = (bNodeSocket *)BLI_findlink(&mix_shader_color->outputs, 0); // Shader
tosock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->inputs, 2); // Shader (second)
nodeAddLink(ntree, mix_shader_color, fromsock, mix_shader_alpha, tosock);
fromsock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->outputs, 0); // Shader
tosock = (bNodeSocket *)BLI_findlink(&output_material->inputs, 0); // Surface
nodeAddLink(ntree, mix_shader_alpha, fromsock, output_material, tosock);
if (output_linestyle) {
bNodeSocket *outsock;
bNodeLink *link;
mix_rgb_color->custom1 = output_linestyle->custom1; // blend_type
mix_rgb_color->custom2 = output_linestyle->custom2; // use_clamp
outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 0); // Color
tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 2); // Color2
link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
if (link) {
nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_color, tosock);
}
else {
float color[4];
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
RNA_float_get_array(&fromptr, "default_value", color);
RNA_float_set_array(&toptr, "default_value", color);
}
outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 1); // Color Fac
tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 0); // Fac
link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
if (link) {
nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_color, tosock);
}
else {
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
RNA_float_set(&toptr, "default_value", RNA_float_get(&fromptr, "default_value"));
}
outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 2); // Alpha
tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 2); // Color2
link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
if (link) {
nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_alpha, tosock);
}
else {
float color[4];
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
color[0] = color[1] = color[2] = RNA_float_get(&fromptr, "default_value");
color[3] = 1.0f;
RNA_float_set_array(&toptr, "default_value", color);
}
outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 3); // Alpha Fac
tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 0); // Fac
link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
if (link) {
nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_alpha, tosock);
}
else {
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
RNA_float_set(&toptr, "default_value", RNA_float_get(&fromptr, "default_value"));
}
for (bNode *node = (bNode *)ntree->nodes.first; node; node = node->next) {
if (node->type == SH_NODE_UVALONGSTROKE) {
// UV output of the UV Along Stroke node
bNodeSocket *sock = (bNodeSocket *)BLI_findlink(&node->outputs, 0);
// add new UV Map node
bNode *input_uvmap = nodeAddStaticNode(NULL, ntree, SH_NODE_UVMAP);
input_uvmap->locx = node->locx - 200.0f;
input_uvmap->locy = node->locy;
NodeShaderUVMap *storage = (NodeShaderUVMap *)input_uvmap->storage;
if (node->custom1 & 1) { // use_tips
BLI_strncpy(storage->uv_map, uvNames[1], sizeof(storage->uv_map));
}
else {
BLI_strncpy(storage->uv_map, uvNames[0], sizeof(storage->uv_map));
}
fromsock = (bNodeSocket *)BLI_findlink(&input_uvmap->outputs, 0); // UV
// replace links from the UV Along Stroke node by links from the UV Map node
for (bNodeLink *link = (bNodeLink *)ntree->links.first; link; link = link->next) {
if (link->fromnode == node && link->fromsock == sock) {
nodeAddLink(ntree, input_uvmap, fromsock, link->tonode, link->tosock);
}
}
nodeRemSocketLinks(ntree, sock);
}
}
}
nodeSetActive(ntree, output_material);
ntreeUpdateTree(bmain, ntree);
return ma;
}
void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
{
RenderStrokeRepBasic(iStrokeRep);
}
void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
{
if (_use_shading_nodes) {
bNodeTree *nt = iStrokeRep->getNodeTree();
Material *ma = (Material *)BLI_ghash_lookup(_nodetree_hash, nt);
if (!ma) {
ma = BlenderStrokeRenderer::GetStrokeShader(freestyle_bmain, nt, false);
BLI_ghash_insert(_nodetree_hash, nt, ma);
}
if (STREQ(freestyle_scene->view_render.engine_id, RE_engine_id_CYCLES)) {
PointerRNA scene_ptr, freestyle_scene_ptr;
RNA_pointer_create(NULL, &RNA_Scene, old_scene, &scene_ptr);
RNA_pointer_create(NULL, &RNA_Scene, freestyle_scene, &freestyle_scene_ptr);
PointerRNA cycles_ptr = RNA_pointer_get(&scene_ptr, "cycles");
PointerRNA freestyle_cycles_ptr = RNA_pointer_get(&freestyle_scene_ptr, "cycles");
int flag;
RNA_STRUCT_BEGIN(&freestyle_cycles_ptr, prop)
{
flag = RNA_property_flag(prop);
if (flag & PROP_HIDDEN)
continue;
RNA_property_copy(&freestyle_cycles_ptr, &cycles_ptr, prop, -1);
}
RNA_STRUCT_END;
RNA_boolean_set(&freestyle_cycles_ptr, "film_transparent", 1);
}
iStrokeRep->setMaterial(ma);
}
else {
bool has_mat = false;
int a = 0;
// Look for a good existing material
for (Link *lnk = (Link *)freestyle_bmain->mat.first; lnk; lnk = lnk->next) {
Material *ma = (Material*)lnk;
bool texs_are_good = true;
// as soon as textures differ it's not the right one
for (int a = 0; a < MAX_MTEX; a++) {
if (ma->mtex[a] != iStrokeRep->getMTex(a)) {
texs_are_good = false;
break;
}
}
if (texs_are_good) {
iStrokeRep->setMaterial(ma);
has_mat = true;
break; // if textures are good, no need to search anymore
}
}
// If still no material, create one
if (!has_mat) {
Material *ma = BKE_material_add(freestyle_bmain, "stroke_material");
DEG_relations_tag_update(freestyle_bmain);
ma->mode |= MA_VERTEXCOLP;
ma->mode |= MA_TRANSP;
ma->mode |= MA_SHLESS;
ma->vcol_alpha = 1;
id_us_min(&ma->id);
// Textures
while (iStrokeRep->getMTex(a)) {
ma->mtex[a] = (MTex *)iStrokeRep->getMTex(a);
// We'll generate both with tips and without tips
// coordinates, on two different UV layers.
2017-06-02 15:38:04 +10:00
if (ma->mtex[a]->texflag & MTEX_TIPS) {
BLI_strncpy(ma->mtex[a]->uvname, uvNames[1], sizeof(ma->mtex[a]->uvname));
}
else {
BLI_strncpy(ma->mtex[a]->uvname, uvNames[0], sizeof(ma->mtex[a]->uvname));
}
a++;
}
iStrokeRep->setMaterial(ma);
}
}
const vector<Strip*>& strips = iStrokeRep->getStrips();
const bool hasTex = iStrokeRep->hasTex();
int totvert = 0, totedge = 0, totpoly = 0, totloop = 0;
int visible_faces, visible_segments;
for (vector<Strip*>::const_iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
Strip::vertex_container& strip_vertices = (*s)->vertices();
// count visible faces and strip segments
test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
if (visible_faces == 0)
continue;
totvert += visible_faces + visible_segments * 2;
totedge += visible_faces * 2 + visible_segments;
totpoly += visible_faces;
totloop += visible_faces * 3;
}
BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this); // FIXME
vector<StrokeGroup*> *groups = hasTex ? &self->texturedStrokeGroups : &self->strokeGroups;
StrokeGroup *group;
if (groups->empty() || !(groups->back()->totvert + totvert < MESH_MAX_VERTS &&
groups->back()->totcol + 1 < MAXMAT))
{
group = new StrokeGroup;
groups->push_back(group);
}
else {
group = groups->back();
}
group->strokes.push_back(iStrokeRep);
group->totvert += totvert;
group->totedge += totedge;
group->totpoly += totpoly;
group->totloop += totloop;
group->totcol++;
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
}
// Check if the triangle is visible (i.e., within the render image boundary)
bool BlenderStrokeRenderer::test_triangle_visibility(StrokeVertexRep *svRep[3]) const
{
int xl, xu, yl, yu;
Vec2r p;
xl = xu = yl = yu = 0;
for (int i = 0; i < 3; i++) {
p = svRep[i]->point2d();
if (p[0] < 0.0)
xl++;
else if (p[0] > _width)
xu++;
if (p[1] < 0.0)
yl++;
else if (p[1] > _height)
yu++;
}
return !(xl == 3 || xu == 3 || yl == 3 || yu == 3);
}
// Check the visibility of faces and strip segments.
void BlenderStrokeRenderer::test_strip_visibility(Strip::vertex_container& strip_vertices,
int *visible_faces, int *visible_segments) const
{
const int strip_vertex_count = strip_vertices.size();
Strip::vertex_container::iterator v[3];
StrokeVertexRep *svRep[3];
bool visible;
// iterate over all vertices and count visible faces and strip segments
// (note: a strip segment is a series of visible faces, while two strip
// segments are separated by one or more invisible faces)
v[0] = strip_vertices.begin();
v[1] = v[0] + 1;
v[2] = v[0] + 2;
*visible_faces = *visible_segments = 0;
visible = false;
for (int n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
svRep[0] = *(v[0]);
svRep[1] = *(v[1]);
svRep[2] = *(v[2]);
if (test_triangle_visibility(svRep)) {
(*visible_faces)++;
if (!visible)
(*visible_segments)++;
visible = true;
}
else {
visible = false;
}
}
}
// Release allocated memory for stroke groups
void BlenderStrokeRenderer::FreeStrokeGroups()
{
vector<StrokeGroup*>::const_iterator it, itend;
for (it = strokeGroups.begin(), itend = strokeGroups.end();
it != itend; ++it)
{
delete (*it);
}
for (it = texturedStrokeGroups.begin(), itend = texturedStrokeGroups.end();
it != itend; ++it)
{
delete (*it);
}
}
// Build a scene populated by mesh objects representing stylized strokes
int BlenderStrokeRenderer::GenerateScene()
{
vector<StrokeGroup*>::const_iterator it, itend;
for (it = strokeGroups.begin(), itend = strokeGroups.end();
it != itend; ++it)
{
GenerateStrokeMesh(*it, false);
}
for (it = texturedStrokeGroups.begin(), itend = texturedStrokeGroups.end();
it != itend; ++it)
{
GenerateStrokeMesh(*it, true);
}
return get_stroke_count();
}
// Return the number of strokes
int BlenderStrokeRenderer::get_stroke_count() const
{
return strokeGroups.size() + texturedStrokeGroups.size();
}
// Build a mesh object representing a group of stylized strokes
void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex)
{
#if 0
Render Layers and Collections (merge from render-layers) Design Documents ---------------- * https://wiki.blender.org/index.php/Dev:2.8/Source/Layers * https://wiki.blender.org/index.php/Dev:2.8/Source/DataDesignRevised User Commit Log --------------- * New Layer and Collection system to replace render layers and viewport layers. * A layer is a set of collections of objects (and their drawing options) required for specific tasks. * A collection is a set of objects, equivalent of the old layers in Blender. A collection can be shared across multiple layers. * All Scenes have a master collection that all other collections are children of. * New collection "context" tab (in Properties Editor) * New temporary viewport "collections" panel to control per-collection visibility Missing User Features --------------------- * Collection "Filter" Option to add objects based on their names * Collection Manager operators The existing buttons are placeholders * Collection Manager drawing The editor main region is empty * Collection Override * Per-Collection engine settings This will come as a separate commit, as part of the clay-engine branch Dev Commit Log -------------- * New DNA file (DNA_layer_types.h) with the new structs We are replacing Base by a new extended Base while keeping it backward compatible with some legacy settings (i.e., lay, flag_legacy). Renamed all Base to BaseLegacy to make it clear the areas of code that still need to be converted Note: manual changes were required on - deg_builder_nodes.h, rna_object.c, KX_Light.cpp * Unittesting for main syncronization requirements - read, write, add/copy/remove objects, copy scene, collection link/unlinking, context) * New Editor: Collection Manager Based on patch by Julian Eisel This is extracted from the layer-manager branch. With the following changes: - Renamed references of layer manager to collections manager - I doesn't include the editors/space_collections/ draw and util files - The drawing code itself will be implemented separately by Julian * Base / Object: A little note about them. Original Blender code would try to keep them in sync through the code, juggling flags back and forth. This will now be handled by Depsgraph, keeping Object and Bases more separated throughout the non-rendering code. Scene.base is being cleared in doversion, and the old viewport drawing code was poorly converted to use the new bases while the new viewport code doesn't get merged and replace the old one. Python API Changes ------------------ ``` - scene.layers + # no longer exists - scene.objects + scene.scene_layers.active.objects - scene.objects.active + scene.render_layers.active.objects.active - bpy.context.scene.objects.link() + bpy.context.scene_collection.objects.link() - bpy_extras.object_utils.object_data_add(context, obdata, operator=None, use_active_layer=True, name=None) + bpy_extras.object_utils.object_data_add(context, obdata, operator=None, name=None) - bpy.context.object.select + bpy.context.object.select = True + bpy.context.object.select = False + bpy.context.object.select_get() + bpy.context.object.select_set(action='SELECT') + bpy.context.object.select_set(action='DESELECT') -AddObjectHelper.layers + # no longer exists ```
2017-02-07 10:18:38 +01:00
Object *object_mesh = BKE_object_add(freestyle_bmain, freestyle_scene, (SceneLayer *)freestyle_scene->render_layers.first, OB_MESH);
DEG_relations_tag_update(freestyle_bmain);
#else
Object *object_mesh = NewMesh();
#endif
Mesh *mesh = (Mesh *)object_mesh->data;
mesh->totvert = group->totvert;
mesh->totedge = group->totedge;
mesh->totpoly = group->totpoly;
mesh->totloop = group->totloop;
mesh->totcol = group->totcol;
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
mesh->mvert = (MVert *)CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
mesh->medge = (MEdge *)CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
mesh->mpoly = (MPoly *)CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
mesh->mloop = (MLoop *)CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
MVert *vertices = mesh->mvert;
MEdge *edges = mesh->medge;
MPoly *polys = mesh->mpoly;
MLoop *loops = mesh->mloop;
MLoopUV *loopsuv[2] = { NULL };
if (hasTex) {
// First UV layer
CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, uvNames[0]);
CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 0);
BKE_mesh_update_customdata_pointers(mesh, true);
loopsuv[0] = mesh->mloopuv;
// Second UV layer
CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, uvNames[1]);
CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 1);
BKE_mesh_update_customdata_pointers(mesh, true);
loopsuv[1] = mesh->mloopuv;
}
// colors and transparency (the latter represented by grayscale colors)
MLoopCol *colors = (MLoopCol *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop, "Color");
MLoopCol *transp = (MLoopCol *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop, "Alpha");
mesh->mloopcol = colors;
mesh->mat = (Material **)MEM_mallocN(sizeof(Material *) * mesh->totcol, "MaterialList");
////////////////////
// Data copy
////////////////////
int vertex_index = 0, edge_index = 0, loop_index = 0, material_index = 0;
int visible_faces, visible_segments;
bool visible;
Strip::vertex_container::iterator v[3];
StrokeVertexRep *svRep[3];
Vec2r p;
for (vector<StrokeRep*>::const_iterator it = group->strokes.begin(), itend = group->strokes.end();
it != itend; ++it)
{
mesh->mat[material_index] = (*it)->getMaterial();
id_us_plus(&mesh->mat[material_index]->id);
vector<Strip*>& strips = (*it)->getStrips();
for (vector<Strip*>::const_iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
Strip::vertex_container& strip_vertices = (*s)->vertices();
int strip_vertex_count = strip_vertices.size();
// count visible faces and strip segments
test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
if (visible_faces == 0)
continue;
v[0] = strip_vertices.begin();
v[1] = v[0] + 1;
v[2] = v[0] + 2;
visible = false;
// Note: Mesh generation in the following loop assumes stroke strips
// to be triangle strips.
for (int n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
svRep[0] = *(v[0]);
svRep[1] = *(v[1]);
svRep[2] = *(v[2]);
if (!test_triangle_visibility(svRep)) {
visible = false;
}
else {
if (!visible) {
// first vertex
vertices->co[0] = svRep[0]->point2d()[0];
vertices->co[1] = svRep[0]->point2d()[1];
vertices->co[2] = get_stroke_vertex_z();
vertices->no[0] = 0;
vertices->no[1] = 0;
vertices->no[2] = SHRT_MAX;
++vertices;
++vertex_index;
// second vertex
vertices->co[0] = svRep[1]->point2d()[0];
vertices->co[1] = svRep[1]->point2d()[1];
vertices->co[2] = get_stroke_vertex_z();
vertices->no[0] = 0;
vertices->no[1] = 0;
vertices->no[2] = SHRT_MAX;
++vertices;
++vertex_index;
// first edge
edges->v1 = vertex_index - 2;
edges->v2 = vertex_index - 1;
++edges;
++edge_index;
}
visible = true;
// vertex
vertices->co[0] = svRep[2]->point2d()[0];
vertices->co[1] = svRep[2]->point2d()[1];
vertices->co[2] = get_stroke_vertex_z();
vertices->no[0] = 0;
vertices->no[1] = 0;
vertices->no[2] = SHRT_MAX;
++vertices;
++vertex_index;
// edges
edges->v1 = vertex_index - 1;
edges->v2 = vertex_index - 3;
++edges;
++edge_index;
edges->v1 = vertex_index - 1;
edges->v2 = vertex_index - 2;
++edges;
++edge_index;
// poly
polys->loopstart = loop_index;
polys->totloop = 3;
polys->mat_nr = material_index;
++polys;
// Even and odd loops connect triangles vertices differently
bool is_odd = n % 2;
// loops
if (is_odd) {
loops[0].v = vertex_index - 1;
loops[0].e = edge_index - 2;
loops[1].v = vertex_index - 3;
loops[1].e = edge_index - 3;
loops[2].v = vertex_index - 2;
loops[2].e = edge_index - 1;
}
else {
loops[0].v = vertex_index - 1;
loops[0].e = edge_index - 1;
loops[1].v = vertex_index - 2;
loops[1].e = edge_index - 3;
loops[2].v = vertex_index - 3;
loops[2].e = edge_index - 2;
}
loops += 3;
loop_index += 3;
// UV
if (hasTex) {
// First UV layer (loopsuv[0]) has no tips (texCoord(0)).
// Second UV layer (loopsuv[1]) has tips: (texCoord(1)).
for (int L = 0; L < 2; L++) {
if (is_odd) {
loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
loopsuv[L][1].uv[0] = svRep[0]->texCoord(L).x();
loopsuv[L][1].uv[1] = svRep[0]->texCoord(L).y();
loopsuv[L][2].uv[0] = svRep[1]->texCoord(L).x();
loopsuv[L][2].uv[1] = svRep[1]->texCoord(L).y();
}
else {
loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
loopsuv[L][1].uv[0] = svRep[1]->texCoord(L).x();
loopsuv[L][1].uv[1] = svRep[1]->texCoord(L).y();
loopsuv[L][2].uv[0] = svRep[0]->texCoord(L).x();
loopsuv[L][2].uv[1] = svRep[0]->texCoord(L).y();
}
loopsuv[L] += 3;
}
}
// colors and alpha transparency. vertex colors are in sRGB
// space by convention, so convert from linear
float rgba[3][4];
for (int i = 0; i < 3; i++) {
copy_v3fl_v3db(rgba[i], &svRep[i]->color()[0]);
rgba[i][3] = svRep[i]->alpha();
}
if (is_odd) {
linearrgb_to_srgb_uchar4(&colors[0].r, rgba[2]);
linearrgb_to_srgb_uchar4(&colors[1].r, rgba[0]);
linearrgb_to_srgb_uchar4(&colors[2].r, rgba[1]);
}
else {
linearrgb_to_srgb_uchar4(&colors[0].r, rgba[2]);
linearrgb_to_srgb_uchar4(&colors[1].r, rgba[1]);
linearrgb_to_srgb_uchar4(&colors[2].r, rgba[0]);
}
transp[0].r = transp[0].g = transp[0].b = colors[0].a;
transp[1].r = transp[1].g = transp[1].b = colors[1].a;
transp[2].r = transp[2].g = transp[2].b = colors[2].a;
colors += 3;
transp += 3;
}
} // loop over strip vertices
} // loop over strips
material_index++;
} // loop over strokes
test_object_materials(object_mesh, (ID *)mesh);
#if 0 // XXX
BLI_assert(mesh->totvert == vertex_index);
BLI_assert(mesh->totedge == edge_index);
BLI_assert(mesh->totloop == loop_index);
BLI_assert(mesh->totcol == material_index);
BKE_mesh_validate(mesh, true, true);
#endif
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +00:00
}
// A replacement of BKE_object_add() for better performance.
Object *BlenderStrokeRenderer::NewMesh() const
{
Object *ob;
char name[MAX_ID_NAME];
unsigned int mesh_id = get_stroke_mesh_id();
BLI_snprintf(name, MAX_ID_NAME, "0%08xOB", mesh_id);
ob = BKE_object_add_only_object(freestyle_bmain, OB_MESH, name);
BLI_snprintf(name, MAX_ID_NAME, "0%08xME", mesh_id);
ob->data = BKE_mesh_add(freestyle_bmain, name);
ob->lay = 1;
SceneCollection *sc_master = BKE_collection_master(freestyle_scene);
BKE_collection_object_add(freestyle_scene, sc_master, ob);
BKE_scene_base_add(freestyle_scene, ob);
DEG_relations_tag_update(freestyle_bmain);
DEG_id_tag_update_ex(freestyle_bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
return ob;
}
Render *BlenderStrokeRenderer::RenderScene(Render * /*re*/, bool render)
{
Camera *camera = (Camera *)freestyle_scene->camera->data;
if (camera->clipend < _z)
camera->clipend = _z + _z_delta * 100.0f;
#if 0
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "clipsta " << camera->clipsta << ", clipend " << camera->clipend << endl;
}
#endif
Render *freestyle_render = RE_NewSceneRender(freestyle_scene);
DEG_scene_relations_update(freestyle_bmain, freestyle_scene);
/* Need to get proper depsgraph. */
2017-07-13 17:20:24 +02:00
freestyle_render->depsgraph = freestyle_scene->depsgraph_legacy;
RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene,
render && get_stroke_count() > 0);
return freestyle_render;
The GL-based renderer was removed. Freestyle now uses Blender's internal renderer to raster strokes. The render generated from Freestyle's data is currently stored in the original scene's render structure ( as 'freestyle_render'): when the render database is generated, the scene's geometrical data is first imported into Freestyle and strokes are calculated. The generated strokes are used to create a Blender scene, rendered independently. The render result is used in the rendering loop. The final rendering is performed the same way edge rendering is, in a function ('freestyle_enhance_add') operating on each individual render part. Freestyle strokes are only included if the toggle button "Freestyle" (in the 'Output' panel) is active and if the "Freestyle" render layer is also selected. Freestyle's panel appears when the toggle button 'Freestyle' is active. IMPORTANT: as of now, rendering ONLY works when OSA is disabled and when Xparts = Yparts = 1. If these settings are not set, a bogus image will be created. To make the render happen, many modifications had to be made: - the Canvas::Draw and Operators::create methods no longer render strokes. They only generate shading and locational information. - a BlenderStrokeRenderer class was added to turn Freestyle's strokes into a Blender scene. Basically, the scene consists of strokes in their projected image 2D coordinates and an orthographic camera centered in the middle of the corresponding canvas. The scene is rendered using vertex colors, in shadeless mode (therefore, no lamp is needed). BlenderStrokeRenderer uses the old GLTextureManager to load textures (as required by the StrokeRenderer class), even though stroke textures are probably not supported (not tested). After the scene is rendered, it is safely and automatically discarded. - AppCanvas' code was greatly reduced to the bare minimum. The former AppCanvas would use an OpenGL-based back buffer and z buffer to determine the scene's color and depth information. In the future, this data will be determined from the corresponding render passes. Currently, the integration is not achieved so all style modules using depth/color information are sure to fail. - before, Freestyle needed an OpenGL context to determine the camera's information and to compute the view map. As of now, the modelview and projection matrices are fully determined using data provided by Blender. This means both perspective and orthographic projections are supported. The AppGLWidget will very soon be removed completely.
2008-12-01 21:30:44 +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 */