`````|````` | |        |                        ..'''' 
     |      | |        |______               .''       
     |      | |        |                  ..'          
     |      | |_______ |___________ ....''             
               merge to TRUNK!

 * The old compositor is still available (Debug Menu: 200)

This commit was brought to you by:

Developers:
 * Monique Dewanchand
 * Jeroen Bakker
 * Dalai Felinto
 * Lukas Tönne

Review:
 * Brecht van Lommel

Testers:
 * Nate Wiebe
 * Wolfgang Faehnle
 * Carlo Andreacchio
 * Daniel Salazar
 * Artur Mag
 * Christian Krupa
 * Francesco Siddi
 * Dan McGrath
 * Bassam Kurdali

But mostly by the community:
Gold:

    Joshua Faulkner
    Michael Tiemann
    Francesco Paglia
    Blender Guru
    Blender Developers Fund

Silver:

    Pablo Vazquez
    Joel Heethaar
    Amrein Olivier
    Ilias Karasavvidis
    Thomas Kumlehn
    Sebastian Koenig
    Hannu Hoffrén
    Benjamin Dansie
    Fred M'ule
    Michel Vilain
    Bradley Cathey
    Gianmichele Mariani
    Gottfried Hofmann
    Bjørnar Frøyse
    Valentijn Bruning
    Paul Holmes
    Clemens Rudolph
    Juris Graphix
    David Strebel
    Ronan Zeegers
    François Tarlier
    Felipe Andres Esquivel Reed
    Olaf Beckman
    Jesus Alberto Olmos Linares
    Kajimba
    Maria Figueiredo
    Alexandr Galperin
    Francesco Siddi
    Julio Iglesias Lopez
    Kjartan Tysdal
    Thomas Torfs
    Film Works
    Teruyuki Nakamura
    Roger Luethi
    Benoit Bolsee
    Stefan Abrahamsen
    Andreas Mattijat
    Xavier Bouchoux
    Blender 3D Graphics and Animation
    Henk Vostermans
    Daniel Blanco Delgado
    BlenderDay/2011
    Bradley Cathey
    Matthieu Dupont de Dinechin
    Gianmichele Mariani
    Jérôme Scaillet

Bronze (Ivo Grigull, Dylan Urquidi, Philippe Derungs, Phil Beauchamp, Bruce Parrott, Mathieu Quiblier, Daniel Martinez, Leandro Inocencio, Lluc Romaní Brasó, 
Jonathan Williamson, Michael Ehlen, Karlis Stigis, Dreamsteep, Martin Lindelöf, Filippo Saracino, Douwe van der Veen, Olli Äkräs, Bruno D'Arcangeli, 
Francisco Sedrez Warmling, Watchmike.ca, peter lener, Matteo Novellino, Martin Kirsch, Austars Schnore, KC Elliott, Massimiliano Puliero, Karl Stein, 
Wood Design Studios, Omer Khan, Jyrki Kanto, Michał Krupa, Lars Brubaker, Neil Richmond, Adam Kalisz, Robert Garlington, Ian Wilson, Carlo Andreacchio, 
Jeremias Boos, Robert Holcomb, Gabriel Zöller, Robert Cude, Natibel de Leon, Nathan Turnage, Nicolas Vergnes, Philipp Kleinhenz, Norman Hartig, Louis Kreusel, 
Christopher Taylor, Giovanni Remondini, Daniel Rentzsch, Nico Partipilo, Thomas Ventresco, Johannes Schwarz, Александр Коротеев, Brendon Harvey, 
Marcelo G. Malheiros, Marius Giurgi, Richard Burns, Perttu Iso-Metsälä, Steve Bazin, Radoslav Borisov, Yoshiyuki Shida, Julien Guigner, Andrew Hunter, 
Philipp Oeser, Daniel Thul, Thobias Johansson, Mauro Bonecchi, Georg Piorczynski, Sebastian Michailidis, L M Weedy, Gen X, Stefan Hinze, Nicolò Zubbini, 
Erik Pusch, Rob Scott, Florian Koch, Charles Razack, Adrian Baker, Oliver Villar Diz, David Revoy, Julio Iglesias Lopez, Coen Spoor, Carlos Folch, 
Joseph Christie, Victor Hernández García, David Mcsween, James Finnerty, Cory Kruckenberg, Giacomo Graziosi, Olivier Saraja, Lars Brubaker, Eric Hudson, 
Johannes Schwarz, David Elguea, Marcus Schulderinsky, Karel De Bruijn, Lucas van Wijngaarden, Stefano Ciarrocchi, Mehmet Eribol, Thomas Berglund, Zuofei Song, 
Dylan Urquidi )
This commit is contained in:
Jeroen Bakker 2012-05-17 12:49:33 +00:00
parent eb57856a19
commit 044e818cf8
542 changed files with 40125 additions and 31 deletions

View File

@ -205,5 +205,25 @@ class NODE_PT_properties(Panel):
col.prop(snode, "backdrop_y", text="Y")
col.operator("node.backimage_move", text="Move")
class NODE_PT_quality(bpy.types.Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
bl_label = "Quality"
@classmethod
def poll(cls, context):
snode = context.space_data
return snode.tree_type == 'COMPOSITING' and snode.node_tree is not None
def draw(self, context):
layout = self.layout
snode = context.space_data
tree = snode.node_tree
layout.prop(tree, "render_quality", text="Render")
layout.prop(tree, "edit_quality", text="Edit")
layout.prop(tree, "chunksize")
layout.prop(tree, "use_opencl")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

View File

@ -94,11 +94,13 @@ add_subdirectory(blenkernel)
add_subdirectory(blenlib)
add_subdirectory(bmesh)
add_subdirectory(render)
add_subdirectory(compositor)
add_subdirectory(blenfont)
add_subdirectory(blenloader)
add_subdirectory(blenpluginapi)
add_subdirectory(ikplugin)
add_subdirectory(gpu)
add_subdirectory(opencl)
add_subdirectory(imbuf)
add_subdirectory(avi)
add_subdirectory(nodes)

View File

@ -9,9 +9,11 @@ SConscript(['avi/SConscript',
'blenloader/SConscript',
'blenpluginapi/SConscript',
'gpu/SConscript',
'opencl/SConscript',
'editors/SConscript',
'imbuf/SConscript',
'makesdna/SConscript',
'compositor/SConscript',
'render/SConscript',
'nodes/SConscript',
'modifiers/SConscript',

View File

@ -145,9 +145,13 @@ typedef struct bNodeType {
void (*uifunc)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr);
/// Additional parameters in the side panel.
void (*uifuncbut)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr);
/// Additional drawing on backdrop.
void (*uibackdropfunc)(struct SpaceNode* snode, struct ImBuf* backdrop, struct bNode* node, int x, int y);
/// Draw a node socket. Default draws the input value button.
NodeSocketButtonFunction drawinputfunc;
NodeSocketButtonFunction drawoutputfunc;
/// Optional custom label function for the node header.
const char *(*labelfunc)(struct bNode *);
/// Optional custom resize handle polling.
@ -647,6 +651,13 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
#define CMP_NODE_TONEMAP 302
#define CMP_NODE_LENSDIST 303
#define CMP_NODE_COLORCORRECTION 312
#define CMP_NODE_MASK_BOX 313
#define CMP_NODE_MASK_ELLIPSE 314
#define CMP_NODE_BOKEHIMAGE 315
#define CMP_NODE_BOKEHBLUR 316
#define CMP_NODE_SWITCH 317
/* channel toggles */
#define CMP_CHAN_RGB 1
#define CMP_CHAN_A 2
@ -674,7 +685,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
struct CompBuf;
struct bNodeTreeExec *ntreeCompositBeginExecTree(struct bNodeTree *ntree, int use_tree_data);
void ntreeCompositEndExecTree(struct bNodeTreeExec *exec, int use_tree_data);
void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews);
void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int rendering, int do_previews);
void ntreeCompositTagRender(struct Scene *sce);
int ntreeCompositTagAnimated(struct bNodeTree *ntree);
void ntreeCompositTagGenerators(struct bNodeTree *ntree);

View File

@ -1930,6 +1930,13 @@ static void registerCompositNodes(bNodeTreeType *ttype)
register_node_type_cmp_transform(ttype);
register_node_type_cmp_stabilize2d(ttype);
register_node_type_cmp_moviedistortion(ttype);
register_node_type_cmp_colorcorrection(ttype);
register_node_type_cmp_boxmask(ttype);
register_node_type_cmp_ellipsemask(ttype);
register_node_type_cmp_bokehimage(ttype);
register_node_type_cmp_bokehblur(ttype);
register_node_type_cmp_switch(ttype);
}
static void registerShaderNodes(bNodeTreeType *ttype)

View File

@ -7402,6 +7402,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 263) {
/* Default for old files is to save particle rotations to pointcache */
ParticleSettings *part;
for (part = main->particle.first; part; part = part->id.next)
part->flag |= PART_ROTATIONS;
{
/* Default for old files is to save particle rotations to pointcache */
ParticleSettings *part;
@ -7419,6 +7423,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (ntree = main->nodetree.first; ntree; ntree=ntree->id.next)
do_versions_nodetree_multi_file_output_path_2_64_0(ntree);
}
}
if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 3)) {
@ -7525,7 +7532,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
{
Scene *scene;
// composite redesign
for (scene=main->scene.first; scene; scene=scene->id.next)
if (scene->nodetree)
if ( scene->nodetree->chunksize == 0) {
scene->nodetree->chunksize = 256;
}
}
/* don't forget to set version number in blender.c! */
}

View File

@ -0,0 +1,607 @@
# $Id: CMakeLists.txt 14444 2008-04-16 22:40:48Z hos $
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2011, Blender Foundation
# All rights reserved.
#
# The Original Code is: all of this file.
#
# Contributor(s): Jeroen Bakker, Monique Dewanchand, Blender Developers Fund.
#
# ***** END GPL LICENSE BLOCK *****
set(INC
.
../blenkernel
../blenlib
../makesdna
../render/extern/include
../render/intern/include
../makesrna
../blenloader
../blenlib
../windowmanager
../imbuf
../../../intern/guardedalloc
nodes
../nodes/
../nodes/composite
../nodes/intern
intern
operations
../opencl
)
set(SRC
COM_compositor.h
COM_defines.h
intern/COM_compositor.cpp
intern/COM_ExecutionSystem.cpp
intern/COM_ExecutionSystem.h
intern/COM_ExecutionSystemHelper.cpp
intern/COM_ExecutionSystemHelper.h
intern/COM_Converter.cpp
intern/COM_Converter.h
intern/COM_ExecutionGroup.cpp
intern/COM_ExecutionGroup.h
intern/COM_Node.cpp
intern/COM_Node.h
intern/COM_NodeBase.cpp
intern/COM_NodeBase.h
intern/COM_NodeOperation.cpp
intern/COM_NodeOperation.h
intern/COM_Socket.cpp
intern/COM_Socket.h
intern/COM_SocketReader.cpp
intern/COM_SocketReader.h
intern/COM_InputSocket.cpp
intern/COM_InputSocket.h
intern/COM_OutputSocket.cpp
intern/COM_OutputSocket.h
intern/COM_SocketConnection.cpp
intern/COM_SocketConnection.h
intern/COM_MemoryProxy.cpp
intern/COM_MemoryProxy.h
intern/COM_MemoryBuffer.cpp
intern/COM_MemoryBuffer.h
intern/COM_MemoryManager.cpp
intern/COM_MemoryManager.h
intern/COM_MemoryManagerState.cpp
intern/COM_MemoryManagerState.h
intern/COM_WorkScheduler.cpp
intern/COM_WorkScheduler.h
intern/COM_WorkPackage.cpp
intern/COM_WorkPackage.h
intern/COM_ChunkOrder.cpp
intern/COM_ChunkOrder.h
intern/COM_ChunkOrderHotspot.cpp
intern/COM_ChunkOrderHotspot.h
intern/COM_Device.cpp
intern/COM_Device.h
intern/COM_CPUDevice.cpp
intern/COM_CPUDevice.h
intern/COM_OpenCLDevice.cpp
intern/COM_OpenCLDevice.h
intern/COM_CompositorContext.cpp
intern/COM_CompositorContext.h
intern/COM_ChannelInfo.cpp
intern/COM_ChannelInfo.h
operations/COM_QualityStepHelper.h
operations/COM_QualityStepHelper.cpp
# Internal nodes
nodes/COM_MuteNode.cpp
nodes/COM_MuteNode.h
nodes/COM_GroupNode.cpp
nodes/COM_GroupNode.h
nodes/COM_SocketProxyNode.cpp
nodes/COM_SocketProxyNode.h
# input nodes
nodes/COM_RenderLayersNode.cpp
nodes/COM_RenderLayersNode.h
nodes/COM_ImageNode.cpp
nodes/COM_ImageNode.h
nodes/COM_TextureNode.cpp
nodes/COM_TextureNode.h
nodes/COM_BokehImageNode.cpp
nodes/COM_BokehImageNode.h
nodes/COM_ColorNode.cpp
nodes/COM_ColorNode.h
nodes/COM_ValueNode.cpp
nodes/COM_ValueNode.h
nodes/COM_TimeNode.cpp
nodes/COM_TimeNode.h
nodes/COM_SwitchNode.cpp
nodes/COM_SwitchNode.h
nodes/COM_MovieClipNode.cpp
nodes/COM_MovieClipNode.h
nodes/COM_OutputFileNode.cpp
nodes/COM_OutputFileNode.h
# output nodes
nodes/COM_CompositorNode.cpp
nodes/COM_CompositorNode.h
nodes/COM_ViewerNode.cpp
nodes/COM_ViewerNode.h
nodes/COM_SplitViewerNode.cpp
nodes/COM_SplitViewerNode.h
nodes/COM_ViewLevelsNode.cpp
nodes/COM_ViewLevelsNode.h
operations/COM_CalculateStandardDeviationOperation.cpp
operations/COM_CalculateStandardDeviationOperation.h
operations/COM_CalculateMeanOperation.cpp
operations/COM_CalculateMeanOperation.h
# distort nodes
nodes/COM_TranslateNode.cpp
nodes/COM_TranslateNode.h
nodes/COM_ScaleNode.cpp
nodes/COM_ScaleNode.h
nodes/COM_RotateNode.cpp
nodes/COM_RotateNode.h
nodes/COM_FlipNode.cpp
nodes/COM_FlipNode.h
nodes/COM_MapUVNode.cpp
nodes/COM_MapUVNode.h
nodes/COM_DisplaceNode.cpp
nodes/COM_DisplaceNode.h
nodes/COM_DifferenceMatteNode.cpp
nodes/COM_DifferenceMatteNode.h
nodes/COM_LuminanceMatteNode.cpp
nodes/COM_LuminanceMatteNode.h
nodes/COM_DistanceMatteNode.cpp
nodes/COM_DistanceMatteNode.h
nodes/COM_ChromaMatteNode.cpp
nodes/COM_ChromaMatteNode.h
nodes/COM_ColorMatteNode.cpp
nodes/COM_ColorMatteNode.h
nodes/COM_ChannelMatteNode.cpp
nodes/COM_ChannelMatteNode.h
nodes/COM_LensDistortionNode.cpp
nodes/COM_LensDistortionNode.h
nodes/COM_GlareNode.cpp
nodes/COM_GlareNode.h
nodes/COM_CropNode.cpp
nodes/COM_CropNode.h
operations/COM_CropOperation.cpp
operations/COM_CropOperation.h
operations/COM_LensGlowOperation.cpp
operations/COM_LensGlowOperation.h
operations/COM_LensGhostOperation.cpp
operations/COM_LensGhostOperation.h
nodes/COM_TransformNode.cpp
nodes/COM_TransformNode.h
nodes/COM_Stabilize2dNode.cpp
nodes/COM_Stabilize2dNode.h
nodes/COM_MovieDistortionNode.cpp
nodes/COM_MovieDistortionNode.h
nodes/COM_DefocusNode.cpp
nodes/COM_DefocusNode.h
# color nodes
nodes/COM_VectorCurveNode.cpp
nodes/COM_VectorCurveNode.h
nodes/COM_ColorCurveNode.cpp
nodes/COM_ColorCurveNode.h
nodes/COM_ColorToBWNode.cpp
nodes/COM_ColorToBWNode.h
nodes/COM_ColorRampNode.cpp
nodes/COM_ColorRampNode.h
nodes/COM_MixNode.cpp
nodes/COM_MixNode.h
nodes/COM_AlphaOverNode.cpp
nodes/COM_AlphaOverNode.h
nodes/COM_ZCombineNode.cpp
nodes/COM_ZCombineNode.h
nodes/COM_BrightnessNode.cpp
nodes/COM_BrightnessNode.h
nodes/COM_ColorBalanceNode.cpp
nodes/COM_ColorBalanceNode.h
nodes/COM_InvertNode.cpp
nodes/COM_InvertNode.h
nodes/COM_GammaNode.cpp
nodes/COM_GammaNode.h
nodes/COM_SetAlphaNode.cpp
nodes/COM_SetAlphaNode.h
nodes/COM_ConvertAlphaNode.cpp
nodes/COM_ConvertAlphaNode.h
nodes/COM_AlphaOverNode.cpp
nodes/COM_AlphaOverNode.h
nodes/COM_HueSaturationValueNode.cpp
nodes/COM_HueSaturationValueNode.h
nodes/COM_HueSaturationValueCorrectNode.cpp
nodes/COM_HueSaturationValueCorrectNode.h
nodes/COM_ColorCorrectionNode.cpp
nodes/COM_ColorCorrectionNode.h
nodes/COM_TonemapNode.cpp
nodes/COM_TonemapNode.h
operations/COM_TonemapOperation.cpp
operations/COM_TonemapOperation.h
# converter nodes
nodes/COM_IDMaskNode.cpp
nodes/COM_IDMaskNode.h
nodes/COM_SeparateRGBANode.cpp
nodes/COM_SeparateRGBANode.h
nodes/COM_CombineRGBANode.cpp
nodes/COM_CombineRGBANode.h
nodes/COM_SeparateHSVANode.cpp
nodes/COM_SeparateHSVANode.h
nodes/COM_CombineHSVANode.cpp
nodes/COM_CombineHSVANode.h
nodes/COM_SeparateYUVANode.cpp
nodes/COM_SeparateYUVANode.h
nodes/COM_CombineYUVANode.cpp
nodes/COM_CombineYUVANode.h
nodes/COM_SeparateYCCANode.cpp
nodes/COM_SeparateYCCANode.h
nodes/COM_CombineYCCANode.cpp
nodes/COM_CombineYCCANode.h
nodes/COM_NormalNode.cpp
nodes/COM_NormalNode.h
nodes/COM_NormalizeNode.cpp
nodes/COM_NormalizeNode.h
nodes/COM_MathNode.cpp
nodes/COM_MathNode.h
nodes/COM_MapValueNode.cpp
nodes/COM_MapValueNode.h
operations/COM_NormalizeOperation.cpp
operations/COM_NormalizeOperation.h
# Filter nodes
nodes/COM_BilateralBlurNode.cpp
nodes/COM_BilateralBlurNode.h
operations/COM_BilateralBlurOperation.cpp
operations/COM_BilateralBlurOperation.h
nodes/COM_VectorBlurNode.cpp
nodes/COM_VectorBlurNode.h
operations/COM_VectorBlurOperation.cpp
operations/COM_VectorBlurOperation.h
nodes/COM_FilterNode.cpp
nodes/COM_FilterNode.h
nodes/COM_DilateErodeNode.cpp
nodes/COM_DilateErodeNode.h
nodes/COM_BlurNode.cpp
nodes/COM_BlurNode.h
nodes/COM_BokehBlurNode.cpp
nodes/COM_BokehBlurNode.h
nodes/COM_DirectionalBlurNode.cpp
nodes/COM_DirectionalBlurNode.h
operations/COM_GaussianXBlurOperation.cpp
operations/COM_GaussianXBlurOperation.h
operations/COM_GaussianYBlurOperation.cpp
operations/COM_GaussianYBlurOperation.h
operations/COM_GaussianBokehBlurOperation.cpp
operations/COM_GaussianBokehBlurOperation.h
operations/COM_BokehBlurOperation.cpp
operations/COM_BokehBlurOperation.h
operations/COM_VariableSizeBokehBlurOperation.cpp
operations/COM_VariableSizeBokehBlurOperation.h
operations/COM_FastGaussianBlurOperation.cpp
operations/COM_FastGaussianBlurOperation.h
operations/COM_BlurBaseOperation.cpp
operations/COM_BlurBaseOperation.h
operations/COM_DirectionalBlurOperation.cpp
operations/COM_DirectionalBlurOperation.h
operations/COM_MovieClipAttributeOperation.cpp
operations/COM_MovieClipAttributeOperation.h
operations/COM_MovieDistortionOperation.cpp
operations/COM_MovieDistortionOperation.h
operations/COM_GammaCorrectOperation.h
operations/COM_GammaCorrectOperation.cpp
# Matte nodes
nodes/COM_BoxMaskNode.cpp
nodes/COM_BoxMaskNode.h
nodes/COM_EllipseMaskNode.cpp
nodes/COM_EllipseMaskNode.h
nodes/COM_ColorSpillNode.cpp
nodes/COM_ColorSpillNode.h
nodes/COM_DoubleEdgeMaskNode.cpp
nodes/COM_DoubleEdgeMaskNode.h
operations/COM_DoubleEdgeMaskOperation.cpp
operations/COM_DoubleEdgeMaskOperation.h
operations/COM_ColorSpillOperation.cpp
operations/COM_ColorSpillOperation.h
operations/COM_RenderLayersBaseProg.cpp
operations/COM_RenderLayersBaseProg.h
operations/COM_RenderLayersImageProg.cpp
operations/COM_RenderLayersImageProg.h
operations/COM_RenderLayersAlphaProg.cpp
operations/COM_RenderLayersAlphaProg.h
operations/COM_RenderLayersDepthProg.cpp
operations/COM_RenderLayersDepthProg.h
operations/COM_RenderLayersNormalOperation.cpp
operations/COM_RenderLayersNormalOperation.h
operations/COM_RenderLayersSpeedOperation.cpp
operations/COM_RenderLayersSpeedOperation.h
operations/COM_RenderLayersColorOperation.cpp
operations/COM_RenderLayersColorOperation.h
operations/COM_RenderLayersUVOperation.cpp
operations/COM_RenderLayersUVOperation.h
operations/COM_RenderLayersMistOperation.cpp
operations/COM_RenderLayersMistOperation.h
operations/COM_RenderLayersObjectIndexOperation.cpp
operations/COM_RenderLayersObjectIndexOperation.h
operations/COM_RenderLayersMaterialIndexOperation.cpp
operations/COM_RenderLayersMaterialIndexOperation.h
operations/COM_RenderLayersDiffuseOperation.cpp
operations/COM_RenderLayersDiffuseOperation.h
operations/COM_RenderLayersSpecularOperation.cpp
operations/COM_RenderLayersSpecularOperation.h
operations/COM_RenderLayersShadowOperation.cpp
operations/COM_RenderLayersShadowOperation.h
operations/COM_RenderLayersAOOperation.cpp
operations/COM_RenderLayersAOOperation.h
operations/COM_RenderLayersEmitOperation.cpp
operations/COM_RenderLayersEmitOperation.h
operations/COM_RenderLayersReflectionOperation.cpp
operations/COM_RenderLayersReflectionOperation.h
operations/COM_RenderLayersRefractionOperation.cpp
operations/COM_RenderLayersRefractionOperation.h
operations/COM_RenderLayersEnvironmentOperation.cpp
operations/COM_RenderLayersEnvironmentOperation.h
operations/COM_RenderLayersIndirectOperation.cpp
operations/COM_RenderLayersIndirectOperation.h
operations/COM_RenderLayersCyclesOperation.cpp
operations/COM_RenderLayersCyclesOperation.h
operations/COM_ImageOperation.cpp
operations/COM_ImageOperation.h
operations/COM_MultilayerImageOperation.cpp
operations/COM_MultilayerImageOperation.h
operations/COM_TextureOperation.cpp
operations/COM_TextureOperation.h
operations/COM_BokehImageOperation.cpp
operations/COM_BokehImageOperation.h
operations/COM_LensGlowImageOperation.cpp
operations/COM_LensGlowImageOperation.h
operations/COM_SocketProxyOperation.h
operations/COM_SocketProxyOperation.cpp
operations/COM_CompositorOperation.h
operations/COM_CompositorOperation.cpp
operations/COM_OutputFileOperation.h
operations/COM_OutputFileOperation.cpp
operations/COM_ViewerBaseOperation.h
operations/COM_ViewerBaseOperation.cpp
operations/COM_ViewerOperation.h
operations/COM_ViewerOperation.cpp
operations/COM_PreviewOperation.h
operations/COM_PreviewOperation.cpp
operations/COM_SplitViewerOperation.h
operations/COM_SplitViewerOperation.cpp
operations/COM_ConvertValueToColourProg.h
operations/COM_ConvertValueToColourProg.cpp
operations/COM_ConvertColourToValueProg.h
operations/COM_ConvertColourToValueProg.cpp
operations/COM_ConvertColorToBWOperation.h
operations/COM_ConvertColorToBWOperation.cpp
operations/COM_ConvertColorToVectorOperation.h
operations/COM_ConvertColorToVectorOperation.cpp
operations/COM_ConvertValueToVectorOperation.h
operations/COM_ConvertValueToVectorOperation.cpp
operations/COM_ConvertVectorToColorOperation.h
operations/COM_ConvertVectorToColorOperation.cpp
operations/COM_ConvertVectorToValueOperation.h
operations/COM_ConvertVectorToValueOperation.cpp
operations/COM_ConvertDepthToRadiusOperation.h
operations/COM_ConvertDepthToRadiusOperation.cpp
operations/COM_ZCombineOperation.cpp
operations/COM_ZCombineOperation.h
operations/COM_ConvertRGBToYCCOperation.h
operations/COM_ConvertRGBToYCCOperation.cpp
operations/COM_ConvertYCCToRGBOperation.h
operations/COM_ConvertYCCToRGBOperation.cpp
operations/COM_ConvertRGBToYUVOperation.h
operations/COM_ConvertRGBToYUVOperation.cpp
operations/COM_ConvertYUVToRGBOperation.h
operations/COM_ConvertYUVToRGBOperation.cpp
operations/COM_ConvertRGBToHSVOperation.h
operations/COM_ConvertRGBToHSVOperation.cpp
operations/COM_ConvertHSVToRGBOperation.h
operations/COM_ConvertHSVToRGBOperation.cpp
operations/COM_ChangeHSVOperation.h
operations/COM_ChangeHSVOperation.cpp
operations/COM_ColorCurveOperation.h
operations/COM_ColorCurveOperation.cpp
operations/COM_ColorRampOperation.h
operations/COM_ColorRampOperation.cpp
operations/COM_VectorCurveOperation.h
operations/COM_VectorCurveOperation.cpp
operations/COM_CurveBaseOperation.h
operations/COM_CurveBaseOperation.cpp
operations/COM_HueSaturationValueCorrectOperation.cpp
operations/COM_HueSaturationValueCorrectOperation.h
operations/COM_DifferenceMatteOperation.cpp
operations/COM_DifferenceMatteOperation.h
operations/COM_LuminanceMatteOperation.cpp
operations/COM_LuminanceMatteOperation.h
operations/COM_DistanceMatteOperation.cpp
operations/COM_DistanceMatteOperation.h
operations/COM_ChromaMatteOperation.cpp
operations/COM_ChromaMatteOperation.h
operations/COM_ColorMatteOperation.cpp
operations/COM_ColorMatteOperation.h
operations/COM_ChannelMatteOperation.cpp
operations/COM_ChannelMatteOperation.h
operations/COM_ConvertPremulToKeyOperation.cpp
operations/COM_ConvertPremulToKeyOperation.h
operations/COM_ConvertKeyToPremulOperation.cpp
operations/COM_ConvertKeyToPremulOperation.h
operations/COM_ReadBufferOperation.cpp
operations/COM_ReadBufferOperation.h
operations/COM_WriteBufferOperation.cpp
operations/COM_WriteBufferOperation.h
operations/COM_MixBaseOperation.h
operations/COM_MixBaseOperation.cpp
operations/COM_MixBlendOperation.cpp
operations/COM_MixBlendOperation.h
operations/COM_MixAddOperation.h
operations/COM_MixAddOperation.cpp
operations/COM_MixMultiplyOperation.h
operations/COM_MixMultiplyOperation.cpp
operations/COM_BrightnessOperation.cpp
operations/COM_BrightnessOperation.h
operations/COM_GammaOperation.cpp
operations/COM_GammaOperation.h
operations/COM_ColorCorrectionOperation.cpp
operations/COM_ColorCorrectionOperation.h
operations/COM_SetValueOperation.h
operations/COM_SetValueOperation.cpp
operations/COM_SetColorOperation.h
operations/COM_SetColorOperation.cpp
operations/COM_SetVectorOperation.h
operations/COM_SetVectorOperation.cpp
operations/COM_MixBurnOperation.h
operations/COM_MixBurnOperation.cpp
operations/COM_MixColorOperation.h
operations/COM_MixColorOperation.cpp
operations/COM_MixDarkenOperation.h
operations/COM_MixDarkenOperation.cpp
operations/COM_MixDodgeOperation.h
operations/COM_MixDodgeOperation.cpp
operations/COM_MixDifferenceOperation.h
operations/COM_MixDifferenceOperation.cpp
operations/COM_MixDivideOperation.h
operations/COM_MixDivideOperation.cpp
operations/COM_MixHueOperation.h
operations/COM_MixHueOperation.cpp
operations/COM_MixLightenOperation.h
operations/COM_MixLightenOperation.cpp
operations/COM_MixLinearLightOperation.h
operations/COM_MixLinearLightOperation.cpp
operations/COM_MixOverlayOperation.h
operations/COM_MixOverlayOperation.cpp
operations/COM_MixSaturationOperation.h
operations/COM_MixSaturationOperation.cpp
operations/COM_MixScreenOperation.h
operations/COM_MixScreenOperation.cpp
operations/COM_MixSoftLightOperation.h
operations/COM_MixSoftLightOperation.cpp
operations/COM_MixValueOperation.h
operations/COM_MixValueOperation.cpp
operations/COM_MixSubtractOperation.h
operations/COM_MixSubtractOperation.cpp
operations/COM_MathBaseOperation.h
operations/COM_MathBaseOperation.cpp
operations/COM_AlphaOverMixedOperation.h
operations/COM_AlphaOverMixedOperation.cpp
operations/COM_AlphaOverPremultiplyOperation.h
operations/COM_AlphaOverPremultiplyOperation.cpp
operations/COM_AlphaOverKeyOperation.h
operations/COM_AlphaOverKeyOperation.cpp
operations/COM_ColorBalanceLGGOperation.h
operations/COM_ColorBalanceLGGOperation.cpp
operations/COM_ColorBalanceASCCDLOperation.h
operations/COM_ColorBalanceASCCDLOperation.cpp
operations/COM_InvertOperation.cpp
operations/COM_InvertOperation.h
operations/COM_SetAlphaOperation.cpp
operations/COM_SetAlphaOperation.h
operations/COM_MapValueOperation.cpp
operations/COM_MapValueOperation.h
# Distort operation
operations/COM_TranslateOperation.h
operations/COM_TranslateOperation.cpp
operations/COM_RotateOperation.h
operations/COM_RotateOperation.cpp
operations/COM_ScaleOperation.h
operations/COM_ScaleOperation.cpp
operations/COM_MapUVOperation.h
operations/COM_MapUVOperation.cpp
operations/COM_DisplaceOperation.h
operations/COM_DisplaceOperation.cpp
operations/COM_DisplaceSimpleOperation.h
operations/COM_DisplaceSimpleOperation.cpp
operations/COM_FlipOperation.h
operations/COM_FlipOperation.cpp
operations/COM_ProjectorLensDistortionOperation.cpp
operations/COM_ProjectorLensDistortionOperation.h
operations/COM_ScreenLensDistortionOperation.cpp
operations/COM_ScreenLensDistortionOperation.h
#Filter operations
operations/COM_ConvolutionFilterOperation.h
operations/COM_ConvolutionFilterOperation.cpp
operations/COM_ConvolutionEdgeFilterOperation.h
operations/COM_ConvolutionEdgeFilterOperation.cpp
operations/COM_DilateErodeOperation.cpp
operations/COM_DilateErodeOperation.h
operations/COM_FogGlowImageOperation.cpp
operations/COM_FogGlowImageOperation.h
operations/COM_GlareThresholdOperation.cpp
operations/COM_GlareThresholdOperation.h
operations/COM_GlareBaseOperation.cpp
operations/COM_GlareBaseOperation.h
operations/COM_GlareSimpleStarOperation.cpp
operations/COM_GlareSimpleStarOperation.h
operations/COM_GlareStreaksOperation.cpp
operations/COM_GlareStreaksOperation.h
operations/COM_SetSamplerOperation.cpp
operations/COM_SetSamplerOperation.h
#Convert operations
operations/COM_IDMaskOperation.cpp
operations/COM_IDMaskOperation.h
operations/COM_SeparateChannelOperation.cpp
operations/COM_SeparateChannelOperation.h
operations/COM_CombineChannelsOperation.cpp
operations/COM_CombineChannelsOperation.h
operations/COM_DotproductOperation.cpp
operations/COM_DotproductOperation.h
# Matte operation
operations/COM_BoxMaskOperation.h
operations/COM_BoxMaskOperation.cpp
operations/COM_EllipseMaskOperation.h
operations/COM_EllipseMaskOperation.cpp
operations/COM_MovieClipOperation.cpp
operations/COM_MovieClipOperation.h
operations/COM_ConvertColorProfileOperation.cpp
operations/COM_ConvertColorProfileOperation.h
operations/COM_AntiAliasOperation.cpp
operations/COM_AntiAliasOperation.h
)
blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}")

View File

@ -0,0 +1,278 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "DNA_node_types.h"
/**
* @defgroup Model The data model of the compositor
* @defgroup Memory The memory management stuff
* @defgroup Execution The execution logic
* @defgroup Conversion Conversion logic
* @defgroup Node All nodes of the compositor
* @defgroup Operation All operations of the compositor
*
* @mainpage Introduction of the Blender Compositor
*
* @section bcomp Blender compositor
* This project redesigns the interals of Blender's compositor. The project has been executed in 2011 by At Mind. At Mind is a technology company located in Amsterdam, The Netherlands.
* The project has been crowdfunded. This code has been released under GPL2 to be used in Blender.
*
* @section goals The goals of the project
* the new compositor has 2 goals.
* - Make a faster compositor (speed of calculation)
* - Make the compositor work faster for you (workflow)
*
* @section speed Faster compositor
* The speedup has been done by making better use of the hardware Blenders is working on. The previous compositor only used a single threaded model to calculate a node. The only exception to this is the Defocus node.
* Only when it is possible to calculate two full nodes in parallel a second thread was used. Current workstations have 8-16 threads available, and most of the time these are idle.
*
* In the new compositor we want to use as much of threads as possible. Even new OpenCL capable GPU-hardware can be used for calculation.
*
* @section workflow Work faster
* The previous compositor only showed the final image. The compositor could wait a long time before seeing the result of his work. The new compositor will work in a way that it will focus on getting information back to the user.
* It will prioritise its work to get earlier user feedback.
*
* @page memory Memory model
* The main issue is the type of memory model to use. Blender is used by consumers and professionals. Ranging from low-end machines to very high-end machines. The system should work on high-end machines and on low-end machines.
*
*
* @page executing Executing
* @section prepare Prepare execution
*
* during the preparation of the execution All ReadBufferOperation will receive an offset. this offset is used during execution as an optimization trick
* Next all operations will be initialized for execution @see NodeOperation.initExecution
* Next all ExecutionGroup's will be initialized for execution @see ExecutionGroup.initExecution
* this all is controlled from @see ExecutionSystem.execute
*
* @section priority Render priority
* Render priority is an priority of an output node. A user has a different need of Render priorities of output nodes than during editing.
* for example. the Active ViewerNode has top priority during editing, but during rendering a CompositeNode has.
* All NodeOperation has a setting for their renderpriority, but only for output NodeOperation these have effect.
* In ExecutionSystem.execute all priorities are checked. For every priority the ExecutionGroup's are check if the priority do match.
* When match the ExecutionGroup will be executed (this happens in serial)
*
* @see ExecutionSystem.execute control of the Render priority
* @see NodeOperation.getRenderPriority receive the render priority
* @see ExecutionGroup.execute the main loop to execute a whole ExecutionGroup
*
* @section order Chunk order
*
* When a ExecutionGroup is executed, first the order of chunks are determined.
* The settings are stored in the ViewerNode inside the ExecutionGroup. ExecutionGroups that have no viewernode, will use a default one.
* There are several possible chunk orders
* - [@ref OrderOfChunks.COM_TO_CENTER_OUT]: Start calculating from a configurable point and order by nearest chunk
* - [@ref OrderOfChunks.COM_TO_RANDOM]: Randomize all chunks.
* - [@ref OrderOfChunks.COM_TO_TOP_DOWN]: Start calculation from the bottom to the top of the image
* - [@ref OrderOfChunks.COM_TO_RULE_OF_THIRDS]: Experimental order based on 9 hotspots in the image
*
* When the chunkorder is determined, the first few chunks will be checked if they can be scheduled.
* Chunks can have three states:
* - [@ref ChunkExecutionState.COM_ES_NOT_SCHEDULED]: Chunk is not yet scheduled, or dependacies are not met
* - [@ref ChunkExecutionState.COM_ES_SCHEDULED]: All dependacies are met, chunk is scheduled, but not finished
* - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished
*
* @see ExecutionGroup.execute
* @see ViewerBaseOperation.getChunkOrder
* @see OrderOfChunks
*
* @section interest Area of interest
* An ExecutionGroup can have dependancies to other ExecutionGroup's. Data passing from one ExecutionGroup to another one are stored in 'chunks'.
* If not all input chunks are available the chunk execution will not be scheduled.
* <pre>
* +-------------------------------------+ +--------------------------------------+
* | ExecutionGroup A | | ExecutionGroup B |
* | +----------------+ +-------------+ | | +------------+ +-----------------+ |
* | | NodeOperation a| | WriteBuffer | | | | ReadBuffer | | ViewerOperation | |
* | | *==* Operation | | | | Operation *===* | |
* | | | | | | | | | | | |
* | +----------------+ +-------------+ | | +------------+ +-----------------+ |
* | | | | | |
* +--------------------------------|----+ +---|----------------------------------+
* | |
* | |
* +---------------------------+
* | MemoryProxy |
* | +----------+ +---------+ |
* | | Chunk a | | Chunk b | |
* | | | | | |
* | +----------+ +---------+ |
* | |
* +---------------------------+
* </pre>
*
* In the above example ExecutionGroup B has an outputoperation (ViewerOperation) and is being executed.
* The first chunk is evaluated [@ref ExecutionGroup.scheduleChunkWhenPossible], but not all input chunks are available. The relevant ExecutionGroup (that can calculate the missing chunks; ExecutionGroup A) is
* Asked to calculate the area ExecutionGroup B is missing. [@ref ExecutionGroup.scheduleAreaWhenPossible]
* ExecutionGroup B checks what chunks the area spans, and tries to schedule these chunks. If all input data is available these chunks are scheduled [@ref ExecutionGroup.scheduleChunk]
*
* <pre>
*
* +-------------------------+ +----------------+ +----------------+
* | ExecutionSystem.execute | | ExecutionGroup | | ExecutionGroup |
* +-------------------------+ | (B) | | (A) |
* O +----------------+ +----------------+
* O | |
* O ExecutionGroup.execute | |
* O------------------------------->O |
* . O |
* . O-------\ |
* . . | ExecutionGroup.scheduleChunkWhenPossible
* . . O----/ (*) |
* . . O |
* . . O |
* . . O ExecutionGroup.scheduleAreaWhenPossible|
* . . O---------------------------------------->O
* . . . O----------\ ExecutionGroup.scheduleChunkWhenPossible
* . . . . | (*)
* . . . . O-------/
* . . . . O
* . . . . O
* . . . . O-------\ ExecutionGroup.scheduleChunk
* . . . . . |
* . . . . . O----/
* . . . . O<=O
* . . . O<=O
* . . . O
* . . O<========================================O
* . . O |
* . O<=O |
* . O |
* . O |
* </pre>
*
* This happens until all chunks of (ExecutionGroup B) are finished executing or the user break's the process.
*
* NodeOperation like the ScaleOperation can influence the area of interest by reimplementing the [@ref NodeOperation.determineAreaOfInterest] method
*
* <pre>
*
* +--------------------------+ +---------------------------------+
* | ExecutionGroup A | | ExecutionGroup B |
* | | | |
* +--------------------------+ +---------------------------------+
* Needed chunks from ExecutionGroup A | Chunk of ExecutionGroup B (to be evaluated)
* +-------+ +-------+ | +--------+
* |Chunk 1| |Chunk 2| +----------------+ |Chunk 1 |
* | | | | | ScaleOperation | | |
* +-------+ +-------+ +----------------+ +--------+
*
* +-------+ +-------+
* |Chunk 3| |Chunk 4|
* | | | |
* +-------+ +-------+
*
* </pre>
*
* @see ExecutionGroup.execute Execute a complete ExecutionGroup. Halts until finished or breaked by user
* @see ExecutionGroup.scheduleChunkWhenPossible Tries to schedule a single chunk, checks if all input data is available. Can trigger dependant chunks to be calculated
* @see ExecutionGroup.scheduleAreaWhenPossible Tries to schedule an area. This can be multiple chunks (is called from [@ref ExecutionGroup.scheduleChunkWhenPossible])
* @see ExecutionGroup.scheduleChunk Schedule a chunk on the WorkScheduler
* @see NodeOperation.determineDependingAreaOfInterest Influence the area of interest of a chunk.
* @see WriteBufferOperation NodeOperation to write to a MemoryProxy/MemoryBuffer
* @see ReadBufferOperation NodeOperation to read from a MemoryProxy/MemoryBuffer
* @see MemoryProxy proxy for information about memory image (a image consist out of multiple chunks)
* @see MemoryBuffer Allocated memory for a single chunk
*
* @section workscheduler WorkScheduler
* the WorkScheduler is implemented as a static class. the responsibility of the WorkScheduler is to balance WorkPackages to the available and free devices.
* the workscheduler can work in 2 states. For witching these between the state you need to recompile blender
*
* @subsection multithread Multi threaded
* Default the workscheduler will place all work as WorkPackage in a queue.
* For every CPUcore a working thread is created. These working threads will ask the WorkScheduler if there is work for a specific Device.
* the workscheduler will find work for the device and the device will be asked to execute the WorkPackage
* @subsection singlethread Single threaded
* For debugging reasons the multi-threading can be disabled. This is done by changing the COM_CURRENT_THREADING_MODEL to COM_TM_NOTHREAD. When compiling the workscheduler
* will be changes to support no threading and run everything on the CPU.
*
* @section devices Devices
* A Device within the compositor context is a Hardware component that can used to calculate chunks. This chunk is encapseled in a WorkPackage.
* the WorkScheduler controls the devices and selects the device where a WorkPackage will be calculated.
*
* @subsection WS_Devices Workscheduler
* The WorkScheduler controls all Devices. When initializing the compositor the WorkScheduler selects all devices that will be used during compositor.
* There are two types of Devices, CPUDevice and OpenCLDevice.
* When an ExecutionGroup schedules a Chunk the schedule method of the WorkScheduler
* The Workscheduler determines if the chunk can be run on an OpenCLDevice (and that there are available OpenCLDevice). If this is the case the chunk will be added to the worklist for OpenCLDevice's
* otherwise the chunk will be added to the worklist of CPUDevices.
*
* A thread will read the work-list and sends a workpackage to its device.
*
* @see WorkScheduler.schedule method that is called to schedule a chunk
* @see Device.execute method called to execute a chunk
*
* @subsection CPUDevice CPUDevice
* When a CPUDevice gets a WorkPackage the Device will get the inputbuffer that is needed to calculate the chunk. Allocation is already done by the ExecutionGroup.
* The outputbuffer of the chunk is being created.
* The OutputOperation of the ExecutionGroup is called to execute the area of the outputbuffer.
*
* @see ExecutionGroup
* @see NodeOperation.executeRegion executes a single chunk of a NodeOperation
* @see CPUDevice.execute
*
* @subsection GPUDevice OpenCLDevice
*
* To be completed!
* @see NodeOperation.executeOpenCLRegion
* @see OpenCLDevice.execute
*
* @section executePixel executing a pixel
* Finally the last step, the node functionality :)
* @page newnode Creating new nodes
*/
/**
* @brief The main method that is used to execute the compositor tree.
* It can be executed during editing (blenkernel/node.c) or rendering
* (renderer/pipeline.c)
*
* @param editingtree [struct bNodeTree]
* reference to the compositor editing tree
*
* @param rendering [true false]
* This parameter determines whether the function is called from rendering (true) or editing (false).
* based on this setting the system will work differently:
* - during rendering only Composite & the File output node will be calculated
* @see NodeOperation.isOutputProgram(int rendering) of the specific operations
*
* - during editing all output nodes will be calculated
* @see NodeOperation.isOutputProgram(int rendering) of the specific operations
*
* - another quality setting can be used bNodeTree. The quality is determined by the bNodeTree fields.
* quality can be modified by the user from within the node panels.
* @see bNodeTree.edit_quality
* @see bNodeTree.render_quality
*
* - output nodes can have different priorities in the WorkScheduler. This is implemented in the COM_execute function.
*/
void COM_execute(bNodeTree *editingtree, int rendering);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,99 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_defines_h_
#define _COM_defines_h_
/**
* @brief possible data types for SocketConnection
* @ingroup Model
*/
typedef enum DataType {
/** @brief Unknown data type (or not yet known) */
COM_DT_UNKNOWN = 0,
/** @brief Value data type */
COM_DT_VALUE = 1,
/** @brief Vector data type */
COM_DT_VECTOR = 2,
/** @brief Color data type */
COM_DT_COLOR = 4
} DataType;
/**
* @brief Possible quality settings
* @see CompositorContext.quality
* @ingroup Execution
*/
typedef enum CompositorQuality {
/** @brief High quality setting */
COM_QUALITY_HIGH = 0 ,
/** @brief Medium quality setting */
COM_QUALITY_MEDIUM = 1,
/** @brief Low quality setting */
COM_QUALITY_LOW = 2
} CompositorQuality;
// configurable items
// chunk size determination
#define COM_PREVIEW_SIZE 140.0f
#define COM_OPENCL_ENABLED
#define COM_PREVIEW_ENABLED
// workscheduler threading models
/**
* COM_TM_QUEUE is a multithreaded model, which uses the BLI_thread_queue pattern. This is the default option.
*/
#define COM_TM_QUEUE 1
/**
* COM_TM_NOTHREAD is a single threading model, everything is executed in the caller thread. easy for debugging
*/
#define COM_TM_NOTHREAD 0
/**
* COM_CURRENT_THREADING_MODEL can be one of the above, COM_TM_QUEUE is currently default.
*/
#define COM_CURRENT_THREADING_MODEL COM_TM_QUEUE
// chunk order
/**
* @brief The order of chunks to be scheduled
* @ingroup Execution
*/
typedef enum OrderOfChunks {
/** @brief order from a distance to centerX/centerY */
COM_TO_CENTER_OUT = 0,
/** @brief order randomly */
COM_TO_RANDOM = 1,
/** @brief no ordering */
COM_TO_TOP_DOWN = 2,
/** @brief experimental ordering with 9 hotspots */
COM_TO_RULE_OF_THIRDS = 3
} OrderOfChunks;
#define COM_RULE_OF_THIRDS_DIVIDER 100.0f
#define COM_NUMBER_OF_CHANNELS 4
#define COM_DEFAULT_RESOLUTION_WIDTH 640
#define COM_DEFAULT_RESOLUTION_HEIGHT 480
#endif

View File

@ -0,0 +1,14 @@
#!/usr/bin/python
Import ('env')
defs = ['GLEW_STATIC']
sources = env.Glob('intern/*.cpp') + env.Glob('nodes/*.cpp') + env.Glob('operations/*.cpp')
incs = '. nodes intern operations ../blenlib ../blenkernel ../makesdna ../render/extern/include ../render/intern/include'
incs += ' ../makesrna ../blenloader ../../../intern/guardedalloc ../imbuf ../windowmanager '
incs += '../opencl ../nodes ../nodes/intern ../nodes/composite '
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
env.BlenderLib ( 'bf_composite', sources, Split(incs), defines=defs, libtype=['core','player'], priority = [191,191] )

View File

@ -0,0 +1,41 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_CPUDevice.h"
void CPUDevice::execute(WorkPackage *work) {
const unsigned int chunkNumber = work->getChunkNumber();
ExecutionGroup * executionGroup = work->getExecutionGroup();
rcti rect;
executionGroup->determineChunkRect(&rect, chunkNumber);
MemoryBuffer ** inputBuffers = executionGroup->getInputBuffers(chunkNumber);
MemoryBuffer * outputBuffer = executionGroup->allocateOutputBuffer(chunkNumber, &rect);
executionGroup->getOutputNodeOperation()->executeRegion(&rect, chunkNumber, inputBuffers);
executionGroup->finalizeChunkExecution(chunkNumber, inputBuffers);
if (outputBuffer != NULL) {
outputBuffer->setCreatedState();
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_CPUDevice_h
#define _COM_CPUDevice_h
#include "COM_Device.h"
/**
* @brief class representing a CPU device.
* @note for every hardware thread in the system a CPUDevice instance will exist in the workscheduler
*/
class CPUDevice: public Device {
public:
/**
* @brief execute a WorkPackage
* @param work the WorkPackage to execute
*/
void execute(WorkPackage *work);
};
#endif

View File

@ -0,0 +1,34 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ChannelInfo.h"
#include "COM_defines.h"
#include <stdio.h>
/**
* @brief create new ChannelInfo instance and sets the defaults.
*/
ChannelInfo::ChannelInfo() {
this->number = 0;
this->premultiplied = true;
this->type = COM_CT_UNUSED;
}

View File

@ -0,0 +1,121 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ChannelInfo_h
#define _COM_ChannelInfo_h
#include <vector>
#include "BKE_text.h"
#include <string>
#include "DNA_node_types.h"
#include "BLI_rect.h"
using namespace std;
/**
* @brief List of possible channel types
* @ingroup Model
*/
typedef enum ChannelType {
COM_CT_ColorComponent /** @brief this channel is contains color information. Specific used is determined by channelnumber, and in the future color space */,
COM_CT_Alpha /** @brief this channel is contains transparency value */,
COM_CT_Value /** @brief this channel is contains a value */,
COM_CT_X /** @brief this channel is contains a X value */,
COM_CT_Y /** @brief this channel is contains a Y value */,
COM_CT_Z /** @brief this channel is contains a Z value */,
COM_CT_W /** @brief this channel is contains a W value */,
COM_CT_UNUSED /** @brief this channel is unused */
} ChannelType;
/**
* @brief ChannelInfo holds information about a channel.
*
* Channels are transported from node to node via a SocketConnection.
* ChannelInfo holds specific setting of these channels in order that the to-node of the connection
* Can handle specific logic per channel setting.
*
* @note currently this is not used, but a future place to implement color spacing and other things.
* @ingroup Model
*/
class ChannelInfo {
private:
/**
* @brief the channel number, in the connection. [0-3]
*/
int number;
/**
* @brief type of channel
*/
ChannelType type;
/**
* @brieg Is this value in this channel premultiplied with its alpha
* @note only valid if type = ColorComponent;
*/
bool premultiplied;
// /**
// * Color space of this value.
// * only valid when type = ColorComponent;
// */
// string colorspacename;
public:
/**
* @brief creates a new ChannelInfo and set default values
*/
ChannelInfo();
/**
* @brief set the index of this channel in the SocketConnection
*/
void setNumber(const int number) { this->number = number; }
/**
* @brief get the index of this channel in the SocketConnection
*/
const int getNumber() const {return this->number; }
/**
* @brief set the type of channel
*/
void setType(const ChannelType type) { this->type = type; }
/**
* @brief get the type of channel
*/
const ChannelType getType() const {return this->type; }
/**
* @brief set the premultiplicatioin of this channel
*/
void setPremultiplied(const bool premultiplied) { this->premultiplied = premultiplied; }
/**
* @brief is this channel premultiplied
*/
const bool isPremultiplied() const {return this->premultiplied;}
};
#endif

View File

@ -0,0 +1,48 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ChunkOrder.h"
#include "BLI_math.h"
ChunkOrder::ChunkOrder() {
this->distance = 0.0;
this->number = 0;
this->x = 0;
this->y = 0;
}
void ChunkOrder::determineDistance(ChunkOrderHotspot **hotspots, unsigned int numberOfHotspots) {
unsigned int index;
double distance = MAXFLOAT;
for (index = 0 ; index < numberOfHotspots ; index ++) {
ChunkOrderHotspot* hotspot = hotspots[index];
double ndistance = hotspot->determineDistance(this->x, this->y);
if (ndistance < distance) {
distance = ndistance;
}
}
this->distance = distance;
}
bool operator<(const ChunkOrder& a, const ChunkOrder& b) {
return a.distance < b.distance;
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ChunkOrder_h_
#define _COM_ChunkOrder_h_
#include "COM_ChunkOrderHotspot.h"
class ChunkOrder {
private:
unsigned int number;
int x;
int y;
double distance;
public:
ChunkOrder();
void determineDistance(ChunkOrderHotspot **hotspots, unsigned int numberOfHotspots);
friend bool operator<(const ChunkOrder& a, const ChunkOrder& b);
void setChunkNumber(unsigned int chunknumber) {this->number = chunknumber;}
void setX(int x) {this->x = x;}
void setY(int y) {this->y = y;}
unsigned int getChunkNumber() {return this->number;}
double getDistance() {return this->distance;}
};
#endif

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ChunkOrderHotspot.h"
#include <math.h>
ChunkOrderHotspot::ChunkOrderHotspot(int x, int y, float addition) {
this->x = x;
this->y = y;
this->addition = addition;
}
double ChunkOrderHotspot::determineDistance(int x, int y) {
int dx = x-this->x;
int dy = y-this->y;
double result = sqrt((double)(dx*dx+dy*dy));
result += this->addition;
return result;
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ChunkOrderHotSpot_h_
#define _COM_ChunkOrderHotSpot_h_
class ChunkOrderHotspot {
private:
int x;
int y;
float addition;
public:
ChunkOrderHotspot(int x, int y, float addition);
double determineDistance(int x, int y);
};
#endif

View File

@ -0,0 +1,47 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_CompositorContext.h"
#include "COM_defines.h"
#include <stdio.h>
CompositorContext::CompositorContext() {
this->scene = NULL;
this->quality = COM_QUALITY_HIGH;
this->hasActiveOpenCLDevices = false;
}
const int CompositorContext::getFramenumber() const {
if (this->scene) {
return this->scene->r.cfra;
} else {
return -1; /* this should never happen */
}
}
const int CompositorContext::isColorManaged() const {
if (this->scene) {
return this->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
} else {
return 0; /* this should never happen */
}
}

View File

@ -0,0 +1,147 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_CompositorContext_h
#define _COM_CompositorContext_h
#include <vector>
#include "BKE_text.h"
#include <string>
#include "DNA_node_types.h"
#include "BLI_rect.h"
#include "DNA_scene_types.h"
#include "COM_defines.h"
/**
* @brief Overall context of the compositor
*/
class CompositorContext {
private:
/**
* @brief The rendering field describes if we are rendering (F12) or if we are editing (Node editor)
* This field is initialized in ExecutionSystem and must only be read from that point on.
* @see ExecutionSystem
*/
bool rendering;
/**
* @brief The quality of the composite.
* This field is initialized in ExecutionSystem and must only be read from that point on.
* @see ExecutionSystem
*/
CompositorQuality quality;
/**
* @brief Reference to the scene that is being composited.
* This field is initialized in ExecutionSystem and must only be read from that point on.
* @see ExecutionSystem
*/
Scene* scene;
/**
* @brief reference to the bNodeTree
* This field is initialized in ExecutionSystem and must only be read from that point on.
* @see ExecutionSystem
*/
bNodeTree* bnodetree;
/**
* @brief does this system have active opencl devices?
*/
bool hasActiveOpenCLDevices;
public:
/**
* @brief constructor initializes the context with default values.
*/
CompositorContext();
/**
* @brief set the rendering field of the context
*/
void setRendering(bool rendering) { this->rendering = rendering; }
/**
* @brief get the rendering field of the context
*/
bool isRendering() const {return this->rendering;}
/**
* @brief set the scene of the context
*/
void setScene(Scene* scene) {this->scene = scene;}
/**
* @brief set the bnodetree of the context
*/
void setbNodeTree(bNodeTree* bnodetree) {this->bnodetree = bnodetree;}
/**
* @brief get the bnodetree of the context
*/
const bNodeTree * getbNodeTree() const {return this->bnodetree;}
/**
* @brief get the scene of the context
*/
const Scene* getScene() const {return this->scene;}
/**
* @brief set the quality
*/
void setQuality(CompositorQuality quality) {
this->quality = quality;
}
/**
* @brief get the quality
*/
const CompositorQuality getQuality() const {
return quality;
}
/**
* @brief get the current framenumber of the scene in this context
*/
const int getFramenumber() const;
/**
* @brief has this system active openclDevices?
*/
const bool getHasActiveOpenCLDevices() const {
return this->hasActiveOpenCLDevices;
}
/**
* @brief set has this system active openclDevices?
*/
void setHasActiveOpenCLDevices(bool hasAvtiveOpenCLDevices) {
this->hasActiveOpenCLDevices = hasAvtiveOpenCLDevices;
}
int getChunksize() {return this->getbNodeTree()->chunksize;}
const int isColorManaged() const;
};
#endif

View File

@ -0,0 +1,492 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_Converter.h"
#include "BKE_node.h"
#include "COM_CompositorNode.h"
#include "COM_RenderLayersNode.h"
#include "COM_ColorToBWNode.h"
#include "string.h"
#include "COM_SocketConnection.h"
#include "COM_ConvertColourToValueProg.h"
#include "COM_ConvertValueToColourProg.h"
#include "COM_ConvertColorToVectorOperation.h"
#include "COM_ConvertValueToVectorOperation.h"
#include "COM_ConvertVectorToColorOperation.h"
#include "COM_ConvertVectorToValueOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_MixNode.h"
#include "COM_MuteNode.h"
#include "COM_TranslateNode.h"
#include "COM_RotateNode.h"
#include "COM_ScaleNode.h"
#include "COM_FlipNode.h"
#include "COM_IDMaskNode.h"
#include "COM_FilterNode.h"
#include "COM_BrightnessNode.h"
#include "COM_SeparateRGBANode.h"
#include "COM_CombineRGBANode.h"
#include "COM_SeparateHSVANode.h"
#include "COM_CombineHSVANode.h"
#include "COM_SeparateYUVANode.h"
#include "COM_CombineYUVANode.h"
#include "COM_SeparateYCCANode.h"
#include "COM_CombineYCCANode.h"
#include "COM_AlphaOverNode.h"
#include "COM_ColorBalanceNode.h"
#include "COM_ViewerNode.h"
#include "COM_SplitViewerNode.h"
#include "COM_InvertNode.h"
#include "COM_GroupNode.h"
#include "COM_NormalNode.h"
#include "COM_NormalizeNode.h"
#include "COM_ImageNode.h"
#include "COM_BokehImageNode.h"
#include "COM_ColorCurveNode.h"
#include "COM_VectorCurveNode.h"
#include "COM_SetAlphaNode.h"
#include "COM_ConvertAlphaNode.h"
#include "COM_MapUVNode.h"
#include "COM_DisplaceNode.h"
#include "COM_MathNode.h"
#include "COM_HueSaturationValueNode.h"
#include "COM_HueSaturationValueCorrectNode.h"
#include "COM_ColorCorrectionNode.h"
#include "COM_BoxMaskNode.h"
#include "COM_EllipseMaskNode.h"
#include "COM_GammaNode.h"
#include "COM_ColorRampNode.h"
#include "COM_DifferenceMatteNode.h"
#include "COM_LuminanceMatteNode.h"
#include "COM_DistanceMatteNode.h"
#include "COM_ChromaMatteNode.h"
#include "COM_ColorMatteNode.h"
#include "COM_ChannelMatteNode.h"
#include "COM_BlurNode.h"
#include "COM_BokehBlurNode.h"
#include "COM_DilateErodeNode.h"
#include "COM_TranslateOperation.h"
#include "COM_LensDistortionNode.h"
#include "COM_TextureNode.h"
#include "COM_ColorNode.h"
#include "COM_ValueNode.h"
#include "COM_TimeNode.h"
#include "COM_DirectionalBlurNode.h"
#include "COM_ZCombineNode.h"
#include "COM_SetValueOperation.h"
#include "COM_ScaleOperation.h"
#include "COM_ExecutionSystemHelper.h"
#include "COM_TonemapNode.h"
#include "COM_SwitchNode.h"
#include "COM_GlareNode.h"
#include "COM_MovieClipNode.h"
#include "COM_ColorSpillNode.h"
#include "COM_OutputFileNode.h"
#include "COM_MapValueNode.h"
#include "COM_TransformNode.h"
#include "COM_Stabilize2dNode.h"
#include "COM_BilateralBlurNode.h"
#include "COM_VectorBlurNode.h"
#include "COM_MovieDistortionNode.h"
#include "COM_ViewLevelsNode.h"
#include "COM_DefocusNode.h"
#include "COM_DoubleEdgeMaskNode.h"
#include "COM_CropNode.h"
Node* Converter::convert(bNode *bNode) {
Node * node;
if (bNode->flag & NODE_MUTED) {
node = new MuteNode(bNode);
return node;
}
switch (bNode->type) {
case CMP_NODE_COMPOSITE:
node = new CompositorNode(bNode);
break;
case CMP_NODE_R_LAYERS:
node = new RenderLayersNode(bNode);
break;
case CMP_NODE_TEXTURE:
node = new TextureNode(bNode);
break;
case CMP_NODE_RGBTOBW:
node = new ColourToBWNode(bNode);
break;
case CMP_NODE_MIX_RGB:
node = new MixNode(bNode);
break;
case CMP_NODE_TRANSLATE:
node = new TranslateNode(bNode);
break;
case CMP_NODE_SCALE:
node = new ScaleNode(bNode);
break;
case CMP_NODE_ROTATE:
node = new RotateNode(bNode);
break;
case CMP_NODE_FLIP:
node = new FlipNode(bNode);
break;
case CMP_NODE_FILTER:
node = new FilterNode(bNode);
break;
case CMP_NODE_ID_MASK:
node = new IDMaskNode(bNode);
break;
case CMP_NODE_BRIGHTCONTRAST:
node = new BrightnessNode(bNode);
break;
case CMP_NODE_SEPRGBA:
node = new SeparateRGBANode(bNode);
break;
case CMP_NODE_COMBRGBA:
node = new CombineRGBANode(bNode);
break;
case CMP_NODE_SEPHSVA:
node = new SeparateHSVANode(bNode);
break;
case CMP_NODE_COMBHSVA:
node = new CombineHSVANode(bNode);
break;
case CMP_NODE_SEPYUVA:
node = new SeparateYUVANode(bNode);
break;
case CMP_NODE_COMBYUVA:
node = new CombineYUVANode(bNode);
break;
case CMP_NODE_SEPYCCA:
node = new SeparateYCCANode(bNode);
break;
case CMP_NODE_COMBYCCA:
node = new CombineYCCANode(bNode);
break;
case CMP_NODE_ALPHAOVER:
node = new AlphaOverNode(bNode);
break;
case CMP_NODE_COLORBALANCE:
node = new ColorBalanceNode(bNode);
break;
case CMP_NODE_VIEWER:
node = new ViewerNode(bNode);
break;
case CMP_NODE_SPLITVIEWER:
node = new SplitViewerNode(bNode);
break;
case CMP_NODE_INVERT:
node = new InvertNode(bNode);
break;
case NODE_GROUP:
node = new GroupNode(bNode);
break;
case CMP_NODE_NORMAL:
node = new NormalNode(bNode);
break;
case CMP_NODE_NORMALIZE:
node = new NormalizeNode(bNode);
break;
case CMP_NODE_IMAGE:
node = new ImageNode(bNode);
break;
case CMP_NODE_SETALPHA:
node = new SetAlphaNode(bNode);
break;
case CMP_NODE_PREMULKEY:
node = new ConvertAlphaNode(bNode);
break;
case CMP_NODE_MATH:
node = new MathNode(bNode);
break;
case CMP_NODE_HUE_SAT:
node = new HueSaturationValueNode(bNode);
break;
case CMP_NODE_COLORCORRECTION:
node = new ColorCorrectionNode(bNode);
break;
case CMP_NODE_MASK_BOX:
node = new BoxMaskNode(bNode);
break;
case CMP_NODE_MASK_ELLIPSE:
node = new EllipseMaskNode(bNode);
break;
case CMP_NODE_GAMMA:
node = new GammaNode(bNode);
break;
case CMP_NODE_CURVE_RGB:
node = new ColorCurveNode(bNode);
break;
case CMP_NODE_CURVE_VEC:
node = new VectorCurveNode(bNode);
break;
case CMP_NODE_HUECORRECT:
node = new HueSaturationValueCorrectNode(bNode);
break;
case CMP_NODE_MAP_UV:
node = new MapUVNode(bNode);
break;
case CMP_NODE_DISPLACE:
node = new DisplaceNode(bNode);
break;
case CMP_NODE_VALTORGB:
node = new ColorRampNode(bNode);
break;
case CMP_NODE_DIFF_MATTE:
node = new DifferenceMatteNode(bNode);
break;
case CMP_NODE_LUMA_MATTE:
node = new LuminanceMatteNode(bNode);
break;
case CMP_NODE_DIST_MATTE:
node = new DistanceMatteNode(bNode);
break;
case CMP_NODE_CHROMA_MATTE:
node = new ChromaMatteNode(bNode);
break;
case CMP_NODE_COLOR_MATTE:
node = new ColorMatteNode(bNode);
break;
case CMP_NODE_CHANNEL_MATTE:
node = new ChannelMatteNode(bNode);
break;
case CMP_NODE_BLUR:
node = new BlurNode(bNode);
break;
case CMP_NODE_BOKEHIMAGE:
node = new BokehImageNode(bNode);
break;
case CMP_NODE_BOKEHBLUR:
node = new BokehBlurNode(bNode);
break;
case CMP_NODE_DILATEERODE:
node = new DilateErodeNode(bNode);
break;
case CMP_NODE_LENSDIST:
node = new LensDistortionNode(bNode);
break;
case CMP_NODE_RGB:
node = new ColorNode(bNode);
break;
case CMP_NODE_VALUE:
node = new ValueNode(bNode);
break;
case CMP_NODE_TIME:
node = new TimeNode(bNode);
break;
case CMP_NODE_DBLUR:
node = new DirectionalBlurNode(bNode);
break;
case CMP_NODE_ZCOMBINE:
node = new ZCombineNode(bNode);
break;
case CMP_NODE_TONEMAP:
node = new TonemapNode(bNode);
break;
case CMP_NODE_SWITCH:
node = new SwitchNode(bNode);
break;
case CMP_NODE_GLARE:
node = new GlareNode(bNode);
break;
case CMP_NODE_MOVIECLIP:
node = new MovieClipNode(bNode);
break;
case CMP_NODE_COLOR_SPILL:
node = new ColorSpillNode(bNode);
break;
case CMP_NODE_OUTPUT_FILE:
node = new OutputFileNode(bNode);
break;
case CMP_NODE_MAP_VALUE:
node = new MapValueNode(bNode);
break;
case CMP_NODE_TRANSFORM:
node = new TransformNode(bNode);
break;
case CMP_NODE_STABILIZE2D:
node = new Stabilize2dNode(bNode);
break;
case CMP_NODE_BILATERALBLUR:
node = new BilateralBlurNode(bNode);
break;
case CMP_NODE_VECBLUR:
node = new VectorBlurNode(bNode);
break;
case CMP_NODE_MOVIEDISTORTION:
node = new MovieDistortionNode(bNode);
break;
case CMP_NODE_VIEW_LEVELS:
node = new ViewLevelsNode(bNode);
break;
case CMP_NODE_DEFOCUS:
node = new DefocusNode(bNode);
break;
case CMP_NODE_DOUBLEEDGEMASK:
node = new DoubleEdgeMaskNode(bNode);
break;
case CMP_NODE_CROP:
node = new CropNode(bNode);
break;
/* not inplemented yet */
default:
node = new MuteNode(bNode);
break;
}
return node;
}
void Converter::convertDataType(SocketConnection* connection, ExecutionSystem *system) {
OutputSocket* outputSocket = connection->getFromSocket();
InputSocket* inputSocket = connection->getToSocket();
DataType fromDatatype = outputSocket->getActualDataType();
DataType toDatatype = inputSocket->getActualDataType();
NodeOperation * converter = NULL;
if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_COLOR) {
converter = new ConvertValueToColourProg();
} else if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_VECTOR) {
converter = new ConvertValueToVectorOperation();
} else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VALUE) {
converter = new ConvertColourToValueProg();
} else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VECTOR) {
converter = new ConvertColorToVectorOperation();
} else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_VALUE) {
converter = new ConvertVectorToValueOperation();
} else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_COLOR) {
converter = new ConvertVectorToColorOperation();
}
if (converter != NULL) {
inputSocket->relinkConnections(converter->getInputSocket(0));
ExecutionSystemHelper::addLink(system->getConnections(), converter->getOutputSocket(), inputSocket);
system->addOperation(converter);
}
}
void Converter::convertResolution(SocketConnection *connection, ExecutionSystem *system) {
InputSocketResizeMode mode = connection->getToSocket()->getResizeMode();
NodeOperation * toOperation = (NodeOperation*)connection->getToNode();
const float toWidth = toOperation->getWidth();
const float toHeight = toOperation->getHeight();
NodeOperation * fromOperation = (NodeOperation*)connection->getFromNode();
const float fromWidth = fromOperation->getWidth();
const float fromHeight = fromOperation->getHeight();
bool doCenter = false;
bool doScale = false;
float addX= (toWidth-fromWidth)/2.0f;
float addY = (toHeight-fromHeight)/2.0f;
float scaleX=0;
float scaleY=0;
switch (mode) {
case COM_SC_NO_RESIZE:
break;
case COM_SC_CENTER:
doCenter = true;
break;
case COM_SC_FIT_WIDTH:
doCenter = true;
doScale = true;
scaleX = scaleY = toWidth/fromWidth;
break;
case COM_SC_FIT_HEIGHT:
doCenter = true;
doScale = true;
scaleX = scaleY = toHeight/fromHeight;
break;
case COM_SC_FIT:
doCenter = true;
doScale = true;
scaleX = toWidth/fromWidth;
scaleY = toHeight/fromHeight;
if (scaleX < scaleY) {
scaleX = scaleY;
} else {
scaleY = scaleX;
}
break;
case COM_SC_STRETCH:
doCenter = true;
doScale = true;
scaleX = toWidth/fromWidth;
scaleY = toHeight/fromHeight;
break;
}
if (doCenter) {
NodeOperation *first = NULL;
SocketConnection *c;
ScaleOperation * scaleOperation = NULL;
if(doScale) {
scaleOperation = new ScaleOperation();
first = scaleOperation;
SetValueOperation * sxop = new SetValueOperation();
sxop->setValue(scaleX);
c = ExecutionSystemHelper::addLink(system->getConnections(), sxop->getOutputSocket(), scaleOperation->getInputSocket(1));
c->setIgnoreResizeCheck(true);
SetValueOperation * syop = new SetValueOperation();
syop->setValue(scaleY);
c = ExecutionSystemHelper::addLink(system->getConnections(), syop->getOutputSocket(), scaleOperation->getInputSocket(2));
c->setIgnoreResizeCheck(true);
system->addOperation(sxop);
system->addOperation(syop);
unsigned int resolution[2] = {fromWidth, fromHeight};
scaleOperation->setResolution(resolution);
sxop->setResolution(resolution);
syop->setResolution(resolution);
system->addOperation(scaleOperation);
c->setIgnoreResizeCheck(true);
}
TranslateOperation * translateOperation = new TranslateOperation();
if (!first) first = translateOperation;
SetValueOperation * xop = new SetValueOperation();
xop->setValue(addX);
c = ExecutionSystemHelper::addLink(system->getConnections(), xop->getOutputSocket(), translateOperation->getInputSocket(1));
c->setIgnoreResizeCheck(true);
SetValueOperation * yop = new SetValueOperation();
yop->setValue(addY);
c = ExecutionSystemHelper::addLink(system->getConnections(), yop->getOutputSocket(), translateOperation->getInputSocket(2));
c->setIgnoreResizeCheck(true);
system->addOperation(xop);
system->addOperation(yop);
unsigned int resolution[2] = {toWidth, toHeight};
translateOperation->setResolution(resolution);
xop->setResolution(resolution);
yop->setResolution(resolution);
system->addOperation(translateOperation);
if (doScale) {
c = ExecutionSystemHelper::addLink(system->getConnections(), scaleOperation->getOutputSocket(), translateOperation->getInputSocket(0));
c->setIgnoreResizeCheck(true);
}
InputSocket * inputSocket = connection->getToSocket();
inputSocket->relinkConnections(first->getInputSocket(0));
c = ExecutionSystemHelper::addLink(system->getConnections(), translateOperation->getOutputSocket(), inputSocket);
c->setIgnoreResizeCheck(true);
}
connection->setIgnoreResizeCheck(true);
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_Converter_h
#define _COM_Converter_h
#include "DNA_node_types.h"
#include "COM_Node.h"
/**
* @brief Conversion methods for the compositor
*/
class Converter {
public:
/**
* @brief Convert/wraps a bNode in its Node instance.
*
* For all nodetypes a wrapper class is created.
* Muted nodes are wrapped with MuteNode.
*
* @note When adding a new node to blender, this method needs to be changed to return the correct Node instance.
*
* @see Node
* @see MuteNode
*/
static Node* convert(bNode* bNode);
/**
* @brief This method will add a datetype conversion rule when the to-socket does not support the from-socket actual data type.
*
* @note this method is called when conversion is needed.
*
* @param connection the SocketConnection what needs conversion
* @param system the ExecutionSystem to add the conversion to.
* @see SocketConnection - a link between two sockets
*/
static void convertDataType(SocketConnection* connection, ExecutionSystem *system);
/**
* @brief This method will add a resolution rule based on the settings of the InputSocket.
*
* @note Conversion logic is implemented in this method
* @see InputSocketResizeMode for the possible conversions.
* @param connection the SocketConnection what needs conversion
* @param system the ExecutionSystem to add the conversion to.
* @see SocketConnection - a link between two sockets
*/
static void convertResolution(SocketConnection* connection, ExecutionSystem *system);
};
#endif

View File

@ -0,0 +1,24 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_Device.h"

View File

@ -0,0 +1,57 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_Device_h
#define _COM_Device_h
#include "COM_ExecutionSystem.h"
#include "COM_WorkPackage.h"
#include "COM_NodeOperation.h"
#include "BLI_rect.h"
#include "COM_MemoryBuffer.h"
/**
* @brief Abstract class for device implementations to be used by the Compositor.
* devices are queried, initialized and used by the WorkScheduler.
* work are packaged as a WorkPackage instance.
*/
class Device {
public:
/**
* @brief initialize the device
*/
virtual bool initialize() {return true;}
/**
* @brief deinitialize the device
*/
virtual void deinitialize() {}
/**
* @brief execute a WorkPackage
* @param work the WorkPackage to execute
*/
virtual void execute(WorkPackage *work) = 0;
};
#endif

View File

@ -0,0 +1,566 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ExecutionGroup.h"
#include "COM_InputSocket.h"
#include "COM_SocketConnection.h"
#include "COM_defines.h"
#include "math.h"
#include "COM_ExecutionSystem.h"
#include <sstream>
#include "COM_ReadBufferOperation.h"
#include "COM_WriteBufferOperation.h"
#include "COM_ReadBufferOperation.h"
#include "COM_WorkScheduler.h"
#include "COM_ViewerOperation.h"
#include <stdlib.h>
#include "BLI_math.h"
#include "COM_MemoryManager.h"
#include "PIL_time.h"
#include "COM_ChunkOrder.h"
#include <algorithm>
#include "BLI_math.h"
#include "COM_ExecutionSystemHelper.h"
ExecutionGroup::ExecutionGroup() {
this->isOutput = false;
this->complex = false;
this->chunkExecutionStates = NULL;
this->bTree = NULL;
this->height = 0;
this->width = 0;
this->cachedMaxReadBufferOffset = 0;
this->numberOfXChunks = 0;
this->numberOfYChunks = 0;
this->numberOfChunks = 0;
this->initialized = false;
this->openCL = false;
this->chunksFinished = 0;
}
int ExecutionGroup::getRenderPriotrity() {
return this->getOutputNodeOperation()->getRenderPriority();
}
bool ExecutionGroup::containsOperation(NodeOperation* operation) {
for (vector<NodeOperation*>::const_iterator iterator = this->operations.begin() ; iterator != this->operations.end() ; ++iterator) {
NodeOperation* inListOperation = *iterator;
if (inListOperation == operation) {
return true;
}
}
return false;
}
const bool ExecutionGroup::isComplex() const {
return this->complex;
}
bool ExecutionGroup::canContainOperation(NodeOperation* operation) {
if (!this->initialized) {return true;}
if (operation->isReadBufferOperation()) {return true;}
if (operation->isWriteBufferOperation()) {return false;}
if (operation->isSetOperation()) {return true;}
if (!this->isComplex()) {
return (!operation->isComplex());
} else {
return false;
}
}
void ExecutionGroup::addOperation(ExecutionSystem *system, NodeOperation *operation) {
if (containsOperation(operation)) return;
if (canContainOperation(operation)) {
if (!operation->isBufferOperation()) {
this->complex = operation->isComplex();
this->openCL = operation->isOpenCL();
this->initialized = true;
}
this->operations.push_back(operation);
if (operation->isReadBufferOperation()) {
ReadBufferOperation* readOperation = (ReadBufferOperation*)operation;
WriteBufferOperation* writeOperation = readOperation->getMemoryProxy()->getWriteBufferOperation();
this->addOperation(system, writeOperation);
} else {
unsigned int index;
for (index = 0 ; index < operation->getNumberOfInputSockets(); index ++) {
InputSocket * inputSocket = operation->getInputSocket(index);
if (inputSocket->isConnected()) {
NodeOperation* node = (NodeOperation*)inputSocket->getConnection()->getFromNode();
this->addOperation(system, node);
}
}
}
} else {
if (operation->isWriteBufferOperation()) {
WriteBufferOperation * writeoperation = (WriteBufferOperation*)operation;
if (writeoperation->getMemoryProxy()->getExecutor() == NULL) {
ExecutionGroup* newGroup = new ExecutionGroup();
writeoperation->getMemoryProxy()->setExecutor(newGroup);
newGroup->addOperation(system, operation);
ExecutionSystemHelper::addExecutionGroup(system->getExecutionGroups(), newGroup);
}
}
}
}
NodeOperation* ExecutionGroup::getOutputNodeOperation() const{
return this->operations[0]; // the first operation of the group is always the output operation.
}
void ExecutionGroup::initExecution()
{
if (this->chunkExecutionStates != NULL) {
delete[] this->chunkExecutionStates;
}
unsigned int index;
determineNumberOfChunks();
this->chunkExecutionStates = NULL;
if (this->numberOfChunks != 0) {
this->chunkExecutionStates = new ChunkExecutionState[numberOfChunks];
for (index = 0 ; index < numberOfChunks ; index ++) {
this->chunkExecutionStates[index] = COM_ES_NOT_SCHEDULED;
}
}
unsigned int maxNumber = 0;
for (index = 0 ; index < this->operations.size(); index ++) {
NodeOperation* operation = this->operations[index];
if (operation->isReadBufferOperation()) {
ReadBufferOperation *readOperation = (ReadBufferOperation*)operation;
this->cachedReadOperations.push_back(readOperation);
maxNumber = max(maxNumber, readOperation->getOffset());
}
}
maxNumber++;
this->cachedMaxReadBufferOffset = maxNumber;
}
void ExecutionGroup::deinitExecution() {
if (this->chunkExecutionStates != NULL) {
delete[] this->chunkExecutionStates;
this->chunkExecutionStates = NULL;
}
this->numberOfChunks = 0;
this->numberOfXChunks = 0;
this->numberOfYChunks = 0;
this->cachedReadOperations.clear();
this->bTree = NULL;
}
void ExecutionGroup::determineResolution(unsigned int resolution[]) {
NodeOperation* operation = this->getOutputNodeOperation();
unsigned int preferredResolution[2];
preferredResolution[0] = 0;
preferredResolution[1] = 0;
operation->determineResolution(resolution, preferredResolution);
operation->setResolution(resolution);
this->setResolution(resolution);
}
void ExecutionGroup::determineNumberOfChunks() {
const float chunkSizef = this->chunkSize;
this->numberOfXChunks = ceil(this->width / chunkSizef);
this->numberOfYChunks = ceil(this->height / chunkSizef);
this->numberOfChunks = this->numberOfXChunks * this->numberOfYChunks;
}
/**
* this method is called for the top execution groups. containing the compositor node or the preview node or the viewer node)
*/
void ExecutionGroup::execute(ExecutionSystem* graph) {
CompositorContext& context = graph->getContext();
const bNodeTree* bTree = context.getbNodeTree();
if (this->width == 0 || this->height == 0) {return;} /// @note: break out... no pixels to calculate.
if (bTree->test_break && bTree->test_break(bTree->tbh)) {return;} /// @note: early break out for blur and preview nodes
if (this->numberOfChunks == 0) {return;} /// @note: early break out
unsigned int chunkNumber;
this->chunksFinished = 0;
this->bTree = bTree;
unsigned int index;
unsigned int *chunkOrder = new unsigned int[this->numberOfChunks];
for (chunkNumber = 0 ; chunkNumber<this->numberOfChunks ; chunkNumber++) {
chunkOrder[chunkNumber] = chunkNumber;
}
NodeOperation *operation = this->getOutputNodeOperation();
float centerX = 0.5;
float centerY = 0.5;
int chunkorder = COM_TO_CENTER_OUT;
if (operation->isViewerOperation()) {
ViewerBaseOperation* viewer = (ViewerBaseOperation*)operation;
centerX = viewer->getCenterX();
centerY = viewer->getCenterY();
chunkorder = viewer->getChunkOrder();
}
switch (chunkorder) {
case COM_TO_RANDOM:
for (index = 0 ; index < 2* numberOfChunks ; index ++) {
int index1 = rand()%numberOfChunks;
int index2 = rand()%numberOfChunks;
int s = chunkOrder[index1];
chunkOrder[index1] = chunkOrder[index2];
chunkOrder[index2] = s;
}
break;
case COM_TO_CENTER_OUT:
{
ChunkOrderHotspot **hotspots = new ChunkOrderHotspot*[1];
hotspots[0] = new ChunkOrderHotspot(this->width*centerX, this->height*centerY, 0.0f);
rcti rect;
ChunkOrder *chunkOrders = new ChunkOrder[this->numberOfChunks];
for (index = 0 ; index < this->numberOfChunks; index ++) {
determineChunkRect(&rect, index);
chunkOrders[index].setChunkNumber(index);
chunkOrders[index].setX(rect.xmin);
chunkOrders[index].setY(rect.ymin);
chunkOrders[index].determineDistance(hotspots, 1);
}
sort(&chunkOrders[0], &chunkOrders[numberOfChunks-1]);
for (index = 0 ; index < numberOfChunks; index ++) {
chunkOrder[index] = chunkOrders[index].getChunkNumber();
}
delete hotspots[0];
delete[] hotspots;
delete[] chunkOrders;
}
break;
case COM_TO_RULE_OF_THIRDS:
{
ChunkOrderHotspot **hotspots = new ChunkOrderHotspot*[9];
unsigned int tx = this->width/6;
unsigned int ty = this->height/6;
unsigned int mx = this->width/2;
unsigned int my = this->height/2;
unsigned int bx = mx+2*tx;
unsigned int by = my+2*ty;
float addition = numberOfChunks/COM_RULE_OF_THIRDS_DIVIDER;
hotspots[0] = new ChunkOrderHotspot(mx, my, addition*0);
hotspots[1] = new ChunkOrderHotspot(tx, my, addition*1);
hotspots[2] = new ChunkOrderHotspot(bx, my, addition*2);
hotspots[3] = new ChunkOrderHotspot(bx, by, addition*3);
hotspots[4] = new ChunkOrderHotspot(tx, ty, addition*4);
hotspots[5] = new ChunkOrderHotspot(bx, ty, addition*5);
hotspots[6] = new ChunkOrderHotspot(tx, by, addition*6);
hotspots[7] = new ChunkOrderHotspot(mx, ty, addition*7);
hotspots[8] = new ChunkOrderHotspot(mx, by, addition*8);
rcti rect;
ChunkOrder *chunkOrders = new ChunkOrder[this->numberOfChunks];
for (index = 0 ; index < this->numberOfChunks; index ++) {
determineChunkRect(&rect, index);
chunkOrders[index].setChunkNumber(index);
chunkOrders[index].setX(rect.xmin);
chunkOrders[index].setY(rect.ymin);
chunkOrders[index].determineDistance(hotspots, 9);
}
sort(&chunkOrders[0], &chunkOrders[numberOfChunks]);
for (index = 0 ; index < numberOfChunks; index ++) {
chunkOrder[index] = chunkOrders[index].getChunkNumber();
}
delete hotspots[0];
delete hotspots[1];
delete hotspots[2];
delete hotspots[3];
delete hotspots[4];
delete hotspots[5];
delete hotspots[6];
delete hotspots[7];
delete hotspots[8];
delete[] hotspots;
delete[] chunkOrders;
}
break;
case COM_TO_TOP_DOWN:
default:
break;
}
bool breaked = false;
bool finished = false;
unsigned int startIndex = 0;
const int maxNumberEvaluated = BLI_system_thread_count()*2;
while (!finished && !breaked) {
unsigned int index;
bool startEvaluated = false;
finished = true;
int numberEvaluated = 0;
for (index = startIndex ; index < numberOfChunks && numberEvaluated < maxNumberEvaluated; index ++) {
int chunkNumber = chunkOrder[index];
int yChunk = chunkNumber/this->numberOfXChunks;
int xChunk = chunkNumber - (yChunk*this->numberOfXChunks);
const ChunkExecutionState state = this->chunkExecutionStates[chunkNumber];
if (state == COM_ES_NOT_SCHEDULED) {
scheduleChunkWhenPossible(graph, xChunk, yChunk);
finished=false;
startEvaluated = true;
numberEvaluated++;
} else if (state == COM_ES_SCHEDULED) {
finished=false;
startEvaluated = true;
numberEvaluated++;
} else if (state == COM_ES_EXECUTED && !startEvaluated) {
startIndex = index+1;
}
}
PIL_sleep_ms(10);
if (bTree->test_break && bTree->test_break(bTree->tbh)) {
breaked = true;
}
}
delete[] chunkOrder;
}
MemoryBuffer** ExecutionGroup::getInputBuffers(int chunkNumber) {
rcti rect;
vector<MemoryProxy*> memoryproxies;
unsigned int index;
determineChunkRect(&rect, chunkNumber);
this->determineDependingMemoryProxies(&memoryproxies);
MemoryBuffer **memoryBuffers = new MemoryBuffer*[this->cachedMaxReadBufferOffset];
for (index= 0 ; index < this->cachedMaxReadBufferOffset ; index ++) {
memoryBuffers[index] = NULL;
}
rcti output;
for (index = 0 ; index < this->cachedReadOperations.size(); index ++) {
ReadBufferOperation *readOperation = (ReadBufferOperation*)this->cachedReadOperations[index];
MemoryProxy * memoryProxy = readOperation->getMemoryProxy();
this->determineDependingAreaOfInterest(&rect, readOperation, &output);
MemoryBuffer* memoryBuffer = memoryProxy->getExecutor()->constructConsolidatedMemoryBuffer(memoryProxy, &output);
memoryBuffers[readOperation->getOffset()] = memoryBuffer;
}
return memoryBuffers;
}
MemoryBuffer* ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *rect) {
// find all chunks inside the rect
// determine minxchunk, minychunk, maxxchunk, maxychunk where x and y are chunknumbers
float chunkSizef = this->chunkSize;
int indexx, indexy;
const int minxchunk = floor(rect->xmin/chunkSizef);
const int maxxchunk = ceil((rect->xmax-1)/chunkSizef);
const int minychunk = floor(rect->ymin/chunkSizef);
const int maxychunk = ceil((rect->ymax-1)/chunkSizef);
if (maxxchunk== minxchunk+1 && maxychunk == minychunk+1) {
const int chunkNumber = minxchunk+minychunk*numberOfXChunks;
MemoryBuffer *result = MemoryManager::getMemoryBuffer(memoryProxy, chunkNumber);
return result;
}
rcti chunkRect;
chunkRect.xmin = minxchunk*this->chunkSize;
chunkRect.xmax = maxxchunk*this->chunkSize;
chunkRect.ymin = minychunk*this->chunkSize;
chunkRect.ymax = maxychunk*this->chunkSize;
CLAMP(chunkRect.xmin, 0, (int)this->width);
CLAMP(chunkRect.xmax, 0, (int)this->width);
CLAMP(chunkRect.ymin, 0, (int)this->height);
CLAMP(chunkRect.ymax, 0, (int)this->height);
MemoryBuffer *result = new MemoryBuffer(memoryProxy, &chunkRect);
for (indexx = max(minxchunk, 0); indexx<min((int)this->numberOfXChunks, maxxchunk) ; indexx++) {
for (indexy = max(minychunk, 0); indexy<min((int)this->numberOfYChunks, maxychunk) ; indexy++) {
int chunkNumber = indexx+indexy*this->numberOfXChunks;
MemoryBuffer *chunkBuffer = MemoryManager::getMemoryBuffer(memoryProxy, chunkNumber);
result->copyContentFrom(chunkBuffer);
}
}
return result;
}
void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer** memoryBuffers) {
if (this->chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED)
this->chunkExecutionStates[chunkNumber] = COM_ES_EXECUTED;
else
throw "Threading inconsistency";
this->chunksFinished++;
if (memoryBuffers) {
for (unsigned int index = 0 ; index < this->cachedMaxReadBufferOffset; index ++) {
MemoryBuffer * buffer = memoryBuffers[index];
if (buffer) {
if (buffer->isTemporarily()) {
memoryBuffers[index] = NULL;
delete buffer;
}
}
}
delete[] memoryBuffers;
}
if (bTree) {
// status report is only performed for top level Execution Groups.
float progress = chunksFinished;
progress/=numberOfChunks;
bTree->progress(bTree->prh, progress);
}
}
inline void ExecutionGroup::determineChunkRect(rcti* rect, const unsigned int xChunk, const unsigned int yChunk ) const {
const unsigned int minx = xChunk * chunkSize;
const unsigned int miny = yChunk * chunkSize;
BLI_init_rcti(rect, minx, min(minx + this->chunkSize, this->width), miny, min(miny + this->chunkSize, this->height));
}
void ExecutionGroup::determineChunkRect(rcti* rect, const unsigned int chunkNumber) const {
const unsigned int yChunk = chunkNumber / numberOfXChunks;
const unsigned int xChunk = chunkNumber - (yChunk * numberOfXChunks);
determineChunkRect(rect, xChunk, yChunk);
}
MemoryBuffer* ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti* rect) {
MemoryBuffer* outputBuffer = NULL;
// output allocation is only valid when our outputoperation is a memorywriter
NodeOperation * operation = this->getOutputNodeOperation();
if (operation->isWriteBufferOperation()) {
WriteBufferOperation* writeOperation = (WriteBufferOperation*)operation;
outputBuffer = MemoryManager::allocateMemoryBuffer(writeOperation->getMemoryProxy(), chunkNumber, rect);
}
return outputBuffer;
}
bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem * graph, rcti *area) {
// find all chunks inside the rect
// determine minxchunk, minychunk, maxxchunk, maxychunk where x and y are chunknumbers
float chunkSizef = this->chunkSize;
int indexx, indexy;
const int minxchunk = floor(area->xmin/chunkSizef);
const int maxxchunk = ceil((area->xmax-1)/chunkSizef);
const int minychunk = floor(area->ymin/chunkSizef);
const int maxychunk = ceil((area->ymax-1)/chunkSizef);
bool result = true;
for (indexx = max(minxchunk, 0); indexx<maxxchunk ; indexx++) {
for (indexy = max(minychunk, 0); indexy<maxychunk ; indexy++) {
if (!scheduleChunkWhenPossible(graph, indexx, indexy)) {
result = false;
}
}
}
return result;
}
bool ExecutionGroup::scheduleChunk(unsigned int chunkNumber) {
if (this->chunkExecutionStates[chunkNumber] == COM_ES_NOT_SCHEDULED) {
this->chunkExecutionStates[chunkNumber] = COM_ES_SCHEDULED;
WorkScheduler::schedule(this, chunkNumber);
return true;
}
return false;
}
bool ExecutionGroup::scheduleChunkWhenPossible(ExecutionSystem * graph, int xChunk, int yChunk) {
if (xChunk < 0 || xChunk >= (int)this->numberOfXChunks) {
return true;
}
if (yChunk < 0 || yChunk >= (int)this->numberOfYChunks) {
return true;
}
int chunkNumber = yChunk*this->numberOfXChunks + xChunk;
// chunk is already executed
if (this->chunkExecutionStates[chunkNumber] == COM_ES_EXECUTED) {
return true;
}
// chunk is scheduled, but not executed
if (this->chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED) {
return false;
}
// chunk is nor executed nor scheduled.
vector<MemoryProxy*> memoryProxies;
this->determineDependingMemoryProxies(&memoryProxies);
rcti rect;
determineChunkRect(&rect, xChunk, yChunk);
unsigned int index;
bool canBeExecuted = true;
rcti area;
for (index = 0 ; index < cachedReadOperations.size() ; index ++) {
ReadBufferOperation * readOperation = (ReadBufferOperation*)cachedReadOperations[index];
BLI_init_rcti(&area, 0, 0, 0, 0);
MemoryProxy * memoryProxy = memoryProxies[index];
determineDependingAreaOfInterest(&rect, readOperation, &area);
ExecutionGroup *group = memoryProxy->getExecutor();
if (group != NULL) {
if (!group->scheduleAreaWhenPossible(graph, &area)) {
canBeExecuted = false;
}
} else {
throw "ERROR";
}
}
if (canBeExecuted) {
scheduleChunk(chunkNumber);
}
return false;
}
void ExecutionGroup::determineDependingAreaOfInterest(rcti * input, ReadBufferOperation* readOperation, rcti* output) {
this->getOutputNodeOperation()->determineDependingAreaOfInterest(input, readOperation, output);
}
void ExecutionGroup::determineDependingMemoryProxies(vector<MemoryProxy*> *memoryProxies) {
unsigned int index;
for (index = 0 ; index < this->cachedReadOperations.size() ; index ++) {
ReadBufferOperation * readOperation = (ReadBufferOperation*) this->cachedReadOperations[index];
memoryProxies->push_back(readOperation->getMemoryProxy());
}
}
bool ExecutionGroup::operator ==(const ExecutionGroup & executionGroup) const {
return this->getOutputNodeOperation() == executionGroup.getOutputNodeOperation();
}
bool ExecutionGroup::isOpenCL() {
return this->openCL;
}

View File

@ -0,0 +1,404 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ExecutionGroup_h
#define _COM_ExecutionGroup_h
#include "COM_Node.h"
#include "COM_NodeOperation.h"
#include <vector>
#include "BLI_rect.h"
#include "COM_MemoryProxy.h"
#include "COM_Device.h"
#include "COM_CompositorContext.h"
/**
* @brief the execution state of a chunk in an ExecutionGroup
* @ingroup Execution
*/
typedef enum ChunkExecutionState {
/**
* @brief chunk is not yet scheduled
*/
COM_ES_NOT_SCHEDULED = 0,
/**
* @brief chunk is scheduled, but not yet executed
*/
COM_ES_SCHEDULED = 1,
/**
* @brief chunk is executed.
*/
COM_ES_EXECUTED = 2
} ChunkExecutionState;
class MemoryProxy;
class ReadBufferOperation;
class Device;
/**
* @brief Class ExecutionGroup is a group of NodeOperations that are executed as one.
* This grouping is used to combine Operations that can be executed as one whole when multi-processing.
* @ingroup Execution
*/
class ExecutionGroup {
private:
// fields
/**
* @brief unique identifier of this node.
*/
string id;
/**
* @brief list of operations in this ExecutionGroup
*/
vector<NodeOperation*> operations;
/**
* @brief is this ExecutionGroup an input ExecutionGroup
* an input execution group is a group that is at the end of the calculation (the output is important for the user)
*/
int isOutput;
/**
* @brief Width of the output
*/
unsigned int width;
/**
* @brief Height of the output
*/
unsigned int height;
/**
* @brief size of a single chunk, being Width or of height
* a chunk is always a square, except at the edges of the MemoryBuffer
*/
unsigned int chunkSize;
/**
* @brief number of chunks in the x-axis
*/
unsigned int numberOfXChunks;
/**
* @brief number of chunks in the y-axis
*/
unsigned int numberOfYChunks;
/**
* @brief total number of chunks
*/
unsigned int numberOfChunks;
/**
* @brief contains this ExecutionGroup a complex NodeOperation.
*/
bool complex;
/**
* @brief can this ExecutionGroup be scheduled on an OpenCLDevice
*/
bool openCL;
/**
* @brief what is the maximum number field of all ReadBufferOperation in this ExecutionGroup.
* @note this is used to construct the MemoryBuffers that will be passed during execution.
*/
unsigned int cachedMaxReadBufferOffset;
/**
* @brief a cached vector of all read operations in the execution group.
*/
vector<NodeOperation*> cachedReadOperations;
/**
* @brief reference to the original bNodeTree, this field is only set for the 'top' execution group.
* @note can only be used to call the callbacks for progress, status and break
*/
const bNodeTree * bTree;
/**
* @brief total number of chunks that have been calculated for this ExecutionGroup
*/
unsigned int chunksFinished;
/**
* @brief the chunkExecutionStates holds per chunk the execution state. this state can be
* - COM_ES_NOT_SCHEDULED: not scheduled
* - COM_ES_SCHEDULED: scheduled
* - COM_ES_EXECUTED: executed
*/
ChunkExecutionState *chunkExecutionStates;
/**
* @brief indicator when this ExecutionGroup has valid NodeOperations in its vector for Execution
* @note When building the ExecutionGroup NodeOperations are added via recursion. First a WriteBufferOperations is added, then the
* @note Operation containing the settings that is important for the ExecutiongGroup is added,
* @note When this occurs, these settings are copied over from the node to the ExecutionGroup
* @note and the Initialized flag is set to true.
* @see complex
* @see openCL
*/
bool initialized;
// methods
/**
* @brief check whether parameter operation can be added to the execution group
* @param operation the operation to be added
*/
bool canContainOperation(NodeOperation* operation);
/**
* @brief get the Render priority of this ExecutionGroup
* @see ExecutionSystem.execute
*/
int getRenderPriotrity();
/**
* @brief calculate the actual chunk size of this execution group.
* @note A chunk size is an unsigned int that is both the height and width of a chunk.
* @note The chunk size will not be stored in the chunkSize field. This needs to be done
* @note by the calling method.
*/
unsigned int determineChunkSize();
/**
* @brief Determine the rect (minx, maxx, miny, maxy) of a chunk at a position.
* @note Only gives usefull results ater the determination of the chunksize
* @see determineChunkSize()
*/
void determineChunkRect(rcti* rect, const unsigned int xChunk, const unsigned int yChunk) const;
/**
* @brief determine the number of chunks, based on the chunkSize, width and height.
* @note The result are stored in the fields numberOfChunks, numberOfXChunks, numberOfYChunks
*/
void determineNumberOfChunks();
/**
* @brief try to schedule a specific chunk.
* @note scheduling succeeds when all input requirements are met and the chunks hasen't been scheduled yet.
* @param graph
* @param xChunk
* @param yChunk
* @return [true:false]
* true: package(s) are scheduled
* false: scheduling is deferred (depending workpackages are scheduled)
*/
bool scheduleChunkWhenPossible(ExecutionSystem * graph, int xChunk, int yChunk);
/**
* @brief try to schedule a specific area.
* @note Check if a certain area is available, when not available this are will be checked.
* @note This method is called from other ExecutionGroup's.
* @param graph
* @param rect
* @return [true:false]
* true: package(s) are scheduled
* false: scheduling is deferred (depending workpackages are scheduled)
*/
bool scheduleAreaWhenPossible(ExecutionSystem * graph, rcti * rect);
/**
* @brief add a chunk to the WorkScheduler.
* @param chunknumber
*/
bool scheduleChunk(unsigned int chunkNumber);
/**
* @brief determine the area of interest of a certain input area
* @note This method only evaluates a single ReadBufferOperation
* @param input the input area
* @param readOperation The ReadBufferOperation where the area needs to be evaluated
* @param output the area needed of the ReadBufferOperation. Result
*/
void determineDependingAreaOfInterest(rcti * input, ReadBufferOperation* readOperation, rcti* output);
public:
// constructors
ExecutionGroup();
/**
* @brief set the id of this ExecutionGroup
* @param id
*/
void setId(string id) {this->id = id;}
/**
* @brief return the id of this ExecutionGroup
*/
const string getId() const {return this->id;}
// methods
/**
* @brief check to see if a NodeOperation is already inside this execution group
* @param operation the NodeOperation to check
* @return [true,false]
*/
bool containsOperation(NodeOperation* operation);
/**
* @brief add an operation to this ExecutionGroup
* @note this method will add input of the operations recursivly
* @note this method can create multiple ExecutionGroup's
* @param system
* @param operation
*/
void addOperation(ExecutionSystem* system, NodeOperation *operation);
/**
* @brief is this ExecutionGroup an output ExecutionGroup
* @note An OutputExecution group are groups containing a
* @note ViewerOperation, CompositeOperation, PreviewOperation.
* @see NodeOperation.isOutputOperation
*/
const int isOutputExecutionGroup() const {return this->isOutput;}
/**
* @brief set whether this ExecutionGroup is an output
* @param isOutput
*/
void setOutputExecutionGroup(int isOutput) {this->isOutput = isOutput;}
/**
* @brief determine the resolution of this ExecutionGroup
* @param resolution
*/
void determineResolution(unsigned int resolution[]);
/**
* @brief set the resolution of this executiongroup
* @param resolution
*/
void setResolution(unsigned int resolution[]) {this->width = resolution[0];this->height = resolution[1];}
/**
* @brief get the width of this execution group
*/
const unsigned int getWidth() {return this->width;}
/**
* @brief get the height of this execution group
*/
const unsigned int getHeight() {return this->height;}
/**
* @brief does this ExecutionGroup contains a complex NodeOperation
*/
const bool isComplex() const;
/**
* @brief get the output operation of this ExecutionGroup
* @return NodeOperation* output operation
*/
NodeOperation* getOutputNodeOperation() const;
/**
* @brief compose multiple chunks into a single chunk
* @return Memorybuffer* consolidated chunk
*/
MemoryBuffer* constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *output);
/**
* @brief initExecution is called just before the execution of the whole graph will be done.
* @note The implementation will calculate the chunkSize of this execution group.
*/
void initExecution();
/**
* @brief get all inputbuffers needed to calculate an chunk
* @note all inputbuffers must be executed
* @param chunkNumber the chunk to be calculated
* @return MemoryBuffer** the inputbuffers
*/
MemoryBuffer** getInputBuffers(int chunkNumber);
/**
* @brief allocate the outputbuffer of a chunk
* @param chunkNumber the number of the chunk in the ExecutionGroup
* @param rect the rect of that chunk
* @see determineChunkRect
*/
MemoryBuffer* allocateOutputBuffer(int chunkNumber, rcti *rect);
/**
* @brief after a chunk is executed the needed resources can be freed or unlocked.
* @param chunknumber
* @param memorybuffers
*/
void finalizeChunkExecution(int chunkNumber, MemoryBuffer** memoryBuffers);
/**
* @brief deinitExecution is called just after execution the whole graph.
* @note It will release all needed resources
*/
void deinitExecution();
/**
* @brief schedule an ExecutionGroup
* @note this method will return when all chunks have been calculated, or the execution has breaked (by user)
*
* first the order of the chunks will be determined. This is determined by finding the ViewerOperation and get the relevant information from it.
* - ChunkOrdering
* - CenterX
* - CenterY
*
* After determining the order of the chunks the chunks will be scheduled
*
* @see ViewerOperation
* @param system
*/
void execute(ExecutionSystem* system);
/**
* @brief this method determines the MemoryProxy's where this execution group depends on.
* @note After this method determineDependingAreaOfInterest can be called to determine
* @note the area of the MemoryProxy.creator thas has to be executed.
* @param memoryProxies result
*/
void determineDependingMemoryProxies(vector<MemoryProxy*> *memoryProxies);
/**
* @brief Determine the rect (minx, maxx, miny, maxy) of a chunk.
* @note Only gives usefull results ater the determination of the chunksize
* @see determineChunkSize()
*/
void determineChunkRect(rcti* rect, const unsigned int chunkNumber) const;
bool operator ==(const ExecutionGroup &executionGroup) const;
/**
* @brief can this ExecutionGroup be scheduled on an OpenCLDevice
* @see WorkScheduler.schedule
*/
bool isOpenCL();
void setChunksize(int chunksize) {this->chunkSize = chunksize;}
};
#endif

View File

@ -0,0 +1,310 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ExecutionSystem.h"
#include "PIL_time.h"
#include "BKE_node.h"
#include "COM_Converter.h"
#include <sstream>
#include "COM_NodeOperation.h"
#include "COM_ExecutionGroup.h"
#include "COM_NodeBase.h"
#include "COM_WorkScheduler.h"
#include "COM_ReadBufferOperation.h"
#include "COM_MemoryManager.h"
#include "stdio.h"
#include "COM_GroupNode.h"
#include "COM_WriteBufferOperation.h"
#include "COM_ReadBufferOperation.h"
#include "COM_ExecutionSystemHelper.h"
#include "BKE_global.h"
ExecutionSystem::ExecutionSystem(bNodeTree* editingtree, bool rendering) {
this->context.setbNodeTree(editingtree);
/* initialize the CompositorContext */
if (rendering) {
context.setQuality((CompositorQuality)editingtree->render_quality);
} else {
context.setQuality((CompositorQuality)editingtree->edit_quality);
}
context.setRendering(rendering);
context.setHasActiveOpenCLDevices(WorkScheduler::hasGPUDevices() && (editingtree->flag & NTREE_COM_OPENCL));
Node* mainOutputNode=NULL;
mainOutputNode = ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree);
if (mainOutputNode) {
context.setScene((Scene*)mainOutputNode->getbNode()->id);
this->convertToOperations();
this->groupOperations(); /* group operations in ExecutionGroups */
vector<ExecutionGroup*> executionGroups;
this->findOutputExecutionGroup(&executionGroups);
unsigned int index;
unsigned int resolution[2];
for (index = 0 ; index < executionGroups.size(); index ++) {
resolution[0]=0;
resolution[1]=0;
ExecutionGroup* executionGroup = executionGroups[index];
executionGroup->determineResolution(resolution);
}
}
if (G.f & G_DEBUG) ExecutionSystemHelper::debugDump(this);
}
ExecutionSystem::~ExecutionSystem() {
unsigned int index;
for(index = 0; index < this->connections.size(); index++) {
SocketConnection* connection = this->connections[index];
delete connection;
}
this->connections.clear();
for(index = 0; index < this->nodes.size(); index++) {
Node* node = this->nodes[index];
delete node;
}
this->nodes.clear();
for(index = 0; index < this->operations.size(); index++) {
NodeOperation* operation = this->operations[index];
delete operation;
}
this->operations.clear();
for(index = 0; index < this->groups.size(); index++) {
ExecutionGroup* group = this->groups[index];
delete group;
}
this->groups.clear();
}
void ExecutionSystem::execute() {
unsigned int order = 0;
for( vector<NodeOperation*>::iterator iter = this->operations.begin(); iter != operations.end(); ++iter ) {
NodeBase* node = *iter;
NodeOperation *operation = (NodeOperation*) node;
if (operation->isReadBufferOperation()) {
ReadBufferOperation * readOperation = (ReadBufferOperation*)operation;
readOperation->setOffset(order);
order ++;
}
}
MemoryManager::initialize();
unsigned int index;
for (index = 0 ; index < this->operations.size() ; index ++) {
NodeOperation * operation = this->operations[index];
operation->initExecution();
}
for (index = 0 ; index < this->groups.size() ; index ++) {
ExecutionGroup * executionGroup = this->groups[index];
executionGroup->setChunksize(context.getChunksize());
executionGroup->initExecution();
}
WorkScheduler::start(this->context);
vector<ExecutionGroup*> executionGroups;
this->findOutputExecutionGroup(&executionGroups);
/* start execution of the ExecutionGroups based on priority of their output node */
for (int priority = 9 ; priority>=0 ; priority--) {
for (index = 0 ; index < executionGroups.size(); index ++) {
ExecutionGroup* group = executionGroups[index];
NodeOperation* output = group->getOutputNodeOperation();
if (output->getRenderPriority() == priority) {
group->execute(this);
}
}
}
WorkScheduler::finish();
WorkScheduler::stop();
for (index = 0 ; index < this->operations.size() ; index ++) {
NodeOperation * operation = this->operations[index];
operation->deinitExecution();
}
for (index = 0 ; index < this->groups.size() ; index ++) {
ExecutionGroup * executionGroup = this->groups[index];
executionGroup->deinitExecution();
}
MemoryManager::clear();
}
void ExecutionSystem::addOperation(NodeOperation *operation) {
ExecutionSystemHelper::addOperation(this->operations, operation);
}
void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) {
// for every input add write and read operation if input is not a read operation
// only add read operation to other links when they are attached to buffered operations.
unsigned int index;
for (index = 0 ; index < operation->getNumberOfInputSockets();index++) {
InputSocket* inputsocket = operation->getInputSocket(index);
if (inputsocket->isConnected()) {
SocketConnection *connection = inputsocket->getConnection();
NodeOperation* otherEnd = (NodeOperation*)connection->getFromNode();
if (!otherEnd->isReadBufferOperation()) {
// check of other end already has write operation
OutputSocket *fromsocket = connection->getFromSocket();
WriteBufferOperation * writeoperation = fromsocket->findAttachedWriteBufferOperation();
if (writeoperation == NULL) {
writeoperation = new WriteBufferOperation();
writeoperation->setbNodeTree(this->getContext().getbNodeTree());
this->addOperation(writeoperation);
ExecutionSystemHelper::addLink(this->getConnections(), fromsocket, writeoperation->getInputSocket(0));
}
ReadBufferOperation *readoperation = new ReadBufferOperation();
readoperation->setMemoryProxy(writeoperation->getMemoryProxy());
connection->setFromSocket(readoperation->getOutputSocket());
readoperation->getOutputSocket()->addConnection(connection);
this->addOperation(readoperation);
}
}
}
/*
link the outputsocket to a write operation
link the writeoperation to a read operation
link the read operation to the next node.
*/
OutputSocket * outputsocket = operation->getOutputSocket();
if (outputsocket->isConnected()) {
int index;
WriteBufferOperation *writeOperation;
writeOperation = new WriteBufferOperation();
writeOperation->setbNodeTree(this->getContext().getbNodeTree());
this->addOperation(writeOperation);
for (index = 0 ; index < outputsocket->getNumberOfConnections();index ++) {
SocketConnection * connection = outputsocket->getConnection(index);
ReadBufferOperation* readoperation = new ReadBufferOperation();
readoperation->setMemoryProxy(writeOperation->getMemoryProxy());
connection->setFromSocket(readoperation->getOutputSocket());
readoperation->getOutputSocket()->addConnection(connection);
this->addOperation(readoperation);
}
ExecutionSystemHelper::addLink(this->getConnections(), outputsocket, writeOperation->getInputSocket(0));
}
}
void ExecutionSystem::convertToOperations() {
unsigned int index;
// first determine data types of the nodes, this can be used by the node to convert to a different operation system
this->determineActualSocketDataTypes((vector<NodeBase*>&)this->nodes);
for(index = 0; index < this->nodes.size(); index++) {
Node* node = (Node*)this->nodes[index];
node->convertToOperations(this, &this->context);
}
// update the socket types of the operations. this will be used to add conversion operations in the system
this->determineActualSocketDataTypes((vector<NodeBase*>&)this->operations);
for (index = 0 ; index < this->connections.size(); index ++) {
SocketConnection *connection = this->connections[index];
if (connection->isValid()) {
if (connection->getFromSocket()->getActualDataType() != connection->getToSocket()->getActualDataType()) {
Converter::convertDataType(connection, this);
}
}
}
// determine all resolutions of the operations (Width/Height)
for (index = 0 ; index < this->operations.size(); index ++) {
NodeOperation* operation= this->operations[index];
if (operation->isOutputOperation(context.isRendering())) {
unsigned int resolution[2] = {0,0};
unsigned int preferredResolution[2] = {0,0};
operation->determineResolution(resolution, preferredResolution);
operation->setResolution(resolution);
}
}
// add convert resolution operations when needed.
for (index = 0 ; index < this->connections.size(); index ++) {
SocketConnection *connection = this->connections[index];
if (connection->isValid()) {
if (connection->needsResolutionConversion()) {
Converter::convertResolution(connection, this);
}
}
}
}
void ExecutionSystem::groupOperations() {
vector<NodeOperation*> outputOperations;
NodeOperation * operation;
unsigned int index;
// surround complex operations with ReadBufferOperation and WriteBufferOperation
for(index = 0; index < this->operations.size(); index++) {
operation = this->operations[index];
if (operation->isComplex()) {
this->addReadWriteBufferOperations(operation);
}
}
ExecutionSystemHelper::findOutputNodeOperations(&outputOperations, this->getOperations(), this->context.isRendering());
for( vector<NodeOperation*>::iterator iter = outputOperations.begin(); iter != outputOperations.end(); ++iter ) {
operation = *iter;
ExecutionGroup *group = new ExecutionGroup();
group->addOperation(this, operation);
group->setOutputExecutionGroup(true);
ExecutionSystemHelper::addExecutionGroup(this->getExecutionGroups(), group);
}
}
void ExecutionSystem::addSocketConnection(SocketConnection *connection)
{
this->connections.push_back(connection);
}
void ExecutionSystem::determineActualSocketDataTypes(vector<NodeBase*> &nodes) {
unsigned int index;
/* first do all input nodes */
for(index = 0; index < nodes.size(); index++) {
NodeBase* node = nodes[index];
if (node->isInputNode()) {
node->determineActualSocketDataTypes();
}
}
/* then all other nodes */
for(index = 0; index < nodes.size(); index++) {
NodeBase* node = nodes[index];
if (!node->isInputNode()) {
node->determineActualSocketDataTypes();
}
}
}
void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup*> *result) const {
unsigned int index;
for (index = 0 ; index < this->groups.size() ; index ++) {
ExecutionGroup* group = this->groups[index];
if (group->isOutputExecutionGroup()) {
result->push_back(group);
}
}
}

View File

@ -0,0 +1,229 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
class ExecutionGroup;
#ifndef _COM_ExecutionSystem_h
#define _COM_ExecutionSystem_h
#include "DNA_node_types.h"
#include <vector>
#include "COM_Node.h"
#include "COM_SocketConnection.h"
#include "BKE_text.h"
#include "COM_ExecutionGroup.h"
#include "COM_NodeOperation.h"
using namespace std;
/**
* @page execution Execution model
* In order to get to an efficient model for execution, serveral steps are being done. these steps are explained below.
*
* @section EM_Step1 Step 1: translating blender node system to the new compsitor system
* Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture. We want to use classes in order to simplify the system.
* during this step the blender node_tree is evaluated and converted to a CPP node system.
*
* @see ExecutionSystem
* @see Converter.convert
* @see Node
*
* @section EM_Step2 Step2: translating nodes to operations
* Ungrouping the GroupNodes. Group nodes are node_tree's in node_tree's. The new system only supports a single level of node_tree. We will 'flatten' the system in a single level.
* @see GroupNode
* @see ExecutionSystemHelper.ungroup
*
* Every node has the ability to convert itself to operations. The node itself is responsible to create a correct NodeOperation setup based on its internal settings.
* Most Node only need to convert it to its NodeOperation. Like a ColorToBWNode doesn't check anything, but replaces itself with a ConvertColorToBWOperation.
* More complex nodes can use different NodeOperation based on settings; like MixNode. based on the selected Mixtype a different operation will be used.
* for more information see the page about creating new Nodes. [@subpage newnode]
*
* @see ExecutionSystem.convertToOperations
* @see Node.convertToOperations
* @see NodeOperation base class for all operations in the system
*
* @section EM_Step3 Step3: add additional conversions to the operation system
* - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR. The user can connect a Value socket to a color socket. As values are ordered differently than colors a conversion happens.
*
* - Image size conversions: the system can automatically convert when resolutions do not match. An InputSocket has a resize mode. This can be any of the folowing settings.
* - [@ref InputSocketResizeMode.COM_SC_CENTER]: The center of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_WIDTH]: The width of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_HEIGHT]: the height of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT]: The width, or the height of both images are aligned to make sure that it fits.
* - [@ref InputSocketResizeMode.COM_SC_STRETCH]: The width and the height of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_NO_RESIZE]: bottom left of the images are aligned.
*
* @see Converter.convertDataType Datatype conversions
* @see Converter.convertResolution Image size conversions
*
* @section EM_Step4 Step4: group operations in executions groups
* ExecutionGroup are groups of operations that are calculated as being one bigger operation. All operations will be part of an ExecutionGroup.
* Complex nodes will be added to separate groups. Between ExecutionGroup's the data will be stored in MemoryBuffers. ReadBufferOperations and WriteBufferOperations are added where needed.
*
* <pre>
*
* +------------------------------+ +----------------+
* | ExecutionGroup A | |ExecutionGroup B| ExecutionGroup
* | +----------+ +----------+| |+----------+ |
* /----->| Operation|---->| Operation|-\ /--->| Operation|-\ | NodeOperation
* | | | A | | B ||| | || C | | |
* | | | cFFA | /->| cFFA ||| | || cFFA | | |
* | | +----------+ | +----------+|| | |+----------+ | |
* | +---------------|--------------+v | +-------------v--+
* +-*----+ +---*--+ +--*-*--+ +--*----+
* |inputA| |inputB| |outputA| |outputB| MemoryBuffer
* |cFAA | |cFAA | |cFAA | |cFAA |
* +------+ +------+ +-------+ +-------+
* </pre>
* @see ExecutionSystem.groupOperations method doing this step
* @see ExecutionSystem.addReadWriteBufferOperations
* @see NodeOperation.isComplex
* @see ExecutionGroup class representing the ExecutionGroup
*/
/**
* @brief the ExecutionSystem contains the whole compositor tree.
*/
class ExecutionSystem {
private:
/**
* @brief the context used during execution
*/
CompositorContext context;
/**
* @brief vector of nodes
*/
vector<Node*> nodes;
/**
* @brief vector of operations
*/
vector<NodeOperation*> operations;
/**
* @brief vector of groups
*/
vector<ExecutionGroup*> groups
/**
* @brief vector of connections
*/;
vector<SocketConnection*> connections;
private: //methods
/**
* @brief add ReadBufferOperation and WriteBufferOperation around an operation
* @param operation the operation to add the bufferoperations around.
*/
void addReadWriteBufferOperations(NodeOperation* operation);
/**
* find all execution group with output nodes
*/
void findOutputExecutionGroup(vector<ExecutionGroup*> *result) const;
public:
/**
* @brief Create a new ExecutionSystem and initialize it with the
* editingtree.
*
* @param editingtree [bNodeTree*]
* @param rendering [true false]
*/
ExecutionSystem(bNodeTree* editingtree, bool rendering);
/**
* Destructor
*/
~ExecutionSystem();
/**
* @brief execute this system
* - initialize the NodeOperation's and ExecutionGroup's
* - schedule the output ExecutionGroup's based on their priority
* - deinitialize the ExecutionGroup's and NodeOperation's
*/
void execute();
/**
* @brief Add an operation to the operation list
*
* @param operation the operation to add
*/
void addOperation(NodeOperation* operation);
/**
* Add an editor link to the system. convert it to an socketconnection (CPP-representative)
* this converted socket is returned.
*/
SocketConnection* addNodeLink(bNodeLink* bNodeLink);
void addSocketConnection(SocketConnection* connection);
/**
* @brief Convert all nodes to operations
*/
void convertToOperations();
/**
* @brief group operations in ExecutionGroup's
* @see ExecutionGroup
*/
void groupOperations();
/**
* @brief get the reference to the compositor context
*/
CompositorContext& getContext() {return this->context;}
/**
* @brief get the reference to the compositor nodes
*/
vector<Node*>& getNodes() {return this->nodes;}
/**
* @brief get the reference to the compositor connections
*/
vector<SocketConnection*>& getConnections() {return this->connections;}
/**
* @brief get the reference to the list of execution groups
*/
vector<ExecutionGroup*>& getExecutionGroups() {return this->groups;}
/**
* @brief get the reference to the list of operations
*/
vector<NodeOperation*>& getOperations() {return this->operations;}
private:
/**
* @brief determine the actual data types of all sockets
* @param nodes list of nodes or operations to do the data type determination
*/
void determineActualSocketDataTypes(vector<NodeBase*> &nodes);
};
#endif

View File

@ -0,0 +1,310 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ExecutionSystemHelper.h"
#include "PIL_time.h"
#include "BKE_node.h"
#include "COM_Converter.h"
#include <sstream>
#include "COM_NodeOperation.h"
#include "COM_ExecutionGroup.h"
#include "COM_NodeBase.h"
#include "COM_WorkScheduler.h"
#include "COM_ReadBufferOperation.h"
#include "COM_MemoryManager.h"
#include "stdio.h"
#include "COM_GroupNode.h"
#include "COM_WriteBufferOperation.h"
#include "COM_ReadBufferOperation.h"
Node* ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree) {
vector<Node*>& nodes = system.getNodes();
vector<SocketConnection*>& links = system.getConnections();
Node* mainnode = NULL;
/* add all nodes of the tree to the node list */
bNode* node = (bNode*)tree->nodes.first;
while (node != NULL) {
Node* execnode = addNode(nodes, node);
if (node->type == CMP_NODE_COMPOSITE) {
mainnode = execnode;
}
node = (bNode*)node->next;
}
NodeRange node_range(nodes.begin()+nodes_start, nodes.end());
/* add all nodelinks of the tree to the link list */
bNodeLink* nodelink = (bNodeLink*)tree->links.first;
while (nodelink != NULL) {
addNodeLink(node_range, links, nodelink);
nodelink = (bNodeLink*)nodelink->next;
}
/* Expand group nodes */
for (int i=nodes_start; i < nodes.size(); ++i) {
Node *execnode = nodes[i];
if (execnode->isGroupNode()) {
GroupNode * groupNode = (GroupNode*)execnode;
groupNode->ungroup(system);
}
}
return mainnode;
}
void ExecutionSystemHelper::addNode(vector<Node*>& nodes, Node *node) {
nodes.push_back(node);
}
Node* ExecutionSystemHelper::addNode(vector<Node*>& nodes, bNode *bNode) {
Converter converter;
Node * node;
node = converter.convert(bNode);
if (node != NULL) {
addNode(nodes, node);
return node;
}
return NULL;
}
void ExecutionSystemHelper::addOperation(vector<NodeOperation*>& operations, NodeOperation *operation) {
operations.push_back(operation);
}
void ExecutionSystemHelper::addExecutionGroup(vector<ExecutionGroup*>& executionGroups, ExecutionGroup *executionGroup) {
executionGroups.push_back(executionGroup);
}
void ExecutionSystemHelper::findOutputNodeOperations(vector<NodeOperation*>* result, vector<NodeOperation*>& operations, bool rendering) {
unsigned int index;
for (index = 0 ; index < operations.size() ; index ++) {
NodeOperation* operation = operations[index];
if (operation->isOutputOperation(rendering)) {
result->push_back(operation);
}
}
}
static InputSocket* find_input(NodeRange &node_range, bNode *bnode, bNodeSocket* bsocket) {
if (bnode != NULL) {
for(NodeIterator it=node_range.first; it!=node_range.second; ++it) {
Node* node = *it;
if (node->getbNode() == bnode)
return node->findInputSocketBybNodeSocket(bsocket);
}
} else {
for(NodeIterator it=node_range.first; it!=node_range.second; ++it) {
Node* node = *it;
if (node->isProxyNode()) {
InputSocket *proxySocket = node->getInputSocket(0);
if (proxySocket->getbNodeSocket()==bsocket)
return proxySocket;
}
}
}
return NULL;
}
static OutputSocket* find_output(NodeRange &node_range, bNode *bnode, bNodeSocket* bsocket) {
if (bnode != NULL) {
for(NodeIterator it=node_range.first; it!=node_range.second; ++it) {
Node* node = *it;
if (node->getbNode() == bnode)
return node->findOutputSocketBybNodeSocket(bsocket);
}
} else {
for(NodeIterator it=node_range.first; it!=node_range.second; ++it) {
Node* node = *it;
if (node->isProxyNode()) {
OutputSocket *proxySocket = node->getOutputSocket(0);
if (proxySocket->getbNodeSocket()==bsocket)
return proxySocket;
}
}
}
return NULL;
}
SocketConnection* ExecutionSystemHelper::addNodeLink(NodeRange &node_range, vector<SocketConnection*>& links, bNodeLink *bNodeLink) {
/// @note: cyclic lines will be ignored. This has been copied from node.c
if (bNodeLink->tonode != 0 && bNodeLink->fromnode != 0) {
if(!(bNodeLink->fromnode->level >= bNodeLink->tonode->level && bNodeLink->tonode->level!=0xFFF)) { // only add non cyclic lines! so execution will procede
return NULL;
}
}
InputSocket *inputSocket = find_input(node_range, bNodeLink->tonode, bNodeLink->tosock);
OutputSocket *outputSocket = find_output(node_range, bNodeLink->fromnode, bNodeLink->fromsock);
if (inputSocket == NULL || outputSocket == NULL) {
return NULL;
}
if (inputSocket->isConnected()) {
return NULL;
}
SocketConnection* connection = addLink(links, outputSocket, inputSocket);
return connection;
}
SocketConnection* ExecutionSystemHelper::addLink(vector<SocketConnection*>& links, OutputSocket* fromSocket, InputSocket* toSocket) {
SocketConnection * newconnection = new SocketConnection();
newconnection->setFromSocket(fromSocket);
newconnection->setToSocket(toSocket);
fromSocket->addConnection(newconnection);
toSocket->setConnection(newconnection);
links.push_back(newconnection);
return newconnection;
}
void ExecutionSystemHelper::debugDump(ExecutionSystem* system) {
Node* node;
NodeOperation* operation;
ExecutionGroup* group;
SocketConnection* connection;
int tot, tot2;
printf("-- BEGIN COMPOSITOR DUMP --\r\n");
printf("digraph compositorexecution {\r\n");
tot = system->getNodes().size();
for (int i = 0 ; i < tot ; i ++) {
node = system->getNodes()[i];
printf("// NODE: %s\r\n", node->getbNode()->typeinfo->name);
}
tot = system->getOperations().size();
for (int i = 0 ; i < tot ; i ++) {
operation = system->getOperations()[i];
printf("// OPERATION: %p\r\n", operation);
printf("\t\"O_%p\"", operation);
printf(" [shape=record,label=\"{");
tot2 = operation->getNumberOfInputSockets();
if (tot2 != 0) {
printf("{");
for (int j = 0 ; j < tot2 ; j ++) {
InputSocket *socket = operation->getInputSocket(j);
if (j != 0) {
printf("|");
}
printf("<IN_%p>", socket);
switch (socket->getActualDataType()) {
case COM_DT_VALUE:
printf("Value");
break;
case COM_DT_VECTOR:
printf("Vector");
break;
case COM_DT_COLOR:
printf("Color");
break;
case COM_DT_UNKNOWN:
printf("Unknown");
break;
}
}
printf("}");
printf("|");
}
if (operation->isViewerOperation()) {
printf("Viewer");
} else if (operation->isOutputOperation(system->getContext().isRendering())) {
printf("Output");
} else if (operation->isSetOperation()) {
printf("Set");
} else if (operation->isReadBufferOperation()) {
printf("ReadBuffer");
} else if (operation->isWriteBufferOperation()) {
printf("WriteBuffer");
} else {
printf("O_%p", operation);
}
tot2 = operation->getNumberOfOutputSockets();
if (tot2 != 0) {
printf("|");
printf("{");
for (int j = 0 ; j < tot2 ; j ++) {
OutputSocket *socket = operation->getOutputSocket(j);
if (j != 0) {
printf("|");
}
printf("<OUT_%p>", socket);
switch (socket->getActualDataType()) {
case COM_DT_VALUE:
printf("Value");
break;
case COM_DT_VECTOR:
printf("Vector");
break;
case COM_DT_COLOR:
printf("Color");
break;
case COM_DT_UNKNOWN:
printf("Unknown");
break;
}
}
printf("}");
}
printf("}\"]");
printf("\r\n");
}
tot = system->getExecutionGroups().size();
for (int i = 0 ; i < tot ; i ++) {
group = system->getExecutionGroups()[i];
printf("// GROUP: %d\r\n", i);
printf("subgraph {\r\n");
printf("// OUTPUTOPERATION: %p\r\n", group->getOutputNodeOperation());
printf(" O_%p\r\n", group->getOutputNodeOperation());
printf("}\r\n");
}
tot = system->getOperations().size();
for (int i = 0 ; i < tot ; i ++) {
operation = system->getOperations()[i];
if (operation->isReadBufferOperation()) {
ReadBufferOperation * read = (ReadBufferOperation*)operation;
WriteBufferOperation * write= read->getMemoryProxy()->getWriteBufferOperation();
printf("\t\"O_%p\" -> \"O_%p\" [style=dotted]\r\n", write, read);
}
}
tot = system->getConnections().size();
for (int i = 0 ; i < tot ; i ++) {
connection = system->getConnections()[i];
printf("// CONNECTION: %p.%p -> %p.%p\r\n", connection->getFromNode(), connection->getFromSocket(), connection->getToNode(), connection->getToSocket());
printf("\t\"O_%p\":\"OUT_%p\" -> \"O_%p\":\"IN_%p\"", connection->getFromNode(), connection->getFromSocket(), connection->getToNode(), connection->getToSocket());
if (!connection->isValid()) {
printf(" [color=red]");
} else {
switch (connection->getFromSocket()->getActualDataType()) {
case COM_DT_VALUE:
printf(" [color=grey]");
break;
case COM_DT_VECTOR:
printf(" [color=blue]");
break;
case COM_DT_COLOR:
printf(" [color=orange]");
break;
case COM_DT_UNKNOWN:
printf(" [color=black]");
break;
}
}
printf("\r\n");
}
printf("}\r\n");
printf("-- END COMPOSITOR DUMP --\r\n");
}

View File

@ -0,0 +1,127 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
class ExecutionGroup;
#ifndef _COM_ExecutionSystemHelper_h
#define _COM_ExecutionSystemHelper_h
#include "DNA_node_types.h"
#include <vector>
#include "COM_Node.h"
#include "COM_SocketConnection.h"
#include "BKE_text.h"
#include "COM_ExecutionGroup.h"
using namespace std;
/**
*
*/
class ExecutionSystemHelper {
public:
/**
* @brief add an bNodeTree to the nodes list and connections
* @param system Execution system
* @param nodes_start Starting index in the system's nodes list for nodes in this tree.
* @param tree bNodeTree to add
* @return Node representing the "Compositor node" of the maintree. or NULL when a subtree is added
*/
static Node* addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree * tree);
/**
* @brief add an editor node to the system.
* this node is converted to a Node instance.
* and the converted node is returned
*
* @param bNode node to add
* @return Node that represents the bNode or null when not able to convert.
*/
static Node* addNode(vector<Node*>& nodes, bNode* bNode);
/**
* @brief Add a Node to a list
*
* @param nodes the list where the node needs to be added to
* @param node the node to be added
*/
static void addNode(vector<Node*>& nodes, Node* node);
/**
* @brief Add an operation to the operation list
*
* The id of the operation is updated.
*
* @param operations the list where the operation need to be added to
* @param operation the operation to add
*/
static void addOperation(vector<NodeOperation*> &operations, NodeOperation* operation);
/**
* @brief Add an ExecutionGroup to a list
*
* The id of the ExecutionGroup is updated.
*
* @param executionGroups the list where the executionGroup need to be added to
* @param executionGroup the ExecutionGroup to add
*/
static void addExecutionGroup(vector<ExecutionGroup*>& executionGroups, ExecutionGroup *executionGroup);
/**
* Find all Node Operations that needs to be executed.
* @param rendering
* the rendering parameter will tell what type of execution we are doing
* FALSE is editing, TRUE is rendering
*/
static void findOutputNodeOperations(vector<NodeOperation*>* result, vector<NodeOperation*>& operations , bool rendering);
/**
* @brief add a bNodeLink to the list of links
* the bNodeLink will be wrapped in a SocketConnection
*
* @note Cyclic links will be ignored
*
* @param node_range list of possible nodes for lookup.
* @param links list of links to add the bNodeLink to
* @param bNodeLink the link to be added
* @return the created SocketConnection or NULL
*/
static SocketConnection* addNodeLink(NodeRange &node_range, vector<SocketConnection*>& links, bNodeLink *bNodeLink);
/**
* @brief create a new SocketConnection and add to a vector of links
* @param links the vector of links
* @param fromSocket the startpoint of the connection
* @param toSocket the endpoint of the connection
* @return the new created SocketConnection
*/
static SocketConnection* addLink(vector<SocketConnection*>& links, OutputSocket* fromSocket, InputSocket* toSocket);
/**
* @brief dumps the content of the execution system to standard out
* @param system the execution system to dump
*/
static void debugDump(ExecutionSystem* system);
};
#endif

View File

@ -0,0 +1,217 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_Socket.h"
#include "COM_Node.h"
#include "COM_SocketConnection.h"
#include "COM_ExecutionSystem.h"
InputSocket::InputSocket(DataType datatype) :Socket(datatype) {
this->connection = NULL;
this->resizeMode = COM_SC_CENTER;
}
InputSocket::InputSocket(DataType datatype, InputSocketResizeMode resizeMode) :Socket(datatype) {
this->connection = NULL;
this->resizeMode = resizeMode;
}
InputSocket::InputSocket(InputSocket* from) :Socket(from->getDataType()) {
this->connection = NULL;
this->resizeMode = from->getResizeMode();
}
int InputSocket::isInputSocket() const { return true; }
const int InputSocket::isConnected() const { return this->connection != NULL; }
void InputSocket::setConnection(SocketConnection *connection) {
this->connection = connection;
}
SocketConnection* InputSocket::getConnection() {return this->connection;}
void InputSocket::determineResolution(unsigned int resolution[],unsigned int preferredResolution[]) {
if (this->isConnected()){
this->connection->getFromSocket()->determineResolution(resolution, preferredResolution);
} else {
return;
}
}
DataType InputSocket::convertToSupportedDataType(DataType datatype) {
int supportedDataTypes = getDataType();
if (supportedDataTypes&datatype) {
return datatype;
}
bool candoValue = supportedDataTypes&COM_DT_VALUE;
bool candoVector = supportedDataTypes&COM_DT_VECTOR;
bool candoColor = supportedDataTypes&COM_DT_COLOR;
if (datatype == COM_DT_VALUE) {
if (candoColor) {
return COM_DT_COLOR;
} else if (candoVector) {
return COM_DT_VECTOR;
}
} else if (datatype == COM_DT_VECTOR) {
if (candoColor) {
return COM_DT_COLOR;
} else if (candoValue) {
return COM_DT_VALUE;
}
} else if (datatype == COM_DT_COLOR) {
if (candoVector) {
return COM_DT_VECTOR;
} else if (candoValue) {
return COM_DT_VALUE;
}
}
return this->getDataType();
}
void InputSocket::determineActualDataType() {
/// @note: this method is only called for inputsocket that are not connected.
/// @note: passes COM_DT_COLOR, the convertToSupportedDataType converts this to a capable DataType
this->setActualDataType(this->convertToSupportedDataType(COM_DT_COLOR));
#if 0 // XXX TODO check for proxy node and use output data type?
if (this->getGroupOutputSocket()) {
if (!this->isInsideOfGroupNode()) {
this->getGroupOutputSocket()->determineActualDataType();
}
}
#endif
}
void InputSocket::notifyActualInputType(DataType datatype) {
DataType supportedDataType = convertToSupportedDataType(datatype);
this->setActualDataType(supportedDataType);
this->fireActualDataTypeSet();
}
void InputSocket::fireActualDataTypeSet() {
this->getNode()->notifyActualDataTypeSet(this, this->getActualDataType());
}
void InputSocket::relinkConnections(InputSocket *relinkToSocket) {
this->relinkConnections(relinkToSocket, false, -1, NULL);
}
void InputSocket::relinkConnections(InputSocket *relinkToSocket, bool autoconnect, int editorNodeInputSocketIndex, bool duplicate, ExecutionSystem* graph) {
if (!duplicate) {
this->relinkConnections(relinkToSocket, autoconnect, editorNodeInputSocketIndex, graph);
} else {
if (!this->isConnected() && autoconnect) {
Node* node = (Node*)this->getNode();
switch (this->getActualDataType()) {
case COM_DT_UNKNOWN:
case COM_DT_COLOR:
node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
break;
case COM_DT_VECTOR:
node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
break;
case COM_DT_VALUE:
node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
break;
}
return;
}
SocketConnection * newConnection = new SocketConnection();
OutputSocket * fromSocket = this->getConnection()->getFromSocket();
newConnection->setToSocket(relinkToSocket);
newConnection->setFromSocket(fromSocket);
relinkToSocket->setConnection(newConnection);
fromSocket->addConnection(newConnection);
graph->addSocketConnection(newConnection);
}
}
void InputSocket::relinkConnections(InputSocket *relinkToSocket, bool autoconnect, int editorNodeInputSocketIndex, ExecutionSystem* graph) {
if (!isConnected()) {
if (autoconnect) {
Node* node = (Node*)this->getNode();
switch (this->getActualDataType()) {
case COM_DT_UNKNOWN:
case COM_DT_COLOR:
node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
break;
case COM_DT_VECTOR:
node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
break;
case COM_DT_VALUE:
node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
break;
}
}
return;
}
SocketConnection *connection = this->getConnection();
connection->setToSocket(relinkToSocket);
relinkToSocket->setConnection(connection);
this->setConnection(NULL);
}
const ChannelInfo* InputSocket::getChannelInfo(const int channelnumber) {
if (this->isConnected() && this->connection->getFromSocket()) {
return this->connection->getFromSocket()->getChannelInfo(channelnumber);
} else {
return NULL;
}
}
bool InputSocket::isStatic() {
if (isConnected()) {
NodeBase* node = this->getConnection()->getFromNode();
if (node) {
return node->isStatic();
}
}
return true;
}
SocketReader* InputSocket::getReader() {
return this->getOperation();
}
NodeOperation* InputSocket::getOperation() const {
if (isConnected()) {
return (NodeOperation*)this->connection->getFromSocket()->getNode();
} else {
return NULL;
}
}
float* InputSocket::getStaticValues() {
/* XXX only works for socket types with actual float input values.
* currently all compositor socket types (value, rgba, vector) support this.
*/
bNodeSocket *b_socket = this->getbNodeSocket();
static float default_null = 0.0f;
switch (this->getDataType()) {
case COM_DT_VALUE:
return &((bNodeSocketValueFloat*)b_socket->default_value)->value;
case COM_DT_COLOR:
return ((bNodeSocketValueRGBA*)b_socket->default_value)->value;
case COM_DT_VECTOR:
return ((bNodeSocketValueVector*)b_socket->default_value)->value;
default:
/* XXX this should never happen, just added to please the compiler */
return &default_null;
}
}

View File

@ -0,0 +1,162 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_InputSocket_h
#define _COM_InputSocket_h
#include <vector>
#include "COM_Socket.h"
#include "COM_SocketReader.h"
using namespace std;
class SocketConnection;
class Node;
class ExecutionSystem;
class OutputSocket;
class ChannelInfo;
class NodeOperation;
/**
* @brief Resize modes of inputsockets
* How are the input and working resolutions matched
* @ingroup Model
*/
typedef enum InputSocketResizeMode {
/** @brief Center the input image to the center of the working area of the node, no resizing occurs */
COM_SC_CENTER = NS_CR_CENTER,
/** @brief The bottom left of the input image is the bottom left of the working area of the node, no resizing occurs */
COM_SC_NO_RESIZE = NS_CR_NONE,
/** @brief Fit the width of the input image to the width of the working area of the node */
COM_SC_FIT_WIDTH = NS_CR_FIT_WIDTH,
/** @brief Fit the height of the input image to the height of the working area of the node */
COM_SC_FIT_HEIGHT = NS_CR_FIT_HEIGHT,
/** @brief Fit the width or the height of the input image to the width or height of the working area of the node, image will be larger than the working area */
COM_SC_FIT = NS_CR_FIT,
/** @brief Fit the width and the height of the input image to the width and height of the working area of the node, image will be equally larger than the working area */
COM_SC_STRETCH = NS_CR_STRETCH
} InputSocketResizeMode;
/**
* @brief InputSocket are sockets that can receive data/input
* @ingroup Model
*/
class InputSocket : public Socket {
private:
/**
* @brief connection connected to this InputSocket.
* An input socket can only have a single connection
*/
SocketConnection* connection;
/**
* @brief resize mode of this socket
*/
InputSocketResizeMode resizeMode;
/**
* @brief convert a data type to a by the socket supported data type.
*
* @param datatype the datatype that needs to be checked
* @section data-conversion
*/
DataType convertToSupportedDataType(DataType datatype);
/**
* @brief called when the ActualDataType is set. notifies other parties
*/
void fireActualDataTypeSet();
public:
InputSocket(DataType datatype);
InputSocket(DataType datatype, InputSocketResizeMode resizeMode);
InputSocket(InputSocket* from);
void setConnection(SocketConnection* connection);
SocketConnection* getConnection();
const int isConnected() const;
int isInputSocket() const;
/**
* @brief determine the resolution of this data going through this socket
* @param resolution the result of this operation
* @param preferredResolution the preferrable resolution as no resolution could be determined
*/
void determineResolution(unsigned int resolution[],unsigned int preferredResolution[]);
void determineActualDataType();
/**
* @brief Notifies the Input of the data type (via a SocketConnection)
* @param datatype the datatype to evaluate
*/
void notifyActualInputType(DataType datatype);
/**
* @brief move all connections of this input socket to another socket
* only use this method when already checked the availability of a SocketConnection
* @param relinkToSocket the socket to move to connections to
*/
void relinkConnections(InputSocket *relinkToSocket);
/**
* @brief move all connections of this input socket to another socket
* @param relinkToSocket the socket to move to connections to
* @param autoconnect will a set operation be added when no connections exist
* @param editorNodeInputSocketIndex index of the socket number of the bNode (used to retrieve the value for autoconnection)
* @param system ExecutionSystem to update to
*/
void relinkConnections(InputSocket *relinkToSocket, bool autoconnect, int editorNodeInputSocketIndex, ExecutionSystem* system);
/**
* @brief move all connections of this input socket to another socket
* @param relinkToSocket the socket to move to connections to
* @param autoconnect will a set operation be added when no connections exist
* @param editorNodeInputSocketIndex index of the socket number of the bNode (used to retrieve the value for autoconnection)
* @param duplicate instead of move do a copy of the connection.
* @param system ExecutionSystem to update to
*/
void relinkConnections(InputSocket *relinkToSocket, bool autoconnect, int editorNodeInputSocketIndex, bool duplicate, ExecutionSystem* system);
/**
* @brief set the resize mode
* @param resizeMode the new resize mode.
*/
void setResizeMode(InputSocketResizeMode resizeMode) {this->resizeMode = resizeMode;}
/**
* @brief get the resize mode of this socket
* @return InputSocketResizeMode
*/
InputSocketResizeMode getResizeMode() const {return this->resizeMode;}
const ChannelInfo* getChannelInfo(const int channelnumber);
bool isStatic();
float* getStaticValues();
SocketReader* getReader();
NodeOperation* getOperation() const;
};
#endif

View File

@ -0,0 +1,338 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_MemoryBuffer.h"
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BKE_global.h"
unsigned int MemoryBuffer::determineBufferSize() {
return getWidth() * getHeight();
}
int MemoryBuffer::getWidth() const {
return this->rect.xmax-this->rect.xmin;
}
int MemoryBuffer::getHeight() const {
return this->rect.ymax-this->rect.ymin;
}
MemoryBuffer::MemoryBuffer(MemoryProxy * memoryProxy, unsigned int chunkNumber, rcti* rect) {
BLI_init_rcti(&this->rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->memoryProxy = memoryProxy;
this->chunkNumber = chunkNumber;
this->buffer = (float*)MEM_mallocN(sizeof(float)*determineBufferSize()*4, "COM_MemoryBuffer");
this->state = COM_MB_ALLOCATED;
this->datatype = COM_DT_COLOR;
this->chunkWidth = this->rect.xmax - this->rect.xmin;
}
MemoryBuffer::MemoryBuffer(MemoryProxy * memoryProxy, rcti* rect) {
BLI_init_rcti(&this->rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->memoryProxy = memoryProxy;
this->chunkNumber = -1;
this->buffer = (float*)MEM_mallocN(sizeof(float)*determineBufferSize()*4, "COM_MemoryBuffer");
this->state = COM_MB_TEMPORARILY;
this->datatype = COM_DT_COLOR;
this->chunkWidth = this->rect.xmax - this->rect.xmin;
}
MemoryBuffer* MemoryBuffer::duplicate() {
MemoryBuffer *result = new MemoryBuffer(this->memoryProxy, &this->rect);
memcpy(result->buffer, this->buffer, this->determineBufferSize()*4*sizeof(float));
return result;
}
void MemoryBuffer::clear() {
memset(this->buffer, 0, this->determineBufferSize()*4*sizeof(float));
}
float* MemoryBuffer::convertToValueBuffer() {
int size = this->determineBufferSize();
int i;
int offset4;
float* result = new float[size];
for (i = 0, offset4 = 0 ; i < size ; i ++, offset4 +=4) {
result[i] = this->buffer[offset4];
}
return result;
}
MemoryBuffer::~MemoryBuffer() {
if (this->buffer) {
MEM_freeN(this->buffer);
this->buffer = NULL;
}
}
void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer) {
if (!otherBuffer) {
return;
}
unsigned int otherY;
unsigned int minX = max(this->rect.xmin, otherBuffer->rect.xmin);
unsigned int maxX = min(this->rect.xmax, otherBuffer->rect.xmax);
unsigned int minY = max(this->rect.ymin, otherBuffer->rect.ymin);
unsigned int maxY = min(this->rect.ymax, otherBuffer->rect.ymax);
int offset;
int otherOffset;
for (otherY = minY ; otherY<maxY ; otherY ++) {
otherOffset = ((otherY-otherBuffer->rect.ymin) * otherBuffer->chunkWidth + minX-otherBuffer->rect.xmin)*4;
offset = ((otherY - this->rect.ymin) * this->chunkWidth + minX-this->rect.xmin)*4;
memcpy(&this->buffer[offset], &otherBuffer->buffer[otherOffset], (maxX-minX) * 4*sizeof(float));
}
}
void MemoryBuffer::read(float* result, int x, int y) {
if (x>=this->rect.xmin && x < this->rect.xmax &&
y>=this->rect.ymin && y < this->rect.ymax) {
int dx = x-this->rect.xmin;
int dy = y-this->rect.ymin;
int offset = (this->chunkWidth*dy+dx)*4;
result[0] = this->buffer[offset];
result[1] = this->buffer[offset+1];
result[2] = this->buffer[offset+2];
result[3] = this->buffer[offset+3];
}
else {
result[0] = 0.0f;
result[1] = 0.0f;
result[2] = 0.0f;
result[3] = 0.0f;
}
}
void MemoryBuffer::writePixel(int x, int y, float color[4]) {
if (x>=this->rect.xmin && x < this->rect.xmax &&
y>=this->rect.ymin && y < this->rect.ymax) {
int offset = (this->chunkWidth*y+x)*4;
this->buffer[offset] = color[0];
this->buffer[offset+1] = color[1];
this->buffer[offset+2] = color[2];
this->buffer[offset+3] = color[3];
}
}
void MemoryBuffer::readCubic(float* result, float x, float y) {
int x1 = floor(x);
int x2 = x1 + 1;
int y1 = floor(y);
int y2 = y1 + 1;
float valuex = x - x1;
float valuey = y - y1;
float mvaluex = 1.0 - valuex;
float mvaluey = 1.0 - valuey;
float color1[4];
float color2[4];
float color3[4];
float color4[4];
read(color1, x1, y1);
read(color2, x1, y2);
read(color3, x2, y1);
read(color4, x2, y2);
color1[0] = color1[0]*mvaluey + color2[0]*valuey;
color1[1] = color1[1]*mvaluey + color2[1]*valuey;
color1[2] = color1[2]*mvaluey + color2[2]*valuey;
color1[3] = color1[3]*mvaluey + color2[3]*valuey;
color3[0] = color3[0]*mvaluey + color4[0]*valuey;
color3[1] = color3[1]*mvaluey + color4[1]*valuey;
color3[2] = color3[2]*mvaluey + color4[2]*valuey;
color3[3] = color3[3]*mvaluey + color4[3]*valuey;
result[0] = color1[0]*mvaluex + color3[0]*valuex;
result[1] = color1[1]*mvaluex + color3[1]*valuex;
result[2] = color1[2]*mvaluex + color3[2]*valuex;
result[3] = color1[3]*mvaluex + color3[3]*valuex;
}
// table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
// used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible
#define EWA_MAXIDX 255
static float EWA_WTS[EWA_MAXIDX + 1] =
{ 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f
};
static void radangle2imp(float a2, float b2, float th, float* A, float* B, float* C, float* F)
{
float ct2 = cosf(th);
const float st2 = 1.f - ct2*ct2; // <- sin(th)^2
ct2 *= ct2;
*A = a2*st2 + b2*ct2;
*B = (b2 - a2)*sinf(2.f*th);
*C = a2*ct2 + b2*st2;
*F = a2*b2;
}
// all tests here are done to make sure possible overflows are hopefully minimized
static void imp2radangle(float A, float B, float C, float F, float* a, float* b, float* th, float* ecc)
{
if (F <= 1e-5f) { // use arbitrary major radius, zero minor, infinite eccentricity
*a = sqrtf(A > C ? A : C);
*b = 0.f;
*ecc = 1e10f;
*th = 0.5f*(atan2f(B, A - C) + (float)M_PI);
}
else {
const float AmC = A - C, ApC = A + C, F2 = F*2.f;
const float r = sqrtf(AmC*AmC + B*B);
float d = ApC - r;
*a = (d <= 0.f) ? sqrtf(A > C ? A : C) : sqrtf(F2 / d);
d = ApC + r;
if (d <= 0.f) {
*b = 0.f;
*ecc = 1e10f;
}
else {
*b = sqrtf(F2 / d);
*ecc = *a / *b;
}
// incr theta by 0.5*pi (angle of major axis)
*th = 0.5f*(atan2f(B, AmC) + (float)M_PI);
}
}
float clipuv(float x, float limit){
x = (x < 0) ? 0 : ((x >= limit) ? (limit - 1) : x);
return x;
}
void MemoryBuffer::readEWA(float* result, float fx, float fy, float dx, float dy) {
int width = this->getWidth(), height = this->getHeight();
// scaling dxt/dyt by full resolution can cause overflow because of huge A/B/C and esp. F values,
// scaling by aspect ratio alone does the opposite, so try something in between instead...
const float ff2 = width, ff = sqrtf(ff2), q = height / ff;
const float Ux = dx*ff, Vx = dx*q, Uy = dy*ff, Vy = dy*q;
float A = Vx*Vx + Vy*Vy;
float B = -2.f*(Ux*Vx + Uy*Vy);
float C = Ux*Ux + Uy*Uy;
float F = A*C - B*B*0.25f;
float a, b, th, ecc, a2, b2, ue, ve, U0, V0, DDQ, U, ac1, ac2, BU, d;
int u, v, u1, u2, v1, v2;
// The so-called 'high' quality ewa method simply adds a constant of 1 to both A & C,
// so the ellipse always covers at least some texels. But since the filter is now always larger,
// it also means that everywhere else it's also more blurry then ideally should be the case.
// So instead here the ellipse radii are modified instead whenever either is too low.
// Use a different radius based on interpolation switch, just enough to anti-alias when interpolation is off,
// and slightly larger to make result a bit smoother than bilinear interpolation when interpolation is on
// (minimum values: const float rmin = intpol ? 1.f : 0.5f;)
const float rmin = 1.5625f/ff2;
imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
if ((b2 = b*b) < rmin) {
if ((a2 = a*a) < rmin) {
B = 0.f;
A = C = rmin;
F = A*C;
}
else {
b2 = rmin;
radangle2imp(a2, b2, th, &A, &B, &C, &F);
}
}
ue = ff*sqrtf(C);
ve = ff*sqrtf(A);
d = (float)(EWA_MAXIDX + 1) / (F*ff2);
A *= d;
B *= d;
C *= d;
U0 = fx;
V0 = fy;
u1 = (int)(floorf(U0 - ue));
u2 = (int)(ceilf(U0 + ue));
v1 = (int)(floorf(V0 - ve));
v2 = (int)(ceilf(V0 + ve));
U0 -= 0.5f;
V0 -= 0.5f;
DDQ = 2.f*A;
U = u1 - U0;
ac1 = A*(2.f*U + 1.f);
ac2 = A*U*U;
BU = B*U;
d = result[0] = result[1] = result[2] = result[3] = 0.f;
for (v=v1; v<=v2; ++v) {
const float V = v - V0;
float DQ = ac1 + B*V;
float Q = (C*V + BU)*V + ac2;
for (u=u1; u<=u2; ++u) {
if (Q < (float)(EWA_MAXIDX + 1)) {
float tc[4];
const float wt = EWA_WTS[(Q < 0.f) ? 0 : (unsigned int)Q];
read(tc, clipuv(u, width), clipuv(v, height));
result[0] += tc[0]*wt;
result[1] += tc[1]*wt;
result[2] += tc[2]*wt;
result[3] += result[3] ? tc[3]*wt : 0.f;
d += wt;
}
Q += DQ;
DQ += DDQ;
}
}
// d should hopefully never be zero anymore
d = 1.f/d;
result[0] *= d;
result[1] *= d;
result[2] *= d;
// clipping can be ignored if alpha used, texr->ta already includes filtered edge
result[3] = result[3] ? result[3] *d : 1.f;
}

View File

@ -0,0 +1,170 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
class MemoryBuffer;
#ifndef _COM_MemoryBuffer_h_
#define _COM_MemoryBuffer_h_
#include "COM_ExecutionGroup.h"
#include "BLI_rect.h"
#include "COM_MemoryProxy.h"
extern "C" {
#include "BLI_threads.h"
}
#include <vector>
/**
* @brief state of a memory buffer
* @ingroup Memory
*/
typedef enum MemoryBufferState {
/** @brief memory has been allocated on creator device and CPU machine, but kernel has not been executed */
COM_MB_ALLOCATED = 1,
/** @brief memory is available for use, content has been created */
COM_MB_AVAILABLE = 2,
/** @brief chunk is consolidated from other chunks. special state.*/
COM_MB_TEMPORARILY = 6
} MemoryBufferState;
class MemoryProxy;
/**
* @brief a MemoryBuffer contains access to the data of a chunk
*/
class MemoryBuffer {
private:
/**
* @brief proxy of the memory (same for all chunks in the same buffer)
*/
MemoryProxy * memoryProxy;
/**
* @brief the type of buffer COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR
*/
DataType datatype;
/**
* @brief region of this buffer inside reative to the MemoryProxy
*/
rcti rect;
/**
* brief refers to the chunknumber within the executiongroup where related to the MemoryProxy
* @see memoryProxy
*/
unsigned int chunkNumber;
/**
* @brief width of the chunk
*/
unsigned int chunkWidth;
/**
* @brief state of the buffer
*/
MemoryBufferState state;
/**
* @brief the actual float buffer/data
*/
float* buffer;
public:
/**
* @brief construct new MemoryBuffer for a chunk
*/
MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti* rect);
/**
* @brief construct new temporarily MemoryBuffer for an area
*/
MemoryBuffer(MemoryProxy *memoryProxy, rcti* rect);
/**
* @brief destructor
*/
~MemoryBuffer();
/**
* @brief read the ChunkNumber of this MemoryBuffer
*/
unsigned int getChunkNumber() {return this->chunkNumber;}
/**
* @brief get the data of this MemoryBuffer
* @note buffer should already be available in memory
*/
float* getBuffer() {return this->buffer;}
/**
* @brief after execution the state will be set to available by calling this method
*/
void setCreatedState() {
this->state = COM_MB_AVAILABLE;
}
void read(float* result, int x, int y);
void writePixel(int x, int y, float color[4]);
void readCubic(float* result, float x, float y);
void readEWA(float *result, float fx, float fy, float dx, float dy);
/**
* @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk)
*/
inline const bool isTemporarily() const {return this->state == COM_MB_TEMPORARILY;}
/**
* @brief add the content from otherBuffer to this MemoryBuffer
* @param otherBuffer source buffer
*/
void copyContentFrom(MemoryBuffer* otherBuffer);
/**
* @brief get the rect of this MemoryBuffer
*/
rcti* getRect() {return &this->rect;}
/**
* @brief get the width of this MemoryBuffer
*/
int getWidth() const;
/**
* @brief get the height of this MemoryBuffer
*/
int getHeight() const;
/**
* @brief clear the buffer. Make all pixels black transparant.
*/
void clear();
MemoryBuffer* duplicate();
float* convertToValueBuffer();
private:
unsigned int determineBufferSize();
};
#endif

View File

@ -0,0 +1,68 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_MemoryManager.h"
#include "BLI_threads.h"
#include <stdio.h>
#include "COM_defines.h"
vector<MemoryBuffer*> buffers;
ThreadMutex mutex;
MemoryBuffer* MemoryManager::allocateMemoryBuffer(MemoryProxy *id, unsigned int chunkNumber, rcti *rect) {
MemoryBuffer *result = new MemoryBuffer(id, chunkNumber, rect);
MemoryManagerState * state = MemoryManager::getState(id);
state->addMemoryBuffer(result);
BLI_mutex_lock(&mutex);
buffers.push_back(result);
BLI_mutex_unlock(&mutex);
return result;
}
void MemoryManager::addMemoryProxy(MemoryProxy *memoryProxy) {
MemoryManagerState * state = MemoryManager::getState(memoryProxy);
if (!state) {
state = new MemoryManagerState(memoryProxy);
memoryProxy->setState(state);
}
}
MemoryBuffer* MemoryManager::getMemoryBuffer(MemoryProxy *id, unsigned int chunkNumber){
MemoryManagerState * state = MemoryManager::getState(id);
if (!state) {
return NULL;
}
MemoryBuffer* buffer = state->getMemoryBuffer(chunkNumber);
if (!buffer) return NULL;
return buffer;
}
MemoryManagerState* MemoryManager::getState(MemoryProxy* memoryProxy) {
return memoryProxy->getState();
}
void MemoryManager::initialize() {
BLI_mutex_init(&mutex);
}
void MemoryManager::clear() {
buffers.clear();
BLI_mutex_end(&mutex);
}

View File

@ -0,0 +1,146 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_MemoryManager_h_
#define _COM_MemoryManager_h_
#include "COM_MemoryBuffer.h"
#include "COM_MemoryProxy.h"
#include "COM_ExecutionGroup.h"
#include "COM_MemoryManagerState.h"
/**
* @page memorymanager The Memory Manager
* The compositor has its own MemoryManager. The goal of the MemoryManager is to manage the memory allocated by chunks.
* During execution new chunks will be created [MemoryManager.allocateMemoryBuffer] When calculation is finished the MemoryBuffer will get the state [MemoryBufferState.COM_MB_AVAILABLE].
* From now on other ExecutionGroup and NodeOperations may read from the MemoryBuffer.
* The MemoryManager also has the capability to save MemoryBuffer's to disk in order to free some memory.
*
* @section S_MEM Memory manager
* The memory manager synchronize and optimize data across devices.
* Only one NodeOperation running on a device is able to write to a MemoryBuffer. This MemoryBuffer is only allocated on the main-device memory (CPU).
* The MemoryBuffer.state will be [MemoryBufferState.COM_MB_ALLOCATED]. As soon as the chunk has been executed the state changes to [MemoryBufferState.COM_MB_AVAILABLE]. This MemoryBuffer can now be used as inputBuffer of ExecutionGroup's.
* When needed the MemoryBuffer will be stored to a file. This will save memory that can be used by other tiles.
* @subsection S_MEM_1 Step one
* When a chunk of an ExecutionGroup is being executed by a device, the MemoryBuffer is allocated on the CPU.
* <pre>
* Allocation of the output MemoryBuffer
* +----------------------------------------+
* | Main device (CPU) |
* | +----------------+ +--------------+ |
* | | ExecutionGroup | | MemoryBuffer | |
* | | | | Chunk a | |
* | +----------------+ +--------------+ |
* | |
* +----------------------------------------+
* </pre>
* @see MemoryManager.allocateMemoryBuffer
*
* @subsection S_MEM_2 Step two
* The Device will execute the ExecutionGroup. This differs per type of Device. CPUDevice will call the NodeOperation.executeRegion method of the outputnode of the ExecutionGroup.
* The [NodeOperation.executeRegion] writes the result to the allocated MemoryBuffer. When finished the state of the MemoryBuffer will be set to [MemoryBufferState.COM_MB_AVAILABLE].
* <pre>
* Execute a chunk and store result to the MemoryBuffer
* +----------------------------------------+
* | Main device (CPU) |
* | +----------------+ +--------------+ |
* | | ExecutionGroup | | MemoryBuffer | |
* | | | | Chunk a | |
* | +----------------+ +--------------+ |
* | | ^ |
* | +----------------+ | |
* | | NodeOperation |--------+ |
* | | | Write result |
* | +----------------+ |
* | |
* +----------------------------------------+
* </pre>
* @subsection S_MEM_3 Step 3
* Other Chunks that depend on the MemoryBuffer can now use it.
* When a MemoryBuffer is being used its number of users are increased. When a 'user' is finished the number of users are decreased, If a MemoryBuffer has no users, the system can decide to store the data to disk and free some memory.
* @see MemoryBuffer.numberOfUsers
* @see MemoryBuffer.saveToDisk
*
* @subsection S_MEM_CON Temporarily MemoryBuffers
* Nodes like blur nodes can depend on multiple MemoryBuffer of the same MemoryProxy. These multiple buffers will be consolidated temporarily to a new MemoryBuffer.
* When execution is finished this temporarily memory buffer is deallicated.
* <pre>
* Original MemoryBuffer's Temporarily
* +-------+ +-------+ MemoryBuffer
* | MB A | | MB B | +-------+-------+
* +-------+ +-------+ | MB A | MB B |
* ==> +-------+-------+
* +-------+ +-------+ | MB C | MB D |
* | MB C | | MB D | +-------+-------+
* +-------+ +-------+
* </pre>
* @see ExecutionGroup.constructConsolidatedMemoryBuffer constructs the temporarily MemoryBuffer
* @see MemoryBuffer.state state is MemoryManagerState.COM_MB_TEMPORARILY
* @see ExecutionGroup.finalizeChunkExecution deallocate the temporarily MemoryBuffer
* @note this MemoryBuffer is not managed by the MemoryManager
*/
/**
* @brief the memory manager for the compostor
* @ingroup Memory
*/
class MemoryManager {
private:
/**
* @brief retrieve the state of a certain MemoryProxy;
* @param memoryProxy the MemoryProxy to retrieve the state from
*/
static MemoryManagerState* getState(MemoryProxy* memoryProxy);
public:
/**
* @brief allocate a memory buffer
* @param memoryProxy the MemoryProxy to get a chunk from
* @param chunkNumber number of the chunk to receive
* @param rect size + position of the chunk
*/
static MemoryBuffer* allocateMemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti* rect);
/**
* @brief get a memory buffer
* @param memoryProxy the MemoryProxy to get a chunk from
* @param chunkNumber number of the chunk to receive
* @param addUser must we add a user to the chunk.
*/
static MemoryBuffer* getMemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber);
/**
* @brief add a MemoryProxy to the scope of the memory manager
* @param memoryProxy the MemoryProxy to add
*/
static void addMemoryProxy(MemoryProxy *memoryProxy);
/**
* @brief clear the memory manager
*/
static void clear();
/**
* @brief initialize the memory manager.
*/
static void initialize();
};
#endif

View File

@ -0,0 +1,94 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_MemoryManagerState.h"
MemoryManagerState::MemoryManagerState(MemoryProxy *memoryProxy) {
this->memoryProxy = memoryProxy;
this->currentSize = 0;
this->chunkBuffers = NULL;
BLI_mutex_init(&this->mutex);
}
MemoryProxy * MemoryManagerState::getMemoryProxy() {
return this->memoryProxy;
}
MemoryManagerState::~MemoryManagerState() {
this->memoryProxy = NULL;
unsigned int index;
for (index = 0 ; index < this->currentSize; index ++){
MemoryBuffer* buffer = this->chunkBuffers[index];
if (buffer) {
delete buffer;
}
}
delete this->chunkBuffers;
BLI_mutex_end(&this->mutex);
}
void MemoryManagerState::addMemoryBuffer(MemoryBuffer *buffer) {
BLI_mutex_lock(&this->mutex);
unsigned int chunkNumber = buffer->getChunkNumber();
unsigned int index;
while (this->currentSize <= chunkNumber) {
unsigned int newSize = this->currentSize + 1000;
MemoryBuffer** newbuffer = new MemoryBuffer*[newSize];
MemoryBuffer** oldbuffer = this->chunkBuffers;
for (index = 0 ; index < this->currentSize ; index++) {
newbuffer[index] = oldbuffer[index];
}
for (index = currentSize ; index < newSize; index++) {
newbuffer[index] = NULL;
}
this->chunkBuffers = newbuffer;
this->currentSize = newSize;
if (oldbuffer) delete oldbuffer;
}
if (this->chunkBuffers[chunkNumber] == NULL) {
this->chunkBuffers[chunkNumber] = buffer;
} else {
throw "ALREADY ALLOCATED!";
}
BLI_mutex_unlock(&this->mutex);
}
MemoryBuffer* MemoryManagerState::getMemoryBuffer(unsigned int chunkNumber) {
MemoryBuffer* result = NULL;
if (chunkNumber< this->currentSize){
result = this->chunkBuffers[chunkNumber];
if (result) {
return result;
}
}
BLI_mutex_lock(&this->mutex);
if (chunkNumber< this->currentSize){
result = this->chunkBuffers[chunkNumber];
}
BLI_mutex_unlock(&this->mutex);
return result;
}

View File

@ -0,0 +1,87 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
class MemoryManagerState;
#ifndef _COM_MemoryManagerState_h_
#define _COM_MemoryManagerState_h_
#include "COM_MemoryProxy.h"
#include "COM_MemoryBuffer.h"
#include <vector>
extern "C" {
#include "BLI_threads.h"
}
/**
* @brief State of a MemoryProxy in the MemoryManager.
* @ingroup Memory
*/
class MemoryManagerState {
private:
/**
* @brief reference to the MemoryProxy of this state
*/
MemoryProxy *memoryProxy;
/**
* @brief list of all chunkbuffers
*/
MemoryBuffer** chunkBuffers;
/**
* @brief size of the chunkBuffers
*/
unsigned int currentSize;
/**
* @brief lock to this memory for multithreading
*/
ThreadMutex mutex;
public:
/**
* @brief creates a new MemoryManagerState for a certain MemoryProxy.
*/
MemoryManagerState(MemoryProxy * memoryProxy);
/**
* @brief destructor
*/
~MemoryManagerState();
/**
* @brief get the reference to the MemoryProxy this state belongs to.
*/
MemoryProxy *getMemoryProxy();
/**
* @brief add a new memorybuffer to the state
*/
void addMemoryBuffer(MemoryBuffer* buffer);
/**
* @brief get the MemoryBuffer assiciated to a chunk.
* @param chunkNumber the chunknumber
*/
MemoryBuffer* getMemoryBuffer(unsigned int chunkNumber);
};
#endif

View File

@ -0,0 +1,37 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_MemoryProxy.h"
MemoryProxy::MemoryProxy() {
this->state = NULL;
this->writeBufferOperation = NULL;
this->executor = NULL;
}
MemoryProxy::~MemoryProxy() {
if (this->state) {
delete this->state;
this->state = NULL;
}
}

View File

@ -0,0 +1,106 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
class MemoryProxy;
#ifndef _COM_MemoryProxy_h
#define _COM_MemoryProxy_h
#include "COM_ExecutionGroup.h"
#include "COM_MemoryManagerState.h"
class ExecutionGroup;
/**
* @brief A MemoryProxy is a unique identifier for a memory buffer.
* A single MemoryProxy is used among all chunks of the same buffer,
* the MemoryBuffer only stores the data of a single chunk.
* @ingroup Memory
*/
class MemoryProxy {
private:
/**
* @brief reference to the ouput operation of the executiongroup
*/
WriteBufferOperation *writeBufferOperation;
/**
* @brief reference to the executor. the Execution group that can fill a chunk
*/
ExecutionGroup *executor;
/**
* @brief data of the different chunks.
* @note state is part of this class due to optimization in the MemoryManager
*/
MemoryManagerState * state;
/**
* @brief datatype of this MemoryProxy
*/
DataType datatype;
/**
* @brief channel information of this buffer
*/
ChannelInfo channelInfo[COM_NUMBER_OF_CHANNELS];
public:
MemoryProxy();
~MemoryProxy();
/**
* @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk.
* @param group the ExecutionGroup to set
*/
void setExecutor(ExecutionGroup *executor) {this->executor = executor;}
/**
* @brief get the ExecutionGroup that can be scheduled to calculate a certain chunk.
*/
ExecutionGroup* getExecutor() {return this->executor;}
/**
* @brief set the WriteBufferOperation that is responsible for writing to this MemoryProxy
* @param operation
*/
void setWriteBufferOperation(WriteBufferOperation* operation) {this->writeBufferOperation = operation;}
/**
* @brief get the WriteBufferOperation that is responsible for writing to this MemoryProxy
* @return WriteBufferOperation
*/
WriteBufferOperation* getWriteBufferOperation() {return this->writeBufferOperation;}
/**
* @brief set the memorymanager state of this MemoryProxy, this is set from the MemoryManager
* @param state the state to set
*/
void setState(MemoryManagerState *state) {this->state = state;}
/**
* @brief get the state of this MemoryProxy
* @return MemoryManagerState reference to the state of this MemoryProxy.
*/
MemoryManagerState* getState() {return this->state;}
};
#endif

View File

@ -0,0 +1,182 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_Node.h"
#include "string.h"
#include "COM_NodeOperation.h"
#include "BKE_node.h"
#include "COM_SetValueOperation.h"
#include "COM_SetVectorOperation.h"
#include "COM_SetColorOperation.h"
#include "COM_SocketConnection.h"
#include "COM_ExecutionSystem.h"
#include "COM_PreviewOperation.h"
#include "COM_TranslateOperation.h"
#include "COM_SocketProxyNode.h"
//#include "stdio.h"
#include "COM_defines.h"
Node::Node(bNode* editorNode, bool create_sockets) {
this->editorNode = editorNode;
if (create_sockets) {
bNodeSocket * input = (bNodeSocket*)editorNode->inputs.first;
while (input != NULL) {
DataType dt = COM_DT_VALUE;
if (input->type == SOCK_RGBA) dt = COM_DT_COLOR;
if (input->type == SOCK_VECTOR) dt = COM_DT_VECTOR;
this->addInputSocket(dt, (InputSocketResizeMode)input->resizemode, input);
input = (bNodeSocket*)input->next;
}
bNodeSocket *output = (bNodeSocket*)editorNode->outputs.first;
while(output != NULL) {
DataType dt = COM_DT_VALUE;
if (output->type == SOCK_RGBA) dt = COM_DT_COLOR;
if (output->type == SOCK_VECTOR) dt = COM_DT_VECTOR;
this->addOutputSocket(dt, output);
output = (bNodeSocket*)output->next;
}
}
}
Node::Node() {
this->editorNode = NULL;
}
bNode* Node::getbNode() {return this->editorNode;}
void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket* inputsocket, int editorNodeInputSocketIndex) {
bNodeSocket *bSock = (bNodeSocket*)this->getEditorInputSocket(editorNodeInputSocketIndex);
SetValueOperation *operation = new SetValueOperation();
bNodeSocketValueFloat *val = (bNodeSocketValueFloat*)bSock->default_value;
operation->setValue(val->value);
this->addLink(graph, operation->getOutputSocket(), inputsocket);
graph->addOperation(operation);
}
void Node::addPreviewOperation(ExecutionSystem *system, OutputSocket *outputSocket, int priority) {
#ifdef COM_PREVIEW_ENABLED
PreviewOperation *operation = new PreviewOperation();
system->addOperation(operation);
operation->setbNode(this->getbNode());
operation->setbNodeTree(system->getContext().getbNodeTree());
operation->setPriority(priority);
this->addLink(system, outputSocket, operation->getInputSocket(0));
#endif
}
void Node::addPreviewOperation(ExecutionSystem *system, InputSocket *inputSocket, int priority) {
if (inputSocket->isConnected()) {
OutputSocket *outputsocket = inputSocket->getConnection()->getFromSocket();
this->addPreviewOperation(system, outputsocket, priority);
}
}
SocketConnection* Node::addLink(ExecutionSystem *graph, OutputSocket* outputSocket, InputSocket* inputsocket) {
if (inputsocket->isConnected()) {
return NULL;
}
SocketConnection *connection = new SocketConnection();
connection->setFromSocket(outputSocket);
outputSocket->addConnection(connection);
connection->setToSocket(inputsocket);
inputsocket->setConnection(connection);
graph->addSocketConnection(connection);
return connection;
}
void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket* inputsocket, int editorNodeInputSocketIndex) {
bNodeSocket *bSock = (bNodeSocket*)this->getEditorInputSocket(editorNodeInputSocketIndex);
SetColorOperation *operation = new SetColorOperation();
bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA*)bSock->default_value;
operation->setChannel1(val->value[0]);
operation->setChannel2(val->value[1]);
operation->setChannel3(val->value[2]);
operation->setChannel4(val->value[3]);
this->addLink(graph, operation->getOutputSocket(), inputsocket);
graph->addOperation(operation);
}
void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket* inputsocket, int editorNodeInputSocketIndex) {
bNodeSocket *bSock = (bNodeSocket*)this->getEditorInputSocket(editorNodeInputSocketIndex);
bNodeSocketValueVector *val = (bNodeSocketValueVector*)bSock->default_value;
SetVectorOperation *operation = new SetVectorOperation();
operation->setX(val->value[0]);
operation->setY(val->value[1]);
operation->setZ(val->value[2]);
operation->setW(val->value[3]);
this->addLink(graph, operation->getOutputSocket(), inputsocket);
graph->addOperation(operation);
}
bNodeSocket* Node::getEditorInputSocket(int editorNodeInputSocketIndex) {
bNodeSocket *bSock = (bNodeSocket*)this->getbNode()->inputs.first;
int index = 0;
while (bSock != NULL) {
if (index == editorNodeInputSocketIndex) {
return bSock;
}
index++;
bSock = bSock->next;
}
return NULL;
}
bNodeSocket* Node::getEditorOutputSocket(int editorNodeInputSocketIndex) {
bNodeSocket *bSock = (bNodeSocket*)this->getbNode()->outputs.first;
int index = 0;
while (bSock != NULL) {
if (index == editorNodeInputSocketIndex) {
return bSock;
}
index++;
bSock = bSock->next;
}
return NULL;
}
InputSocket* Node::findInputSocketBybNodeSocket(bNodeSocket* socket) {
vector<InputSocket*> &inputsockets = this->getInputSockets();
unsigned int index;
for (index = 0 ; index < inputsockets.size(); index ++) {
InputSocket* input = inputsockets[index];
if (input->getbNodeSocket() == socket) {
return input;
}
}
return NULL;
}
OutputSocket* Node::findOutputSocketBybNodeSocket(bNodeSocket* socket) {
vector<OutputSocket*> &outputsockets = this->getOutputSockets();
unsigned int index;
for (index = 0 ; index < outputsockets.size(); index ++) {
OutputSocket* output = outputsockets[index];
if (output->getbNodeSocket() == socket) {
return output;
}
}
return NULL;
}

View File

@ -0,0 +1,131 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_Node_h
#define _COM_Node_h
#include "COM_NodeBase.h"
#include "COM_InputSocket.h"
#include "COM_OutputSocket.h"
#include "COM_CompositorContext.h"
#include "DNA_node_types.h"
#include "BKE_text.h"
#include <vector>
#include <string>
using namespace std;
class Node;
class NodeOperation;
class ExecutionSystem;
typedef vector<Node*> NodeList;
typedef NodeList::iterator NodeIterator;
typedef pair<NodeIterator, NodeIterator> NodeRange;
/**
* My node documentation.
*/
class Node:public NodeBase {
private:
/**
* @brief stores the reference to the SDNA bNode struct
*/
bNode* editorNode;
public:
Node(bNode* editorNode, bool create_sockets=true);
/**
* @brief get the reference to the SDNA bNode struct
*/
bNode* getbNode();
/**
* @brief convert node to operation
*
* @todo this must be described furter
*
* @param system the ExecutionSystem where the operations need to be added
* @param context reference to the CompositorContext
*/
virtual void convertToOperations(ExecutionSystem* system, CompositorContext * context) =0;
/**
* this method adds a SetValueOperation as input of the input socket.
* This can only be used from the convertToOperation method. all other usages are not allowed
*/
void addSetValueOperation(ExecutionSystem *graph, InputSocket* inputsocket, int editorNodeInputSocketIndex);
/**
* this method adds a SetColorOperation as input of the input socket.
* This can only be used from the convertToOperation method. all other usages are not allowed
*/
void addSetColorOperation(ExecutionSystem *graph, InputSocket* inputsocket, int editorNodeInputSocketIndex);
/**
* this method adds a SetVectorOperation as input of the input socket.
* This can only be used from the convertToOperation method. all other usages are not allowed
*/
void addSetVectorOperation(ExecutionSystem *graph, InputSocket* inputsocket, int editorNodeInputSocketIndex);
/**
* Creates a new link between an outputSocket and inputSocket and registrates the link to the graph
* @return the new created link
*/
SocketConnection* addLink(ExecutionSystem *graph, OutputSocket* outputSocket, InputSocket* inputsocket);
/**
* is this node a group node.
*/
virtual bool isGroupNode() const { return false; }
/**
* is this node a proxy node.
*/
virtual bool isProxyNode() const { return false; }
/**
* @brief find the InputSocket by bNodeSocket
*
* @param socket
*/
InputSocket* findInputSocketBybNodeSocket(bNodeSocket* socket);
/**
* @brief find the OutputSocket by bNodeSocket
*
* @param socket
*/
OutputSocket* findOutputSocketBybNodeSocket(bNodeSocket* socket);
protected:
Node();
void addPreviewOperation(ExecutionSystem *system, InputSocket* inputSocket, int priority);
void addPreviewOperation(ExecutionSystem *system, OutputSocket* inputSocket, int priority);
bNodeSocket* getEditorInputSocket(int editorNodeInputSocketIndex);
bNodeSocket* getEditorOutputSocket(int editorNodeOutputSocketIndex);
private:
};
#endif

View File

@ -0,0 +1,128 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_NodeBase.h"
#include "string.h"
#include "COM_NodeOperation.h"
#include "BKE_node.h"
#include "COM_SetValueOperation.h"
#include "COM_SetColorOperation.h"
#include "COM_SocketConnection.h"
#include "COM_ExecutionSystem.h"
NodeBase::NodeBase() {
}
NodeBase::~NodeBase(){
while (!this->outputsockets.empty()) {
delete (this->outputsockets.back());
this->outputsockets.pop_back();
}
while (!this->inputsockets.empty()) {
delete (this->inputsockets.back());
this->inputsockets.pop_back();
}
}
void NodeBase::addInputSocket(DataType datatype) {
this->addInputSocket(datatype, COM_SC_CENTER, NULL);
}
void NodeBase::addInputSocket(DataType datatype, InputSocketResizeMode resizeMode) {
this->addInputSocket(datatype, resizeMode, NULL);
}
void NodeBase::addInputSocket(DataType datatype, InputSocketResizeMode resizeMode, bNodeSocket* bSocket) {
InputSocket *socket = new InputSocket(datatype, resizeMode);
socket->setEditorSocket(bSocket);
socket->setNode(this);
this->inputsockets.push_back(socket);
}
void NodeBase::addOutputSocket(DataType datatype) {
this->addOutputSocket(datatype, NULL);
}
void NodeBase::addOutputSocket(DataType datatype, bNodeSocket* bSocket) {
OutputSocket *socket = new OutputSocket(datatype);
socket->setEditorSocket(bSocket);
socket->setNode(this);
this->outputsockets.push_back(socket);
}
const bool NodeBase::isInputNode() const {
return this->inputsockets.size() == 0;
}
OutputSocket* NodeBase::getOutputSocket(int index) {
return this->outputsockets[index];
}
InputSocket* NodeBase::getInputSocket(int index) {
return this->inputsockets[index];
}
void NodeBase::determineActualSocketDataTypes() {
unsigned int index;
for (index = 0 ; index < this->outputsockets.size() ; index ++) {
OutputSocket* socket = this->outputsockets[index];
if (socket->getActualDataType() ==COM_DT_UNKNOWN && socket->isConnected()) {
socket->determineActualDataType();
}
}
for (index = 0 ; index < this->inputsockets.size() ; index ++) {
InputSocket* socket = this->inputsockets[index];
if (socket->getActualDataType() ==COM_DT_UNKNOWN) {
socket->determineActualDataType();
}
}
}
DataType NodeBase::determineActualDataType(OutputSocket *outputsocket) {
const int inputIndex = outputsocket->getInputSocketDataTypeDeterminatorIndex();
if (inputIndex != -1) {
return this->getInputSocket(inputIndex)->getActualDataType();
} else {
return outputsocket->getDataType();
}
}
void NodeBase::notifyActualDataTypeSet(InputSocket *socket, DataType actualType) {
unsigned int index;
int socketIndex = -1;
for (index = 0 ; index < this->inputsockets.size() ; index ++) {
if (this->inputsockets[index] == socket) {
socketIndex = (int)index;
break;
}
}
if (socketIndex == -1) return;
for (index = 0 ; index < this->outputsockets.size() ; index ++) {
OutputSocket* socket = this->outputsockets[index];
if (socket->isActualDataTypeDeterminedByInputSocket() &&
socket->getInputSocketDataTypeDeterminatorIndex() == socketIndex) {
socket->setActualDataType(actualType);
socket->fireActualDataType();
}
}
}

View File

@ -0,0 +1,174 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_NodeBase_h
#define _COM_NodeBase_h
#include "COM_InputSocket.h"
#include "COM_OutputSocket.h"
#include "DNA_node_types.h"
#include "BKE_text.h"
#include <vector>
#include <string>
using namespace std;
class NodeOperation;
class ExecutionSystem;
/**
* @brief The NodeBase class is the super-class of all node related objects like @see Node @see NodeOperation
* the reason for the existence of this class is to support graph-nodes when using ExecutionSystem
* the NodeBase also contains the reference to InputSocket and OutputSocket.
* @ingroup Model
*/
class NodeBase {
private:
/**
* @brief the list of actual inputsockets @see InputSocket
*/
vector<InputSocket*> inputsockets;
/**
* @brief the list of actual outputsockets @see OutputSocket
*/
vector<OutputSocket*> outputsockets;
protected:
/**
* @brief get access to the vector of input sockets
*/
inline vector<InputSocket*>& getInputSockets() {return this->inputsockets;}
/**
* @brief get access to the vector of input sockets
*/
inline vector<OutputSocket*>& getOutputSockets() {return this->outputsockets;}
public:
/**
* @brief destructor
* clean up memory related to this NodeBase.
*/
virtual ~NodeBase();
/**
* @brief determine the actual socket data types that will go through the system
*/
virtual void determineActualSocketDataTypes();
/**
* @brief determine the actual socket data types of a specific outputsocket
*
* @param outputsocket
* a reference to the actual outputsocket where the datatype must be determined from
*
* @return
* COM_DT_VALUE if it is a value (1 float buffer)
* COM_DT_COLOR if it is a value (4 float buffer)
* COM_DT_VECTOR if it is a value (3 float buffer)
*/
virtual DataType determineActualDataType(OutputSocket *outputsocket);
/**
* @brief is this node an operation?
* This is true when the instance is of the subclass NodeOperation.
* @return [true:false]
* @see NodeOperation
*/
virtual const int isOperation() const {return false;}
/**
* @brief check if this is an input node
* An input node is a node that only has output sockets and no input sockets
* @return [false..true]
*/
const bool isInputNode() const;
/**
* @brief Return the number of input sockets of this node.
*/
const unsigned int getNumberOfInputSockets() const {return this->inputsockets.size();}
/**
* @brief Return the number of output sockets of this node.
*/
const unsigned int getNumberOfOutputSockets() const {return this->outputsockets.size();}
/**
* after the data has been determined of an outputsocket that has a connection with an inputsocket this method is called on the
* node that contains the inputsocket.
* @param socket
* the reference of the inputsocket where connected data type is found
* @param actualType [COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR]
* the actual data type that is coming from the connected output socket
*/
virtual void notifyActualDataTypeSet(InputSocket* socket, const DataType actualType);
/**
* get the reference to a certain outputsocket
* @param index
* the index of the needed outputsocket
*/
OutputSocket* getOutputSocket(const int index);
/**
* get the reference to the first outputsocket
* @param index
* the index of the needed outputsocket
*/
inline OutputSocket* getOutputSocket() {return getOutputSocket(0);}
/**
* get the reference to a certain inputsocket
* @param index
* the index of the needed inputsocket
*/
InputSocket* getInputSocket(const int index);
virtual bool isStatic() const {return false;}
void getStaticValues(float* result) const {}
protected:
NodeBase();
/**
* @brief add an InputSocket to the collection of inputsockets
* @note may only be called in an constructor
* @param socket the InputSocket to add
*/
void addInputSocket(DataType datatype);
void addInputSocket(DataType datatype, InputSocketResizeMode resizeMode);
void addInputSocket(DataType datatype, InputSocketResizeMode resizeMode, bNodeSocket* socket);
/**
* @brief add an OutputSocket to the collection of outputsockets
* @note may only be called in an constructor
* @param socket the OutputSocket to add
*/
void addOutputSocket(DataType datatype);
void addOutputSocket(DataType datatype, bNodeSocket* socket);
};
#endif

View File

@ -0,0 +1,114 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_NodeOperation.h"
#include <typeinfo>
#include "COM_InputSocket.h"
#include "COM_SocketConnection.h"
#include "COM_defines.h"
#include "stdio.h"
NodeOperation::NodeOperation() {
this->resolutionInputSocketIndex = 0;
this->complex = false;
this->width = 0;
this->height = 0;
this->openCL = false;
}
void NodeOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) {
unsigned int temp[2];
unsigned int temp2[2];
vector<InputSocket*> &inputsockets = this->getInputSockets();
for (unsigned int index = 0 ; index < inputsockets.size();index++) {
InputSocket* inputSocket = inputsockets[index];
if (inputSocket->isConnected()) {
if (index == this->resolutionInputSocketIndex) {
inputSocket->determineResolution(resolution, preferredResolution);
temp2[0] = resolution[0];
temp2[1] = resolution[1];
break;
}
}
}
for (unsigned int index = 0 ; index < inputsockets.size();index++) {
InputSocket* inputSocket = inputsockets[index];
if (inputSocket->isConnected()) {
if (index != resolutionInputSocketIndex) {
inputSocket->determineResolution(temp, temp2);
}
}
}
}
void NodeOperation::setResolutionInputSocketIndex(unsigned int index) {
this->resolutionInputSocketIndex = index;
}
void NodeOperation::initExecution() {
}
void NodeOperation::initMutex() {
BLI_mutex_init(&mutex);
}
void NodeOperation::deinitMutex() {
BLI_mutex_end(&mutex);
}
void NodeOperation::deinitExecution() {
}
SocketReader* NodeOperation::getInputSocketReader(unsigned int inputSocketIndex) {
return this->getInputSocket(inputSocketIndex)->getReader();
}
NodeOperation* NodeOperation::getInputOperation(unsigned int inputSocketIndex) {
return this->getInputSocket(inputSocketIndex)->getOperation();
}
void NodeOperation::getConnectedInputSockets(vector<InputSocket*> *sockets) {
vector<InputSocket*> &inputsockets = this->getInputSockets();
for (vector<InputSocket*>::iterator iterator = inputsockets.begin() ; iterator!= inputsockets.end() ; iterator++) {
InputSocket *socket = *iterator;
if (socket->isConnected()) {
sockets->push_back(socket);
}
}
}
bool NodeOperation::determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti* output) {
if (this->isInputNode()) {
BLI_init_rcti(output, input->xmin, input->xmax, input->ymin, input->ymax);
return false;
} else {
unsigned int index;
vector<InputSocket*> &inputsockets = this->getInputSockets();
for (index = 0 ; index < inputsockets.size() ; index++) {
InputSocket* inputsocket = inputsockets[index];
if (inputsocket->isConnected()) {
NodeOperation* inputoperation = (NodeOperation*)inputsocket->getConnection()->getFromNode();
bool result = inputoperation->determineDependingAreaOfInterest(input, readOperation, output);
if (result) {
return true;
}
}
}
return false;
}
}

View File

@ -0,0 +1,247 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_NodeProgram_h
#define _COM_NodeProgram_h
class NodeOperation;
#include "COM_Node.h"
#include <string>
#include <sstream>
#include "COM_MemoryBuffer.h"
#include "COM_MemoryProxy.h"
#include "COM_SocketReader.h"
#include "OCL_opencl.h"
#include "list"
class ReadBufferOperation;
/**
* @brief NodeOperation are contains calculation logic
*
* Subclasses needs to implement the execution method (defined in SocketReader) to implement logic.
* @ingroup Model
*/
class NodeOperation : public NodeBase, public SocketReader {
private:
/**
* @brief the index of the input socket that will be used to determine the resolution
*/
unsigned int resolutionInputSocketIndex;
/**
* @brief is this operation a complex one.
*
* Complex operations are typically doing many reads to calculate the output of a single pixel.
* Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true.
*/
bool complex;
/**
* @brief can this operation be scheduled on an OpenCL device.
* @note Only applicable if complex is True
*/
bool openCL;
/**
* @brief mutex reference for very special node initializations
* @note only use when you really know what you are doing.
* this mutex is used to share data among chunks in the same operation
* @see TonemapOperation for an example of usage
* @see NodeOperation.initMutex initializes this mutex
* @see NodeOperation.deinitMutex deinitializes this mutex
* @see NodeOperation.getMutex retrieve a pointer to this mutex.
*/
ThreadMutex mutex;
public:
/**
* @brief is this node an operation?
* This is true when the instance is of the subclass NodeOperation.
* @return [true:false]
* @see NodeBase
*/
const int isOperation() const {return true;}
/**
* @brief determine the resolution of this node
* @note this method will not set the resolution, this is the responsibility of the caller
* @param resolution the result of this operation
* @param preferredResolution the preferrable resolution as no resolution could be determined
*/
virtual void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]);
/**
* @brief isOutputOperation determines whether this operation is an output of the ExecutionSystem during rendering or editing.
*
* Default behaviour if not overriden, this operation will not be evaluated as being an output of the ExecutionSystem.
*
* @see ExecutionSystem
* @group check
* @param rendering [true false]
* true: rendering
* false: editing
*
* @return bool the result of this method
*/
virtual bool isOutputOperation(bool rendering) const {return false;}
/**
* isBufferOperation returns if this is an operation that work directly on buffers.
*
* there are only 2 implementation where this is true:
* @see ReadBufferOperation
* @see WriteBufferOperation
* for all other operations this will result in false.
*/
virtual int isBufferOperation() {return false;}
virtual void initExecution();
void initMutex();
/**
* @brief when a chunk is executed by a CPUDevice, this method is called
* @ingroup execution
* @param rect the rectangle of the chunk (location and size)
* @param chunkNumber the chunkNumber to be calculated
* @param memoryBuffers all input MemoryBuffer's needed
*/
virtual void executeRegion(rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers) {}
/**
* @brief when a chunk is executed by an OpenCLDevice, this method is called
* @ingroup execution
* @note this method is only implemented in WriteBufferOperation
* @param context the OpenCL context
* @param program the OpenCL program containing all compositor kernels
* @param queue the OpenCL command queue of the device the chunk is executed on
* @param rect the rectangle of the chunk (location and size)
* @param chunkNumber the chunkNumber to be calculated
* @param memoryBuffers all input MemoryBuffer's needed
*/
virtual void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers) {}
/**
* @brief custom handle to add new tasks to the OpenCL command queue in order to execute a chunk on an GPUDevice
* @ingroup execution
* @param context the OpenCL context
* @param program the OpenCL program containing all compositor kernels
* @param queue the OpenCL command queue of the device the chunk is executed on
* @param outputMemoryBuffer the allocated memory buffer in main CPU memory
* @param clOutputBuffer the allocated memory buffer in OpenCLDevice memory
* @param inputMemoryBuffers all input MemoryBuffer's needed
* @param clMemToCleanUp all created cl_mem references must be added to this list. Framework will clean this after execution
* @param clKernelsToCleanUp all created cl_kernel references must be added to this list. Framework will clean this after execution
*/
virtual void executeOpenCL(cl_context context,cl_program program, cl_command_queue queue, MemoryBuffer* outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer** inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) {}
virtual void deinitExecution();
void deinitMutex();
/**
* @brief set the resolution
* @param resolution the resolution to set
*/
void setResolution(unsigned int resolution[]) {this->width = resolution[0];this->height = resolution[1];}
void getConnectedInputSockets(vector<InputSocket*> *sockets);
/**
* @brief is this operation complex
*
* Complex operations are typically doing many reads to calculate the output of a single pixel.
* Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true.
*/
const bool isComplex() const {return this->complex;}
virtual const bool isSetOperation() const {return false;}
/**
* @brief is this operation of type ReadBufferOperation
* @return [true:false]
* @see ReadBufferOperation
*/
virtual const bool isReadBufferOperation() const {return false;}
/**
* @brief is this operation of type WriteBufferOperation
* @return [true:false]
* @see WriteBufferOperation
*/
virtual const bool isWriteBufferOperation() const {return false;}
/**
* @brief is this operation the active viewer output
* user can select an ViewerNode to be active (the result of this node will be drawn on the backdrop)
* @return [true:false]
* @see BaseViewerOperation
*/
virtual const bool isActiveViewerOutput() const {return false;}
virtual bool determineDependingAreaOfInterest(rcti * input, ReadBufferOperation* readOperation, rcti* output);
/**
* @brief set the index of the input socket that will determine the resolution of this operation
* @param index the index to set
*/
void setResolutionInputSocketIndex(unsigned int index);
/**
* @brief get the render priority of this node.
* @note only applicable for output operations like ViewerOperation
* @return [0:9] 9 is highest priority
*/
virtual const int getRenderPriority() const {return 0;}
/**
* @brief can this NodeOperation be scheduled on an OpenCLDevice
* @see WorkScheduler.schedule
* @see ExecutionGroup.addOperation
*/
bool isOpenCL() { return this->openCL; }
virtual bool isViewerOperation() {return false;}
protected:
NodeOperation();
void setWidth(unsigned int width) {this->width = width;}
void setHeight(unsigned int height) {this->height= height;}
SocketReader* getInputSocketReader(unsigned int inputSocketindex);
NodeOperation* getInputOperation(unsigned int inputSocketindex);
inline ThreadMutex* getMutex() {return &this->mutex;}
/**
* @brief set whether this operation is complex
*
* Complex operations are typically doing many reads to calculate the output of a single pixel.
* Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true.
*/
void setComplex(bool complex) {this->complex = complex;}
/**
* @brief set if this NodeOperation can be scheduled on a OpenCLDevice
*/
void setOpenCL(bool openCL) {this->openCL = openCL;}
};
#endif

View File

@ -0,0 +1,7 @@
#ifndef _COM_NodeProgram_h
#define _COM_NodeProgram_h
class NodeProgram{
};
#endif

View File

@ -0,0 +1,61 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_OpenCLDevice.h"
#include "COM_WorkScheduler.h"
OpenCLDevice::OpenCLDevice(cl_context context, cl_device_id device, cl_program program){
this->device = device;
this->context = context;
this->program = program;
this->queue = NULL;
}
bool OpenCLDevice::initialize(){
cl_int error;
queue = clCreateCommandQueue(context, device, 0, &error);
return false;
}
void OpenCLDevice::deinitialize(){
if(queue){
clReleaseCommandQueue(queue);
}
}
void OpenCLDevice::execute(WorkPackage *work) {
const unsigned int chunkNumber = work->getChunkNumber();
ExecutionGroup * executionGroup = work->getExecutionGroup();
rcti rect;
executionGroup->determineChunkRect(&rect, chunkNumber);
MemoryBuffer ** inputBuffers = executionGroup->getInputBuffers(chunkNumber);
MemoryBuffer * outputBuffer = executionGroup->allocateOutputBuffer(chunkNumber, &rect);
executionGroup->getOutputNodeOperation()->executeOpenCLRegion(this->context, this->program, this->queue, &rect, chunkNumber, inputBuffers);
executionGroup->finalizeChunkExecution(chunkNumber, inputBuffers);
if (outputBuffer != NULL) {
outputBuffer->setCreatedState();
}
}

View File

@ -0,0 +1,88 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
class OpenCLDevice;
#ifndef _COM_OpenCLDevice_h
#define _COM_OpenCLDevice_h
#include "COM_Device.h"
#include "OCL_opencl.h"
#include "COM_WorkScheduler.h"
/**
* @brief device representing an GPU OpenCL device.
* an instance of this class represents a single cl_device
*/
class OpenCLDevice: public Device {
private:
/**
*@brief opencl context
*/
cl_context context;
/**
*@brief opencl device
*/
cl_device_id device;
/**
*@brief opencl program
*/
cl_program program;
/**
*@brief opencl command queue
*/
cl_command_queue queue;
public:
/**
*@brief constructor with opencl device
*@param context
*@param device
*/
OpenCLDevice(cl_context context, cl_device_id device, cl_program program);
/**
* @brief initialize the device
* During initialization the OpenCL cl_command_queue is created
* the command queue is stored in the field queue.
* @see queue
*/
bool initialize();
/**
* @brief deinitialize the device
* During deintiialization the command queue is cleared
*/
void deinitialize();
/**
* @brief execute a WorkPackage
* @param work the WorkPackage to execute
*/
void execute(WorkPackage *work);
};
#endif

View File

@ -0,0 +1,146 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_Socket.h"
#include "COM_Node.h"
#include "COM_SocketConnection.h"
#include "COM_NodeOperation.h"
OutputSocket::OutputSocket(DataType datatype) :Socket(datatype) {
this->inputSocketDataTypeDeterminatorIndex = -1;
}
OutputSocket::OutputSocket(DataType datatype, int inputSocketDataTypeDeterminatorIndex) :Socket(datatype) {
this->inputSocketDataTypeDeterminatorIndex = inputSocketDataTypeDeterminatorIndex;
}
OutputSocket::OutputSocket(OutputSocket *from): Socket(from->getDataType()) {
this->inputSocketDataTypeDeterminatorIndex = from->getInputSocketDataTypeDeterminatorIndex();
}
int OutputSocket::isOutputSocket() const { return true; }
const int OutputSocket::isConnected() const { return this->connections.size()!=0; }
void OutputSocket::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) {
NodeBase* node = this->getNode();
if (node->isOperation()) {
NodeOperation* operation = (NodeOperation*)node;
operation->determineResolution(resolution, preferredResolution);
operation->setResolution(resolution);
}
}
void OutputSocket::determineActualDataType() {
DataType actualDatatype = this->getNode()->determineActualDataType(this);
/** @todo: set the channel info needs to be moved after integration with OCIO */
this->channelinfo[0].setNumber(0);
this->channelinfo[1].setNumber(1);
this->channelinfo[2].setNumber(2);
this->channelinfo[3].setNumber(3);
switch (actualDatatype) {
case COM_DT_VALUE:
this->channelinfo[0].setType(COM_CT_Value);
break;
case COM_DT_VECTOR:
this->channelinfo[0].setType(COM_CT_X);
this->channelinfo[1].setType(COM_CT_Y);
this->channelinfo[2].setType(COM_CT_Z);
break;
case COM_DT_COLOR:
this->channelinfo[0].setType(COM_CT_ColorComponent);
this->channelinfo[1].setType(COM_CT_ColorComponent);
this->channelinfo[2].setType(COM_CT_ColorComponent);
this->channelinfo[3].setType(COM_CT_Alpha);
break;
default:
break;
}
this->setActualDataType(actualDatatype);
this->fireActualDataType();
}
void OutputSocket::addConnection(SocketConnection *connection) {
this->connections.push_back(connection);
}
void OutputSocket::fireActualDataType() {
unsigned int index;
for (index = 0 ; index < this->connections.size();index ++) {
SocketConnection *connection = this->connections[index];
connection->getToSocket()->notifyActualInputType(this->getActualDataType());
}
}
void OutputSocket::relinkConnections(OutputSocket *relinkToSocket, bool single) {
if (isConnected()) {
if (single) {
SocketConnection *connection = this->connections[0];
connection->setFromSocket(relinkToSocket);
relinkToSocket->addConnection(connection);
// relinkToSocket->setActualDataType(this->getActualDataType());
this->connections.erase(this->connections.begin());
} else {
unsigned int index;
for (index = 0 ; index < this->connections.size();index ++) {
SocketConnection *connection = this->connections[index];
connection->setFromSocket(relinkToSocket);
relinkToSocket->addConnection(connection);
}
// relinkToSocket->setActualDataType(this->getActualDataType());
this->connections.clear();
}
}
}
void OutputSocket::removeFirstConnection() {
SocketConnection *connection = this->connections[0];
InputSocket* inputSocket = connection->getToSocket();
if (inputSocket != NULL) {
inputSocket->setConnection(NULL);
}
this->connections.erase(this->connections.begin());
}
void OutputSocket::clearConnections() {
while (this->isConnected()) {
removeFirstConnection();
}
}
WriteBufferOperation* OutputSocket::findAttachedWriteBufferOperation() const {
unsigned int index;
for (index = 0 ; index < this->connections.size();index++) {
SocketConnection* connection = this->connections[index];
NodeBase* node = connection->getToNode();
if (node->isOperation()) {
NodeOperation* operation = (NodeOperation*)node;
if (operation->isWriteBufferOperation()) {
return (WriteBufferOperation*)operation;
}
}
}
return NULL;
}
ChannelInfo* OutputSocket::getChannelInfo(const int channelnumber) {
return &this->channelinfo[channelnumber];
}

View File

@ -0,0 +1,105 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_OutputSocket_h
#define _COM_OutputSocket_h
#include <vector>
#include "COM_Socket.h"
#include "COM_ChannelInfo.h"
using namespace std;
class SocketConnection;
class Node;
class InputSocket;
class WriteBufferOperation;
//#define COM_ST_INPUT 0
//#define COM_ST_OUTPUT 1
/**
* @brief OutputSocket are sockets that can send data/input
* @ingroup Model
*/
class OutputSocket : public Socket {
private:
vector<SocketConnection*> connections;
/**
* @brief index of the inputsocket that determines the datatype of this outputsocket
* -1 will not use any inputsocket to determine the datatype, but use the outputsocket
* default datatype.
*/
int inputSocketDataTypeDeterminatorIndex;
ChannelInfo channelinfo[4];
void removeFirstConnection();
public:
OutputSocket(DataType datatype);
OutputSocket(DataType datatype, int inputSocketDataTypeDeterminatorIndex);
OutputSocket(OutputSocket * from);
void addConnection(SocketConnection *connection);
SocketConnection* getConnection(unsigned int index) {return this->connections[index];}
const int isConnected() const;
int isOutputSocket() const;
/**
* @brief determine the resolution of this socket
* @param resolution the result of this operation
* @param preferredResolution the preferrable resolution as no resolution could be determined
*/
void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]);
/**
* @brief determine the actual data type and channel info.
*/
void determineActualDataType();
void relinkConnections(OutputSocket *relinkToSocket) {this->relinkConnections(relinkToSocket, false);};
void relinkConnections(OutputSocket *relinkToSocket, bool single);
bool isActualDataTypeDeterminedByInputSocket() {
return this->inputSocketDataTypeDeterminatorIndex>-1;
}
const int getNumberOfConnections() {return connections.size();}
/**
* @brief get the index of the inputsocket that determines the datatype of this outputsocket
*/
int getInputSocketDataTypeDeterminatorIndex() {return this->inputSocketDataTypeDeterminatorIndex;}
void clearConnections();
/**
* @brief find a connected write buffer operation to this OutputSocket
* @return WriteBufferOperation or NULL
*/
WriteBufferOperation* findAttachedWriteBufferOperation() const;
ChannelInfo* getChannelInfo(const int channelnumber);
/**
* @brief trigger determine actual data type to all connected sockets
* @note will only be triggered just after the actual data type is set.
*/
void fireActualDataType();
private:
};
#endif

View File

@ -0,0 +1,47 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_Socket.h"
#include "COM_Node.h"
#include "COM_SocketConnection.h"
Socket::Socket(DataType datatype) {
this->datatype = datatype;
this->actualType = COM_DT_UNKNOWN;
this->editorSocket = NULL;
this->node = NULL;
}
DataType Socket::getDataType() const {
return this->datatype;
}
int Socket::isInputSocket() const { return false; }
int Socket::isOutputSocket() const { return false; }
const int Socket::isConnected() const {return false;}
void Socket::setNode(NodeBase *node) {this->node = node;}
NodeBase* Socket::getNode() const {return this->node;}
DataType Socket::getActualDataType() const {return this->actualType;}
void Socket::setActualDataType(DataType actualType) {
this->actualType = actualType;
}

View File

@ -0,0 +1,100 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_Socket_h
#define _COM_Socket_h
#include <vector>
#include "BKE_text.h"
#include <string>
#include "DNA_node_types.h"
#include "COM_defines.h"
using namespace std;
class SocketConnection;
class NodeBase;
/**
* @brief Base class for InputSocket and OutputSocket.
*
* A socket are the points on an node where the user can make a connection between.
* Sockets are always part of a node or an operation.
*
* @see InputSocket
* @see OutputSocket
* @see SocketConnection - a connection between an InputSocket and an OutputSocket
* @ingroup Model
*/
class Socket {
private:
/**
* Reference to the node where this Socket belongs to
*/
NodeBase* node;
/**
* the datatype of this socket. Is used for automatically data transformation.
* @section data-conversion
*/
DataType datatype;
/**
* the actual data type during execution. This can be different than the field datatype, based on the conversion rules of the node
* @section data-conversion
*/
DataType actualType;
bNodeSocket* editorSocket;
public:
Socket(DataType datatype);
DataType getDataType() const;
void setNode(NodeBase* node);
NodeBase* getNode() const;
/**
* @brief get the actual data type
*
* @note The actual data type can differ from the data type this socket expects.
* @return actual DataType
*/
DataType getActualDataType() const;
/**
* @brief set the actual data type
* @param actualType the new actual type
*/
void setActualDataType(DataType actualType);
const virtual int isConnected() const;
int isInputSocket() const;
int isOutputSocket() const;
virtual void determineResolution(int resolution[], unsigned int preferredResolution[]) {}
virtual void determineActualDataType() {}
void setEditorSocket(bNodeSocket* editorSocket) {this->editorSocket = editorSocket;}
bNodeSocket* getbNodeSocket() const {return this->editorSocket;}
};
#endif

View File

@ -0,0 +1,86 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_SocketConnection.h"
#include "COM_NodeOperation.h"
SocketConnection::SocketConnection() {
this->fromSocket = NULL;
this->toSocket = NULL;
this->setIgnoreResizeCheck(false);
}
void SocketConnection::setFromSocket(OutputSocket* fromsocket){
if (fromsocket == NULL) {
throw "ERROR";
}
this->fromSocket = fromsocket;
}
OutputSocket* SocketConnection::getFromSocket() const {return this->fromSocket;}
void SocketConnection::setToSocket(InputSocket* tosocket) {
if (tosocket == NULL) {
throw "ERROR";
}
this->toSocket = tosocket;
}
InputSocket* SocketConnection::getToSocket() const {return this->toSocket;}
NodeBase* SocketConnection::getFromNode() const {
if (this->getFromSocket() == NULL) {
return NULL;
} else {
return this->getFromSocket()->getNode();
}
}
NodeBase* SocketConnection::getToNode() const {
if (this->getToSocket() == NULL) {
return NULL;
} else {
return this->getToSocket()->getNode();
}
}
bool SocketConnection::isValid() const {
if ((this->getToSocket() != NULL && this->getFromSocket() != NULL)) {
if (this->getFromNode()->isOperation() && this->getToNode()->isOperation()) {
return true;
}
}
return false;
}
bool SocketConnection::needsResolutionConversion() const {
if (this->ignoreResizeCheck) {return false;}
NodeOperation* fromOperation = (NodeOperation*)this->getFromNode();
NodeOperation* toOperation = (NodeOperation*)this->getToNode();
if (this->toSocket->getResizeMode() == COM_SC_NO_RESIZE) {return false;}
const unsigned int fromWidth = fromOperation->getWidth();
const unsigned int fromHeight = fromOperation->getHeight();
const unsigned int toWidth = toOperation->getWidth();
const unsigned int toHeight = toOperation->getHeight();
if (fromWidth == toWidth && fromHeight == toHeight) {
return false;
}
return true;
}

View File

@ -0,0 +1,123 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_SocketConnection_h
#define _COM_SocketConnection_h
#include "DNA_node_types.h"
#include "COM_Node.h"
#include "COM_Socket.h"
#include "COM_ChannelInfo.h"
/**
* @brief An SocketConnection is an connection between an InputSocket and an OutputSocket.
*
* <pre>
* +----------+ To InputSocket +----------+
* | From | SocketConnection \| To Node |
* | Node *====================* |
* | |\ | |
* | | From OutputSocket +----------+
* +----------+
* </pre>
* @ingroup Model
* @see InputSocket
* @see OutputSocket
*/
class SocketConnection {
private:
/**
* @brief Startpoint of the connection
*/
OutputSocket *fromSocket;
/**
* @brief Endpoint of the connection
*/
InputSocket *toSocket;
/**
* @brief has the resize already been done for this connection
*/
bool ignoreResizeCheck;
public:
SocketConnection();
/**
* @brief set the startpoint of the connection
* @param fromsocket
*/
void setFromSocket(OutputSocket* fromsocket);
/**
* @brief get the startpoint of the connection
* @return from OutputSocket
*/
OutputSocket* getFromSocket() const;
/**
* @brief set the endpoint of the connection
* @param tosocket
*/
void setToSocket(InputSocket* tosocket);
/**
* @brief get the endpoint of the connection
* @return to InputSocket
*/
InputSocket* getToSocket() const;
/**
* @brief check if this connection is valid
*/
bool isValid() const;
/**
* @brief return the Node where this connection is connected from
*/
NodeBase * getFromNode() const;
/**
* @brief return the Node where this connection is connected to
*/
NodeBase * getToNode() const;
/**
* @brief set, whether the resize has already been done for this SocketConnection
*/
void setIgnoreResizeCheck(bool check) {this->ignoreResizeCheck = check;}
/**
* @brief has the resize already been done for this SocketConnection
*/
bool isIgnoreResizeCheck() const { return this->ignoreResizeCheck;}
/**
* @brief does this SocketConnection need resolution conversion
* @note PreviewOperation's will be ignored
* @note Already converted SocketConnection's will be ignored
* @return needs conversion [true:false]
*/
bool needsResolutionConversion() const;
};
#endif

View File

@ -0,0 +1,25 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_SocketReader.h"

View File

@ -0,0 +1,113 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_SocketReader_h
#define _COM_SocketReader_h
#include "BLI_rect.h"
#include "COM_defines.h"
typedef enum PixelSampler {
COM_PS_NEAREST,
COM_PS_BILINEAR,
COM_PS_BICUBIC
} PixelSampler;
class MemoryBuffer;
/**
* @brief Helper class for reading socket data.
* Only use this class for dispatching (un-ary and n-ary) executions.
* @ingroup Execution
*/
class SocketReader {
private:
protected:
/**
* @brief Holds the width of the output of this operation.
*/
unsigned int width;
/**
* @brief Holds the height of the output of this operation.
*/
unsigned int height;
/**
* @brief calculate a single pixel
* @note this method is called for non-complex
* @param result is a float[4] array to store the result
* @param x the x-coordinate of the pixel to calculate in image space
* @param y the y-coordinate of the pixel to calculate in image space
* @param inputBuffers chunks that can be read by their ReadBufferOperation.
*/
virtual void executePixel(float* result, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) {}
/**
* @brief calculate a single pixel
* @note this method is called for complex
* @param result is a float[4] array to store the result
* @param x the x-coordinate of the pixel to calculate in image space
* @param y the y-coordinate of the pixel to calculate in image space
* @param inputBuffers chunks that can be read by their ReadBufferOperation.
* @param chunkData chunk specific data a during execution time.
*/
virtual void executePixel(float* result, int x, int y, MemoryBuffer *inputBuffers[], void* chunkData) {
executePixel(result, x, y, COM_PS_NEAREST, inputBuffers);
}
/**
* @brief calculate a single pixel using an EWA filter
* @note this method is called for complex
* @param result is a float[4] array to store the result
* @param x the x-coordinate of the pixel to calculate in image space
* @param y the y-coordinate of the pixel to calculate in image space
* @param dx
* @param dy
* @param inputBuffers chunks that can be read by their ReadBufferOperation.
*/
virtual void executePixel(float* result, float x, float y, float dx, float dy, MemoryBuffer *inputBuffers[]) {}
public:
inline void read(float* result, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) {
executePixel(result, x, y, sampler, inputBuffers);
}
inline void read(float* result, int x, int y, MemoryBuffer *inputBuffers[], void* chunkData) {
executePixel(result, x, y, inputBuffers, chunkData);
}
inline void read(float* result, float x, float y, float dx, float dy, MemoryBuffer *inputBuffers[]) {
executePixel(result, x, y, dx, dy, inputBuffers);
}
virtual void* initializeTileData(rcti *rect, MemoryBuffer** memoryBuffers) {
return 0;
}
virtual void deinitializeTileData(rcti *rect, MemoryBuffer** memoryBuffers, void* data) {
}
virtual MemoryBuffer* getInputMemoryBuffer(MemoryBuffer** memoryBuffers) {return 0;}
inline const unsigned int getWidth() const {return this->width;}
inline const unsigned int getHeight() const {return this->height;}
};
#endif

View File

@ -0,0 +1,28 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_WorkPackage.h"
WorkPackage::WorkPackage(ExecutionGroup *group, unsigned int chunkNumber) {
this->executionGroup = group;
this->chunkNumber = chunkNumber;
}

View File

@ -0,0 +1,64 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
class WorkPackage;
#ifndef _COM_WorkPackage_h_
#define _COM_WorkPackage_h_
#include "COM_ExecutionGroup.h"
/**
* @brief contains data about work that can be scheduled
* @see WorkScheduler
*/
class WorkPackage {
private:
/**
* @brief executionGroup with the operations-setup to be evaluated
*/
ExecutionGroup* executionGroup;
/**
* @brief number of the chunk to be executed
*/
unsigned int chunkNumber;
public:
/**
* @constructor
* @param group the ExecutionGroup
* @param chunkNumber the number of the chunk
*/
WorkPackage(ExecutionGroup* group, unsigned int chunkNumber);
/**
* @brief get the ExecutionGroup
*/
ExecutionGroup* getExecutionGroup() const {return this->executionGroup;}
/**
* @brief get the number of the chunk
*/
unsigned int getChunkNumber() const {return this->chunkNumber;}
};
#endif

View File

@ -0,0 +1,313 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include <list>
#include "COM_WorkScheduler.h"
#include "PIL_time.h"
#include "BLI_threads.h"
#include "COM_CPUDevice.h"
#include "COM_OpenCLDevice.h"
#include "OCL_opencl.h"
#include "stdio.h"
#include "COM_OpenCLKernels.cl.cpp"
#if COM_CURRENT_THREADING_MODEL == COM_TM_NOTHREAD
#warning COM_CURRENT_THREADING_MODEL COM_TM_NOTHREAD is activated. Use only for debugging.
#elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
#else
#error COM_CURRENT_THREADING_MODEL No threading model selected
#endif
/// @brief global state of the WorkScheduler.
static WorkSchedulerState state;
/// @brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is created
static vector<CPUDevice*> cpudevices;
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
/// @brief list of all thread for every CPUDevice in cpudevices a thread exists
static ListBase cputhreads;
/// @brief all scheduled work for the cpu
static ThreadQueue * cpuqueue;
static ThreadQueue * gpuqueue;
#ifdef COM_OPENCL_ENABLED
static cl_context context;
static cl_program program;
/// @brief list of all OpenCLDevices. for every OpenCL GPU device an instance of OpenCLDevice is created
static vector<OpenCLDevice*> gpudevices;
/// @brief list of all thread for every GPUDevice in cpudevices a thread exists
static ListBase gputhreads;
/// @brief all scheduled work for the gpu
#ifdef COM_OPENCL_ENABLED
static bool openclActive = false;
#endif
#endif
#endif
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
void* WorkScheduler::thread_execute_cpu(void* data) {
bool continueLoop = true;
Device* device = (Device*)data;
while (continueLoop) {
WorkPackage* work = (WorkPackage*)BLI_thread_queue_pop(cpuqueue);
if (work) {
device->execute(work);
delete work;
}
PIL_sleep_ms(10);
if (WorkScheduler::isStopping()) {
continueLoop = false;
}
}
return NULL;
}
void* WorkScheduler::thread_execute_gpu(void* data) {
bool continueLoop = true;
Device* device = (Device*)data;
while (continueLoop) {
WorkPackage* work = (WorkPackage*)BLI_thread_queue_pop(gpuqueue);
if (work) {
device->execute(work);
delete work;
}
PIL_sleep_ms(10);
if (WorkScheduler::isStopping()) {
continueLoop = false;
}
}
return NULL;
}
bool WorkScheduler::isStopping() {return state == COM_WSS_STOPPING;}
#endif
void WorkScheduler::schedule(ExecutionGroup *group, int chunkNumber) {
WorkPackage* package = new WorkPackage(group, chunkNumber);
#if COM_CURRENT_THREADING_MODEL == COM_TM_NOTHREAD
CPUDevice device;
device.execute(package);
delete package;
#elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
#ifdef COM_OPENCL_ENABLED
if (group->isOpenCL() && openclActive){
BLI_thread_queue_push(gpuqueue, package);
} else{
BLI_thread_queue_push(cpuqueue, package);
}
#else
BLI_thread_queue_push(cpuqueue, package);
#endif
#endif
}
void WorkScheduler::start(CompositorContext &context) {
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
unsigned int index;
cpuqueue = BLI_thread_queue_init();
BLI_thread_queue_nowait(cpuqueue);
BLI_init_threads(&cputhreads, thread_execute_cpu, cpudevices.size());
for (index = 0 ; index < cpudevices.size() ; index ++) {
Device* device = cpudevices[index];
BLI_insert_thread(&cputhreads, device);
}
#ifdef COM_OPENCL_ENABLED
if (context.getHasActiveOpenCLDevices()) {
gpuqueue = BLI_thread_queue_init();
BLI_thread_queue_nowait(gpuqueue);
BLI_init_threads(&gputhreads, thread_execute_gpu, gpudevices.size());
for (index = 0 ; index < gpudevices.size() ; index ++) {
Device* device = gpudevices[index];
BLI_insert_thread(&gputhreads, device);
}
openclActive = true;
} else {
openclActive = false;
}
#endif
#endif
state = COM_WSS_STARTED;
}
void WorkScheduler::finish() {
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
#ifdef COM_OPENCL_ENABLED
if (openclActive) {
while (BLI_thread_queue_size(gpuqueue) + BLI_thread_queue_size(cpuqueue) > 0) {
PIL_sleep_ms(10);
}
} else {
while (BLI_thread_queue_size(cpuqueue) > 0) {
PIL_sleep_ms(10);
}
}
#else
while (BLI_thread_queue_size(cpuqueue) > 0) {
PIL_sleep_ms(10);
}
#endif
#endif
}
void WorkScheduler::stop() {
state = COM_WSS_STOPPING;
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
BLI_end_threads(&cputhreads);
BLI_thread_queue_free(cpuqueue);
cpuqueue = NULL;
#ifdef COM_OPENCL_ENABLED
if (openclActive) {
BLI_end_threads(&gputhreads);
BLI_thread_queue_free(gpuqueue);
gpuqueue = NULL;
}
#endif
#endif
state = COM_WSS_STOPPED;
}
bool WorkScheduler::hasGPUDevices() {
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
#ifdef COM_OPENCL_ENABLED
return gpudevices.size()>0;
#else
return 0;
#endif
#else
return 0;
#endif
}
extern void clContextError(const char *errinfo, const void *private_info, size_t cb, void *user_data) {
printf("OPENCL error: %s\n", errinfo);
}
void WorkScheduler::initialize() {
state = COM_WSS_UNKNOWN;
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
int numberOfCPUThreads = BLI_system_thread_count();
for (int index = 0 ; index < numberOfCPUThreads ; index ++) {
CPUDevice *device = new CPUDevice();
device->initialize();
cpudevices.push_back(device);
}
#ifdef COM_OPENCL_ENABLED
context = NULL;
program = NULL;
if (clCreateContextFromType) {
cl_uint numberOfPlatforms;
cl_int error;
error = clGetPlatformIDs(0, 0, &numberOfPlatforms);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
printf("%d number of platforms\n", numberOfPlatforms);
cl_platform_id *platforms = new cl_platform_id[numberOfPlatforms];
error = clGetPlatformIDs(numberOfPlatforms, platforms, 0);
unsigned int indexPlatform;
cl_uint totalNumberOfDevices = 0;
for (indexPlatform = 0 ; indexPlatform < numberOfPlatforms ; indexPlatform ++) {
cl_platform_id platform = platforms[indexPlatform];
cl_uint numberOfDevices;
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, 0, &numberOfDevices);
totalNumberOfDevices += numberOfDevices;
}
cl_device_id *cldevices = new cl_device_id[totalNumberOfDevices];
unsigned int numberOfDevicesReceived = 0;
for (indexPlatform = 0 ; indexPlatform < numberOfPlatforms ; indexPlatform ++) {
cl_platform_id platform = platforms[indexPlatform];
cl_uint numberOfDevices;
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, 0, &numberOfDevices);
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numberOfDevices, cldevices+numberOfDevicesReceived*sizeof (cl_device_id), 0);
numberOfDevicesReceived += numberOfDevices;
}
context = clCreateContext(NULL, totalNumberOfDevices, cldevices, clContextError, NULL, &error);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
program = clCreateProgramWithSource(context, 1, &sourcecode, 0, &error);
error = clBuildProgram(program, totalNumberOfDevices, cldevices, 0, 0, 0);
if (error != CL_SUCCESS) {
cl_int error2;
size_t ret_val_size;
printf("CLERROR[%d]: %s\n", error, clewErrorString(error));
error2 = clGetProgramBuildInfo(program, cldevices[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
char* build_log = new char[ret_val_size+1];
error2 = clGetProgramBuildInfo(program, cldevices[0], CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
build_log[ret_val_size] = '\0';
printf("%s", build_log);
delete build_log;
}
unsigned int indexDevices;
for (indexDevices = 0 ; indexDevices < totalNumberOfDevices ; indexDevices ++) {
cl_device_id device = cldevices[indexDevices];
OpenCLDevice* clDevice = new OpenCLDevice(context, device, program);
clDevice->initialize(),
gpudevices.push_back(clDevice);
char resultString[32];
error = clGetDeviceInfo(device, CL_DEVICE_NAME, 32, resultString, 0);
printf("OPENCL_DEVICE: %s, ", resultString);
error = clGetDeviceInfo(device, CL_DEVICE_VENDOR, 32, resultString, 0);
printf("%s\n", resultString);
}
delete cldevices;
delete platforms;
}
#endif
#endif
state = COM_WSS_INITIALIZED;
}
void WorkScheduler::deinitialize() {
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
Device* device;
while(cpudevices.size()>0) {
device = cpudevices.back();
cpudevices.pop_back();
device->deinitialize();
delete device;
}
#ifdef COM_OPENCL_ENABLED
while(gpudevices.size()>0) {
device = gpudevices.back();
gpudevices.pop_back();
device->deinitialize();
delete device;
}
if (program) {
clReleaseProgram(program);
program = NULL;
}
if (context) {
clReleaseContext(context);
context = NULL;
}
#endif
#endif
state = COM_WSS_DEINITIALIZED;
}

View File

@ -0,0 +1,127 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_WorkScheduler_h_
#define _COM_WorkScheduler_h_
#include "COM_ExecutionGroup.h"
extern "C" {
#include "BLI_threads.h"
}
#include "COM_WorkPackage.h"
#include "COM_defines.h"
#include "COM_Device.h"
// STATES
/** @brief states of the WorkScheduler
* @ingroup execution
*/
typedef enum WorkSchedulerState {
COM_WSS_UNKNOWN = -1,
COM_WSS_INITIALIZED = 0,
COM_WSS_STARTED = 1,
COM_WSS_STOPPING = 2,
COM_WSS_STOPPED = 3,
COM_WSS_DEINITIALIZED = 4
} WorkSchedulerState;
/** @brief the workscheduler
* @ingroup execution
*/
class WorkScheduler {
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
/**
* @brief are we being stopped.
*/
static bool isStopping();
/**
* @brief main thread loop for cpudevices
* inside this loop new work is queried and being executed
*/
static void* thread_execute_cpu(void* data);
/**
* @brief main thread loop for gpudevices
* inside this loop new work is queried and being executed
*/
static void* thread_execute_gpu(void* data);
#endif
public:
/**
* @brief schedule a chunk of a group to be calculated.
* An execution group schedules a chunk in the WorkScheduler
* when ExecutionGroup.isOpenCL is set the work will be handled by a OpenCLDevice
* otherwide the work is scheduled for an CPUDevice
* @see ExecutionGroup.execute
* @param group the execution group
* @param chunkNumber the number of the chunk in the group to be executed
*/
static void schedule(ExecutionGroup* group, int chunkNumber);
/**
* @brief initialize the WorkScheduler
*
* during initialization the mutexes are initialized.
* there are two mutexes (for every device type one)
* After mutex initialization the system is queried in order to count the number of CPUDevices and GPUDevices to be created.
* For every hardware thread a CPUDevice and for every OpenCL GPU device a OpenCLDevice is created.
* these devices are stored in a separate list (cpudevices & gpudevices)
*/
static void initialize();
/**
* @brief deinitialize the WorkScheduler
* free all allocated resources
*/
static void deinitialize();
/**
* @brief Start the execution
* this methods will start the WorkScheduler. Inside this method all threads are initialized.
* for every device a thread is created.
* @see initialize Initialization and query of the number of devices
*/
static void start(CompositorContext &context);
/**
* @brief stop the execution
* All created thread by the start method are destroyed.
* @see start
*/
static void stop();
/**
* @brief wait for all work to be completed.
*/
static void finish();
/**
* @brief Are there OpenCL capable GPU devices initialized?
* the result of this method is stored in the CompositorContext
* A node can generate a different operation tree when OpenCLDevices exists.
* @see CompositorContext.getHasActiveOpenCLDevices
*/
static bool hasGPUDevices();
};
#endif

View File

@ -0,0 +1,59 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "BKE_node.h"
extern "C" {
#include "BLI_threads.h"
}
#include "COM_compositor.h"
#include "COM_ExecutionSystem.h"
#include "COM_WorkScheduler.h"
static ThreadMutex *compositorMutex;
void COM_execute(bNodeTree *editingtree, int rendering) {
if (compositorMutex == NULL) { /// TODO: move to blender startup phase
compositorMutex = new ThreadMutex();
BLI_mutex_init(compositorMutex);
WorkScheduler::initialize(); ///TODO: call workscheduler.deinitialize somewhere
}
BLI_mutex_lock(compositorMutex);
if (editingtree->test_break && editingtree->test_break(editingtree->tbh)) {
// during editing multiple calls to this method can be triggered.
// make sure one the last one will be doing the work.
BLI_mutex_unlock(compositorMutex);
return;
}
/* set progress bar to 0% and status to init compositing*/
editingtree->progress(editingtree->prh, 0.0);
editingtree->stats_draw(editingtree->sdh, (char*)"Compositing");
/* initialize execution system */
ExecutionSystem* system = new ExecutionSystem(editingtree, rendering);
system->execute();
delete system;
BLI_mutex_unlock(compositorMutex);
}

View File

@ -0,0 +1,67 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_AlphaOverNode.h"
#include "COM_MixBaseOperation.h"
#include "COM_AlphaOverKeyOperation.h"
#include "COM_AlphaOverMixedOperation.h"
#include "COM_AlphaOverPremultiplyOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_SetValueOperation.h"
#include "DNA_material_types.h" // the ramp types
void AlphaOverNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
InputSocket *valueSocket = this->getInputSocket(0);
InputSocket *color1Socket = this->getInputSocket(1);
InputSocket *color2Socket = this->getInputSocket(2);
OutputSocket *outputSocket = this->getOutputSocket(0);
bNode* editorNode = this->getbNode();
MixBaseOperation *convertProg;
NodeTwoFloats *ntf= (NodeTwoFloats*)editorNode->storage;
if (ntf->x!= 0.0f) {
AlphaOverMixedOperation *mixOperation = new AlphaOverMixedOperation();
mixOperation->setX(ntf->x);
convertProg = mixOperation;
} else if (editorNode->custom1) {
convertProg = new AlphaOverKeyOperation();
} else {
convertProg = new AlphaOverPremultiplyOperation();
}
convertProg->setUseValueAlphaMultiply(false);
if (color1Socket->isConnected()) {
convertProg->setResolutionInputSocketIndex(1);
} else if (color2Socket->isConnected()) {
convertProg->setResolutionInputSocketIndex(2);
} else {
convertProg->setResolutionInputSocketIndex(0);
}
valueSocket->relinkConnections(convertProg->getInputSocket(0), true, 0, graph);
color1Socket->relinkConnections(convertProg->getInputSocket(1), true, 1, graph);
color2Socket->relinkConnections(convertProg->getInputSocket(2), true, 2, graph);
outputSocket->relinkConnections(convertProg->getOutputSocket(0));
graph->addOperation(convertProg);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_AlphaOverNode_h
#define _COM_AlphaOverNode_h
#include "COM_Node.h"
/**
* @brief AlphaOverNode
* @ingroup Node
*/
class AlphaOverNode: public Node {
public:
AlphaOverNode(bNode* editorNode) :Node(editorNode) {}
void convertToOperations(ExecutionSystem *graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,41 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_BilateralBlurNode.h"
#include "DNA_scene_types.h"
#include "DNA_node_types.h"
#include "COM_ExecutionSystem.h"
#include "COM_BilateralBlurOperation.h"
BilateralBlurNode::BilateralBlurNode(bNode *editorNode): Node(editorNode) {
}
void BilateralBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
NodeBilateralBlurData *data = (NodeBilateralBlurData*)this->getbNode()->storage;
BilateralBlurOperation *operation = new BilateralBlurOperation();
operation->setQuality(context->getQuality());
operation->setData(data);
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), true, 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), true, 1, graph);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
graph->addOperation(operation);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_BilateralBlurNode_h_
#define _COM_BilateralBlurNode_h_
#include "COM_Node.h"
/**
* @brief BilateralBlurNode
* @ingroup Node
*/
class BilateralBlurNode: public Node {
public:
BilateralBlurNode(bNode *editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,79 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_BlurNode.h"
#include "DNA_scene_types.h"
#include "DNA_node_types.h"
#include "COM_GaussianXBlurOperation.h"
#include "COM_GaussianYBlurOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_GaussianBokehBlurOperation.h"
#include "COM_FastGaussianBlurOperation.h"
BlurNode::BlurNode(bNode *editorNode): Node(editorNode) {
}
void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
bNode* editorNode = this->getbNode();
NodeBlurData * data = (NodeBlurData*)editorNode->storage;
const bNodeSocket *sock = this->getInputSocket(1)->getbNodeSocket();
//const float size = ((const bNodeSocketValueFloat*)sock->default_value)->value;
CompositorQuality quality = context->getQuality();
if (data->filtertype == R_FILTER_MITCH || data->filtertype == R_FILTER_CATROM) {
quality = COM_QUALITY_HIGH;
}
if (data->filtertype == R_FILTER_FAST_GAUSS) {
FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation();
operationfgb->setData(data);
this->getInputSocket(0)->relinkConnections(operationfgb->getInputSocket(0), true, 0, graph);
this->getInputSocket(1)->relinkConnections(operationfgb->getInputSocket(1), true, 1, graph);
this->getOutputSocket(0)->relinkConnections(operationfgb->getOutputSocket(0));
graph->addOperation(operationfgb);
addPreviewOperation(graph, operationfgb->getOutputSocket(), 5);
}else if (!data->bokeh) {
GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
operationx->setData(data);
operationx->setQuality(quality);
this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), true, 0, graph);
this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), true, 1, graph);
graph->addOperation(operationx);
GaussianYBlurOperation *operationy = new GaussianYBlurOperation();
operationy->setData(data);
operationy->setQuality(quality);
this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket());
graph->addOperation(operationy);
addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
addLink(graph, operationx->getInputSocket(1)->getConnection()->getFromSocket(), operationy->getInputSocket(1));
addPreviewOperation(graph, operationy->getOutputSocket(), 5);
} else {
GaussianBokehBlurOperation *operation = new GaussianBokehBlurOperation();
operation->setData(data);
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), true, 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), true, 1, graph);
operation->setQuality(quality);
graph->addOperation(operation);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
addPreviewOperation(graph, operation->getOutputSocket(), 5);
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_BlurNode_h_
#define _COM_BlurNode_h_
#include "COM_Node.h"
/**
* @brief BlurNode
* @ingroup Node
*/
class BlurNode: public Node {
public:
BlurNode(bNode *editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,63 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_BokehBlurNode.h"
#include "DNA_scene_types.h"
#include "DNA_camera_types.h"
#include "DNA_object_types.h"
#include "DNA_node_types.h"
#include "COM_ExecutionSystem.h"
#include "COM_BokehBlurOperation.h"
#include "COM_VariableSizeBokehBlurOperation.h"
#include "COM_ConvertDepthToRadiusOperation.h"
BokehBlurNode::BokehBlurNode(bNode *editorNode): Node(editorNode) {
}
void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
Object* camob = context->getScene()->camera;
if (this->getInputSocket(2)->isConnected()) {
VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation();
ConvertDepthToRadiusOperation *converter = new ConvertDepthToRadiusOperation();
converter->setfStop(4.0f);
converter->setCameraObject(camob);
operation->setMaxBlur(16);
operation->setQuality(context->getQuality());
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), true, 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), true, 1, graph);
this->getInputSocket(2)->relinkConnections(converter->getInputSocket(0), true, 2, graph);
addLink(graph, converter->getOutputSocket(), operation->getInputSocket(2));
graph->addOperation(operation);
graph->addOperation(converter);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
} else {
BokehBlurOperation *operation = new BokehBlurOperation();
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), true, 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), true, 1, graph);
this->getInputSocket(3)->relinkConnections(operation->getInputSocket(2), true, 3, graph);
operation->setSize(((bNodeSocketValueFloat*)this->getInputSocket(2)->getbNodeSocket()->default_value)->value);
operation->setQuality(context->getQuality());
graph->addOperation(operation);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_BokehBlurNode_h_
#define _COM_BokehBlurNode_h_
#include "COM_Node.h"
/**
* @brief BokehBlurNode
* @ingroup Node
*/
class BokehBlurNode: public Node {
public:
BokehBlurNode(bNode *editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,37 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_BokehImageNode.h"
#include "DNA_scene_types.h"
#include "COM_BokehImageOperation.h"
#include "COM_ExecutionSystem.h"
BokehImageNode::BokehImageNode(bNode *editorNode): Node(editorNode) {
}
void BokehImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
BokehImageOperation *operation = new BokehImageOperation();
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
graph->addOperation(operation);
operation->setData((NodeBokehImage*)this->getbNode()->storage);
addPreviewOperation(graph, operation->getOutputSocket(0), 9);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_BokehImageNode_h_
#define _COM_BokehImageNode_h_
#include "COM_Node.h"
/**
* @brief BokehImageNode
* @ingroup Node
*/
class BokehImageNode: public Node {
public:
BokehImageNode(bNode *editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,41 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_BoxMaskNode.h"
#include "DNA_scene_types.h"
#include "COM_BoxMaskOperation.h"
#include "COM_ExecutionSystem.h"
BoxMaskNode::BoxMaskNode(bNode *editorNode): Node(editorNode) {
}
void BoxMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
BoxMaskOperation *operation;
operation = new BoxMaskOperation();
operation->setData((NodeBoxMask*)this->getbNode()->storage);
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), true, 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), true, 1, graph);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
operation->setMaskType(this->getbNode()->custom1);
graph->addOperation(operation);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_BoxMaskNode_h_
#define _COM_BoxMaskNode_h_
#include "COM_Node.h"
/**
* @brief BoxMaskNode
* @ingroup Node
*/
class BoxMaskNode: public Node {
public:
BoxMaskNode(bNode *editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,39 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_BrightnessNode.h"
#include "DNA_scene_types.h"
#include "COM_BrightnessOperation.h"
#include "COM_ExecutionSystem.h"
BrightnessNode::BrightnessNode(bNode *editorNode): Node(editorNode) {
}
/// @todo: add anti alias when not FSA
void BrightnessNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
BrightnessOperation *operation = new BrightnessOperation();
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0));
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1),true, 1, graph);
this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2),true, 2, graph);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
graph->addOperation(operation);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_BrightnessNode_h_
#define _COM_BrightnessNode_h_
#include "COM_Node.h"
/**
* @brief BrightnessNode
* @ingroup Node
*/
class BrightnessNode: public Node {
public:
BrightnessNode(bNode *editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,89 @@
/*
* Copyright 2012, Blender Foundation.
*
* 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.
*
* Contributor:
* Dalai Felinto
*/
#include "COM_ChannelMatteNode.h"
#include "BKE_node.h"
#include "COM_ChannelMatteOperation.h"
#include "COM_ConvertRGBToHSVOperation.h"
#include "COM_ConvertRGBToYCCOperation.h"
#include "COM_ConvertRGBToYUVOperation.h"
#include "COM_SetAlphaOperation.h"
ChannelMatteNode::ChannelMatteNode(bNode *editorNode): Node(editorNode)
{}
void ChannelMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) {
InputSocket *inputSocketImage = this->getInputSocket(0);
OutputSocket *outputSocketImage = this->getOutputSocket(0);
OutputSocket *outputSocketMatte = this->getOutputSocket(1);
NodeOperation *convert=NULL;
bNode* node = this->getbNode();
/* colorspace */
switch(node->custom1) {
case CMP_NODE_CHANNEL_MATTE_CS_RGB:
break;
case CMP_NODE_CHANNEL_MATTE_CS_HSV: /*HSV*/
convert = new ConvertRGBToHSVOperation();
break;
case CMP_NODE_CHANNEL_MATTE_CS_YUV: /*YUV*/
convert = new ConvertRGBToYUVOperation();
break;
case CMP_NODE_CHANNEL_MATTE_CS_YCC: /*YCC*/
convert = new ConvertRGBToYCCOperation();
((ConvertRGBToYCCOperation *)convert)->setMode(0); /* BLI_YCC_ITU_BT601 */
break;
default:
break;
}
ChannelMatteOperation *operation = new ChannelMatteOperation();
/* pass the ui properties to the operation */
operation->setSettings((NodeChroma*)node->storage, node->custom2);
SetAlphaOperation *operationAlpha = new SetAlphaOperation();
if (convert) {
inputSocketImage->relinkConnections(convert->getInputSocket(0), true, 0, graph);
addLink(graph, convert->getOutputSocket(), operation->getInputSocket(0));
addLink(graph, convert->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0));
graph->addOperation(convert);
}
else {
inputSocketImage->relinkConnections(operation->getInputSocket(0), true, 0, graph);
addLink(graph, operation->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0));
}
if (outputSocketMatte->isConnected()) {
outputSocketMatte->relinkConnections(operation->getOutputSocket(0));
}
graph->addOperation(operation);
graph->addOperation(operationAlpha);
addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1));
addPreviewOperation(graph, operationAlpha->getOutputSocket(), 9);
if (outputSocketImage->isConnected()) {
outputSocketImage->relinkConnections(operationAlpha->getOutputSocket());
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2012, Blender Foundation.
*
* 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.
*
* Contributor:
* Dalai Felinto
*/
#ifndef COM_ChannelMatteNODE_H
#define COM_ChannelMatteNODE_H
#include "COM_Node.h"
/**
* @brief ChannelMatteNode
* @ingroup Node
*/
class ChannelMatteNode : public Node
{
public:
ChannelMatteNode(bNode *editorNode);
void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
};
#endif // COM_ChannelMatteNODE_H

View File

@ -0,0 +1,70 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Dalai Felinto
*/
#include "COM_ChromaMatteNode.h"
#include "BKE_node.h"
#include "COM_ChromaMatteOperation.h"
#include "COM_ConvertRGBToYCCOperation.h"
#include "COM_SetAlphaOperation.h"
ChromaMatteNode::ChromaMatteNode(bNode *editorNode): Node(editorNode)
{}
void ChromaMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) {
InputSocket *inputSocketImage = this->getInputSocket(0);
InputSocket *inputSocketKey = this->getInputSocket(1);
OutputSocket *outputSocketImage = this->getOutputSocket(0);
OutputSocket *outputSocketMatte = this->getOutputSocket(1);
ConvertRGBToYCCOperation *operationRGBToYCC_Image = new ConvertRGBToYCCOperation();
ConvertRGBToYCCOperation *operationRGBToYCC_Key = new ConvertRGBToYCCOperation();
operationRGBToYCC_Image->setMode(0); /* BLI_YCC_ITU_BT601 */
operationRGBToYCC_Key->setMode(0); /* BLI_YCC_ITU_BT601 */
ChromaMatteOperation *operation = new ChromaMatteOperation();
bNode* editorsnode = getbNode();
operation->setSettings((NodeChroma*)editorsnode->storage);
inputSocketImage->relinkConnections(operationRGBToYCC_Image->getInputSocket(0), true, 0, graph);
inputSocketKey->relinkConnections(operationRGBToYCC_Key->getInputSocket(0), true, 0, graph);
addLink(graph, operationRGBToYCC_Image->getOutputSocket(), operation->getInputSocket(0));
addLink(graph, operationRGBToYCC_Key->getOutputSocket(), operation->getInputSocket(1));
graph->addOperation(operationRGBToYCC_Image);
graph->addOperation(operationRGBToYCC_Key);
graph->addOperation(operation);
if (outputSocketMatte->isConnected()) {
outputSocketMatte->relinkConnections(operation->getOutputSocket());
}
SetAlphaOperation *operationAlpha = new SetAlphaOperation();
addLink(graph, operationRGBToYCC_Image->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0));
addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1));
graph->addOperation(operationAlpha);
addPreviewOperation(graph, operationAlpha->getOutputSocket(), 9);
if (outputSocketImage->isConnected()) {
outputSocketImage->relinkConnections(operationAlpha->getOutputSocket());
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Dalai Felinto
*/
#ifndef COM_ChromaMatteNODE_H
#define COM_ChromaMatteNODE_H
#include "COM_Node.h"
/**
* @brief ChromaMatteNode
* @ingroup Node
*/
class ChromaMatteNode : public Node
{
public:
ChromaMatteNode(bNode *editorNode);
void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
};
#endif // COM_ChromaMatteNODE_H

View File

@ -0,0 +1,68 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ColorBalanceNode.h"
#include "COM_ColorBalanceLGGOperation.h"
#include "COM_ColorBalanceASCCDLOperation.h"
#include "COM_ExecutionSystem.h"
#include "BKE_node.h"
#include "COM_MixBlendOperation.h"
ColorBalanceNode::ColorBalanceNode(bNode* editorNode): Node(editorNode)
{
}
void ColorBalanceNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
InputSocket *inputSocket = this->getInputSocket(0);
InputSocket *inputImageSocket = this->getInputSocket(1);
OutputSocket *outputSocket = this->getOutputSocket(0);
bNode* node = this->getbNode();
NodeColorBalance *n= (NodeColorBalance *)node->storage;
NodeOperation*operation;
if (node->custom1 == 0) {
ColorBalanceLGGOperation* operationLGG = new ColorBalanceLGGOperation();
{
int c;
for (c = 0; c < 3; c++) {
n->lift_lgg[c] = 2.0f - n->lift[c];
n->gamma_inv[c] = (n->gamma[c] != 0.0f) ? 1.0f/n->gamma[c] : 1000000.0f;
}
}
operationLGG->setGain(n->gain);
operationLGG->setLift(n->lift_lgg);
operationLGG->setGammaInv(n->gamma_inv);
operation = operationLGG;
} else {
ColorBalanceASCCDLOperation *operationCDL = new ColorBalanceASCCDLOperation();
operationCDL->setGain(n->gain);
operationCDL->setLift(n->lift);
operationCDL->setGamma(n->gamma);
operation = operationCDL;
}
inputSocket->relinkConnections(operation->getInputSocket(0), true, 0, graph);
inputImageSocket->relinkConnections(operation->getInputSocket(1), true, 0, graph);
outputSocket->relinkConnections(operation->getOutputSocket(0));
graph->addOperation(operation);
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef COM_ColorBalanceNODE_H
#define COM_ColorBalanceNODE_H
#include "COM_Node.h"
/**
* @brief ColorBalanceNode
* @ingroup Node
*/
class ColorBalanceNode : public Node
{
public:
ColorBalanceNode(bNode* editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif // COM_ColorBalanceNODE_H

View File

@ -0,0 +1,42 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ColorCorrectionNode.h"
#include "DNA_scene_types.h"
#include "COM_ColorCorrectionOperation.h"
#include "COM_ExecutionSystem.h"
ColorCorrectionNode::ColorCorrectionNode(bNode *editorNode): Node(editorNode) {
}
void ColorCorrectionNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
ColorCorrectionOperation *operation = new ColorCorrectionOperation();
bNode* editorNode = getbNode();
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0),true, 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1),true, 1, graph);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
operation->setData((NodeColorCorrection*)editorNode->storage);
operation->setRedChannelEnabled((editorNode->custom1&1)>0);
operation->setGreenChannelEnabled((editorNode->custom1&2)>0);
operation->setBlueChannelEnabled((editorNode->custom1&4)>0);
graph->addOperation(operation);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ColorCorrectionNode_h_
#define _COM_ColorCorrectionNode_h_
#include "COM_Node.h"
/**
* @brief ColorCorrectionNode
* @ingroup Node
*/
class ColorCorrectionNode: public Node {
public:
ColorCorrectionNode(bNode *editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,44 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ColorCurveNode.h"
#include "DNA_scene_types.h"
#include "COM_ColorCurveOperation.h"
#include "COM_ExecutionSystem.h"
ColorCurveNode::ColorCurveNode(bNode *editorNode): Node(editorNode) {
}
void ColorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
ColorCurveOperation *operation = new ColorCurveOperation();
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), true, 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), true, 1, graph);
this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), true, 2, graph);
this->getInputSocket(3)->relinkConnections(operation->getInputSocket(3), true, 3, graph);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
operation->setCurveMapping((CurveMapping*)this->getbNode()->storage);
graph->addOperation(operation);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ColorCurveNode_h_
#define _COM_ColorCurveNode_h_
#include "COM_Node.h"
/**
* @brief ColorCurveNode
* @ingroup Node
*/
class ColorCurveNode: public Node {
public:
ColorCurveNode(bNode *editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,67 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Dalai Felinto
*/
#include "COM_ColorMatteNode.h"
#include "BKE_node.h"
#include "COM_ColorMatteOperation.h"
#include "COM_ConvertRGBToHSVOperation.h"
#include "COM_SetAlphaOperation.h"
ColorMatteNode::ColorMatteNode(bNode *editorNode): Node(editorNode)
{}
void ColorMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) {
InputSocket *inputSocketImage = this->getInputSocket(0);
InputSocket *inputSocketKey = this->getInputSocket(1);
OutputSocket *outputSocketImage = this->getOutputSocket(0);
OutputSocket *outputSocketMatte = this->getOutputSocket(1);
ConvertRGBToHSVOperation *operationRGBToHSV_Image = new ConvertRGBToHSVOperation();
ConvertRGBToHSVOperation *operationRGBToHSV_Key = new ConvertRGBToHSVOperation();
ColorMatteOperation *operation = new ColorMatteOperation();
bNode* editorsnode = getbNode();
operation->setSettings((NodeChroma*)editorsnode->storage);
inputSocketImage->relinkConnections(operationRGBToHSV_Image->getInputSocket(0), true, 0, graph);
inputSocketKey->relinkConnections(operationRGBToHSV_Key->getInputSocket(0), true, 1, graph);
addLink(graph, operationRGBToHSV_Image->getOutputSocket(), operation->getInputSocket(0));
addLink(graph, operationRGBToHSV_Key->getOutputSocket(), operation->getInputSocket(1));
if (outputSocketMatte->isConnected()) {
outputSocketMatte->relinkConnections(operation->getOutputSocket(0));
}
graph->addOperation(operationRGBToHSV_Image);
graph->addOperation(operationRGBToHSV_Key);
graph->addOperation(operation);
SetAlphaOperation *operationAlpha = new SetAlphaOperation();
addLink(graph, operationRGBToHSV_Image->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0));
addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1));
graph->addOperation(operationAlpha);
addPreviewOperation(graph, operationAlpha->getOutputSocket(), 9);
if (outputSocketImage->isConnected()) {
outputSocketImage->relinkConnections(operationAlpha->getOutputSocket());
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Dalai Felinto
*/
#ifndef COM_ColorMatteNODE_H
#define COM_ColorMatteNODE_H
#include "COM_Node.h"
/**
* @brief ColorMatteNode
* @ingroup Node
*/
class ColorMatteNode : public Node
{
public:
ColorMatteNode(bNode *editorNode);
void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
};
#endif // COM_ColorMatteNODE_H

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ColorNode.h"
#include "DNA_scene_types.h"
#include "COM_SetColorOperation.h"
#include "COM_ExecutionSystem.h"
ColorNode::ColorNode(bNode *editorNode): Node(editorNode) {
}
void ColorNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
SetColorOperation *operation = new SetColorOperation();
bNodeSocket* socket = this->getEditorOutputSocket(0);
bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA*)socket->default_value;
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
operation->setChannels(dval->value);
graph->addOperation(operation);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ColorNode_h_
#define _COM_ColorNode_h_
#include "COM_Node.h"
/**
* @brief ColorNode
* @ingroup Node
*/
class ColorNode: public Node {
public:
ColorNode(bNode *editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,51 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ColorRampNode.h"
#include "COM_ExecutionSystem.h"
#include "BKE_node.h"
#include "COM_ColorRampOperation.h"
#include "COM_SeparateChannelOperation.h"
#include "DNA_texture_types.h"
ColorRampNode::ColorRampNode(bNode* editorNode): Node(editorNode)
{}
void ColorRampNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
InputSocket *inputSocket = this->getInputSocket(0);
OutputSocket *outputSocket = this->getOutputSocket(0);
OutputSocket *outputSocketAlpha = this->getOutputSocket(1);
bNode* editorNode = this->getbNode();
ColorRampOperation * operation = new ColorRampOperation();
outputSocket->relinkConnections(operation->getOutputSocket(0));
if (outputSocketAlpha->isConnected()) {
SeparateChannelOperation *operation2 = new SeparateChannelOperation();
outputSocketAlpha->relinkConnections(operation2->getOutputSocket());
addLink(graph, operation->getOutputSocket(), operation2->getInputSocket(0));
operation2->setChannel(3);
graph->addOperation(operation2);
}
operation->setColorBand((ColorBand*)editorNode->storage);
inputSocket->relinkConnections(operation->getInputSocket(0), true, 0, graph);
graph->addOperation(operation);
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef COM_ColorRampNODE_H
#define COM_ColorRampNODE_H
#include "COM_Node.h"
/**
* @brief ColorRampNode
* @ingroup Node
*/
class ColorRampNode : public Node
{
public:
ColorRampNode(bNode* editorNode);
void convertToOperations(ExecutionSystem* graph, CompositorContext * context);
};
#endif // COM_ColorRampNODE_H

View File

@ -0,0 +1,55 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ColorSpillNode.h"
#include "BKE_node.h"
#include "COM_ColorSpillOperation.h"
ColorSpillNode::ColorSpillNode(bNode *editorNode): Node(editorNode)
{}
void ColorSpillNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) {
InputSocket *inputSocketImage = this->getInputSocket(0);
InputSocket *inputSocketFac = this->getInputSocket(1);
OutputSocket *outputSocketImage = this->getOutputSocket(0);
bNode* editorsnode = getbNode();
ColorSpillOperation *operation;
if (editorsnode->custom2 == 0) {
// Simple color spill
operation = new ColorSpillOperation();
} else {
// Average color spill
operation = new ColorSpillAverageOperation();
}
operation->setSettings((NodeColorspill*)editorsnode->storage);
operation->setSpillChannel(editorsnode->custom1-1); // Channel for spilling
inputSocketImage->relinkConnections(operation->getInputSocket(0), true, 0, graph);
inputSocketFac->relinkConnections(operation->getInputSocket(1), true, 1, graph);
outputSocketImage->relinkConnections(operation->getOutputSocket());
graph->addOperation(operation);
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef COM_ColorSpillNODE_H
#define COM_ColorSpillNODE_H
#include "COM_Node.h"
/**
* @brief ColorSpillNode
* @ingroup Node
*/
class ColorSpillNode : public Node
{
public:
ColorSpillNode(bNode *editorNode);
void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
};
#endif // COM_ColorSpillNODE_H

View File

@ -0,0 +1,39 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ColorToBWNode.h"
#include "COM_ConvertColorToBWOperation.h"
#include "COM_ExecutionSystem.h"
ColourToBWNode::ColourToBWNode(bNode *editorNode): Node(editorNode) {
}
void ColourToBWNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
InputSocket *colourSocket = this->getInputSocket(0);
OutputSocket *valueSocket = this->getOutputSocket(0);
ConvertColorToBWOperation *convertProg = new ConvertColorToBWOperation();
colourSocket->relinkConnections(convertProg->getInputSocket(0), true, 0, graph);
valueSocket->relinkConnections(convertProg->getOutputSocket(0));
graph->addOperation(convertProg);
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ColourToBWNode_h
#define _COM_ColourToBWNode_h
#include "COM_Node.h"
#include "DNA_node_types.h"
/**
* @brief ColourToBWNode
* @ingroup Node
*/
class ColourToBWNode : public Node {
public:
ColourToBWNode(bNode *editorNode);
void convertToOperations(ExecutionSystem *graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,43 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_CombineHSVANode.h"
#include "COM_CombineChannelsOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_SetValueOperation.h"
#include "COM_ConvertHSVToRGBOperation.h"
CombineHSVANode::CombineHSVANode(bNode *editorNode): CombineRGBANode(editorNode) {
}
void CombineHSVANode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
ConvertHSVToRGBOperation *operation = new ConvertHSVToRGBOperation();
OutputSocket *outputSocket = this->getOutputSocket(0);
if (outputSocket->isConnected()) {
outputSocket->relinkConnections(operation->getOutputSocket());
addLink(graph, outputSocket, operation->getInputSocket(0));
}
graph->addOperation(operation);
CombineRGBANode::convertToOperations(graph, context);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_CombineHSVANode_h
#define _COM_CombineHSVANode_h
#include "COM_Node.h"
#include "DNA_node_types.h"
#include "COM_CombineRGBANode.h"
/**
* @brief CombineHSVANode
* @ingroup Node
*/
class CombineHSVANode : public CombineRGBANode {
public:
CombineHSVANode(bNode *editorNode);
void convertToOperations(ExecutionSystem *graph, CompositorContext * context);
};
#endif

View File

@ -0,0 +1,59 @@
/*
* Copyright 2011, Blender Foundation.
*
* 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.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_CombineRGBANode.h"
#include "COM_CombineChannelsOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_SetValueOperation.h"
#include "DNA_material_types.h" // the ramp types
CombineRGBANode::CombineRGBANode(bNode *editorNode): Node(editorNode) {
}
void CombineRGBANode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) {
InputSocket *inputRSocket = this->getInputSocket(0);
InputSocket *inputGSocket = this->getInputSocket(1);
InputSocket *inputBSocket = this->getInputSocket(2);
InputSocket *inputASocket = this->getInputSocket(3);
OutputSocket *outputSocket = this->getOutputSocket(0);
CombineChannelsOperation *operation = new CombineChannelsOperation();
if (inputRSocket->isConnected()) {
operation->setResolutionInputSocketIndex(0);
} else if (inputGSocket->isConnected()) {
operation->setResolutionInputSocketIndex(1);
} else if (inputBSocket->isConnected()) {
operation->setResolutionInputSocketIndex(2);
} else {
operation->setResolutionInputSocketIndex(3);
}
inputRSocket->relinkConnections(operation->getInputSocket(0), true, 0, graph);
inputGSocket->relinkConnections(operation->getInputSocket(1), true, 1, graph);
inputBSocket->relinkConnections(operation->getInputSocket(2), true, 2, graph);
inputASocket->relinkConnections(operation->getInputSocket(3), true, 3, graph);
outputSocket->relinkConnections(operation->getOutputSocket(0));
graph->addOperation(operation);
}

Some files were not shown because too many files have changed in this diff Show More