svn merge -r39900:40000 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorCampbell Barton <ideasman42@gmail.com>
Tue, 13 Sep 2011 09:07:20 +0000 (09:07 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 13 Sep 2011 09:07:20 +0000 (09:07 +0000)
274 files changed:
CMakeLists.txt
build_files/cmake/macros.cmake
build_files/scons/config/win32-mingw-config.py
doc/python_api/rst/bgl.rst
doc/python_api/rst/info_quickstart.rst
doc/python_api/rst/info_tips_and_tricks.rst
doc/python_api/sphinx_doc_gen.py
intern/ghost/intern/GHOST_NDOFManager.cpp
intern/guardedalloc/MEM_sys_types.h
intern/opennl/CMakeLists.txt
intern/smoke/CMakeLists.txt
intern/smoke/SConscript
intern/smoke/intern/FFT_NOISE.h
intern/smoke/intern/WTURBULENCE.cpp
release/datafiles/blenderbuttons
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_global.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_sound.h
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/sound.c
source/blender/blenkernel/intern/texture.c
source/blender/blenlib/BLI_math_inline.h
source/blender/blenlib/BLI_math_matrix.h
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/intern/math_matrix.c
source/blender/blenlib/intern/math_vector.c
source/blender/blenlib/intern/noise.c
source/blender/blenlib/intern/string.c
source/blender/blenloader/BLO_sys_types.h
source/blender/blenloader/CMakeLists.txt
source/blender/blenloader/SConscript
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/collada/AnimationExporter.cpp
source/blender/collada/AnimationImporter.cpp
source/blender/collada/AnimationImporter.h
source/blender/collada/ArmatureImporter.cpp
source/blender/collada/CMakeLists.txt
source/blender/collada/DocumentExporter.cpp
source/blender/collada/DocumentImporter.cpp
source/blender/collada/ErrorHandler.cpp [new file with mode: 0644]
source/blender/collada/ErrorHandler.h [new file with mode: 0644]
source/blender/collada/MeshImporter.cpp
source/blender/collada/SceneExporter.cpp [new file with mode: 0644]
source/blender/collada/SceneExporter.h [new file with mode: 0644]
source/blender/collada/TransformReader.cpp
source/blender/collada/collada.cpp
source/blender/editors/animation/anim_ops.c
source/blender/editors/datafiles/blenderbuttons.c
source/blender/editors/gpencil/CMakeLists.txt
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/gpencil_edit.c
source/blender/editors/gpencil/gpencil_intern.h
source/blender/editors/gpencil/gpencil_ops.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/gpencil/gpencil_undo.c [new file with mode: 0644]
source/blender/editors/include/ED_gpencil.h
source/blender/editors/include/ED_node.h
source/blender/editors/include/ED_sequencer.h
source/blender/editors/include/UI_icons.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/object/object_hook.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_relations.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/sound/sound_ops.c
source/blender/editors/space_graph/graph_ops.c
source/blender/editors/space_logic/logic_ops.c
source/blender/editors/space_logic/logic_window.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_buttons.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_header.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_node/node_ops.c
source/blender/editors/space_node/node_select.c
source/blender/editors/space_node/node_state.c
source/blender/editors/space_node/space_node.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_sequencer/space_sequencer.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/util/undo.c
source/blender/gpu/SConscript
source/blender/imbuf/intern/cineon/cineonlib.c
source/blender/imbuf/intern/cineon/logImageCore.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesdna/DNA_node_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/RNA_types.h
source/blender/makesrna/SConscript
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/SConscript
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_actuator.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_nodetree_types.h
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_particle.c
source/blender/makesrna/intern/rna_rna.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_screen.c
source/blender/makesrna/intern/rna_smoke.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_texture.c
source/blender/makesrna/intern/rna_texture_api.c
source/blender/makesrna/intern/rna_wm.c
source/blender/makesrna/intern/rna_world.c
source/blender/modifiers/CMakeLists.txt
source/blender/modifiers/MOD_modifiertypes.h
source/blender/modifiers/SConscript
source/blender/modifiers/intern/MOD_screw.c
source/blender/modifiers/intern/MOD_util.c
source/blender/modifiers/intern/MOD_weightvg_util.c [new file with mode: 0644]
source/blender/modifiers/intern/MOD_weightvg_util.h [new file with mode: 0644]
source/blender/modifiers/intern/MOD_weightvgedit.c [new file with mode: 0644]
source/blender/modifiers/intern/MOD_weightvgmix.c [new file with mode: 0644]
source/blender/modifiers/intern/MOD_weightvgproximity.c [new file with mode: 0644]
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_composite.h [moved from source/blender/nodes/CMP_node.h with 94% similarity]
source/blender/nodes/NOD_shader.h [moved from source/blender/nodes/SHD_node.h with 90% similarity]
source/blender/nodes/NOD_socket.h [new file with mode: 0644]
source/blender/nodes/NOD_texture.h [moved from source/blender/nodes/TEX_node.h with 91% similarity]
source/blender/nodes/SConscript
source/blender/nodes/composite/node_composite_tree.c [new file with mode: 0644]
source/blender/nodes/composite/node_composite_util.c [moved from source/blender/nodes/intern/CMP_util.c with 99% similarity]
source/blender/nodes/composite/node_composite_util.h [moved from source/blender/nodes/intern/CMP_util.h with 98% similarity]
source/blender/nodes/composite/nodes/node_composite_alphaOver.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c with 87% similarity]
source/blender/nodes/composite/nodes/node_composite_bilateralblur.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c with 91% similarity]
source/blender/nodes/composite/nodes/node_composite_blur.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_blur.c with 96% similarity]
source/blender/nodes/composite/nodes/node_composite_brightness.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_brightness.c with 81% similarity]
source/blender/nodes/composite/nodes/node_composite_channelMatte.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c with 90% similarity]
source/blender/nodes/composite/nodes/node_composite_chromaMatte.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c with 89% similarity]
source/blender/nodes/composite/nodes/node_composite_colorMatte.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c with 85% similarity]
source/blender/nodes/composite/nodes/node_composite_colorSpill.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_colorSpill.c with 93% similarity]
source/blender/nodes/composite/nodes/node_composite_colorbalance.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_colorbalance.c with 91% similarity]
source/blender/nodes/composite/nodes/node_composite_common.c [new file with mode: 0644]
source/blender/nodes/composite/nodes/node_composite_composite.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_composite.c with 87% similarity]
source/blender/nodes/composite/nodes/node_composite_crop.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_crop.c with 87% similarity]
source/blender/nodes/composite/nodes/node_composite_curves.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_curves.c with 78% similarity]
source/blender/nodes/composite/nodes/node_composite_defocus.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_defocus.c with 97% similarity]
source/blender/nodes/composite/nodes/node_composite_diffMatte.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c with 85% similarity]
source/blender/nodes/composite/nodes/node_composite_dilate.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_dilate.c with 88% similarity]
source/blender/nodes/composite/nodes/node_composite_directionalblur.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c with 88% similarity]
source/blender/nodes/composite/nodes/node_composite_displace.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_displace.c with 89% similarity]
source/blender/nodes/composite/nodes/node_composite_distanceMatte.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c with 85% similarity]
source/blender/nodes/composite/nodes/node_composite_filter.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_filter.c with 93% similarity]
source/blender/nodes/composite/nodes/node_composite_flip.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_flip.c with 87% similarity]
source/blender/nodes/composite/nodes/node_composite_gamma.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_gamma.c with 82% similarity]
source/blender/nodes/composite/nodes/node_composite_glare.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_glare.c with 96% similarity]
source/blender/nodes/composite/nodes/node_composite_hueSatVal.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c with 83% similarity]
source/blender/nodes/composite/nodes/node_composite_huecorrect.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_huecorrect.c with 88% similarity]
source/blender/nodes/composite/nodes/node_composite_idMask.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_idMask.c with 86% similarity]
source/blender/nodes/composite/nodes/node_composite_image.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_image.c with 94% similarity]
source/blender/nodes/composite/nodes/node_composite_invert.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_invert.c with 85% similarity]
source/blender/nodes/composite/nodes/node_composite_lensdist.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_lensdist.c with 90% similarity]
source/blender/nodes/composite/nodes/node_composite_levels.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_levels.c with 87% similarity]
source/blender/nodes/composite/nodes/node_composite_lummaMatte.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c with 84% similarity]
source/blender/nodes/composite/nodes/node_composite_mapUV.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_mapUV.c with 91% similarity]
source/blender/nodes/composite/nodes/node_composite_mapValue.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_mapValue.c with 82% similarity]
source/blender/nodes/composite/nodes/node_composite_math.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_math.c with 90% similarity]
source/blender/nodes/composite/nodes/node_composite_mixrgb.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_mixrgb.c with 83% similarity]
source/blender/nodes/composite/nodes/node_composite_normal.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_normal.c with 74% similarity]
source/blender/nodes/composite/nodes/node_composite_normalize.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_normalize.c with 87% similarity]
source/blender/nodes/composite/nodes/node_composite_outputFile.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c with 87% similarity]
source/blender/nodes/composite/nodes/node_composite_premulkey.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c with 81% similarity]
source/blender/nodes/composite/nodes/node_composite_rgb.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_rgb.c with 66% similarity]
source/blender/nodes/composite/nodes/node_composite_rotate.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_rotate.c with 85% similarity]
source/blender/nodes/composite/nodes/node_composite_scale.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_scale.c with 85% similarity]
source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_sepcombHSVA.c with 81% similarity]
source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_sepcombRGBA.c with 79% similarity]
source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_sepcombYCCA.c with 87% similarity]
source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_sepcombYUVA.c with 80% similarity]
source/blender/nodes/composite/nodes/node_composite_setalpha.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_setalpha.c with 83% similarity]
source/blender/nodes/composite/nodes/node_composite_splitViewer.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_splitViewer.c with 89% similarity]
source/blender/nodes/composite/nodes/node_composite_texture.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_texture.c with 91% similarity]
source/blender/nodes/composite/nodes/node_composite_tonemap.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c with 90% similarity]
source/blender/nodes/composite/nodes/node_composite_translate.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_translate.c with 75% similarity]
source/blender/nodes/composite/nodes/node_composite_valToRgb.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_valToRgb.c with 81% similarity]
source/blender/nodes/composite/nodes/node_composite_value.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_value.c with 62% similarity]
source/blender/nodes/composite/nodes/node_composite_vecBlur.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_vecBlur.c with 82% similarity]
source/blender/nodes/composite/nodes/node_composite_viewer.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_viewer.c with 87% similarity]
source/blender/nodes/composite/nodes/node_composite_zcombine.c [moved from source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c with 90% similarity]
source/blender/nodes/intern/SHD_util.c [deleted file]
source/blender/nodes/intern/node_common.c [new file with mode: 0644]
source/blender/nodes/intern/node_common.h [new file with mode: 0644]
source/blender/nodes/intern/node_exec.c [new file with mode: 0644]
source/blender/nodes/intern/node_exec.h [new file with mode: 0644]
source/blender/nodes/intern/node_socket.c [new file with mode: 0644]
source/blender/nodes/intern/node_util.c
source/blender/nodes/intern/node_util.h
source/blender/nodes/shader/node_shader_tree.c [new file with mode: 0644]
source/blender/nodes/shader/node_shader_util.c [new file with mode: 0644]
source/blender/nodes/shader/node_shader_util.h [moved from source/blender/nodes/intern/SHD_util.h with 88% similarity]
source/blender/nodes/shader/nodes/node_shader_camera.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_camera.c with 80% similarity]
source/blender/nodes/shader/nodes/node_shader_common.c [new file with mode: 0644]
source/blender/nodes/shader/nodes/node_shader_curves.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_curves.c with 77% similarity]
source/blender/nodes/shader/nodes/node_shader_dynamic.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c with 99% similarity]
source/blender/nodes/shader/nodes/node_shader_geom.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_geom.c with 84% similarity]
source/blender/nodes/shader/nodes/node_shader_hueSatVal.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c with 77% similarity]
source/blender/nodes/shader/nodes/node_shader_invert.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_invert.c with 82% similarity]
source/blender/nodes/shader/nodes/node_shader_mapping.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_mapping.c with 87% similarity]
source/blender/nodes/shader/nodes/node_shader_material.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_material.c with 77% similarity]
source/blender/nodes/shader/nodes/node_shader_math.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_math.c with 93% similarity]
source/blender/nodes/shader/nodes/node_shader_mixRgb.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_mixRgb.c with 80% similarity]
source/blender/nodes/shader/nodes/node_shader_normal.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_normal.c with 69% similarity]
source/blender/nodes/shader/nodes/node_shader_output.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_output.c with 85% similarity]
source/blender/nodes/shader/nodes/node_shader_rgb.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_rgb.c with 66% similarity]
source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c with 74% similarity]
source/blender/nodes/shader/nodes/node_shader_squeeze.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_squeeze.c with 72% similarity]
source/blender/nodes/shader/nodes/node_shader_texture.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_texture.c with 89% similarity]
source/blender/nodes/shader/nodes/node_shader_valToRgb.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_valToRgb.c with 78% similarity]
source/blender/nodes/shader/nodes/node_shader_value.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_value.c with 63% similarity]
source/blender/nodes/shader/nodes/node_shader_vectMath.c [moved from source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c with 88% similarity]
source/blender/nodes/texture/node_texture_tree.c [new file with mode: 0644]
source/blender/nodes/texture/node_texture_util.c [moved from source/blender/nodes/intern/TEX_util.c with 78% similarity]
source/blender/nodes/texture/node_texture_util.h [moved from source/blender/nodes/intern/TEX_util.h with 93% similarity]
source/blender/nodes/texture/nodes/node_texture_at.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_at.c with 82% similarity]
source/blender/nodes/texture/nodes/node_texture_bricks.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_bricks.c with 76% similarity]
source/blender/nodes/texture/nodes/node_texture_checker.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_checker.c with 79% similarity]
source/blender/nodes/texture/nodes/node_texture_common.c [new file with mode: 0644]
source/blender/nodes/texture/nodes/node_texture_compose.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_compose.c with 71% similarity]
source/blender/nodes/texture/nodes/node_texture_coord.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_coord.c with 85% similarity]
source/blender/nodes/texture/nodes/node_texture_curves.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_curves.c with 80% similarity]
source/blender/nodes/texture/nodes/node_texture_decompose.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_decompose.c with 80% similarity]
source/blender/nodes/texture/nodes/node_texture_distance.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_distance.c with 84% similarity]
source/blender/nodes/texture/nodes/node_texture_hueSatVal.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c with 78% similarity]
source/blender/nodes/texture/nodes/node_texture_image.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_image.c with 88% similarity]
source/blender/nodes/texture/nodes/node_texture_invert.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_invert.c with 82% similarity]
source/blender/nodes/texture/nodes/node_texture_math.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_math.c with 88% similarity]
source/blender/nodes/texture/nodes/node_texture_mixRgb.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c with 79% similarity]
source/blender/nodes/texture/nodes/node_texture_output.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_output.c with 89% similarity]
source/blender/nodes/texture/nodes/node_texture_proc.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_proc.c with 72% similarity]
source/blender/nodes/texture/nodes/node_texture_rotate.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_rotate.c with 84% similarity]
source/blender/nodes/texture/nodes/node_texture_scale.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_scale.c with 84% similarity]
source/blender/nodes/texture/nodes/node_texture_texture.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_texture.c with 84% similarity]
source/blender/nodes/texture/nodes/node_texture_translate.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_translate.c with 82% similarity]
source/blender/nodes/texture/nodes/node_texture_valToNor.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c with 80% similarity]
source/blender/nodes/texture/nodes/node_texture_valToRgb.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c with 78% similarity]
source/blender/nodes/texture/nodes/node_texture_viewer.c [moved from source/blender/nodes/intern/TEX_nodes/TEX_viewer.c with 83% similarity]
source/blender/python/generic/bpy_internal_import.c
source/blender/python/intern/bpy_driver.c
source/blender/python/intern/bpy_rna.c
source/blender/python/mathutils/mathutils_geometry.c
source/blender/render/intern/source/render_texture.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_operators.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/CMakeLists.txt
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/BL_ArmatureObject.cpp
source/gameengine/Converter/BL_SkinDeformer.cpp
source/gameengine/Converter/KX_BlenderSceneConverter.cpp
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Expressions/ListValue.cpp
source/gameengine/Expressions/Value.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_SoundActuator.cpp
source/gameengine/VideoTexture/CMakeLists.txt

index 38ce86898552da0509a9143d596c3362e15507b3..8b5693fb1aaecfb84b5fa68bb323eca7b6223e75 100644 (file)
@@ -797,7 +797,7 @@ elseif(WIN32)
        else()
                # keep GCC spesific stuff here
                if(CMAKE_COMPILER_IS_GNUCC)
-                       set(PLATFORM_LINKLIBS "-lshell32 -lshfolder -lgdi32 -lmsvcrt -lwinmm -lmingw32 -lm -lws2_32 -lz -lstdc++ -lole32 -luuid")
+                       set(PLATFORM_LINKLIBS "-lshell32 -lshfolder -lgdi32 -lmsvcrt -lwinmm -lmingw32 -lm -lws2_32 -lz -lstdc++ -lole32 -luuid -lwsock32")
                        set(PLATFORM_CFLAGS "-pipe -funsigned-char -fno-strict-aliasing")
 
                        add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
@@ -1267,6 +1267,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
        ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
        ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
        ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_WRITE_STRINGS -Wwrite-strings)
+       ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNDEFINED -Wundef)
        # disable because it gives warnings for printf() & friends.
        # ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion)
        ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
@@ -1274,6 +1275,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
        ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
        ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
        ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
+       ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEFINED -Wundef)
 
 elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
 
index 58938c8b0b02d57b30aa3b5b78a959a60e666b69..d09215d040df8a528c1e6fd11fa78a4df888487f 100644 (file)
@@ -392,6 +392,7 @@ macro(remove_strict_flags)
                remove_flag("-Wstrict-prototypes")
                remove_flag("-Wunused-parameter")
                remove_flag("-Wwrite-strings")
+               remove_flag("-Wundef")
                remove_flag("-Wshadow")
                remove_flag("-Werror=[^ ]+")
                remove_flag("-Werror")
index c815b76ef73ff4412080bb5ef5aa2c0675e99a0b..37d693db5609ed3dcde1cdb131ce4633082cfe3f 100644 (file)
@@ -174,7 +174,7 @@ C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wstrict-pro
 
 CC_WARN = [ '-Wall' ]
 
-LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid']
+LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid', '-lwsock32']
 
 PLATFORM_LINKFLAGS = ['--stack,2097152']
 
index 5f3158bf5dd2ec82d4bcd3dc5ae097ba01f7e7cc..61400351d166fd59ec4493e54025563f50887ccf 100644 (file)
@@ -56,9 +56,9 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    :type n: int
    :arg n: Specifies the number of textures to be queried.
-   :type textures: :class:`Buffer` object I{type GL_INT}
+   :type textures: :class:`bgl.Buffer` object I{type GL_INT}
    :arg textures: Specifies an array containing the names of the textures to be queried
-   :type residences: :class:`Buffer` object I{type GL_INT}(boolean)
+   :type residences: :class:`bgl.Buffer` object I{type GL_INT}(boolean)
    :arg residences: An array in which the texture residence status in returned.
       The residence status of a texture named by an element of textures is
       returned in the corresponding element of residences.
@@ -101,7 +101,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :type xmove, ymove: float
    :arg xmove, ymove: Specify the x and y offsets to be added to the current raster position after
       the bitmap is drawn.
-   :type bitmap: :class:`Buffer` object I{type GL_BYTE}
+   :type bitmap: :class:`bgl.Buffer` object I{type GL_BYTE}
    :arg bitmap: Specifies the address of the bitmap image.
 
 
@@ -139,7 +139,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg n: Specifies the number of display lists to be executed.
    :type type: Enumerated constant
    :arg type: Specifies the type of values in lists.
-   :type lists: :class:`Buffer` object
+   :type lists: :class:`bgl.Buffer` object
    :arg lists: Specifies the address of an array of name offsets in the display list.
       The pointer type is void because the offsets can be bytes, shorts, ints, or floats,
       depending on the value of type.
@@ -217,7 +217,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    :type plane: Enumerated constant
    :arg plane: Specifies which clipping plane is being positioned.
-   :type equation: :class:`Buffer` object I{type GL_FLOAT}(double)
+   :type equation: :class:`bgl.Buffer` object I{type GL_FLOAT}(double)
    :arg equation: Specifies the address of an array of four double- precision
       floating-point values. These values are interpreted as a plane equation.
 
@@ -340,7 +340,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    :type n: int
    :arg n: Specifies the number of textures to be deleted
-   :type textures: :class:`Buffer` I{GL_INT}
+   :type textures: :class:`bgl.Buffer` I{GL_INT}
    :arg textures: Specifies an array of textures to be deleted
 
 
@@ -413,7 +413,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg format: Specifies the format of the pixel data.
    :type type: Enumerated constant
    :arg type: Specifies the data type for pixels.
-   :type pixels: :class:`Buffer` object
+   :type pixels: :class:`bgl.Buffer` object
    :arg pixels: Specifies a pointer to the pixel data.
 
 
@@ -512,7 +512,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :type type: Enumerated constant
    :arg type: Specifies a symbolic constant that describes the information that
       will be returned for each vertex.
-   :type buffer: :class:`Buffer` object I{GL_FLOAT}
+   :type buffer: :class:`bgl.Buffer` object I{GL_FLOAT}
    :arg buffer: Returns the feedback data.
 
 
@@ -592,7 +592,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    :type n: int
    :arg n: Specifies the number of textures name to be generated.
-   :type textures: :class:`Buffer` object I{type GL_INT}
+   :type textures: :class:`bgl.Buffer` object I{type GL_INT}
    :arg textures: Specifies an array in which the generated textures names are stored.
 
 
@@ -620,7 +620,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg plane: Specifies a clipping plane. The number of clipping planes depends on the
       implementation, but at least six clipping planes are supported. They are identified by
       symbolic names of the form GL_CLIP_PLANEi where 0 < i < GL_MAX_CLIP_PLANES.
-   :type equation:  :class:`Buffer` object I{type GL_FLOAT}
+   :type equation:  :class:`bgl.Buffer` object I{type GL_FLOAT}
    :arg equation:  Returns four float (double)-precision values that are the coefficients of the
       plane equation of plane in eye coordinates. The initial value is (0, 0, 0, 0).
 
@@ -646,7 +646,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
       names of the form GL_LIGHTi where 0 < i < GL_MAX_LIGHTS.
    :type pname: Enumerated constant
    :arg pname: Specifies a light source parameter for light.
-   :type params:  :class:`Buffer` object. Depends on function prototype.
+   :type params:  :class:`bgl.Buffer` object. Depends on function prototype.
    :arg params: Returns the requested data.
 
 
@@ -662,7 +662,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg target: Specifies the symbolic name of a map.
    :type query: Enumerated constant
    :arg query: Specifies which parameter to return.
-   :type v: :class:`Buffer` object. Depends on function prototype.
+   :type v: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg v: Returns the requested data.
 
 
@@ -679,7 +679,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
       representing the front and back materials, respectively.
    :type pname: Enumerated constant
    :arg pname: Specifies the material parameter to return.
-   :type params: :class:`Buffer` object. Depends on function prototype.
+   :type params: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg params: Returns the requested data.
 
 
@@ -693,7 +693,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    :type map:  Enumerated constant
    :arg map: Specifies the name of the pixel map to return.
-   :type values: :class:`Buffer` object. Depends on function prototype.
+   :type values: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg values: Returns the pixel map contents.
 
 
@@ -703,7 +703,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/getpolygonstipple.html>`_
 
-   :type mask: :class:`Buffer` object I{type GL_BYTE}
+   :type mask: :class:`bgl.Buffer` object I{type GL_BYTE}
    :arg mask: Returns the stipple pattern. The initial value is all 1's.
 
 
@@ -730,7 +730,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg target: Specifies a texture environment. Must be GL_TEXTURE_ENV.
    :type pname: Enumerated constant
    :arg pname: Specifies the symbolic name of a texture environment parameter.
-   :type params: :class:`Buffer` object. Depends on function prototype.
+   :type params: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg params: Returns the requested data.
 
 
@@ -746,7 +746,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg coord: Specifies a texture coordinate.
    :type pname: Enumerated constant
    :arg pname: Specifies the symbolic name of the value(s) to be returned.
-   :type params: :class:`Buffer` object. Depends on function prototype.
+   :type params: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg params: Returns the requested data.
 
 
@@ -765,7 +765,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg format: Specifies a pixel format for the returned data.
    :type type: Enumerated constant
    :arg type: Specifies a pixel type for the returned data.
-   :type pixels: :class:`Buffer` object.
+   :type pixels: :class:`bgl.Buffer` object.
    :arg pixels: Returns the texture image. Should be a pointer to an array of the
       type specified by type
 
@@ -785,7 +785,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
       Level 0 is the base image level. Level n is the nth mipmap reduction image.
    :type pname: Enumerated constant
    :arg pname: Specifies the symbolic name of a texture parameter.
-   :type params: :class:`Buffer` object. Depends on function prototype.
+   :type params: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg params: Returns the requested data.
 
 
@@ -801,7 +801,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg target: Specifies the symbolic name of the target texture.
    :type pname: Enumerated constant
    :arg pname: Specifies the symbolic name the target texture.
-   :type params: :class:`Buffer` object. Depends on function prototype.
+   :type params: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg params: Returns the texture parameters.
 
 
@@ -826,7 +826,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/index_.html>`_
 
-   :type c: :class:`Buffer` object. Depends on function prototype.
+   :type c: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg c: Specifies a pointer to a one element array that contains the new value for
       the current color index.
 
@@ -956,7 +956,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/loadmatrix.html>`_
 
-   :type m: :class:`Buffer` object. Depends on function prototype.
+   :type m: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg m: Specifies a pointer to 16 consecutive values, which are used as the elements
       of a 4x4 column-major matrix.
 
@@ -1002,7 +1002,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
       occupy contiguous memory locations.
    :type order: int
    :arg order: Specifies the number of control points. Must be positive.
-   :type points: :class:`Buffer` object. Depends on function prototype.
+   :type points: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg points: Specifies a pointer to the array of control points.
 
 
@@ -1043,7 +1043,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :type vorder: int
    :arg vorder: Specifies the dimension of the control point array in the v axis.
       Must be positive. The initial value is 1.
-   :type points: :class:`Buffer` object. Depends on function prototype.
+   :type points: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg points: Specifies a pointer to the array of control points.
 
 
@@ -1103,7 +1103,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/multmatrix.html>`_
 
-   :type m: :class:`Buffer` object. Depends on function prototype.
+   :type m: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg m: Points to 16 consecutive values that are used as the elements of a 4x4 column
       major matrix.
 
@@ -1132,7 +1132,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :type nx, ny, nz: Depends on function prototype. (non - 'v' prototypes only)
    :arg nx, ny, nz: Specify the x, y, and z coordinates of the new current normal.
       The initial value of the current normal is the unit vector, (0, 0, 1).
-   :type v: :class:`Buffer` object. Depends on function prototype. ('v' prototypes)
+   :type v: :class:`bgl.Buffer` object. Depends on function prototype. ('v' prototypes)
    :arg v: Specifies a pointer to an array of three elements: the x, y, and z coordinates
       of the new current normal.
 
@@ -1177,7 +1177,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg map: Specifies a symbolic map name.
    :type mapsize: int
    :arg mapsize: Specifies the size of the map being defined.
-   :type values: :class:`Buffer` object. Depends on function prototype.
+   :type values: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg values: Specifies an array of mapsize values.
 
 
@@ -1266,7 +1266,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/polygonstipple.html>`_
 
-   :type mask: :class:`Buffer` object I{type GL_BYTE}
+   :type mask: :class:`bgl.Buffer` object I{type GL_BYTE}
    :arg mask: Specifies a pointer to a 32x32 stipple pattern that will be unpacked
       from memory in the same way that glDrawPixels unpacks pixels.
 
@@ -1307,9 +1307,9 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    :type n: int
    :arg n: Specifies the number of textures to be prioritized.
-   :type textures: :class:`Buffer` I{type GL_INT}
+   :type textures: :class:`bgl.Buffer` I{type GL_INT}
    :arg textures: Specifies an array containing the names of the textures to be prioritized.
-   :type priorities: :class:`Buffer` I{type GL_FLOAT}
+   :type priorities: :class:`bgl.Buffer` I{type GL_FLOAT}
    :arg priorities: Specifies an array containing the texture priorities.
       A priority given in an element of priorities applies to the texture named
       by the corresponding element of textures.
@@ -1417,7 +1417,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg format: Specifies the format of the pixel data.
    :type type: Enumerated constant
    :arg type: Specifies the data type of the pixel data.
-   :type pixels: :class:`Buffer` object
+   :type pixels: :class:`bgl.Buffer` object
    :arg pixels: Returns the pixel data.
 
 
@@ -1496,7 +1496,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    :type size: int
    :arg size: Specifies the size of buffer
-   :type buffer: :class:`Buffer` I{type GL_INT}
+   :type buffer: :class:`bgl.Buffer` I{type GL_INT}
    :arg buffer: Returns the selection data
 
 
@@ -1575,7 +1575,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :type s, t, r, q: Depends on function prototype. (r and q for '3' and '4' prototypes only)
    :arg s, t, r, q: Specify s, t, r, and q texture coordinates. Not all parameters are
       present in all forms of the command.
-   :type v: :class:`Buffer` object. Depends on function prototype. (for 'v' prototypes only)
+   :type v: :class:`bgl.Buffer` object. Depends on function prototype. (for 'v' prototypes only)
    :arg v: Specifies a pointer to an array of one, two, three, or four elements,
       which in turn specify the s, t, r, and q texture coordinates.
 
@@ -1642,7 +1642,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg format: Specifies the format of the pixel data.
    :type type: Enumerated constant
    :arg type: Specifies the data type of the pixel data.
-   :type pixels: :class:`Buffer` object.
+   :type pixels: :class:`bgl.Buffer` object.
    :arg pixels: Specifies a pointer to the image data in memory.
 
 
@@ -1673,7 +1673,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg format: Specifies the format of the pixel data.
    :type type: Enumerated constant
    :arg type: Specifies the data type of the pixel data.
-   :type pixels: :class:`Buffer` object.
+   :type pixels: :class:`bgl.Buffer` object.
    :arg pixels: Specifies a pointer to the image data in memory.
 
 
@@ -1720,7 +1720,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :type x, y, z, w: Depends on function prototype (z and w for '3' and '4' prototypes only)
    :arg x, y, z, w: Specify x, y, z, and w coordinates of a vertex. Not all parameters
       are present in all forms of the command.
-   :type v: :class:`Buffer` object. Depends of function prototype (for 'v'
+   :type v: :class:`bgl.Buffer` object. Depends of function prototype (for 'v'
       prototypes only)
    :arg v: Specifies a pointer to an array of two, three, or four elements. The
       elements of a two-element array are x and y; of a three-element array,
@@ -1795,7 +1795,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
    :arg x, y: Specify the center of a picking region in window coordinates.
    :type width, height: double
    :arg width, height: Specify the width and height, respectively, of the picking region in window coordinates.
-   :type viewport: :class:`Buffer` object. [int]
+   :type viewport: :class:`bgl.Buffer` object. [int]
    :arg viewport: Specifies the current viewport.
 
 
@@ -1807,13 +1807,13 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    :type objx, objy, objz: double
    :arg objx, objy, objz: Specify the object coordinates.
-   :type modelMatrix: :class:`Buffer` object. [double]
+   :type modelMatrix: :class:`bgl.Buffer` object. [double]
    :arg modelMatrix: Specifies the current modelview matrix (as from a glGetDoublev call).
-   :type projMatrix: :class:`Buffer` object. [double]
+   :type projMatrix: :class:`bgl.Buffer` object. [double]
    :arg projMatrix: Specifies the current projection matrix (as from a glGetDoublev call).
-   :type viewport: :class:`Buffer` object. [int]
+   :type viewport: :class:`bgl.Buffer` object. [int]
    :arg viewport: Specifies the current viewport (as from a glGetIntegerv call).
-   :type winx, winy, winz: :class:`Buffer` object. [double]
+   :type winx, winy, winz: :class:`bgl.Buffer` object. [double]
    :arg winx, winy, winz: Return the computed window coordinates.
 
 
@@ -1825,13 +1825,13 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    :type winx, winy, winz: double
    :arg winx, winy, winz: Specify the window coordinates to be mapped.
-   :type modelMatrix: :class:`Buffer` object. [double]
+   :type modelMatrix: :class:`bgl.Buffer` object. [double]
    :arg modelMatrix: Specifies the current modelview matrix (as from a glGetDoublev call).
-   :type projMatrix: :class:`Buffer` object. [double]
+   :type projMatrix: :class:`bgl.Buffer` object. [double]
    :arg projMatrix: Specifies the current projection matrix (as from a glGetDoublev call).
-   :type viewport: :class:`Buffer` object. [int]
+   :type viewport: :class:`bgl.Buffer` object. [int]
    :arg viewport: Specifies the current viewport (as from a glGetIntegerv call).
-   :type objx, objy, objz: :class:`Buffer` object. [double]
+   :type objx, objy, objz: :class:`bgl.Buffer` object. [double]
    :arg objx, objy, objz: Return the computed object coordinates.
 
 
index e77e9a76d7f05cdd6f59adbe477bb5e0252e3a4f..751e5e1ec6191d47730620dcd5f1c0b2d9e6f2ca 100644 (file)
@@ -156,7 +156,7 @@ Note that these properties can only be assigned  basic Python types.
 
 * array of ints/floats
 
-* dictionary (only string keys types on this list)
+* dictionary (only string keys are supported, values must be basic types too)
 
 These properties are valid outside of Python. They can be animated by curves or used in driver paths.
 
index bd5faf000c862553aa5e73477fef7e1f147ad2fb..3ce2cfd48ad67316fd41441bfb87091072740ea3 100644 (file)
-###############
+***************
 Tips and Tricks
-###############
+***************
 
 Some of these are just python features that scripters may not have thaught to use with blender.
 
 
-****************
 Use The Terminal
-****************
+================
+
+When writing python scripts, its useful to have a terminal open, this is not the built-in python console but a terminal application which is used to start blender.
+
+There are 3 main uses for the terminal, these are:
+
+* You can see the output of `print()` as you're script runs, which is useful to view debug info.
+
+* The error tracebacks are printed in full to the terminal which wont always generate an error popup in blenders user interface (depending on how the script is executed).
+
+* If the script runs for too long or you accidentally enter an infinate loop, Ctrl+C in the terminal (Ctrl+Break on Windows) will quit the script early.
+
+.. note::
+   For Linux and OSX users this means starting the terminal first, then running blender from within it. On Windows the terminal can be enabled from the help menu.
 
-For Linux and OSX users this means starting the terminal first, then running blender from within it. on Windows the terminal can be enabled from the help menu.
 
-********************
 Run External Scripts
-********************
+====================
+
+Blenders text editor is fine for edits and writing small tests but it is not a full featured editor so for larger projects you'll probably want to use an external editor.
+
+Editing a text file externally and having the same text open in blender does work but isn't that optimal so here are 2 ways you can easily use an external file from blender.
+
+
+Executing External Scripts
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This is the equivilent to running the script directly, referencing a scripts path from a 2 line textblock.
+
+.. code-block::
+
+   filename = "/full/path/to/myscript.py"
+   exec(compile(open(filename).read(), filename, 'exec'))
+
+
+You might also want to reference the file relative to the blend file.
+
+.. code-block::
+
+   filename = "/full/path/to/script.py"
+   exec(compile(open(filename).read(), filename, 'exec'))
+
+
+You might want to reference a script thats at the same location as the blend file.
+
+.. code-block::
+
+   import bpy
+   import os
+
+   filename = os.path.join(os.path.basename(bpy.data.filepath), "myscript.py")
+   exec(compile(open(filename).read(), filename, 'exec'))
+
+
+Executing Modules
+^^^^^^^^^^^^^^^^^
+
+This example shows loading a script in as a module and executing a module function.
+
+.. code-block::
+
+   import myscript
+   import imp
+
+   imp.reload(myscript)
+   myscript.main()
+
+
+Notice that the script is reloaded every time, this forces an update, normally the module stays cached in `sys.modules`.
+
+The main difference between this and executing the script directly is it has to call a function in the module, in this case `main()` but it can be any function, an advantage with this is you can pass argumnents to the function from this small script which is often useful for testing differnt settings quickly.
+
+The other issue with this is the script has to be in pythons module search path.
+While this is not best practice - for testing you can extend the search path, this example adds the current blend files directory to the search path, then loads the script as a module.
+
+.. code-block::
+
+   import sys
+   import os
+   impory bpy
+
+   blend_dir = os.path.basename(bpy.data.filepath)
+   if blend_dir not in sys.path:
+      sys.path.append(blend_dir)
+
+   import myscript
+   import imp
+   imp.reload(myscript)
+   myscript.main()
 
 
-******************
 Don't Use Blender!
-******************
+==================
+
+While developing your own scripts blenders interface can get in the way, manually reloading, running the scripts, opening file import etc is just overhead.
+
+For scripts that are not interactive it can end up being easier not to use blender at all and run blender from a terminal, without opening a window and execute the script on the command line.
+
+.. code-block::
+
+   blender --backgruond --python myscript.py
+
+
+You might want to run this with a blend file too.
+
+.. code-block::
+
+   blender myscene.blend --backgruond --python myscript.py
+
 
 
-******************
 Use External Tools
-******************
+==================
 
 
-**************
 Bundled Python
-**************
+==============
 
 Blender from blender.org includes a compleate python installation on all platforms, this has the disadvantage that any extensions you have installed in you're systems python wont be found by blender.
 
@@ -38,20 +132,18 @@ There are 2 ways around this:
 
 * copy the extensions into blender's python subdirectry so blender can access them, you could also copy the entire python installation into blenders subdirectory, replacing the one blender comes with. This works as long as the python versions match and the paths are created in the same location relative locations. Doing this has the advantage that you can redistribute this bundle to others with blender and/or the game player, including any extensions you rely on.
 
-********
+
 Advanced
-********
+========
 
 
-===================
 Blender as a module
-===================
+-------------------
 
 
-============================
 Python Safety (Build Option)
-============================
+----------------------------
+
 
-=================
 CTypes in Blender
-=================
+-----------------
index e378dd19e733d7082397e63a8040c97c21b6459d..661d41af4ef77a8aecbb71798a06e933a442129c 100644 (file)
@@ -578,6 +578,7 @@ def pycontext2sphinx(BASEPATH):
         "sequences": ("Sequence", True),
         "smoke": ("SmokeModifier", False),
         "soft_body": ("SoftBodyModifier", False),
+        "speaker": ("Speaker", False),
         "texture": ("Texture", False),
         "texture_slot": ("MaterialTextureSlot", False),
         "vertex_paint_object": ("Object", False),
index a24ccc3ff6c8d860eaae00ad196887d50e29c948..c2e6f278c6baa1709fd33bbb42114630c0cb9da1 100644 (file)
@@ -366,11 +366,11 @@ void GHOST_NDOFManager::setDeadZone(float dz)
        }
        else if (dz > 0.5f) {
                // warn the rogue user/programmer, but allow it
-               printf("ndof: dead zone of %.2f is rather high...\n", dz);
+               GHOST_PRINTF("ndof: dead zone of %.2f is rather high...\n", dz);
        }
        m_deadZone = dz;
 
-       printf("ndof: dead zone set to %.2f\n", dz);
+       GHOST_PRINTF("ndof: dead zone set to %.2f\n", dz);
 }
 
 static bool atHomePosition(GHOST_TEventNDOFMotionData* ndof)
index 48230db23a339f126839afe4ed0e6612806b473f..4debb32b5c401499a5592f551d7b8a35d4c61f1e 100644 (file)
@@ -98,7 +98,8 @@ typedef unsigned long uintptr_t;
 #include <inttypes.h>
 
 #elif defined(FREE_WINDOWS)
-
+/* define htoln here, there must be a syntax error in winsock2.h in MinGW */
+unsigned long __attribute__((__stdcall__)) htonl(unsigned long);
 #include <stdint.h>
 
 #else
@@ -109,12 +110,14 @@ typedef unsigned long uintptr_t;
 #endif /* ifdef platform for types */
 
 #ifdef _WIN32
+#ifndef FREE_WINDOWS
 #ifndef htonl
 #define htonl(x) correctByteOrder(x)
 #endif
 #ifndef ntohl
 #define ntohl(x) correctByteOrder(x)
 #endif
+#endif
 #elif defined (__FreeBSD__) || defined (__OpenBSD__) 
 #include <sys/param.h>
 #elif defined (__APPLE__)
index 55b0bc5855fa7b94b87a4395b4e75cf5f318350a..7d6a579819e8e491d3bd454c5a2de557ee61af19 100644 (file)
@@ -31,6 +31,13 @@ remove_strict_flags()
 # and debug gives a lot of prints on UV unwrapping. developers can enable if they need to.
 remove_flag("-DDEBUG")
 
+
+# quiet compiler warnings about undefined defines
+add_definitions(
+       -DDEBUGlevel=0
+       -DPRNTlevel=0
+)
+
 set(INC
        extern
        superlu
index 094d398a83ce1dfe288b0419b44206c577d5e858..228ff6ec389bb12d5ff3967832d4f98bdf90fddb 100644 (file)
@@ -88,7 +88,7 @@ if(WITH_OPENMP)
 endif()
 
 if(WITH_FFTW3)
-       add_definitions(-DFFTW3=1)
+       add_definitions(-DWITH_FFTW3)
        list(APPEND INC
                ${FFTW3_INCLUDE_DIRS}
        )
index fa32c5f36c3a04526a183960e1105fd7985d892b..0511257d31941da9181d5c12690330677fb49ceb 100644 (file)
@@ -16,7 +16,7 @@ incs += ' ' + env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC']
 incs += ' intern ../../extern/bullet2/src ../memutil ../guardealloc '
 
 if env['WITH_BF_FFTW3']:
-    defs += ' FFTW3=1'
+    defs += ' WITH_FFTW3'
     incs += env['BF_FFTW3_INC'] 
 
 env.BlenderLib ('bf_intern_smoke', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
index b0597d7b20cc2beab15ac3ab70ec2a07eaea1bcd..a087b4e139140a367ffb1e387cd0f838b68259f5 100644 (file)
@@ -25,7 +25,7 @@
 #ifndef FFT_NOISE_H_
 #define FFT_NOISE_H_
 
-#if FFTW3==1
+#ifdef WITH_FFTW3
 #include <iostream>
 #include <fftw3.h>
 #include <MERSENNETWISTER.h>
index 9934e3017cf6f4d1c24db6c1fc7b67dbc4e7aa3a..cd18cf7b34441f53d7f8378b940c82a65862ed0a 100644 (file)
@@ -155,7 +155,7 @@ void WTURBULENCE::setNoise(int type)
        if(type == (1<<1)) // FFT
        {
                // needs fft
-               #if FFTW3==1
+               #ifdef WITH_FFTW3
                std::string noiseTileFilename = std::string("noise.fft");
                generatTile_FFT(_noiseTile, noiseTileFilename);
                #endif
index 4c064182a8cc83d7e1dd686c2a042c5f55254945..a68a1f8394c4ffbed66b5fbbaeb36321a9a7f084 100644 (file)
Binary files a/release/datafiles/blenderbuttons and b/release/datafiles/blenderbuttons differ
index 179921c3c85784fdcaae0693dddd0332282ea39f..058e8161fe6e3529f1d0f128f4c5b3092193cca2 100644 (file)
@@ -737,5 +737,120 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         col.prop(md, "width", slider=True)
         col.prop(md, "narrowness", slider=True)
 
+    @staticmethod
+    def weight_vg_mask(layout, ob, md):
+        layout.label(text="Influence/Mask Options:")
+        split = layout.split()
+        col1 = split.column()
+        col2 = split.column()
+
+        col1.label(text="Global Influence:")
+        col2.prop(md, "mask_constant", text="")
+
+        if not md.mask_texture:
+            col1.label(text="Vertex Group Mask:")
+            col2.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
+
+        if not md.mask_vertex_group:
+            col1.label(text="Texture Mask:")
+            col2.template_ID(md, "mask_texture", new="texture.new")
+            if md.mask_texture:
+                split = layout.split()
+                col = split.column()
+                col.label(text="Texture Coordinates:")
+                col.prop(md, "mask_tex_mapping", text="")
+                col = split.column()
+                col.label(text="Use Channel:")
+                col.prop(md, "mask_tex_use_channel", text="")
+
+                if md.mask_tex_mapping == 'OBJECT':
+                    layout.prop(md, "mask_tex_map_object", text="Object")
+                elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
+                    layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
+
+    def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
+        if ob.type == 'MESH':
+            split = layout.split()
+            col = split.column()
+            col.label(text="Vertex Group:")
+            col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+
+            col = split.column()
+            col.label(text="Default Weight:")
+            col.prop(md, "default_weight", text="")
+
+            layout.prop(md, "falloff_type")
+            if md.falloff_type == 'CURVE':
+                col = layout.column()
+                col.template_curve_mapping(md, "map_curve")
+
+            split = layout.split(percentage=0.4)
+            split.prop(md, "use_add")
+            row = split.row()
+            row.active = md.use_add
+            row.prop(md, "add_threshold")
+
+            split = layout.split(percentage=0.4)
+            split.prop(md, "use_remove")
+            row = split.row()
+            row.active = md.use_remove
+            row.prop(md, "remove_threshold")
+
+            # Common mask options…
+            layout.separator()
+            self.weight_vg_mask(layout, ob, md)
+
+    def VERTEX_WEIGHT_MIX(self, layout, ob, md):
+        if ob.type == 'MESH':
+            split = layout.split()
+            col = split.column()
+            col.label(text="Vertex Group A:")
+            col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
+            col.label(text="Default Weight A:")
+            col.prop(md, "default_weight_a", text="")
+
+            col.label(text="Mix Mode:")
+            col.prop(md, "mix_mode", text="")
+
+            col = split.column()
+            col.label(text="Vertex Group B:")
+            col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
+            col.label(text="Default Weight B:")
+            col.prop(md, "default_weight_b", text="")
+
+            col.label(text="Mix Set:")
+            col.prop(md, "mix_set", text="")
+
+            # Common mask options…
+            layout.separator()
+            self.weight_vg_mask(layout, ob, md)
+
+    def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
+        if ob.type == 'MESH':
+            split = layout.split()
+            col = split.column()
+            col.label(text="Vertex Group:")
+            col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+
+            col = split.column()
+            col.label(text="Target Object:")
+            col.prop(md, "target", text="")
+
+            row = layout.row()
+            row.prop(md, "proximity_mode", expand=True)
+            if md.proximity_mode == 'GEOMETRY':
+                row = layout.row()
+                row.prop(md, "proximity_geometry", expand=True)
+
+            row = layout.split()
+            row.prop(md, "min_dist")
+            row.prop(md, "max_dist")
+
+            layout.prop(md, "falloff_type")
+
+            # Common mask options…
+            layout.separator()
+            self.weight_vg_mask(layout, ob, md)
+
 if __name__ == "__main__":  # only for live edit.
     bpy.utils.register_module(__name__)
index 23d896abdbba7d5e1c76db285fde90ff9e23e11b..fd70cc9edb3537b230f9acd2e55b631bc4f978f2 100644 (file)
@@ -54,6 +54,9 @@ def draw_gpencil_tools(context, layout):
     row = col.row()
     row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
     row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
+
+    row = col.row()
+    row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
     row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
 
     row = col.row()
index 0f19cfbc481ff54380e265d7a0810e1135385f4a..742240d53b52a1e3d53b627d1db967516eddd101 100644 (file)
@@ -44,7 +44,7 @@ extern "C" {
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION                        259
-#define BLENDER_SUBVERSION             1
+#define BLENDER_SUBVERSION             2
 
 #define BLENDER_MINVERSION             250
 #define BLENDER_MINSUBVERSION  0
index 17876c6ec9d3faea372b1ce8a89063bcad1f7601..0e48673f1b1c688399fc870858c1d95acedbe7aa 100644 (file)
@@ -111,7 +111,7 @@ typedef struct Global {
 #define G_SCRIPT_OVERRIDE_PREF (1 << 14) /* when this flag is set ignore the userprefs */
 
 /* #define G_NOFROZEN  (1 << 17) also removed */
-#define G_GREASEPENCIL         (1 << 17)
+/* #define G_GREASEPENCIL      (1 << 17)   also removed */
 
 /* #define G_AUTOMATKEYS       (1 << 30)   also removed */
 
index e44b5d96852151748a4694bbf2cba30f83672a88..1de3c295f4da30af5b3640a50f245890960a40a5 100644 (file)
  *  \ingroup bke
  */
 
+#include "DNA_listBase.h"
+
+#include "RNA_types.h"
+
 /* not very important, but the stack solver likes to know a maximum */
 #define MAX_SOCKET     64
 
@@ -46,63 +50,151 @@ struct bNodeLink;
 struct bNodeSocket;
 struct bNodeStack;
 struct bNodeTree;
+struct bNodeTreeExec;
 struct GPUMaterial;
 struct GPUNode;
 struct GPUNodeStack;
 struct ID;
 struct ListBase;
 struct Main;
+struct uiBlock;
+struct uiLayout;
 struct MTex;
 struct PointerRNA;
 struct rctf;
 struct RenderData;
 struct Scene;
 struct Tex;
-struct uiLayout;
-
+struct SpaceNode;
+struct ARegion;
+struct Object;
 
 /* ************** NODE TYPE DEFINITIONS ***** */
 
-typedef struct bNodeSocketType {
+/** Compact definition of a node socket.
+ * Can be used to quickly define a list of static sockets for a node,
+ * which are added to each new node of that type. 
+ *
+ * \deprecated New nodes should add default sockets in the initialization
+ * function instead. This struct is mostly kept for old nodes and should
+ * be removed some time.
+ */
+typedef struct bNodeSocketTemplate {
        int type, limit;
-       const char *name;
-       float val1, val2, val3, val4;   /* default alloc value for inputs */
-       float min, max;                                 /* default range for inputs */
+       char name[32];
+       float val1, val2, val3, val4;   /* default alloc value for inputs */
+       float min, max;
+       PropertySubType subtype;
        
        /* after this line is used internal only */
-       struct bNodeSocket *sock;               /* used during verify_types */
+       struct bNodeSocket *sock;               /* used to hold verified socket */
+} bNodeSocketTemplate;
+
+typedef void (*NodeSocketButtonFunction)(const struct bContext *C, struct uiBlock *block, 
+                                                                                struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock,
+                                                                                const char *name, int x, int y, int width);
+
+/** Defines a socket type.
+ * Defines the appearance and behavior of a socket in the UI.
+ */
+typedef struct bNodeSocketType {
+       int type;
+       char ui_name[32];
+       char ui_description[128];
+       int ui_icon;
+       char ui_color[4];
+       
+       const char *value_structname;
+       int value_structsize;
+       
+       NodeSocketButtonFunction buttonfunc;
 } bNodeSocketType;
 
+/** Template for creating a node.
+ * Stored required parameters to make a new node of a specific type.
+ */
+typedef struct bNodeTemplate {
+       int type;
+       
+       /* group tree */
+       struct bNodeTree *ngroup;
+} bNodeTemplate;
+
+/** Defines a node type.
+ * Initial attributes and constants for a node as well as callback functions
+ * implementing the node behavior.
+ */
 typedef struct bNodeType {
        void *next,*prev;
+       short needs_free;               /* set for allocated types that need to be freed */
+       
        int type;
-       const char *name; /* can be allocated too */
+       char name[32];
        float width, minwidth, maxwidth;
+       float height, minheight, maxheight;
        short nclass, flag;
        
-       bNodeSocketType *inputs, *outputs;
+       /* templates for static sockets */
+       bNodeSocketTemplate *inputs, *outputs;
        
        char storagename[64];                   /* struct name for DNA */
        
-       void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **);
-       
-       /* this line is set on startup of blender */
+       /// Main draw function for the node.
+       void (*drawfunc)(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode, struct bNodeTree *ntree, struct bNode *node);
+       /// Updates the node geometry attributes according to internal state before actual drawing.
+       void (*drawupdatefunc)(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node);
+       /// Draw the option buttons on the node.
        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);
+       /// Optional custom label function for the node header.
        const char *(*labelfunc)(struct bNode *);
-
-       void (*initfunc)(struct bNode *);
-       void (*freestoragefunc)(struct bNode *);
-       void (*copystoragefunc)(struct bNode *, struct bNode *);
+       /// Optional custom resize handle polling.
+       int (*resize_area_func)(struct bNode *node, int x, int y);
        
-       /* for use with dynamic typedefs */
-       ID *id;
-       void *pynode; /* holds pointer to python script */
-       void *pydict; /* holds pointer to python script dictionary (scope)*/
-
+       /// Called when the node is updated in the editor.
+       void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node);
+       /// Check and update if internal ID data has changed.
+       void (*verifyfunc)(struct bNodeTree *ntree, struct bNode *node, struct ID *id);
+       
+       /// Initialize a new node instance of this type after creation.
+       void (*initfunc)(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp);
+       /// Free the custom storage data.
+       void (*freestoragefunc)(struct bNode *node);
+       /// Make a copy of the custom storage data.
+       void (*copystoragefunc)(struct bNode *node, struct bNode *target);
+       
+       /// Create a template from an existing node.
+       struct bNodeTemplate (*templatefunc)(struct bNode *);
+       /** If a node can be made from the template in the given node tree.
+        * \example Node groups can not be created inside their own node tree.
+        */
+       int (*validfunc)(struct bNodeTree *ntree, struct bNodeTemplate *ntemp);
+       
+       /// Initialize a node tree associated to this node type.
+       void (*inittreefunc)(struct bNodeTree *ntree);
+       /// Update a node tree associated to this node type.
+       void (*updatetreefunc)(struct bNodeTree *ntree);
+       
+       /* group edit callbacks for operators */
+       /* XXX this is going to be changed as required by the UI */
+       struct bNodeTree *(*group_edit_get)(struct bNode *node);
+       struct bNodeTree *(*group_edit_set)(struct bNode *node, int edit);
+       void (*group_edit_clear)(struct bNode *node);
+       
+       
+       /* **** execution callbacks **** */
+       void *(*initexecfunc)(struct bNode *node);
+       void (*freeexecfunc)(struct bNode *node, void *nodedata);
+       void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **);
+       /* XXX this alternative exec function has been added to avoid changing all node types.
+        * when a final generic version of execution code is defined, this will be changed anyway
+        */
+       void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, struct bNodeStack **, struct bNodeStack **);
        /* gpu */
        int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out);
-
+       /* extended gpu function */
+       int (*gpuextfunc)(struct GPUMaterial *mat, struct bNode *node, void *nodedata, struct GPUNodeStack *in, struct GPUNodeStack *out);
 } bNodeType;
 
 /* node->exec, now in use for composites (#define for break is same as ready yes) */
@@ -113,72 +205,124 @@ typedef struct bNodeType {
 #define NODE_FREEBUFS  8
 #define NODE_SKIPPED   16
 
+/* sim_exec return value */
+#define NODE_EXEC_FINISHED     0
+#define NODE_EXEC_SUSPEND      1
+
 /* nodetype->nclass, for add-menu and themes */
-#define NODE_CLASS_INPUT               0
-#define NODE_CLASS_OUTPUT              1
-#define NODE_CLASS_OP_COLOR            3
-#define NODE_CLASS_OP_VECTOR   4
-#define NODE_CLASS_OP_FILTER   5
-#define NODE_CLASS_GROUP               6
-#define NODE_CLASS_FILE                        7
-#define NODE_CLASS_CONVERTOR   8
-#define NODE_CLASS_MATTE               9
-#define NODE_CLASS_DISTORT             10
-#define NODE_CLASS_OP_DYNAMIC  11
-#define NODE_CLASS_PATTERN 12
-#define NODE_CLASS_TEXTURE 13
+#define NODE_CLASS_INPUT                       0
+#define NODE_CLASS_OUTPUT                      1
+#define NODE_CLASS_OP_COLOR                    3
+#define NODE_CLASS_OP_VECTOR           4
+#define NODE_CLASS_OP_FILTER           5
+#define NODE_CLASS_GROUP                       6
+#define NODE_CLASS_FILE                                7
+#define NODE_CLASS_CONVERTOR           8
+#define NODE_CLASS_MATTE                       9
+#define NODE_CLASS_DISTORT                     10
+#define NODE_CLASS_OP_DYNAMIC          11
+#define NODE_CLASS_PATTERN                     12
+#define NODE_CLASS_TEXTURE                     13
+#define NODE_CLASS_EXECUTION           14
+#define NODE_CLASS_GETDATA                     15
+#define NODE_CLASS_SETDATA                     16
+#define NODE_CLASS_MATH                                17
+#define NODE_CLASS_MATH_VECTOR         18
+#define NODE_CLASS_MATH_ROTATION       19
+#define NODE_CLASS_PARTICLES           25
+#define NODE_CLASS_TRANSFORM           30
+#define NODE_CLASS_COMBINE                     31
+#define NODE_CLASS_LAYOUT                      100
 
 /* enum values for input/output */
 #define SOCK_IN                1
 #define SOCK_OUT       2
 
+struct bNodeTreeExec;
+
+typedef void (*bNodeTreeCallback)(void *calldata, struct ID *owner_id, struct bNodeTree *ntree);
+typedef struct bNodeTreeType
+{
+       int type;                                               /* type identifier */
+       char idname[64];                                /* id name for RNA identification */
+       
+       ListBase node_types;                    /* type definitions */
+       
+       /* callbacks */
+       void (*free_cache)(struct bNodeTree *ntree);
+       void (*free_node_cache)(struct bNodeTree *ntree, struct bNode *node);
+       void (*foreach_nodetree)(struct Main *main, void *calldata, bNodeTreeCallback func);            /* iteration over all node trees */
+
+       /* calls allowing threaded composite */
+       void (*localize)(struct bNodeTree *localtree, struct bNodeTree *ntree);
+       void (*local_sync)(struct bNodeTree *localtree, struct bNodeTree *ntree);
+       void (*local_merge)(struct bNodeTree *localtree, struct bNodeTree *ntree);
+
+       /* Tree update. Overrides nodetype->updatetreefunc! */
+       void (*update)(struct bNodeTree *ntree);
+       /* Node update. Overrides nodetype->updatefunc! */
+       void (*update_node)(struct bNodeTree *ntree, struct bNode *node);
+       
+       int (*validate_link)(struct bNodeTree *ntree, struct bNodeLink *link);
+} bNodeTreeType;
+
 /* ************** GENERIC API, TREES *************** */
 
-void                   ntreeVerifyTypes(struct bNodeTree *ntree);
+struct bNodeTreeType *ntreeGetType(int type);
+struct bNodeType *ntreeGetNodeType(struct bNodeTree *ntree);
+struct bNodeSocketType *ntreeGetSocketType(int type);
 
-struct bNodeTree *ntreeAddTree(const char *name, int type, const short is_group);
+struct bNodeTree *ntreeAddTree(const char *name, int type, int nodetype);
 void                   ntreeInitTypes(struct bNodeTree *ntree);
 
-//void                 ntreeMakeGroupSockets(struct bNodeTree *ntree);
-void                   ntreeUpdateType(struct bNodeTree *ntree, struct bNodeType *ntype);
 void                   ntreeFreeTree(struct bNodeTree *ntree);
 struct bNodeTree *ntreeCopyTree(struct bNodeTree *ntree);
 void                   ntreeSwitchID(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to);
 void                   ntreeMakeLocal(struct bNodeTree *ntree);
+int                            ntreeHasType(struct bNodeTree *ntree, int type);
 
 void                   ntreeSocketUseFlags(struct bNodeTree *ntree);
 
-void                   ntreeSolveOrder(struct bNodeTree *ntree);
+void                   ntreeUpdateTree(struct bNodeTree *ntree);
+/* XXX Currently each tree update call does call to ntreeVerifyNodes too.
+ * Some day this should be replaced by a decent depsgraph automatism!
+ */
+void                   ntreeVerifyNodes(struct Main *main, struct ID *id);
 
-void                   ntreeBeginExecTree(struct bNodeTree *ntree);
-void                   ntreeExecTree(struct bNodeTree *ntree, void *callerdata, int thread);
-void                   ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews);
-void                   ntreeEndExecTree(struct bNodeTree *ntree);
+void                   ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes);
 
+/* XXX old trees handle output flags automatically based on special output node types and last active selection.
+ * new tree types have a per-output socket flag to indicate the final output to use explicitly.
+ */
+void                   ntreeSetOutput(struct bNodeTree *ntree);
 void                   ntreeInitPreview(struct bNodeTree *, int xsize, int ysize);
 void                   ntreeClearPreview(struct bNodeTree *ntree);
 
 void                   ntreeFreeCache(struct bNodeTree *ntree);
-                               
-                               /* calls allowing threaded composite */
+
+int                            ntreeNodeExists(struct bNodeTree *ntree, struct bNode *testnode);
+int                            ntreeOutputExists(struct bNode *node, struct bNodeSocket *testsock);
 struct bNodeTree *ntreeLocalize(struct bNodeTree *ntree);
 void                   ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree);
 void                   ntreeLocalMerge(struct bNodeTree *localtree, struct bNodeTree *ntree);
 
 /* ************** GENERIC API, NODES *************** */
 
-void                   nodeVerifyType(struct bNodeTree *ntree, struct bNode *node);
+struct bNodeSocket *nodeAddSocket(struct bNodeTree *ntree, struct bNode *node, int in_out, const char *name, int type);
+struct bNodeSocket *nodeInsertSocket(struct bNodeTree *ntree, struct bNode *node, int in_out, struct bNodeSocket *next_sock, const char *name, int type);
+void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock);
+void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node);
 
 void                   nodeAddToPreview(struct bNode *, float *, int, int, int);
 
+struct bNode   *nodeAddNode(struct bNodeTree *ntree, struct bNodeTemplate *ntemp);
 void                   nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node);
 void                   nodeUniqueName(struct bNodeTree *ntree, struct bNode *node);
-void                   nodeAddSockets(struct bNode *node, struct bNodeType *ntype);
-struct bNode   *nodeAddNodeType(struct bNodeTree *ntree, int type, struct bNodeTree *ngroup, struct ID *id);
-void                   nodeRegisterType(struct ListBase *typelist, const struct bNodeType *ntype) ;
-void                   nodeUpdateType(struct bNodeTree *ntree, struct bNode* node, struct bNodeType *ntype);
+
+void                   nodeRegisterType(struct ListBase *typelist, struct bNodeType *ntype) ;
 void                   nodeMakeDynamicType(struct bNode *node);
 int                            nodeDynamicUnlinkText(struct ID *txtid);
+
 void                   nodeFreeNode(struct bNodeTree *ntree, struct bNode *node);
 struct bNode   *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node);
 
@@ -186,6 +330,10 @@ struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, s
 void                   nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link);
 void                   nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
 
+void                   nodeSpaceCoords(struct bNode *node, float *locx, float *locy);
+void                   nodeAttachNode(struct bNode *node, struct bNode *parent);
+void                   nodeDetachNode(struct bNode *node);
+
 struct bNode   *nodeFindNodebyName(struct bNodeTree *ntree, const char *name);
 int                            nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex, int *in_out);
 
@@ -202,41 +350,71 @@ void                      NodeTagChanged(struct bNodeTree *ntree, struct bNode *node);
 int                            NodeTagIDChanged(struct bNodeTree *ntree, struct ID *id);
 void                   ntreeClearTags(struct bNodeTree *ntree);
 
-/* ************** Groups ****************** */
-
-struct bNode   *nodeMakeGroupFromSelected(struct bNodeTree *ntree);
-int                            nodeGroupUnGroup(struct bNodeTree *ntree, struct bNode *gnode);
-
-void                   nodeGroupVerify(struct bNodeTree *ngroup);
-void                   nodeGroupSocketUseFlags(struct bNodeTree *ngroup);
-
-void                   nodeGroupCopy(struct bNode *gnode);
+void                   nodeFreePreview(struct bNode *node);
 
-struct bNodeSocket *nodeGroupAddSocket(struct bNodeTree *ngroup, const char *name, int type, int in_out);
-struct bNodeSocket *nodeGroupExposeSocket(struct bNodeTree *ngroup, struct bNodeSocket *sock, int in_out);
-void                   nodeGroupExposeAllSockets(struct bNodeTree *ngroup);
-void                   nodeGroupRemoveSocket(struct bNodeTree *ngroup, struct bNodeSocket *gsock, int in_out);
+/* ************** NODE TYPE ACCESS *************** */
 
-/* ************** COMMON NODES *************** */
+struct bNodeTemplate nodeMakeTemplate(struct bNode *node);
+int                            nodeValid(struct bNodeTree *ntree, struct bNodeTemplate *ntemp);
+const char*            nodeLabel(struct bNode *node);
+struct bNodeTree *nodeGroupEditGet(struct bNode *node);
+struct bNodeTree *nodeGroupEditSet(struct bNode *node, int edit);
+void                   nodeGroupEditClear(struct bNode *node);
 
 /* Init a new node type struct with default values and callbacks */
-void                   node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag,
-                                                          struct bNodeSocketType *inputs, struct bNodeSocketType *outputs);
+void                   node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
+void                   node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs);
 void                   node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth);
-void                   node_type_init(struct bNodeType *ntype, void (*initfunc)(struct bNode *));
+void                   node_type_init(struct bNodeType *ntype, void (*initfunc)(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp));
+void                   node_type_valid(struct bNodeType *ntype, int (*validfunc)(struct bNodeTree *ntree, struct bNodeTemplate *ntemp));
 void                   node_type_storage(struct bNodeType *ntype,
                                                                  const char *storagename,
                                                                  void (*freestoragefunc)(struct bNode *),
                                                                  void (*copystoragefunc)(struct bNode *, struct bNode *));
+void                   node_type_label(struct bNodeType *ntype, const char *(*labelfunc)(struct bNode *));
+void                   node_type_template(struct bNodeType *ntype, struct bNodeTemplate (*templatefunc)(struct bNode *));
+void                   node_type_update(struct bNodeType *ntype,
+                                                                void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node),
+                                                                void (*verifyfunc)(struct bNodeTree *ntree, struct bNode *node, struct ID *id));
+void                   node_type_tree(struct bNodeType *ntype,
+                                                          void (*inittreefunc)(struct bNodeTree *),
+                                                          void (*updatetreefunc)(struct bNodeTree *));
+void                   node_type_group_edit(struct bNodeType *ntype,
+                                                                        struct bNodeTree *(*group_edit_get)(struct bNode *node),
+                                                                        struct bNodeTree *(*group_edit_set)(struct bNode *node, int edit),
+                                                                        void (*group_edit_clear)(struct bNode *node));
+
 void                   node_type_exec(struct bNodeType *ntype, void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **));
+void                   node_type_exec_new(struct bNodeType *ntype,
+                                                                  void *(*initexecfunc)(struct bNode *node),
+                                                                  void (*freeexecfunc)(struct bNode *node, void *nodedata),
+                                                                  void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, struct bNodeStack **, struct bNodeStack **));
 void                   node_type_gpu(struct bNodeType *ntype, int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out));
-void                   node_type_label(struct bNodeType *ntype, const char *(*labelfunc)(struct bNode *));
+void                   node_type_gpu_ext(struct bNodeType *ntype, int (*gpuextfunc)(struct GPUMaterial *mat, struct bNode *node, void *nodedata, struct GPUNodeStack *in, struct GPUNodeStack *out));
+
+/* ************** COMMON NODES *************** */
 
 #define NODE_GROUP             2
-#define NODE_GROUP_MENU                1000
-#define NODE_DYNAMIC_MENU      4000
+#define NODE_FORLOOP   3
+#define NODE_WHILELOOP 4
+#define NODE_FRAME             5
+#define NODE_GROUP_MENU                10000
+#define NODE_DYNAMIC_MENU      20000
+
+/* look up a socket on a group node by the internal group socket */
+struct bNodeSocket *node_group_find_input(struct bNode *gnode, struct bNodeSocket *gsock);
+struct bNodeSocket *node_group_find_output(struct bNode *gnode, struct bNodeSocket *gsock);
+
+struct bNodeSocket *node_group_add_socket(struct bNodeTree *ngroup, const char *name, int type, int in_out);
+struct bNodeSocket *node_group_expose_socket(struct bNodeTree *ngroup, struct bNodeSocket *sock, int in_out);
+void node_group_expose_all_sockets(struct bNodeTree *ngroup);
+void node_group_remove_socket(struct bNodeTree *ngroup, struct bNodeSocket *gsock, int in_out);
 
-void register_node_type_group(ListBase *lb);
+struct bNode   *node_group_make_from_selected(struct bNodeTree *ntree);
+int                            node_group_ungroup(struct bNodeTree *ntree, struct bNode *gnode);
+
+/* in node_common.c */
+void register_node_type_frame(ListBase *lb);
 
 /* ************** SHADER NODES *************** */
 
@@ -286,11 +464,10 @@ struct ShadeResult;
 #define NODE_DYNAMIC_REPARSE   6 /* 64 */
 #define NODE_DYNAMIC_SET       15 /* sign */
 
-/* the type definitions array */
-extern struct ListBase node_all_shaders;
-
 /* API */
 
+struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree, int use_tree_data);
+void                   ntreeShaderEndExecTree(struct bNodeTreeExec *exec, int use_tree_data);
 void                   ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr);
 void                   ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode);
 void                   nodeShaderSynchronizeID(struct bNode *node, int copyto);
@@ -415,11 +592,11 @@ void                      ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
 #define CMP_SCALE_RENDERPERCENT 3
 
 
-/* the type definitions array */
-extern struct ListBase node_all_composit;
-
 /* API */
 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 ntreeCompositTagRender(struct Scene *sce);
 int ntreeCompositTagAnimated(struct bNodeTree *ntree);
 void ntreeCompositTagGenerators(struct bNodeTree *ntree);
@@ -459,23 +636,22 @@ struct TexResult;
 #define TEX_NODE_PROC      500
 #define TEX_NODE_PROC_MAX  600
 
-extern struct ListBase node_all_textures;
-
 /* API */
 int  ntreeTexTagAnimated(struct bNodeTree *ntree);
 void ntreeTexSetPreviewFlag(int);
-int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, int osatex, short thread, struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex);
 void ntreeTexCheckCyclics(struct bNodeTree *ntree);
 char* ntreeTexOutputMenu(struct bNodeTree *ntree);
 
+struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree, int use_tree_data);
+void ntreeTexEndExecTree(struct bNodeTreeExec *exec, int use_tree_data);
+int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, int osatex, short thread, struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex);
+
 
-/**/
+/*************************************************/
 
 void init_nodesystem(void);
 void free_nodesystem(void);
 
-/**/
-
 void clear_scene_in_nodes(struct Main *bmain, struct Scene *sce);
 
 #endif
index fac5bf1cfd2848ad42a1a57b9a0349bc7291e858..3728dd41089e805c967b8b5ecb01032255cbc863 100644 (file)
@@ -39,7 +39,6 @@
 
 struct PackedFile;
 struct bSound;
-struct bContext;
 struct ListBase;
 struct Main;
 struct Sequence;
@@ -65,12 +64,12 @@ struct bSound* sound_new_file(struct Main *main, const char *filename);
 
 // XXX unused currently
 #if 0
-struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source);
+struct bSound* sound_new_buffer(struct Main *bmain, struct bSound *source);
 
-struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, float start, float end);
+struct bSound* sound_new_limiter(struct Main *bmain, struct bSound *source, float start, float end);
 #endif
 
-void sound_delete(struct bContext *C, struct bSound* sound);
+void sound_delete(struct Main *bmain, struct bSound* sound);
 
 void sound_cache(struct bSound* sound);
 
@@ -124,7 +123,7 @@ void sound_play_scene(struct Scene *scene);
 
 void sound_stop_scene(struct Scene *scene);
 
-void sound_seek_scene(struct bContext *C);
+void sound_seek_scene(struct Main *bmain, struct Scene *scene);
 
 float sound_sync_scene(struct Scene *scene);
 
index 5f33059e117d7400cd2680891a8295c47884f57a..2d4354bdd9fc9141b56fcc770868a84d2f899a61 100644 (file)
@@ -324,17 +324,14 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
        MEM_freeN(bfd);
 }
 
-static int handle_subversion_warning(Main *main)
+static int handle_subversion_warning(Main *main, ReportList *reports)
 {
        if(main->minversionfile > BLENDER_VERSION ||
           (main->minversionfile == BLENDER_VERSION && 
                 main->minsubversionfile > BLENDER_SUBVERSION)) {
-               
-               char str[128];
-               
-               BLI_snprintf(str, sizeof(str), "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile);
-// XXX         error(str);
+               BKE_reportf(reports, RPT_ERROR, "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile);
        }
+
        return 1;
 }
 
@@ -392,7 +389,7 @@ int BKE_read_file(bContext *C, const char *filepath, ReportList *reports)
        if (bfd) {
                if(bfd->user) retval= BKE_READ_FILE_OK_USERPREFS;
                
-               if(0==handle_subversion_warning(bfd->main)) {
+               if(0==handle_subversion_warning(bfd->main, reports)) {
                        free_main(bfd->main);
                        MEM_freeN(bfd);
                        bfd= NULL;
index 296159861919b71dd2904e8defa9c1ed716437fc..aab8e1abbeaa86908a6de0bdefc093f213a66cf0 100644 (file)
@@ -925,7 +925,8 @@ void init_render_material(Material *mat, int r_mode, float *amb)
        if(mat->nodetree && mat->use_nodes) {
                init_render_nodetree(mat->nodetree, mat, r_mode, amb);
                
-               ntreeBeginExecTree(mat->nodetree); /* has internal flag to detect it only does it once */
+               if (!mat->nodetree->execdata)
+                       mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree, 1);
        }
 }
 
@@ -957,8 +958,10 @@ void init_render_materials(Main *bmain, int r_mode, float *amb)
 /* only needed for nodes now */
 void end_render_material(Material *mat)
 {
-       if(mat && mat->nodetree && mat->use_nodes)
-               ntreeEndExecTree(mat->nodetree); /* has internal flag to detect it only does it once */
+       if(mat && mat->nodetree && mat->use_nodes) {
+               if (mat->nodetree->execdata)
+                       ntreeShaderEndExecTree(mat->nodetree->execdata, 1);
+       }
 }
 
 void end_render_materials(Main *bmain)
index 5f1a6c911bc511b8a77149d9ca34267e739a8476..292f38b9472bd3d8e14f8796671c3c30cb2561fd 100644 (file)
 #include <limits.h>
 
 #include "DNA_anim_types.h"
-#include "DNA_action_types.h"
 #include "DNA_node_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_action_types.h"
 
+#include "BLI_string.h"
+#include "BLI_math.h"
 #include "BLI_listbase.h"
-
-#include "RNA_access.h"
+#include "BLI_path_util.h"
+#include "BLI_utildefines.h"
 
 #include "BKE_animsys.h"
 #include "BKE_action.h"
 #include "BKE_fcurve.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
 #include "BKE_node.h"
 #include "BKE_utildefines.h"
+#include "BKE_utildefines.h"
 
-#include "PIL_time.h"
-
-#include "CMP_node.h"
-#include "intern/CMP_util.h"   /* stupid include path... */
+#include "BLI_listbase.h"
 
-#include "SHD_node.h"
-#include "TEX_node.h"
-#include "intern/TEX_util.h"
+#include "RNA_access.h"
 
-#include "GPU_material.h"
+#include "NOD_socket.h"
+#include "NOD_composite.h"
+#include "NOD_shader.h"
+#include "NOD_texture.h"
 
-static ListBase empty_list = {NULL, NULL};
-ListBase node_all_composit = {NULL, NULL};
-ListBase node_all_shaders = {NULL, NULL};
-ListBase node_all_textures = {NULL, NULL};
 
-/* ************** Type stuff **********  */
+bNodeTreeType *ntreeGetType(int type)
+{
+       static bNodeTreeType *types[NUM_NTREE_TYPES];
+       static int types_init = 1;
+       if (types_init) {
+               types[NTREE_SHADER] = &ntreeType_Shader;
+               types[NTREE_COMPOSIT] = &ntreeType_Composite;
+               types[NTREE_TEXTURE] = &ntreeType_Texture;
+               types_init = 0;
+       }
+       
+       if(type >= 0 && type < NUM_NTREE_TYPES) {
+               return types[type];
+       }
+       else {
+               return NULL;
+       }
+}
 
-static bNodeType *node_get_type(bNodeTree *ntree, int type, ID *id)
+static bNodeType *node_get_type(bNodeTree *ntree, int type)
 {
-       bNodeType *ntype = ntree->alltypes.first;
+       bNodeType *ntype = ntreeGetType(ntree->type)->node_types.first;
        for(; ntype; ntype= ntype->next)
-               if(ntype->type==type && id==ntype->id )
+               if(ntype->type==type)
                        return ntype;
        
        return NULL;
 }
 
-void ntreeInitTypes(bNodeTree *ntree)
+bNodeType *ntreeGetNodeType(bNodeTree *ntree)
 {
-       bNode *node, *next;
-       
-       if(ntree->type==NTREE_SHADER)
-               ntree->alltypes= node_all_shaders;
-       else if(ntree->type==NTREE_COMPOSIT)
-               ntree->alltypes= node_all_composit;
-       else if(ntree->type==NTREE_TEXTURE)
-               ntree->alltypes= node_all_textures;
+       return node_get_type(ntree, ntree->nodetype);
+}
+
+bNodeSocketType *ntreeGetSocketType(int type)
+{
+       static bNodeSocketType *types[NUM_SOCKET_TYPES]= {NULL};
+       static int types_init = 1;
+
+       if (types_init) {
+               node_socket_type_init(types);
+               types_init= 0;
+       }
+
+       if(type < NUM_SOCKET_TYPES) {
+               return types[type];
+       }
        else {
-               ntree->alltypes= empty_list;
-               printf("Error: no type definitions for nodes\n");
+               return NULL;
        }
+}
+
+void ntreeInitTypes(bNodeTree *ntree)
+{
+       bNode *node, *next;
        
        for(node= ntree->nodes.first; node; node= next) {
                next= node->next;
+               
+               node->typeinfo= node_get_type(ntree, node->type);
+               
                if(node->type==NODE_DYNAMIC) {
-                       bNodeType *stype= NULL;
-                       if(node->id==NULL) { /* empty script node */
-                               stype= node_get_type(ntree, node->type, NULL);
-                       } else { /* not an empty script node */
-                               stype= node_get_type(ntree, node->type, node->id);
-                               if(!stype) {
-                                       stype= node_get_type(ntree, node->type, NULL);
-                                       /* needed info if the pynode script fails now: */
-                                       if (node->id) node->storage= ntree;
-                               } else {
-                                       node->custom1= 0;
-                                       node->custom1= BSET(node->custom1,NODE_DYNAMIC_ADDEXIST);
-                               }
+                       /* needed info if the pynode script fails now: */
+                       node->storage= ntree;
+                       if(node->id!=NULL) { /* not an empty script node */
+                               node->custom1= 0;
+                               node->custom1= BSET(node->custom1,NODE_DYNAMIC_ADDEXIST);
                        }
-                       node->typeinfo= stype;
-                       if(node->typeinfo)
-                               node->typeinfo->initfunc(node);
-               } else {
-                       node->typeinfo= node_get_type(ntree, node->type, NULL);
+//                     if(node->typeinfo)
+//                             node->typeinfo->initfunc(node);
                }
 
                if(node->typeinfo==NULL) {
@@ -135,66 +158,51 @@ void ntreeInitTypes(bNodeTree *ntree)
        ntree->init |= NTREE_TYPE_INIT;
 }
 
-/* updates node with (modified) bNodeType.. this should be done for all trees */
-void ntreeUpdateType(bNodeTree *ntree, bNodeType *ntype)
+static bNodeSocket *make_socket(bNodeTree *UNUSED(ntree), int in_out, const char *name, int type)
 {
-       bNode *node;
-
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->typeinfo== ntype) {
-                       nodeUpdateType(ntree, node, ntype);
-               }
-       }
+       bNodeSocketType *stype= ntreeGetSocketType(type);
+       bNodeSocket *sock;
+       
+       sock= MEM_callocN(sizeof(bNodeSocket), "sock");
+       
+       BLI_strncpy(sock->name, name, NODE_MAXSTR);
+       sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF);
+       sock->type= type;
+       sock->storage = NULL;
+       
+       if (stype->value_structsize > 0)
+               sock->default_value = MEM_callocN(stype->value_structsize, "default socket value");
+       
+       return sock;
 }
 
-/* only used internal... we depend on type definitions! */
-static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype)
+bNodeSocket *nodeAddSocket(bNodeTree *ntree, bNode *node, int in_out, const char *name, int type)
 {
-       bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock");
+       bNodeSocket *sock = make_socket(ntree, in_out, name, type);
+       if (in_out==SOCK_IN)
+               BLI_addtail(&node->inputs, sock);
+       else if (in_out==SOCK_OUT)
+               BLI_addtail(&node->outputs, sock);
        
-       BLI_strncpy(sock->name, stype->name, NODE_MAXSTR);
-       if(stype->limit==0) sock->limit= 0xFFF;
-       else sock->limit= stype->limit;
-       sock->type= stype->type;
+       ntree->update |= NTREE_UPDATE_NODES;
        
-       sock->ns.vec[0]= stype->val1;
-       sock->ns.vec[1]= stype->val2;
-       sock->ns.vec[2]= stype->val3;
-       sock->ns.vec[3]= stype->val4;
-       sock->ns.min= stype->min;
-       sock->ns.max= stype->max;
-       
-       if(lb)
-               BLI_addtail(lb, sock);
-
        return sock;
 }
 
-static bNodeSocket *node_add_group_socket(ListBase *lb, bNodeSocket *gsock)
+bNodeSocket *nodeInsertSocket(bNodeTree *ntree, bNode *node, int in_out, bNodeSocket *next_sock, const char *name, int type)
 {
-       bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock");
+       bNodeSocket *sock = make_socket(ntree, in_out, name, type);
+       if (in_out==SOCK_IN)
+               BLI_insertlinkbefore(&node->inputs, next_sock, sock);
+       else if (in_out==SOCK_OUT)
+               BLI_insertlinkbefore(&node->outputs, next_sock, sock);
        
-       /* make a copy of the group socket */
-       *sock = *gsock;
-       sock->link = NULL;
-       sock->next = sock->prev = NULL;
-       sock->new_sock = NULL;
-       sock->ns.data = NULL;
+       ntree->update |= NTREE_UPDATE_NODES;
        
-       sock->own_index = gsock->own_index;
-       sock->groupsock = gsock;
-       /* XXX hack: group socket input/output roles are inverted internally,
-        * need to change the limit value when making actual node sockets from them.
-        */
-       sock->limit = (gsock->limit==1 ? 0xFFF : 1);
-       
-       if(lb)
-               BLI_addtail(lb, sock);
-
        return sock;
 }
 
-static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock)
+void nodeRemoveSocket(bNodeTree *ntree, bNode *node, bNodeSocket *sock)
 {
        bNodeLink *link, *next;
        
@@ -205,428 +213,42 @@ static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock)
                }
        }
        
-       BLI_remlink(lb, sock);
-       MEM_freeN(sock);
-}
-
-static bNodeSocket *verify_socket(ListBase *lb, bNodeSocketType *stype)
-{
-       bNodeSocket *sock;
-       
-       for(sock= lb->first; sock; sock= sock->next) {
-               if(strncmp(sock->name, stype->name, NODE_MAXSTR)==0)
-                       break;
-       }
-       if(sock) {
-               sock->type= stype->type;                /* in future, read this from tydefs! */
-               if(stype->limit==0) sock->limit= 0xFFF;
-               else sock->limit= stype->limit;
-               
-               sock->ns.min= stype->min;
-               sock->ns.max= stype->max;
-               
-               BLI_remlink(lb, sock);
-               
-               return sock;
-       }
-       else {
-               return node_add_socket_type(NULL, stype);
-       }
-}
-
-static bNodeSocket *verify_group_socket(ListBase *lb, bNodeSocket *gsock)
-{
-       bNodeSocket *sock;
-       
-       for(sock= lb->first; sock; sock= sock->next) {
-               if(sock->own_index==gsock->own_index)
-                               break;
-       }
-       if(sock) {
-               sock->groupsock = gsock;
-               
-               strcpy(sock->name, gsock->name);
-               sock->type= gsock->type;
-               
-               /* XXX hack: group socket input/output roles are inverted internally,
-                * need to change the limit value when making actual node sockets from them.
-                */
-               sock->limit = (gsock->limit==1 ? 0xFFF : 1);
-               
-               sock->ns.min= gsock->ns.min;
-               sock->ns.max= gsock->ns.max;
-               
-               BLI_remlink(lb, sock);
-               
-               return sock;
-       }
-       else {
-               return node_add_group_socket(NULL, gsock);
-       }
-}
-
-static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType *stype_first)
-{
-       bNodeSocketType *stype;
-       
-       /* no inputs anymore? */
-       if(stype_first==NULL) {
-               while(lb->first)
-                       node_rem_socket(ntree, lb, lb->first);
-       }
-       else {
-               /* step by step compare */
-               stype= stype_first;
-               while(stype->type != -1) {
-                       stype->sock= verify_socket(lb, stype);
-                       stype++;
-               }
-               /* leftovers are removed */
-               while(lb->first)
-                       node_rem_socket(ntree, lb, lb->first);
-               /* and we put back the verified sockets */
-               stype= stype_first;
-               while(stype->type != -1) {
-                       BLI_addtail(lb, stype->sock);
-                       stype++;
-               }
-       }
-}
-
-static void verify_group_socket_list(bNodeTree *ntree, ListBase *lb, ListBase *glb)
-{
-       bNodeSocket *gsock;
-       
-       /* step by step compare */
-       for (gsock= glb->first; gsock; gsock=gsock->next) {
-               /* abusing new_sock pointer for verification here! only used inside this function */
-               gsock->new_sock= verify_group_socket(lb, gsock);
-       }
-       /* leftovers are removed */
-       while(lb->first)
-               node_rem_socket(ntree, lb, lb->first);
-       /* and we put back the verified sockets */
-       for (gsock= glb->first; gsock; gsock=gsock->next) {
-               BLI_addtail(lb, gsock->new_sock);
-               gsock->new_sock = NULL;
-       }
-}
-
-void nodeVerifyType(bNodeTree *ntree, bNode *node)
-{
-       /* node groups don't have static sock lists, but use external sockets from the tree instead */
-       if (node->type==NODE_GROUP) {
-               bNodeTree *ngroup= (bNodeTree*)node->id;
-               if (ngroup) {
-                       verify_group_socket_list(ntree, &node->inputs, &ngroup->inputs);
-                       verify_group_socket_list(ntree, &node->outputs, &ngroup->outputs);
-               }
-       }
-       else {
-               bNodeType *ntype= node->typeinfo;
-               if(ntype) {
-                       verify_socket_list(ntree, &node->inputs, ntype->inputs);
-                       verify_socket_list(ntree, &node->outputs, ntype->outputs);
-               }
-       }
-}
-
-void ntreeVerifyTypes(bNodeTree *ntree)
-{
-       bNode *node;
-       
-       /* if((ntree->init & NTREE_TYPE_INIT)==0) */
-       ntreeInitTypes(ntree);
-
-       /* check inputs and outputs, and remove or insert them */
-       for(node= ntree->nodes.first; node; node= node->next)
-               nodeVerifyType(ntree, node);
+       /* this is fast, this way we don't need an in_out argument */
+       BLI_remlink(&node->inputs, sock);
+       BLI_remlink(&node->outputs, sock);
        
-}
-
-/* ************** Group stuff ********** */
-
-/* XXX group typeinfo struct is used directly in ntreeMakeOwnType, needs cleanup */
-static bNodeType ntype_group;
-
-/* groups display their internal tree name as label */
-static const char *group_label(bNode *node)
-{
-       return (node->id)? node->id->name+2: "Missing Datablock";
-}
-
-void register_node_type_group(ListBase *lb)
-{
-       node_type_base(&ntype_group, NODE_GROUP, "Group", NODE_CLASS_GROUP, NODE_OPTIONS, NULL, NULL);
-       node_type_size(&ntype_group, 120, 60, 200);
-       node_type_label(&ntype_group, group_label);
+       if (sock->default_value)
+               MEM_freeN(sock->default_value);
+       MEM_freeN(sock);
        
-       nodeRegisterType(lb, &ntype_group);
+       ntree->update |= NTREE_UPDATE_NODES;
 }
 
-static bNodeSocket *find_group_node_input(bNode *gnode, bNodeSocket *gsock)
+void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node)
 {
        bNodeSocket *sock;
-       for (sock=gnode->inputs.first; sock; sock=sock->next)
-               if (sock->groupsock == gsock)
-                       return sock;
-       return NULL;
-}
-
-static bNodeSocket *find_group_node_output(bNode *gnode, bNodeSocket *gsock)
-{
-       bNodeSocket *sock;
-       for (sock=gnode->outputs.first; sock; sock=sock->next)
-               if (sock->groupsock == gsock)
-                       return sock;
-       return NULL;
-}
-
-bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
-{
-       bNodeLink *link, *linkn;
-       bNode *node, *gnode, *nextn;
-       bNodeTree *ngroup;
-       bNodeSocket *gsock;
-       ListBase anim_basepaths = {NULL, NULL};
-       float min[2], max[2];
-       int totnode=0;
-       
-       INIT_MINMAX2(min, max);
-       
-       /* is there something to group? also do some clearing */
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->flag & NODE_SELECT) {
-                       /* no groups in groups */
-                       if(node->type==NODE_GROUP)
-                               return NULL;
-                       DO_MINMAX2( (&node->locx), min, max);
-                       totnode++;
-               }
-               node->done= 0;
-       }
-       if(totnode==0) return NULL;
-       
-       /* check if all connections are OK, no unselected node has both
-               inputs and outputs to a selection */
-       for(link= ntree->links.first; link; link= link->next) {
-               if(link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT)
-                       link->tonode->done |= 1;
-               if(link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT)
-                       link->fromnode->done |= 2;
-       }       
-       
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if((node->flag & NODE_SELECT)==0)
-                       if(node->done==3)
-                               break;
-       }
-       if(node) 
-               return NULL;
+       bNodeLink *link, *next;
        
-       /* OK! new nodetree */
-       ngroup= ntreeAddTree("NodeGroup", ntree->type, TRUE);
-       
-       /* move nodes over */
-       for(node= ntree->nodes.first; node; node= nextn) {
-               nextn= node->next;
-               if(node->flag & NODE_SELECT) {
-                       /* keep track of this node's RNA "base" path (the part of the pat identifying the node) 
-                        * if the old nodetree has animation data which potentially covers this node
-                        */
-                       if (ntree->adt) {
-                               PointerRNA ptr;
-                               char *path;
-                               
-                               RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
-                               path = RNA_path_from_ID_to_struct(&ptr);
-                               
-                               if (path)
-                                       BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
-                       }
-                       
-                       /* change node-collection membership */
-                       BLI_remlink(&ntree->nodes, node);
-                       BLI_addtail(&ngroup->nodes, node);
-                       
-                       node->locx-= 0.5f*(min[0]+max[0]);
-                       node->locy-= 0.5f*(min[1]+max[1]);
-               }
-       }
-
-       /* move animation data over */
-       if (ntree->adt) {
-               LinkData *ld, *ldn=NULL;
-               
-               BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);
-               
-               /* paths + their wrappers need to be freed */
-               for (ld = anim_basepaths.first; ld; ld = ldn) {
-                       ldn = ld->next;
-                       
-                       MEM_freeN(ld->data);
-                       BLI_freelinkN(&anim_basepaths, ld);
+       for(link= ntree->links.first; link; link= next) {
+               next= link->next;
+               if(link->fromnode==node || link->tonode==node) {
+                       nodeRemLink(ntree, link);
                }
        }
        
-       /* make group node */
-       gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup, NULL);
-       gnode->locx= 0.5f*(min[0]+max[0]);
-       gnode->locy= 0.5f*(min[1]+max[1]);
+       for (sock=node->inputs.first; sock; sock=sock->next)
+               if (sock->default_value)
+                       MEM_freeN(sock->default_value);
+       BLI_freelistN(&node->inputs);
+       for (sock=node->outputs.first; sock; sock=sock->next)
+               if (sock->default_value)
+                       MEM_freeN(sock->default_value);
        
-       /* relink external sockets */
-       for(link= ntree->links.first; link; link= linkn) {
-               linkn= link->next;
-               
-               if(link->fromnode && link->tonode && (link->fromnode->flag & link->tonode->flag & NODE_SELECT)) {
-                       BLI_remlink(&ntree->links, link);
-                       BLI_addtail(&ngroup->links, link);
-               }
-               else if(link->tonode && (link->tonode->flag & NODE_SELECT)) {
-                       gsock = nodeGroupExposeSocket(ngroup, link->tosock, SOCK_IN);
-                       link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock);
-                       link->tosock = node_add_group_socket(&gnode->inputs, gsock);
-                       link->tonode = gnode;
-               }
-               else if(link->fromnode && (link->fromnode->flag & NODE_SELECT)) {
-                       /* search for existing group node socket */
-                       for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next)
-                               if (gsock->link && gsock->link->fromsock==link->fromsock)
-                                       break;
-                       if (!gsock) {
-                               gsock = nodeGroupExposeSocket(ngroup, link->fromsock, SOCK_OUT);
-                               gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock);
-                               link->fromsock = node_add_group_socket(&gnode->outputs, gsock);
-                       }
-                       else
-                               link->fromsock = find_group_node_output(gnode, gsock);
-                       link->fromnode = gnode;
-               }
-       }
-
-       /* update node levels */
-       ntreeSolveOrder(ntree);
-
-       return gnode;
-}
-
-/* here's a nasty little one, need to check users... */
-/* should become callbackable... */
-void nodeGroupVerify(bNodeTree *ngroup)
-{
-       /* group changed, so we rebuild the type definition */
-//     ntreeMakeGroupSockets(ngroup);
+       BLI_freelistN(&node->outputs);
        
-       if(ngroup->type==NTREE_SHADER) {
-               Material *ma;
-               for(ma= G.main->mat.first; ma; ma= ma->id.next) {
-                       if(ma->nodetree) {
-                               bNode *node;
-                               for(node= ma->nodetree->nodes.first; node; node= node->next)
-                                       if(node->id == (ID *)ngroup)
-                                               nodeVerifyType(ma->nodetree, node);
-                       }
-               }
-       }
-       else if(ngroup->type==NTREE_COMPOSIT) {
-               Scene *sce;
-               for(sce= G.main->scene.first; sce; sce= sce->id.next) {
-                       if(sce->nodetree) {
-                               bNode *node;
-                               for(node= sce->nodetree->nodes.first; node; node= node->next)
-                                       if(node->id == (ID *)ngroup)
-                                               nodeVerifyType(sce->nodetree, node);
-                       }
-               }
-       }
-       else if(ngroup->type==NTREE_TEXTURE) {
-               Tex *tx;
-               for(tx= G.main->tex.first; tx; tx= tx->id.next) {
-                       if(tx->nodetree) {
-                               bNode *node;
-                               for(node= tx->nodetree->nodes.first; node; node= node->next)
-                                       if(node->id == (ID *)ngroup)
-                                               nodeVerifyType(tx->nodetree, node);
-                       }
-               }
-       }
+       ntree->update |= NTREE_UPDATE_NODES;
 }
 
-/* also to check all users of groups. Now only used in editor for hide/unhide */
-/* should become callbackable? */
-void nodeGroupSocketUseFlags(bNodeTree *ngroup)
-{
-       bNode *node;
-       bNodeSocket *sock;
-
-       /* clear flags */
-       for(node= ngroup->nodes.first; node; node= node->next) {
-               for(sock= node->inputs.first; sock; sock= sock->next)
-                       sock->flag &= ~SOCK_IN_USE;
-               for(sock= node->outputs.first; sock; sock= sock->next)
-                       sock->flag &= ~SOCK_IN_USE;
-       }
-       
-       /* tag all thats in use */
-       if(ngroup->type==NTREE_SHADER) {
-               Material *ma;
-               for(ma= G.main->mat.first; ma; ma= ma->id.next) {
-                       if(ma->nodetree) {
-                               for(node= ma->nodetree->nodes.first; node; node= node->next) {
-                                       if(node->id==&ngroup->id) {
-                                               for(sock= node->inputs.first; sock; sock= sock->next)
-                                                       if(sock->link)
-                                                               if(sock->groupsock) 
-                                                                       sock->groupsock->flag |= SOCK_IN_USE;
-                                               for(sock= node->outputs.first; sock; sock= sock->next)
-                                                       if(nodeCountSocketLinks(ma->nodetree, sock))
-                                                               if(sock->groupsock) 
-                                                                       sock->groupsock->flag |= SOCK_IN_USE;
-                                       }
-                               }
-                       }
-               }
-       }
-       else if(ngroup->type==NTREE_COMPOSIT) {
-               Scene *sce;
-               for(sce= G.main->scene.first; sce; sce= sce->id.next) {
-                       if(sce->nodetree) {
-                               for(node= sce->nodetree->nodes.first; node; node= node->next) {
-                                       if(node->id==(ID *)ngroup) {
-                                               for(sock= node->inputs.first; sock; sock= sock->next)
-                                                       if(sock->link)
-                                                               if(sock->groupsock) 
-                                                                       sock->groupsock->flag |= SOCK_IN_USE;
-                                               for(sock= node->outputs.first; sock; sock= sock->next)
-                                                       if(nodeCountSocketLinks(sce->nodetree, sock))
-                                                               if(sock->groupsock) 
-                                                                       sock->groupsock->flag |= SOCK_IN_USE;
-                                       }
-                               }
-                       }
-               }
-       }
-       else if(ngroup->type==NTREE_TEXTURE) {
-               Tex *tx;
-               for(tx= G.main->tex.first; tx; tx= tx->id.next) {
-                       if(tx->nodetree) {
-                               for(node= tx->nodetree->nodes.first; node; node= node->next) {
-                                       if(node->id==(ID *)ngroup) {
-                                               for(sock= node->inputs.first; sock; sock= sock->next)
-                                                       if(sock->link)
-                                                               if(sock->groupsock) 
-                                                                       sock->groupsock->flag |= SOCK_IN_USE;
-                                               for(sock= node->outputs.first; sock; sock= sock->next)
-                                                       if(nodeCountSocketLinks(tx->nodetree, sock))
-                                                               if(sock->groupsock) 
-                                                                       sock->groupsock->flag |= SOCK_IN_USE;
-                                       }
-                               }
-                       }
-               }
-       }
-       
-}
 /* finds a node based on its name */
 bNode *nodeFindNodebyName(bNodeTree *ntree, const char *name)
 {
@@ -669,341 +291,70 @@ int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockin
        return 0;
 }
 
-/* returns 1 if its OK */
-int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
+/* ************** Add stuff ********** */
+static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
 {
-       bNodeLink *link, *linkn;
-       bNode *node, *nextn;
-       bNodeTree *ngroup, *wgroup;
-       ListBase anim_basepaths = {NULL, NULL};
-       
-       ngroup= (bNodeTree *)gnode->id;
-       if(ngroup==NULL) return 0;
-       
-       /* clear new pointers, set in copytree */
-       for(node= ntree->nodes.first; node; node= node->next)
-               node->new_node= NULL;
-       
-       /* wgroup is a temporary copy of the NodeTree we're merging in
-        *      - all of wgroup's nodes are transferred across to their new home
-        *      - ngroup (i.e. the source NodeTree) is left unscathed
-        */
-       wgroup= ntreeCopyTree(ngroup);
-       
-       /* add the nodes into the ntree */
-       for(node= wgroup->nodes.first; node; node= nextn) {
-               nextn= node->next;
-               
-               /* keep track of this node's RNA "base" path (the part of the pat identifying the node) 
-                * if the old nodetree has animation data which potentially covers this node
-                */
-               if (wgroup->adt) {
-                       PointerRNA ptr;
-                       char *path;
-                       
-                       RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
-                       path = RNA_path_from_ID_to_struct(&ptr);
+       bNodeSocketTemplate *sockdef;
+       bNodeSocket *sock;
+
+       if(ntype->inputs) {
+               sockdef= ntype->inputs;
+               while(sockdef->type != -1) {
+                       sock = node_add_input_from_template(ntree, node, sockdef);
                        
-                       if (path)
-                               BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
-               }
-               
-               /* migrate node */
-               BLI_remlink(&wgroup->nodes, node);
-               BLI_addtail(&ntree->nodes, node);
-               
-               node->locx+= gnode->locx;
-               node->locy+= gnode->locy;
-               
-               node->flag |= NODE_SELECT;
-       }
-       
-       /* restore external links to and from the gnode */
-       for(link= ntree->links.first; link; link= link->next) {
-               if (link->fromnode==gnode) {
-                       if (link->fromsock->groupsock) {
-                               bNodeSocket *gsock= link->fromsock->groupsock;
-                               if (gsock->link) {
-                                       if (gsock->link->fromnode) {
-                                               /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */
-                                               link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL);
-                                               link->fromsock = gsock->link->fromsock->new_sock;
-                                       }
-                                       else {
-                                               /* group output directly maps to group input */
-                                               bNodeSocket *insock= find_group_node_input(gnode, gsock->link->fromsock);
-                                               if (insock->link) {
-                                                       link->fromnode = insock->link->fromnode;
-                                                       link->fromsock = insock->link->fromsock;
-                                               }
-                                       }
-                               }
-                               else {
-                                       /* constant group output: copy the stack value to the external socket.
-                                        * the link is kept here until all possible external users have been fixed.
-                                        */
-                                       QUATCOPY(link->tosock->ns.vec, gsock->ns.vec);
-                               }
-                       }
-               }
-       }
-       /* remove internal output links, these are not used anymore */
-       for(link=wgroup->links.first; link; link= linkn) {
-               linkn = link->next;
-               if (!link->tonode)
-                       nodeRemLink(wgroup, link);
-       }
-       /* restore links from internal nodes */
-       for(link= wgroup->links.first; link; link= link->next) {
-               /* indicates link to group input */
-               if (!link->fromnode) {
-                       /* NB: can't use find_group_node_input here,
-                        * because gnode sockets still point to the old tree!
-                        */
-                       bNodeSocket *insock;
-                       for (insock= gnode->inputs.first; insock; insock= insock->next)
-                               if (insock->groupsock->new_sock == link->fromsock)
-                                       break;
-                       if (insock->link) {
-                               link->fromnode = insock->link->fromnode;
-                               link->fromsock = insock->link->fromsock;
-                       }
-                       else {
-                               /* uses group constant input. copy the input value and remove the dead link. */
-                               QUATCOPY(link->tosock->ns.vec, insock->ns.vec);
-                               nodeRemLink(wgroup, link);
-                       }
+                       sockdef++;
                }
        }
-       
-       /* add internal links to the ntree */
-       for(link= wgroup->links.first; link; link= linkn) {
-               linkn= link->next;
-               BLI_remlink(&wgroup->links, link);
-               BLI_addtail(&ntree->links, link);
-       }
-       
-       /* and copy across the animation */
-       if (wgroup->adt) {
-               LinkData *ld, *ldn=NULL;
-               bAction *waction;
-               
-               /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
-               waction = wgroup->adt->action = copy_action(wgroup->adt->action);
-               
-               /* now perform the moving */
-               BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
-               
-               /* paths + their wrappers need to be freed */
-               for (ld = anim_basepaths.first; ld; ld = ldn) {
-                       ldn = ld->next;
+       if(ntype->outputs) {
+               sockdef= ntype->outputs;
+               while(sockdef->type != -1) {
+                       sock = node_add_output_from_template(ntree, node, sockdef);
                        
-                       MEM_freeN(ld->data);
-                       BLI_freelinkN(&anim_basepaths, ld);
+                       sockdef++;
                }
-               
-               /* free temp action too */
-               free_libblock(&G.main->action, waction);
        }
-       
-       /* delete the group instance. this also removes old input links! */
-       nodeFreeNode(ntree, gnode);
-       
-       /* free the group tree (takes care of user count) */
-       free_libblock(&G.main->nodetree, wgroup);
-       
-       /* solve order goes fine, but the level tags not... doing it twice works for now. solve this once */
-       /* XXX is this still necessary with new groups? it may have been caused by non-updated sock->link pointers. lukas */
-       ntreeSolveOrder(ntree);
-       ntreeSolveOrder(ntree);
-
-       return 1;
 }
 
-void nodeGroupCopy(bNode *gnode)
-{
-       bNodeSocket *sock;
-
-       gnode->id->us--;
-       gnode->id= (ID *)ntreeCopyTree((bNodeTree *)gnode->id);
-
-       /* new_sock was set in nodeCopyNode */
-       for(sock=gnode->inputs.first; sock; sock=sock->next)
-               if(sock->groupsock)
-                       sock->groupsock= sock->groupsock->new_sock;
-
-       for(sock=gnode->outputs.first; sock; sock=sock->next)
-               if(sock->groupsock)
-                       sock->groupsock= sock->groupsock->new_sock;
-}
-
-bNodeSocket *nodeGroupAddSocket(bNodeTree *ngroup, const char *name, int type, int in_out)
-{
-       bNodeSocket *gsock = MEM_callocN(sizeof(bNodeSocket), "bNodeSocket");
-       
-       strncpy(gsock->name, name, sizeof(gsock->name));
-       gsock->type = type;
-       gsock->ns.sockettype = type;
-       gsock->ns.min = INT_MIN;
-       gsock->ns.max = INT_MAX;
-       zero_v4(gsock->ns.vec);
-       gsock->ns.data = NULL;
-       gsock->flag = 0;
-
-       gsock->next = gsock->prev = NULL;
-       gsock->new_sock = NULL;
-       gsock->link = NULL;
-       gsock->ns.data = NULL;
-       /* assign new unique index */
-       gsock->own_index = ngroup->cur_index++;
-       gsock->limit = (in_out==SOCK_IN ? 0xFFF : 1);
-       
-       BLI_addtail(in_out==SOCK_IN ? &ngroup->inputs : &ngroup->outputs, gsock);
-       
-       return gsock;
-}
-
-bNodeSocket *nodeGroupExposeSocket(bNodeTree *ngroup, bNodeSocket *sock, int in_out)
-{
-       bNodeSocket *gsock= nodeGroupAddSocket(ngroup, sock->name, sock->type, in_out);
-       /* initialize the default socket value */
-       QUATCOPY(gsock->ns.vec, sock->ns.vec);
-       return gsock;
-}
-
-void nodeGroupExposeAllSockets(bNodeTree *ngroup)
-{
-       bNode *node;
-       bNodeSocket *sock, *gsock;
-       
-       for (node=ngroup->nodes.first; node; node=node->next) {
-               for (sock=node->inputs.first; sock; sock=sock->next) {
-                       if (!sock->link && !(sock->flag & SOCK_HIDDEN)) {
-                               gsock = nodeGroupAddSocket(ngroup, sock->name, sock->type, SOCK_IN);
-                               /* initialize the default socket value */
-                               QUATCOPY(gsock->ns.vec, sock->ns.vec);
-                               sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock);
-                       }
-               }
-               for (sock=node->outputs.first; sock; sock=sock->next) {
-                       if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) {
-                               gsock = nodeGroupAddSocket(ngroup, sock->name, sock->type, SOCK_OUT);
-                               /* initialize the default socket value */
-                               QUATCOPY(gsock->ns.vec, sock->ns.vec);
-                               gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock);
-                       }
-               }
-       }
-}
-
-void nodeGroupRemoveSocket(bNodeTree *ngroup, bNodeSocket *gsock, int in_out)
-{
-       nodeRemSocketLinks(ngroup, gsock);
-       switch (in_out) {
-       case SOCK_IN:   BLI_remlink(&ngroup->inputs, gsock);    break;
-       case SOCK_OUT:  BLI_remlink(&ngroup->outputs, gsock);   break;
-       }
-       MEM_freeN(gsock);
-}
-
-/* ************** Add stuff ********** */
-void nodeAddSockets(bNode *node, bNodeType *ntype)
-{
-       if (node->type==NODE_GROUP) {
-               bNodeTree *ntree= (bNodeTree*)node->id;
-               if (ntree) {
-                       bNodeSocket *gsock;
-                       for (gsock=ntree->inputs.first; gsock; gsock=gsock->next)
-                               node_add_group_socket(&node->inputs, gsock);
-                       for (gsock=ntree->outputs.first; gsock; gsock=gsock->next)
-                               node_add_group_socket(&node->outputs, gsock);
-               }
-       }
-       else {
-               bNodeSocketType *stype;
-               
-               if(ntype->inputs) {
-                       stype= ntype->inputs;
-                       while(stype->type != -1) {
-                               node_add_socket_type(&node->inputs, stype);
-                               stype++;
-                       }
-               }
-               if(ntype->outputs) {
-                       stype= ntype->outputs;
-                       while(stype->type != -1) {
-                               node_add_socket_type(&node->outputs, stype);
-                               stype++;
-                       }
-               }
-       }
-}
-
-/* Find the first available, non-duplicate name for a given node */
-void nodeUniqueName(bNodeTree *ntree, bNode *node)
+/* Find the first available, non-duplicate name for a given node */
+void nodeUniqueName(bNodeTree *ntree, bNode *node)
 {
        BLI_uniquename(&ntree->nodes, node, "Node", '.', offsetof(bNode, name), sizeof(node->name));
 }
 
-bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
+bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp)
 {
-       bNode *node= NULL;
-       bNodeType *ntype= NULL;
-
-       if (ngroup && BLI_findindex(&G.main->nodetree, ngroup)==-1) {
-               printf("nodeAddNodeType() error: '%s' not in main->nodetree\n", ngroup->id.name);
-               return NULL;
-       }
-
-       if(type>=NODE_DYNAMIC_MENU) {
-               int a=0, idx= type-NODE_DYNAMIC_MENU;
-               ntype= ntree->alltypes.first;
-               while(ntype) {
-                       if(ntype->type==NODE_DYNAMIC) {
-                               if(a==idx)
-                                       break;
-                               a++;
-                       }
-                       ntype= ntype->next;
-               }
-       } else
-               ntype= node_get_type(ntree, type, id);
-
+       bNode *node;
+       bNodeType *ntype;
+       
+       ntype= node_get_type(ntree, ntemp->type);
        if(ntype == NULL) {
-               printf("nodeAddNodeType() error: '%d' type invalid\n", type);
+               printf("nodeAddNodeType() error: '%d' type invalid\n", ntemp->type);
                return NULL;
        }
-
-       node= MEM_callocN(sizeof(bNode), "new node");
-       BLI_addtail(&ntree->nodes, node);
-       node->typeinfo= ntype;
-       if(type>=NODE_DYNAMIC_MENU)
-               node->custom2= type; /* for node_dynamic_init */
-
-       if(ngroup)
-               BLI_strncpy(node->name, ngroup->id.name+2, NODE_MAXSTR);
-       else if(type>NODE_DYNAMIC_MENU) {
-               BLI_strncpy(node->name, ntype->id->name+2, NODE_MAXSTR);
-       }
-       else
-               BLI_strncpy(node->name, ntype->name, NODE_MAXSTR);
-
-       nodeUniqueName(ntree, node);
+       /* validity check */
+       if (!nodeValid(ntree, ntemp))
+               return NULL;
        
+       node= MEM_callocN(sizeof(bNode), "new node");
        node->type= ntype->type;
+       node->typeinfo= ntype;
        node->flag= NODE_SELECT|ntype->flag;
        node->width= ntype->width;
-       node->miniwidth= 42.0f;         /* small value only, allows print of first chars */
-
-       if(type==NODE_GROUP)
-               node->id= (ID *)ngroup;
-
-       /* need init handler later? */
-       /* got it-bob*/
+       node->miniwidth= 42.0f;
+       node->height= ntype->height;
+       
+       node_add_sockets_from_type(ntree, node, ntype);
+       
        if(ntype->initfunc!=NULL)
-               ntype->initfunc(node);
+               ntype->initfunc(ntree, node, ntemp);
        
-       nodeAddSockets(node, ntype);
+       /* initialize the node name with the node label */
+       BLI_strncpy(node->name, nodeLabel(node), NODE_MAXSTR);
+       nodeUniqueName(ntree, node);
+       
+       BLI_addtail(&ntree->nodes, node);
+       
+       ntree->update |= NTREE_UPDATE_NODES;
        
        return node;
 }
@@ -1011,9 +362,9 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
 void nodeMakeDynamicType(bNode *node)
 {
        /* find SH_DYNAMIC_NODE ntype */
-       bNodeType *ntype= node_all_shaders.first;
+       bNodeType *ntype= ntreeGetType(NTREE_SHADER)->node_types.first;
        while(ntype) {
-               if(ntype->type==NODE_DYNAMIC && ntype->id==NULL)
+               if(ntype->type==NODE_DYNAMIC)
                        break;
                ntype= ntype->next;
        }
@@ -1023,17 +374,11 @@ void nodeMakeDynamicType(bNode *node)
                /*node->typeinfo= MEM_dupallocN(ntype);*/
                bNodeType *newtype= MEM_callocN(sizeof(bNodeType), "dynamic bNodeType");
                *newtype= *ntype;
-               newtype->name= BLI_strdup(ntype->name);
+               strcpy(newtype->name, ntype->name);
                node->typeinfo= newtype;
        }
 }
 
-void nodeUpdateType(bNodeTree *ntree, bNode* node, bNodeType *ntype)
-{
-       verify_socket_list(ntree, &node->inputs, ntype->inputs);
-       verify_socket_list(ntree, &node->outputs, ntype->outputs);
-}
-
 /* keep socket listorder identical, for copying links */
 /* ntree is the target tree */
 bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
@@ -1045,19 +390,23 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
        nodeUniqueName(ntree, nnode);
        
        BLI_addtail(&ntree->nodes, nnode);
-       
+
        BLI_duplicatelist(&nnode->inputs, &node->inputs);
        oldsock= node->inputs.first;
        for(sock= nnode->inputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
                oldsock->new_sock= sock;
+               sock->stack_index= 0;
+               
+               sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
        }
        
        BLI_duplicatelist(&nnode->outputs, &node->outputs);
        oldsock= node->outputs.first;
        for(sock= nnode->outputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
-               sock->stack_index= 0;
-               sock->ns.data= NULL;
                oldsock->new_sock= sock;
+               sock->stack_index= 0;
+               
+               sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
        }
        
        /* don't increase node->id users, freenode doesn't decrement either */
@@ -1069,10 +418,11 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
        nnode->new_node= NULL;
        nnode->preview= NULL;
        
+       ntree->update |= NTREE_UPDATE_NODES;
+       
        return nnode;
 }
 
-/* fromsock and tosock can be NULL */
 /* also used via rna api, so we check for proper input output direction */
 bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
 {
@@ -1095,6 +445,21 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock,
                                from= -1; /* OK but flip */
                }
        }
+       else {
+               /* check tree sockets */
+               for(sock= ntree->inputs.first; sock; sock= sock->next)
+                       if(sock==fromsock)
+                               break;
+               if(sock)
+                       from= 1; /* OK */
+               else {
+                       for(sock= ntree->outputs.first; sock; sock= sock->next)
+                               if(sock==fromsock)
+                                       break;
+                       if(sock)
+                               from= -1; /* OK but flip */
+               }
+       }
        if(tonode) {
                for(sock= tonode->inputs.first; sock; sock= sock->next)
                        if(sock==tosock)
@@ -1109,8 +474,22 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock,
                                to= -1; /* OK but flip */
                }
        }
+       else {
+               /* check tree sockets */
+               for(sock= ntree->outputs.first; sock; sock= sock->next)
+                       if(sock==tosock)
+                               break;
+               if(sock)
+                       to= 1; /* OK */
+               else {
+                       for(sock= ntree->inputs.first; sock; sock= sock->next)
+                               if(sock==tosock)
+                                       break;
+                       if(sock)
+                               to= -1; /* OK but flip */
+               }
+       }
        
-       /* this allows NULL sockets to work */
        if(from >= 0 && to >= 0) {
                link= MEM_callocN(sizeof(bNodeLink), "link");
                BLI_addtail(&ntree->links, link);
@@ -1128,6 +507,8 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock,
                link->tosock= fromsock;
        }
        
+       ntree->update |= NTREE_UPDATE_LINKS;
+       
        return link;
 }
 
@@ -1137,6 +518,8 @@ void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
        if(link->tosock)
                link->tosock->link= NULL;
        MEM_freeN(link);
+       
+       ntree->update |= NTREE_UPDATE_LINKS;
 }
 
 void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
@@ -1149,26 +532,73 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
                        nodeRemLink(ntree, link);
                }
        }
+       
+       ntree->update |= NTREE_UPDATE_LINKS;
 }
 
+/* transforms node location to area coords */
+void nodeSpaceCoords(bNode *node, float *locx, float *locy)
+{
+       if (node->parent) {
+               nodeSpaceCoords(node->parent, locx, locy);
+               *locx += node->locx;
+               *locy += node->locy;
+       }
+       else {
+               *locx = node->locx;
+               *locy = node->locy;
+       }
+}
 
-bNodeTree *ntreeAddTree(const char *name, int type, const short is_group)
+void nodeAttachNode(bNode *node, bNode *parent)
 {
-       bNodeTree *ntree;
+       float parentx, parenty;
+       
+       node->parent = parent;
+       /* transform to parent space */
+       nodeSpaceCoords(parent, &parentx, &parenty);
+       node->locx -= parentx;
+       node->locy -= parenty;
+}
 
-       if (is_group)
-               ntree= alloc_libblock(&G.main->nodetree, ID_NT, name);
-       else {
+void nodeDetachNode(struct bNode *node)
+{
+       float parentx, parenty;
+       
+       if (node->parent) {
+               /* transform to "global" (area) space */
+               nodeSpaceCoords(node->parent, &parentx, &parenty);
+               node->locx += parentx;
+               node->locy += parenty;
+               node->parent = NULL;
+       }
+}
+
+bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
+{
+       bNodeTree *ntree;
+       bNodeType *ntype;
+       
+       /* trees are created as local trees if they of compositor, material or texture type,
+        * node groups and other tree types are created as library data.
+        */
+       if (ELEM3(type, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE) && nodetype==0) {
                ntree= MEM_callocN(sizeof(bNodeTree), "new node tree");
                *( (short *)ntree->id.name )= ID_NT; /* not "type", as that is ntree->type */
                BLI_strncpy(ntree->id.name+2, name, sizeof(ntree->id.name));
        }
-
+       else
+               ntree= alloc_libblock(&G.main->nodetree, ID_NT, name);
+       
        ntree->type= type;
-       ntree->alltypes.first = NULL;
-       ntree->alltypes.last = NULL;
-
+       ntree->nodetype = nodetype;
+       
        ntreeInitTypes(ntree);
+       
+       ntype = node_get_type(ntree, ntree->nodetype);
+       if (ntype && ntype->inittreefunc)
+               ntype->inittreefunc(ntree);
+       
        return ntree;
 }
 
@@ -1199,9 +629,7 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree)
        id_us_plus((ID *)newtree->gpd);
 
        /* in case a running nodetree is copied */
-       newtree->init &= ~(NTREE_EXEC_INIT);
-       newtree->threadstack= NULL;
-       newtree->stack= NULL;
+       newtree->execdata= NULL;
        
        newtree->nodes.first= newtree->nodes.last= NULL;
        newtree->links.first= newtree->links.last= NULL;
@@ -1210,7 +638,10 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree)
        for(node= ntree->nodes.first; node; node= node->next) {
                node->new_node= NULL;
                nnode= nodeCopyNode(newtree, node);     /* sets node->new */
-               if(node==last) break;
+               
+               /* make sure we don't copy new nodes again! */
+               if (node==last)
+                       break;
        }
        
        /* socket definition for group usage */
@@ -1218,14 +649,15 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree)
        for(gsock= newtree->inputs.first, oldgsock= ntree->inputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) {
                oldgsock->new_sock= gsock;
                gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL);
+               gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL);
        }
-       
        BLI_duplicatelist(&newtree->outputs, &ntree->outputs);
        for(gsock= newtree->outputs.first, oldgsock= ntree->outputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) {
                oldgsock->new_sock= gsock;
                gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL);
+               gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL);
        }
-
+       
        /* copy links */
        BLI_duplicatelist(&newtree->links, &ntree->links);
        for(link= newtree->links.first; link; link= link->next) {
@@ -1237,7 +669,13 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree)
                if (link->tosock)
                        link->tosock->link = link;
        }
-
+       
+       /* update node->parent pointers */
+       for (node=newtree->nodes.first; node; node=node->next) {
+               if (node->parent)
+                       node->parent = node->parent->new_node;
+       }
+       
        return newtree;
 }
 
@@ -1256,7 +694,7 @@ void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to)
 /* *************** preview *********** */
 /* if node->preview, then we assume the rect to exist */
 
-static void node_free_preview(bNode *node)
+void nodeFreePreview(bNode *node)
 {
        if(node->preview) {
                if(node->preview->rect)
@@ -1360,7 +798,6 @@ void nodeAddToPreview(bNode *node, float *col, int x, int y, int do_manage)
        }
 }
 
-
 /* ************** Free stuff ********** */
 
 /* goes over entire tree */
@@ -1395,50 +832,84 @@ void nodeUnlinkNode(bNodeTree *ntree, bNode *node)
        }
 }
 
-static void composit_free_node_cache(bNode *node)
+static void node_unlink_attached(bNodeTree *ntree, bNode *parent)
 {
-       bNodeSocket *sock;
-       
-       for(sock= node->outputs.first; sock; sock= sock->next) {
-               if(sock->ns.data) {
-                       free_compbuf(sock->ns.data);
-                       sock->ns.data= NULL;
-               }
+       bNode *node;
+       for (node=ntree->nodes.first; node; node=node->next) {
+               if (node->parent == parent)
+                       nodeDetachNode(node);
        }
 }
 
 void nodeFreeNode(bNodeTree *ntree, bNode *node)
 {
+       bNodeTreeType *treetype= ntreeGetType(ntree->type);
+       bNodeSocket *sock, *nextsock;
+       
+       /* remove all references to this node */
        nodeUnlinkNode(ntree, node);
+       node_unlink_attached(ntree, node);
+       
        BLI_remlink(&ntree->nodes, node);
 
        /* since it is called while free database, node->id is undefined */
        
-       if(ntree->type==NTREE_COMPOSIT)
-               composit_free_node_cache(node);
-       BLI_freelistN(&node->inputs);
-       BLI_freelistN(&node->outputs);
+       if (treetype->free_node_cache)
+               treetype->free_node_cache(ntree, node);
        
-       node_free_preview(node);
+       for (sock=node->inputs.first; sock; sock = nextsock) {
+               nextsock = sock->next;
+               if (sock->default_value)
+                       MEM_freeN(sock->default_value);
+               MEM_freeN(sock);
+       }
+       for (sock=node->outputs.first; sock; sock = nextsock) {
+               nextsock = sock->next;
+               if (sock->default_value)
+                       MEM_freeN(sock->default_value);
+               MEM_freeN(sock);
+       }
+
+       nodeFreePreview(node);
 
        if(node->typeinfo && node->typeinfo->freestoragefunc) {
                node->typeinfo->freestoragefunc(node);
        }
 
        MEM_freeN(node);
+       
+       ntree->update |= NTREE_UPDATE_NODES;
 }
 
 /* do not free ntree itself here, free_libblock calls this function too */
 void ntreeFreeTree(bNodeTree *ntree)
 {
        bNode *node, *next;
+       bNodeSocket *sock;
        
        if(ntree==NULL) return;
        
-       ntreeEndExecTree(ntree);        /* checks for if it is still initialized */
+       /* XXX hack! node trees should not store execution graphs at all.
+        * This should be removed when old tree types no longer require it.
+        * Currently the execution data for texture nodes remains in the tree
+        * after execution, until the node tree is updated or freed.
+        */
+       if (ntree->execdata) {
+               switch (ntree->type) {
+               case NTREE_COMPOSIT:
+                       ntreeCompositEndExecTree(ntree->execdata, 1);
+                       break;
+               case NTREE_SHADER:
+                       ntreeShaderEndExecTree(ntree->execdata, 1);
+                       break;
+               case NTREE_TEXTURE:
+                       ntreeTexEndExecTree(ntree->execdata, 1);
+                       break;
+               }
+       }
        
        BKE_free_animdata((ID *)ntree);
-
+       
        id_us_min((ID *)ntree->gpd);
 
        BLI_freelistN(&ntree->links);   /* do first, then unlink_node goes fast */
@@ -1448,25 +919,120 @@ void ntreeFreeTree(bNodeTree *ntree)
                nodeFreeNode(ntree, node);
        }
        
+       for (sock=ntree->inputs.first; sock; sock=sock->next)
+               if (sock->default_value)
+                       MEM_freeN(sock->default_value);
        BLI_freelistN(&ntree->inputs);
+       for (sock=ntree->outputs.first; sock; sock=sock->next)
+               if (sock->default_value)
+                       MEM_freeN(sock->default_value);
        BLI_freelistN(&ntree->outputs);
 }
 
 void ntreeFreeCache(bNodeTree *ntree)
 {
-       bNode *node;
+       bNodeTreeType *treetype;
        
        if(ntree==NULL) return;
+       
+       treetype= ntreeGetType(ntree->type);
+       if (treetype->free_cache)
+               treetype->free_cache(ntree);
+}
 
-       if(ntree->type==NTREE_COMPOSIT)
-               for(node= ntree->nodes.first; node; node= node->next)
-                       composit_free_node_cache(node);
+void ntreeSetOutput(bNodeTree *ntree)
+{
+       bNode *node;
+
+       /* find the active outputs, might become tree type dependant handler */
+       for(node= ntree->nodes.first; node; node= node->next) {
+               if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
+                       bNode *tnode;
+                       int output= 0;
+                       
+                       /* we need a check for which output node should be tagged like this, below an exception */
+                       if(node->type==CMP_NODE_OUTPUT_FILE)
+                          continue;
+                          
+                       /* there is more types having output class, each one is checked */
+                       for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
+                               if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) {
+                                       
+                                       if(ntree->type==NTREE_COMPOSIT) {
+                                                       
+                                               /* same type, exception for viewer */
+                                               if(tnode->type==node->type ||
+                                                  (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) &&
+                                                       ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) {
+                                                       if(tnode->flag & NODE_DO_OUTPUT) {
+                                                               output++;
+                                                               if(output>1)
+                                                                       tnode->flag &= ~NODE_DO_OUTPUT;
+                                                       }
+                                               }
+                                       }
+                                       else {
+                                               /* same type */
+                                               if(tnode->type==node->type) {
+                                                       if(tnode->flag & NODE_DO_OUTPUT) {
+                                                               output++;
+                                                               if(output>1)
+                                                                       tnode->flag &= ~NODE_DO_OUTPUT;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       if(output==0)
+                               node->flag |= NODE_DO_OUTPUT;
+               }
+       }
+       
+       /* here we could recursively set which nodes have to be done,
+               might be different for editor or for "real" use... */
+}
+
+typedef struct MakeLocalCallData {
+       ID *group_id;
+       ID *new_id;
+       int lib, local;
+} MakeLocalCallData;
+
+static void ntreeMakeLocal_CheckLocal(void *calldata, ID *owner_id, bNodeTree *ntree)
+{
+       MakeLocalCallData *cd= (MakeLocalCallData*)calldata;
+       bNode *node;
+       
+       /* find if group is in tree */
+       for(node= ntree->nodes.first; node; node= node->next) {
+               if(node->id == cd->group_id) {
+                       if(owner_id->lib) cd->lib= 1;
+                       else cd->local= 1;
+               }
+       }
+}
 
+static void ntreeMakeLocal_LinkNew(void *calldata, ID *owner_id, bNodeTree *ntree)
+{
+       MakeLocalCallData *cd= (MakeLocalCallData*)calldata;
+       bNode *node;
+       
+       /* find if group is in tree */
+       for(node= ntree->nodes.first; node; node= node->next) {
+               if(node->id == cd->group_id) {
+                       if(owner_id->lib==NULL) {
+                               node->id= cd->new_id;
+                               cd->new_id->us++;
+                               cd->group_id->us--;
+                       }
+               }
+       }
 }
 
 void ntreeMakeLocal(bNodeTree *ntree)
 {
-       int local=0, lib=0;
+       bNodeTreeType *treetype= ntreeGetType(ntree->type);
+       MakeLocalCallData cd;
        
        /* - only lib users: do nothing
                * - only local users: set flag
@@ -1475,138 +1041,146 @@ void ntreeMakeLocal(bNodeTree *ntree)
        
        if(ntree->id.lib==NULL) return;
        if(ntree->id.us==1) {
-               ntree->id.lib= NULL;
+               ntree->id.lib= 0;
                ntree->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)ntree, NULL);
+               new_id(0, (ID *)ntree, 0);
                return;
        }
        
        /* now check users of groups... again typedepending, callback... */
-       if(ntree->type==NTREE_SHADER) {
-               Material *ma;
-               for(ma= G.main->mat.first; ma; ma= ma->id.next) {
-                       if(ma->nodetree) {
-                               bNode *node;
-                               
-                               /* find if group is in tree */
-                               for(node= ma->nodetree->nodes.first; node; node= node->next) {
-                                       if(node->id == (ID *)ntree) {
-                                               if(ma->id.lib) lib= 1;
-                                               else local= 1;
-                                       }
-                               }
-                       }
-               }
+       cd.group_id = &ntree->id;
+       cd.new_id = NULL;
+       cd.local = 0;
+       cd.lib = 0;
+       
+       treetype->foreach_nodetree(G.main, &cd, &ntreeMakeLocal_CheckLocal);
+       
+       /* if all users are local, we simply make tree local */
+       if(cd.local && cd.lib==0) {
+               ntree->id.lib= NULL;
+               ntree->id.flag= LIB_LOCAL;
+               new_id(0, (ID *)ntree, 0);
        }
-       else if(ntree->type==NTREE_COMPOSIT) {
-               Scene *sce;
-               for(sce= G.main->scene.first; sce; sce= sce->id.next) {
-                       if(sce->nodetree) {
-                               bNode *node;
-                               
-                               /* find if group is in tree */
-                               for(node= sce->nodetree->nodes.first; node; node= node->next) {
-                                       if(node->id == (ID *)ntree) {
-                                               if(sce->id.lib) lib= 1;
-                                               else local= 1;
-                                       }
-                               }
-                       }
-               }
-       }
-       else if(ntree->type==NTREE_TEXTURE) {
-               Tex *tx;
-               for(tx= G.main->tex.first; tx; tx= tx->id.next) {
-                       if(tx->nodetree) {
-                               bNode *node;
-                               
-                               /* find if group is in tree */
-                               for(node= tx->nodetree->nodes.first; node; node= node->next) {
-                                       if(node->id == (ID *)ntree) {
-                                               if(tx->id.lib) lib= 1;
-                                               else local= 1;
-                                       }
-                               }
-                       }
-               }
-       }
-       
-       /* if all users are local, we simply make tree local */
-       if(local && lib==0) {
-               ntree->id.lib= NULL;
-               ntree->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)ntree, NULL);
-       }
-       else if(local && lib) {
+       else if(cd.local && cd.lib) {
                /* this is the mixed case, we copy the tree and assign it to local users */
                bNodeTree *newtree= ntreeCopyTree(ntree);
                
                newtree->id.us= 0;
                
-               if(ntree->type==NTREE_SHADER) {
-                       Material *ma;
-                       for(ma= G.main->mat.first; ma; ma= ma->id.next) {
-                               if(ma->nodetree) {
-                                       bNode *node;
-                                       
-                                       /* find if group is in tree */
-                                       for(node= ma->nodetree->nodes.first; node; node= node->next) {
-                                               if(node->id == (ID *)ntree) {
-                                                       if(ma->id.lib==NULL) {
-                                                               node->id= &newtree->id;
-                                                               newtree->id.us++;
-                                                               ntree->id.us--;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-               else if(ntree->type==NTREE_COMPOSIT) {
-                       Scene *sce;
-                       for(sce= G.main->scene.first; sce; sce= sce->id.next) {
-                               if(sce->nodetree) {
-                                       bNode *node;
-                                       
-                                       /* find if group is in tree */
-                                       for(node= sce->nodetree->nodes.first; node; node= node->next) {
-                                               if(node->id == (ID *)ntree) {
-                                                       if(sce->id.lib==NULL) {
-                                                               node->id= &newtree->id;
-                                                               newtree->id.us++;
-                                                               ntree->id.us--;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-               else if(ntree->type==NTREE_TEXTURE) {
-                       Tex *tx;
-                       for(tx= G.main->tex.first; tx; tx= tx->id.next) {
-                               if(tx->nodetree) {
-                                       bNode *node;
-                                       
-                                       /* find if group is in tree */
-                                       for(node= tx->nodetree->nodes.first; node; node= node->next) {
-                                               if(node->id == (ID *)ntree) {
-                                                       if(tx->id.lib==NULL) {
-                                                               node->id= &newtree->id;
-                                                               newtree->id.us++;
-                                                               ntree->id.us--;
-                                                       }
-                                               }
-                                       }
-                               }
+
+               cd.new_id = &newtree->id;
+               treetype->foreach_nodetree(G.main, &cd, &ntreeMakeLocal_LinkNew);
+       }
+}
+
+int ntreeNodeExists(bNodeTree *ntree, bNode *testnode)
+{
+       bNode *node= ntree->nodes.first;
+       for(; node; node= node->next)
+               if(node==testnode)
+                       return 1;
+       return 0;
+}
+
+int ntreeOutputExists(bNode *node, bNodeSocket *testsock)
+{
+       bNodeSocket *sock= node->outputs.first;
+       for(; sock; sock= sock->next)
+               if(sock==testsock)
+                       return 1;
+       return 0;
+}
+
+/* returns localized tree for execution in threads */
+bNodeTree *ntreeLocalize(bNodeTree *ntree)
+{
+       bNodeTreeType *ntreetype= ntreeGetType(ntree->type);
+
+       bNodeTree *ltree;
+       bNode *node;
+       
+       bAction *action_backup= NULL, *tmpact_backup= NULL;
+       
+       /* Workaround for copying an action on each render!
+        * set action to NULL so animdata actions dont get copied */
+       AnimData *adt= BKE_animdata_from_id(&ntree->id);
+
+       if(adt) {
+               action_backup= adt->action;
+               tmpact_backup= adt->tmpact;
+
+               adt->action= NULL;
+               adt->tmpact= NULL;
+       }
+
+       /* node copy func */
+       ltree= ntreeCopyTree(ntree);
+
+       if(adt) {
+               AnimData *ladt= BKE_animdata_from_id(&ltree->id);
+
+               adt->action= ladt->action= action_backup;
+               adt->tmpact= ladt->tmpact= tmpact_backup;
+
+               if(action_backup) action_backup->id.us++;
+               if(tmpact_backup) tmpact_backup->id.us++;
+               
+       }
+       /* end animdata uglyness */
+
+       /* ensures only a single output node is enabled */
+       ntreeSetOutput(ntree);
+
+       for(node= ntree->nodes.first; node; node= node->next) {
+               /* store new_node pointer to original */
+               node->new_node->new_node= node;
+       }
+
+       if (ntreetype->localize)
+               ntreetype->localize(ltree, ntree);
+
+       return ltree;
+}
+
+/* sync local composite with real tree */
+/* local tree is supposed to be running, be careful moving previews! */
+/* is called by jobs manager, outside threads, so it doesnt happen during draw */
+void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
+{
+       bNodeTreeType *ntreetype= ntreeGetType(ntree->type);
+
+       if (ntreetype->local_sync)
+               ntreetype->local_sync(localtree, ntree);
+}
+
+/* merge local tree results back, and free local tree */
+/* we have to assume the editor already changed completely */
+void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
+{
+       bNodeTreeType *ntreetype= ntreeGetType(ntree->type);
+       bNode *lnode;
+       
+       /* move over the compbufs and previews */
+       for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
+               if(ntreeNodeExists(ntree, lnode->new_node)) {
+                       if(lnode->preview && lnode->preview->rect) {
+                               nodeFreePreview(lnode->new_node);
+                               lnode->new_node->preview= lnode->preview;
+                               lnode->preview= NULL;
                        }
                }
        }
-}
 
+       if (ntreetype->local_merge)
+               ntreetype->local_merge(localtree, ntree);
+
+       ntreeFreeTree(localtree);
+       MEM_freeN(localtree);
+}
 
 /* ************ find stuff *************** */
 
-static int ntreeHasType(bNodeTree *ntree, int type)
+int ntreeHasType(bNodeTree *ntree, int type)
 {
        bNode *node;
        
@@ -1734,1663 +1308,365 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
                        if(GS(node->id->name) == GS(tnode->id->name))
                                tnode->flag &= ~NODE_ACTIVE_ID;
                }
-       }
-       
-       node->flag |= NODE_ACTIVE;
-       if(node->id)
-               node->flag |= NODE_ACTIVE_ID;
-}
-
-/* use flags are not persistant yet, groups might need different tagging, so we do it each time
-   when we need to get this info */
-void ntreeSocketUseFlags(bNodeTree *ntree)
-{
-       bNode *node;
-       bNodeSocket *sock;
-       bNodeLink *link;
-       
-       /* clear flags */
-       for(node= ntree->nodes.first; node; node= node->next) {
-               for(sock= node->inputs.first; sock; sock= sock->next)
-                       sock->flag &= ~SOCK_IN_USE;
-               for(sock= node->outputs.first; sock; sock= sock->next)
-                       sock->flag &= ~SOCK_IN_USE;
-       }
-       
-       /* tag all thats in use */
-       for(link= ntree->links.first; link; link= link->next) {
-       
-               if(link->fromsock) // FIXME, see below
-                       link->fromsock->flag |= SOCK_IN_USE;
-               if(link->tosock) // FIXME This can be NULL, when dragging a new link in the UI, should probably copy the node tree for preview render - campbell
-                       link->tosock->flag |= SOCK_IN_USE;
-       }
-}
-
-/* ************** dependency stuff *********** */
-
-/* node is guaranteed to be not checked before */
-static int node_recurs_check(bNode *node, bNode ***nsort)
-{
-       bNode *fromnode;
-       bNodeSocket *sock;
-       int level = 0xFFF;
-       
-       node->done= 1;
-       
-       for(sock= node->inputs.first; sock; sock= sock->next) {
-               if(sock->link) {
-                       fromnode= sock->link->fromnode;
-                       if(fromnode) {
-                               if (fromnode->done==0)
-                                       fromnode->level= node_recurs_check(fromnode, nsort);
-                               if (fromnode->level <= level)
-                                       level = fromnode->level - 1;
-                       }
-               }
-       }
-       **nsort= node;
-       (*nsort)++;
-       
-       return level;
-}
-
-
-static void ntreeSetOutput(bNodeTree *ntree)
-{
-       bNode *node;
-
-       /* find the active outputs, might become tree type dependant handler */
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
-                       bNode *tnode;
-                       int output= 0;
-                       
-                       /* we need a check for which output node should be tagged like this, below an exception */
-                       if(node->type==CMP_NODE_OUTPUT_FILE)
-                          continue;
-                          
-                       /* there is more types having output class, each one is checked */
-                       for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
-                               if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) {
-                                       
-                                       if(ntree->type==NTREE_COMPOSIT) {
-                                                       
-                                               /* same type, exception for viewer */
-                                               if(tnode->type==node->type ||
-                                                  (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) &&
-                                                       ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) {
-                                                       if(tnode->flag & NODE_DO_OUTPUT) {
-                                                               output++;
-                                                               if(output>1)
-                                                                       tnode->flag &= ~NODE_DO_OUTPUT;
-                                                       }
-                                               }
-                                       }
-                                       else {
-                                               /* same type */
-                                               if(tnode->type==node->type) {
-                                                       if(tnode->flag & NODE_DO_OUTPUT) {
-                                                               output++;
-                                                               if(output>1)
-                                                                       tnode->flag &= ~NODE_DO_OUTPUT;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       if(output==0)
-                               node->flag |= NODE_DO_OUTPUT;
-               }
-       }
-       
-       /* here we could recursively set which nodes have to be done,
-               might be different for editor or for "real" use... */
-}
-
-void ntreeSolveOrder(bNodeTree *ntree)
-{
-       bNode *node, **nodesort, **nsort;
-       bNodeSocket *sock;
-       bNodeLink *link;
-       int a, totnode=0;
-       
-       /* the solve-order is called on each tree change, so we should be sure no exec can be running */
-       ntreeEndExecTree(ntree);
-
-       /* set links pointers the input sockets, to find dependencies */
-       /* first clear data */
-       for(node= ntree->nodes.first; node; node= node->next) {
-               node->done= 0;
-               totnode++;
-               for(sock= node->inputs.first; sock; sock= sock->next)
-                       sock->link= NULL;
-       }
-       /* clear group socket links */
-       for(sock= ntree->outputs.first; sock; sock= sock->next)
-               sock->link= NULL;
-       if(totnode==0)
-               return;
-       
-       for(link= ntree->links.first; link; link= link->next) {
-               link->tosock->link= link;
-       }
-       
-       nsort= nodesort= MEM_callocN(totnode*sizeof(void *), "sorted node array");
-       
-       /* recursive check */
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->done==0) {
-                       node->level= node_recurs_check(node, &nsort);
-               }
-       }
-       
-       /* re-insert nodes in order, first a paranoia check */
-       for(a=0; a<totnode; a++) {
-               if(nodesort[a]==NULL)
-                       break;
-       }
-       if(a<totnode)
-               printf("sort error in node tree");
-       else {
-               ntree->nodes.first= ntree->nodes.last= NULL;
-               for(a=0; a<totnode; a++)
-                       BLI_addtail(&ntree->nodes, nodesort[a]);
-       }
-       
-       MEM_freeN(nodesort);
-
-       ntreeSetOutput(ntree);
-}
-
-
-/* Should be callback! */
-/* Do not call execs here */
-void NodeTagChanged(bNodeTree *ntree, bNode *node)
-{
-       if(ntree->type==NTREE_COMPOSIT) {
-               bNodeSocket *sock;
-
-               for(sock= node->outputs.first; sock; sock= sock->next) {
-                       if(sock->ns.data) {
-                               //free_compbuf(sock->ns.data);
-                               //sock->ns.data= NULL;
-                       }
-               }
-               node->need_exec= 1;
-       }
-}
-
-int NodeTagIDChanged(bNodeTree *ntree, ID *id)
-{
-       int change = FALSE;
-
-       if(ELEM(NULL, id, ntree))
-               return change;
-       
-       if(ntree->type==NTREE_COMPOSIT) {
-               bNode *node;
-               
-               for(node= ntree->nodes.first; node; node= node->next) {
-                       if(node->id==id) {
-                               change= TRUE;
-                               NodeTagChanged(ntree, node);
-                       }
-               }
-       }
-       
-       return change;
-}
-
-
-
-/* ******************* executing ************* */
-
-/* for a given socket, find the actual stack entry */
-static bNodeStack *get_socket_stack(bNodeStack *stack, bNodeSocket *sock, bNodeStack **gin)
-{
-       switch (sock->stack_type) {
-       case SOCK_STACK_LOCAL:
-               return stack + sock->stack_index;
-       case SOCK_STACK_EXTERN:
-               return (gin ? gin[sock->stack_index] : NULL);
-       case SOCK_STACK_CONST:
-               return sock->stack_ptr;
-       }
-       return NULL;
-}
-
-/* see notes at ntreeBeginExecTree */
-static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out, bNodeStack **gin)
-{
-       bNodeSocket *sock;
-       
-       /* build pointer stack */
-       if (in) {
-               for(sock= node->inputs.first; sock; sock= sock->next) {
-                       *(in++) = get_socket_stack(stack, sock, gin);
-               }
-       }
-       
-       if (out) {
-               for(sock= node->outputs.first; sock; sock= sock->next) {
-                       *(out++) = get_socket_stack(stack, sock, gin);
-               }
-       }
-}
-
-static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in)
-{
-       bNode *node;
-       bNodeTree *ntree= (bNodeTree *)gnode->id;
-       bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
-       bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
-       
-       if(ntree==NULL) return;
-       
-       stack+= gnode->stack_index;
-               
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->typeinfo->execfunc) {
-                       node_get_stack(node, stack, nsin, nsout, in);
-                       
-                       /* for groups, only execute outputs for edited group */
-                       if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
-                               if(node->type==CMP_NODE_OUTPUT_FILE || (gnode->flag & NODE_GROUP_EDIT))
-                                       node->typeinfo->execfunc(data, node, nsin, nsout);
-                       }
-                       else
-                               node->typeinfo->execfunc(data, node, nsin, nsout);
-               }
-       }
-       
-       /* free internal buffers */
-       if (ntree->type==NTREE_COMPOSIT) {
-               bNodeSocket *sock;
-               bNodeStack *ns;
-               
-               /* clear hasoutput on all local stack data,
-                * only the group output will be used from now on
-                */
-               for (node=ntree->nodes.first; node; node=node->next) {
-                       for (sock=node->outputs.first; sock; sock=sock->next) {
-                               if (sock->stack_type==SOCK_STACK_LOCAL) {
-                                       ns= get_socket_stack(stack, sock, in);
-                                       ns->hasoutput = 0;
-                               }
-                       }
-               }
-               /* use the hasoutput flag to tag external sockets */
-               for (sock=ntree->outputs.first; sock; sock=sock->next) {
-                       if (sock->stack_type==SOCK_STACK_LOCAL) {
-                               ns= get_socket_stack(stack, sock, in);
-                               ns->hasoutput = 1;
-                       }
-               }
-               /* now free all stacks that are not used from outside */
-               for (node=ntree->nodes.first; node; node=node->next) {
-                       for (sock=node->outputs.first; sock; sock=sock->next) {
-                               if (sock->stack_type==SOCK_STACK_LOCAL ) {
-                                       ns= get_socket_stack(stack, sock, in);
-                                       if (ns->hasoutput==0 && ns->data) {
-                                               free_compbuf(ns->data);
-                                               ns->data = NULL;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-static int set_stack_indexes_default(bNode *node, int index)
-{
-       bNodeSocket *sock;
-       
-       for (sock=node->inputs.first; sock; sock=sock->next) {
-               if (sock->link && sock->link->fromsock) {
-                       sock->stack_type = sock->link->fromsock->stack_type;
-                       sock->stack_index = sock->link->fromsock->stack_index;
-                       sock->stack_ptr = sock->link->fromsock->stack_ptr;
-               }
-               else {
-                       sock->stack_type = SOCK_STACK_CONST;
-                       sock->stack_index = -1;
-                       sock->stack_ptr = &sock->ns;
-               }
-       }
-       
-       for (sock=node->outputs.first; sock; sock=sock->next) {
-               sock->stack_type = SOCK_STACK_LOCAL;
-               sock->stack_index = index++;
-               sock->stack_ptr = NULL;
-       }
-       
-       return index;
-}
-
-static int ntree_begin_exec_tree(bNodeTree *ntree);
-static int set_stack_indexes_group(bNode *node, int index)
-{
-       bNodeTree *ngroup= (bNodeTree*)node->id;
-       bNodeSocket *sock;
-       
-       if(ngroup && (ngroup->init & NTREE_TYPE_INIT)==0)
-               ntreeInitTypes(ngroup);
-       
-       node->stack_index = index;
-       if(ngroup)
-               index += ntree_begin_exec_tree(ngroup);
-       
-       for (sock=node->inputs.first; sock; sock=sock->next) {
-               if (sock->link && sock->link->fromsock) {
-                       sock->stack_type = sock->link->fromsock->stack_type;
-                       sock->stack_index = sock->link->fromsock->stack_index;
-                       sock->stack_ptr = sock->link->fromsock->stack_ptr;
-               }
-               else {
-                       sock->stack_type = SOCK_STACK_CONST;
-                       sock->stack_index = -1;
-                       sock->stack_ptr = &sock->ns;
-               }
-       }
-       
-       /* identify group node outputs from internal group sockets */
-       for(sock= node->outputs.first; sock; sock= sock->next) {
-               if (sock->groupsock) {
-                       bNodeSocket *insock, *gsock = sock->groupsock;
-                       switch (gsock->stack_type) {
-                       case SOCK_STACK_EXTERN:
-                               /* extern stack is resolved for this group node instance */
-                               insock= find_group_node_input(node, gsock->link->fromsock);
-                               sock->stack_type = insock->stack_type;
-                               sock->stack_index = insock->stack_index;
-                               sock->stack_ptr = insock->stack_ptr;
-                               break;
-                       case SOCK_STACK_LOCAL:
-                               sock->stack_type = SOCK_STACK_LOCAL;
-                               /* local stack index must be offset by group node instance */
-                               sock->stack_index = gsock->stack_index + node->stack_index;
-                               sock->stack_ptr = NULL;
-                               break;
-                       case SOCK_STACK_CONST:
-                               sock->stack_type = SOCK_STACK_CONST;
-                               sock->stack_index = -1;
-                               sock->stack_ptr = gsock->stack_ptr;
-                               break;
-                       }
-               }
-               else {
-                       sock->stack_type = SOCK_STACK_LOCAL;
-                       sock->stack_index = index++;
-                       sock->stack_ptr = NULL;
-               }
-       }
-       
-       return index;
-}
-
-/* recursively called for groups */
-/* we set all trees on own local indices, but put a total counter
-   in the groups, so each instance of a group has own stack */
-static int ntree_begin_exec_tree(bNodeTree *ntree)
-{
-       bNode *node;
-       bNodeSocket *gsock;
-       int index= 0, i;
-       
-       if((ntree->init & NTREE_TYPE_INIT)==0)
-               ntreeInitTypes(ntree);
-       
-       /* group inputs are numbered 0..totinputs, so external stack can easily be addressed */
-       i = 0;
-       for(gsock=ntree->inputs.first; gsock; gsock = gsock->next) {
-               gsock->stack_type = SOCK_STACK_EXTERN;
-               gsock->stack_index = i++;
-               gsock->stack_ptr = NULL;
-       }
-       
-       /* create indices for stack, check preview */
-       for(node= ntree->nodes.first; node; node= node->next) {
-               /* XXX can this be done by a generic one-for-all function?
-                * otherwise should use node-type callback.
-                */
-               if(node->type==NODE_GROUP)
-                       index = set_stack_indexes_group(node, index);
-               else
-                       index = set_stack_indexes_default(node, index);
-       }
-       
-       /* group outputs */
-       for(gsock=ntree->outputs.first; gsock; gsock = gsock->next) {
-               if (gsock->link && gsock->link->fromsock) {
-                       gsock->stack_type = gsock->link->fromsock->stack_type;
-                       gsock->stack_index = gsock->link->fromsock->stack_index;
-                       gsock->stack_ptr = gsock->link->fromsock->stack_ptr;
-               }
-               else {
-                       gsock->stack_type = SOCK_STACK_CONST;
-                       gsock->stack_index = -1;
-                       gsock->stack_ptr = &gsock->ns;
-               }
-       }
-       
-       return index;
-}
-
-/* copy socket compbufs to stack, initialize usage of curve nodes */
-static void composit_begin_exec(bNodeTree *ntree, bNodeStack *stack)
-{
-       bNode *node;
-       bNodeSocket *sock;
-       
-       for(node= ntree->nodes.first; node; node= node->next) {
-               
-               /* initialize needed for groups */
-               node->exec= 0;  
-               
-               for(sock= node->outputs.first; sock; sock= sock->next) {
-                       bNodeStack *ns= get_socket_stack(stack, sock, NULL);
-                       if(ns && sock->ns.data) {
-                               ns->data= sock->ns.data;
-                               sock->ns.data= NULL;
-                       }
-               }
-               
-               /* cannot initialize them while using in threads */
-               if(ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) {
-                       curvemapping_initialize(node->storage);
-                       if(node->type==CMP_NODE_CURVE_RGB)
-                               curvemapping_premultiply(node->storage, 0);
-               }
-               if(node->type==NODE_GROUP && node->id)
-                       composit_begin_exec((bNodeTree *)node->id, stack + node->stack_index);
-
-       }
-}
-
-/* copy stack compbufs to sockets */
-static void composit_end_exec(bNodeTree *ntree, bNodeStack *stack)
-{
-       bNode *node;
-       bNodeStack *ns;
-
-       for(node= ntree->nodes.first; node; node= node->next) {
-               bNodeSocket *sock;
-               
-               for(sock= node->outputs.first; sock; sock= sock->next) {
-                       ns = get_socket_stack(stack, sock, NULL);
-                       if(ns && ns->data) {
-                               sock->ns.data= ns->data;
-                               ns->data= NULL;
-                       }
-               }
-               
-               if(node->type==CMP_NODE_CURVE_RGB)
-                       curvemapping_premultiply(node->storage, 1);
-               
-               if(node->type==NODE_GROUP && node->id)
-                       composit_end_exec((bNodeTree *)node->id, stack + node->stack_index);
-
-               node->need_exec= 0;
-       }
-}
-
-static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack, bNodeStack **gin)
-{
-       bNodeTree *ntree= (bNodeTree *)gnode->id;
-       bNode *node;
-       bNodeSocket *sock;
-       
-       stack+= gnode->stack_index;
-       
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->typeinfo->execfunc) {
-                       for(sock= node->inputs.first; sock; sock= sock->next) {
-                               bNodeStack *ns = get_socket_stack(stack, sock, gin);
-                               ns->hasoutput= 1;
-                       }
-               }
-               
-               /* non-composite trees do all nodes by default */
-               if (ntree->type!=NTREE_COMPOSIT)
-                       node->need_exec = 1;
-               
-               for(sock= node->inputs.first; sock; sock= sock->next) {
-                       bNodeStack *ns = get_socket_stack(stack, sock, gin);
-                       if (ns) {
-                               ns->hasoutput = 1;
-                               
-                               /* sock type is needed to detect rgba or value or vector types */
-                               if(sock->link && sock->link->fromsock)
-                                       ns->sockettype= sock->link->fromsock->type;
-                               else
-                                       sock->ns.sockettype= sock->type;
-                       }
-                       
-                       if(sock->link) {
-                               bNodeLink *link= sock->link;
-                               /* this is the test for a cyclic case */
-                               if(link->fromnode && link->tonode) {
-                                       if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF);
-                                       else {
-                                               node->need_exec= 0;
-                                       }
-                               }
-                       }
-               }
-               
-               /* set stack types (for local stack entries) */
-               for(sock= node->outputs.first; sock; sock= sock->next) {
-                       bNodeStack *ns = get_socket_stack(stack, sock, gin);
-                       if (ns)
-                               ns->sockettype = sock->type;
-               }
-       }
-}
-
-/* notes below are ancient! (ton) */
-/* stack indices make sure all nodes only write in allocated data, for making it thread safe */
-/* only root tree gets the stack, to enable instances to have own stack entries */
-/* per tree (and per group) unique indices are created */
-/* the index_ext we need to be able to map from groups to the group-node own stack */
-
-typedef struct bNodeThreadStack {
-       struct bNodeThreadStack *next, *prev;
-       bNodeStack *stack;
-       int used;
-} bNodeThreadStack;
-
-static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread)
-{
-       ListBase *lb= &ntree->threadstack[thread];
-       bNodeThreadStack *nts;
-       
-       for(nts=lb->first; nts; nts=nts->next) {
-               if(!nts->used) {
-                       nts->used= 1;
-                       return nts;
-               }
-       }
-       nts= MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
-       nts->stack= MEM_dupallocN(ntree->stack);
-       nts->used= 1;
-       BLI_addtail(lb, nts);
-
-       return nts;
-}
-
-static void ntreeReleaseThreadStack(bNodeThreadStack *nts)
-{
-       nts->used= 0;
-}
-
-/* free texture delegates */
-static void tex_end_exec(bNodeTree *ntree)
-{
-       bNodeThreadStack *nts;
-       bNodeStack *ns;
-       int th, a;
-       
-       if(ntree->threadstack) {
-               for(th=0; th<BLENDER_MAX_THREADS; th++) {
-                       for(nts=ntree->threadstack[th].first; nts; nts=nts->next) {
-                               for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++) {
-                                       if(ns->data) {
-                                               MEM_freeN(ns->data);
-                                               ns->data= NULL;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-void ntreeBeginExecTree(bNodeTree *ntree)
-{
-       bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
-       
-       /* let's make it sure */
-       if(ntree->init & NTREE_EXEC_INIT)
-               return;
-       
-       /* allocate the thread stack listbase array */
-       if(ntree->type!=NTREE_COMPOSIT)
-               ntree->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array");
-
-       /* goes recursive over all groups */
-       ntree->stacksize= ntree_begin_exec_tree(ntree);
-
-       if(ntree->stacksize) {
-               bNode *node;
-               bNodeStack *ns;
-               int a;
-               
-               /* allocate the base stack */
-               ns=ntree->stack= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack");
-               
-               /* tag inputs, the get_stack() gives own socket stackdata if not in use */
-               for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
-               
-               /* tag used outputs, so we know when we can skip operations */
-               for(node= ntree->nodes.first; node; node= node->next) {
-                       bNodeSocket *sock;
-                       
-                       /* non-composite trees do all nodes by default */
-                       if(ntree->type!=NTREE_COMPOSIT)
-                               node->need_exec= 1;
-
-                       for(sock= node->inputs.first; sock; sock= sock->next) {
-                               ns = get_socket_stack(ntree->stack, sock, NULL);
-                               if (ns) {
-                                       ns->hasoutput = 1;
-                                       
-                                       /* sock type is needed to detect rgba or value or vector types */
-                                       if(sock->link && sock->link->fromsock)
-                                               ns->sockettype= sock->link->fromsock->type;
-                                       else
-                                               sock->ns.sockettype= sock->type;
-                               }
-                               
-                               if(sock->link) {
-                                       bNodeLink *link= sock->link;
-                                       /* this is the test for a cyclic case */
-                                       if(link->fromnode && link->tonode) {
-                                               if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF);
-                                               else {
-                                                       node->need_exec= 0;
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       /* set stack types (for local stack entries) */
-                       for(sock= node->outputs.first; sock; sock= sock->next) {
-                               ns = get_socket_stack(ntree->stack, sock, NULL);
-                               if (ns)
-                                       ns->sockettype = sock->type;
-                       }
-                       
-                       if(node->type==NODE_GROUP && node->id) {
-                               node_get_stack(node, ntree->stack, nsin, NULL, NULL);
-                               group_tag_used_outputs(node, ntree->stack, nsin);
-                       }
-               }
-               
-               if(ntree->type==NTREE_COMPOSIT)
-                       composit_begin_exec(ntree, ntree->stack);
-               
-               /* ensures only a single output node is enabled, texnode allows multiple though */
-               if(ntree->type!=NTREE_TEXTURE)
-                       ntreeSetOutput(ntree);
-               
-       }
-       
-       ntree->init |= NTREE_EXEC_INIT;
-}
-
-void ntreeEndExecTree(bNodeTree *ntree)
-{
-       bNodeStack *ns;
-       
-       if(ntree->init & NTREE_EXEC_INIT) {
-               bNodeThreadStack *nts;
-               int a;
-               
-               /* another callback candidate! */
-               if(ntree->type==NTREE_COMPOSIT) {
-                       composit_end_exec(ntree, ntree->stack);
-                       
-                       for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) {
-                               if(ns->data) {
-                                       printf("freed leftover buffer from stack\n");
-                                       free_compbuf(ns->data);
-                                       ns->data= NULL;
-                               }
-                       }
-               }
-               else if(ntree->type==NTREE_TEXTURE)
-                       tex_end_exec(ntree);
-               
-               if(ntree->stack) {
-                       MEM_freeN(ntree->stack);
-                       ntree->stack= NULL;
-               }
-
-               if(ntree->threadstack) {
-                       for(a=0; a<BLENDER_MAX_THREADS; a++) {
-                               for(nts=ntree->threadstack[a].first; nts; nts=nts->next)
-                                       if (nts->stack) MEM_freeN(nts->stack);
-                               BLI_freelistN(&ntree->threadstack[a]);
-                       }
-
-                       MEM_freeN(ntree->threadstack);
-                       ntree->threadstack= NULL;
-               }
-
-               ntree->init &= ~NTREE_EXEC_INIT;
-       }
-}
-
-/* nodes are presorted, so exec is in order of list */
-void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
-{
-       bNode *node;
-       bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
-       bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
-       bNodeStack *stack;
-       bNodeThreadStack *nts = NULL;
-       
-       /* only when initialized */
-       if((ntree->init & NTREE_EXEC_INIT)==0)
-               ntreeBeginExecTree(ntree);
-       
-       /* composite does 1 node per thread, so no multiple stacks needed */
-       if(ntree->type==NTREE_COMPOSIT) {
-               stack= ntree->stack;
-       }
-       else {
-               nts= ntreeGetThreadStack(ntree, thread);
-               stack= nts->stack;
-       }
-       
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->need_exec) {
-                       if(node->typeinfo->execfunc) {
-                               node_get_stack(node, stack, nsin, nsout, NULL);
-                               node->typeinfo->execfunc(callerdata, node, nsin, nsout);
-                       }
-                       else if(node->type==NODE_GROUP && node->id) {
-                               node_get_stack(node, stack, nsin, NULL, NULL);
-                               node_group_execute(stack, callerdata, node, nsin);
-                       }
-               }
-       }
-
-       if(nts)
-               ntreeReleaseThreadStack(nts);
-}
-
-
-/* ***************************** threaded version for execute composite nodes ************* */
-/* these are nodes without input, only giving values */
-/* or nodes with only value inputs */
-static int node_only_value(bNode *node)
-{
-       bNodeSocket *sock;
-       
-       if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
-               return 1;
-       
-       /* doing this for all node types goes wrong. memory free errors */
-       if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
-               int retval= 1;
-               for(sock= node->inputs.first; sock; sock= sock->next) {
-                       if(sock->link && sock->link->fromnode)
-                               retval &= node_only_value(sock->link->fromnode);
-               }
-               return retval;
-       }
-       return 0;
-}
-
-
-/* not changing info, for thread callback */
-typedef struct ThreadData {
-       bNodeStack *stack;
-       RenderData *rd;
-} ThreadData;
-
-static void *exec_composite_node(void *node_v)
-{
-       bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
-       bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
-       bNode *node= node_v;
-       ThreadData *thd= (ThreadData *)node->threaddata;
-       
-       node_get_stack(node, thd->stack, nsin, nsout, NULL);
-       
-       if((node->flag & NODE_MUTED) && (!node_only_value(node))) {
-               /* viewers we execute, for feedback to user */
-               if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) 
-                       node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
-               else
-                       node_compo_pass_on(node, nsin, nsout);
-       }
-       else if(node->typeinfo->execfunc) {
-               node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
-       }
-       else if(node->type==NODE_GROUP && node->id) {
-               node_group_execute(thd->stack, thd->rd, node, nsin); 
-       }
-       
-       node->exec |= NODE_READY;
-       return NULL;
-}
-
-/* return total of executable nodes, for timecursor */
-/* only compositor uses it */
-static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
-{
-       bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
-       bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
-       bNode *node;
-       bNodeSocket *sock;
-       int totnode= 0, group_edit= 0;
-       
-       /* note; do not add a dependency sort here, the stack was created already */
-       
-       /* if we are in group edit, viewer nodes get skipped when group has viewer */
-       for(node= ntree->nodes.first; node; node= node->next)
-               if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
-                       if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
-                               group_edit= 1;
-       
-       for(node= ntree->nodes.first; node; node= node->next) {
-               int a;
-               
-               node_get_stack(node, thd->stack, nsin, nsout, NULL);
-               
-               /* test the outputs */
-               /* skip value-only nodes (should be in type!) */
-               if(!node_only_value(node)) {
-                       for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
-                               if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
-                                       node->need_exec= 1;
-                                       break;
-                               }
-                       }
-               }
-               
-               /* test the inputs */
-               for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
-                       /* skip viewer nodes in bg render or group edit */
-                       if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit))
-                               node->need_exec= 0;
-                       /* is sock in use? */
-                       else if(sock->link) {
-                               bNodeLink *link= sock->link;
-                               
-                               /* this is the test for a cyclic case */
-                               if(link->fromnode==NULL || link->tonode==NULL);
-                               else if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
-                                       if(link->fromnode->need_exec) {
-                                               node->need_exec= 1;
-                                               break;
-                                       }
-                               }
-                               else {
-                                       node->need_exec= 0;
-                                       printf("Node %s skipped, cyclic dependency\n", node->name);
-                               }
-                       }
-               }
-               
-               if(node->need_exec) {
-                       
-                       /* free output buffers */
-                       for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
-                               if(nsout[a]->data) {
-                                       free_compbuf(nsout[a]->data);
-                                       nsout[a]->data= NULL;
-                               }
-                       }
-                       totnode++;
-                       /* printf("node needs exec %s\n", node->name); */
-                       
-                       /* tag for getExecutableNode() */
-                       node->exec= 0;
-               }
-               else {
-                       /* tag for getExecutableNode() */
-                       node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED;
-                       
-               }
-       }
-       
-       /* last step: set the stack values for only-value nodes */
-       /* just does all now, compared to a full buffer exec this is nothing */
-       if(totnode) {
-               for(node= ntree->nodes.first; node; node= node->next) {
-                       if(node->need_exec==0 && node_only_value(node)) {
-                               if(node->typeinfo->execfunc) {
-                                       node_get_stack(node, thd->stack, nsin, nsout, NULL);
-                                       node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
-                               }
-                       }
-               }
-       }
-       
-       return totnode;
-}
-
-/* while executing tree, free buffers from nodes that are not needed anymore */
-static void freeExecutableNode(bNodeTree *ntree)
-{
-       /* node outputs can be freed when:
-       - not a render result or image node
-       - when node outputs go to nodes all being set NODE_FINISHED
-       */
-       bNode *node;
-       bNodeSocket *sock;
-       
-       /* set exec flag for finished nodes that might need freed */
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->type!=CMP_NODE_R_LAYERS)
-                       if(node->exec & NODE_FINISHED)
-                               node->exec |= NODE_FREEBUFS;
-       }
-       /* clear this flag for input links that are not done yet */
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if((node->exec & NODE_FINISHED)==0) {
-                       for(sock= node->inputs.first; sock; sock= sock->next)
-                               if(sock->link && sock->link->fromnode)
-                                       sock->link->fromnode->exec &= ~NODE_FREEBUFS;
-               }
-       }
-       /* now we can free buffers */
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->exec & NODE_FREEBUFS) {
-                       for(sock= node->outputs.first; sock; sock= sock->next) {
-                               bNodeStack *ns= get_socket_stack(ntree->stack, sock, NULL);
-                               if(ns && ns->data) {
-                                       free_compbuf(ns->data);
-                                       ns->data= NULL;
-                                       // printf("freed buf node %s \n", node->name);
-                               }
-                       }
-               }
-       }
-}
-
-static bNode *getExecutableNode(bNodeTree *ntree)
-{
-       bNode *node;
-       bNodeSocket *sock;
-       
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->exec==0) {
-                       
-                       /* input sockets should be ready */
-                       for(sock= node->inputs.first; sock; sock= sock->next) {
-                               if(sock->link && sock->link->fromnode)
-                                       if((sock->link->fromnode->exec & NODE_READY)==0)
-                                               break;
-                       }
-                       if(sock==NULL)
-                               return node;
-               }
-       }
-       return NULL;
-}
-
-/* check if texture nodes need exec or end */
-static  void ntree_composite_texnode(bNodeTree *ntree, int init)
-{
-       bNode *node;
-       
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->type==CMP_NODE_TEXTURE && node->id) {
-                       Tex *tex= (Tex *)node->id;
-                       if(tex->nodetree && tex->use_nodes) {
-                               /* has internal flag to detect it only does it once */
-                               if(init)
-                                       ntreeBeginExecTree(tex->nodetree); 
-                               else
-                                       ntreeEndExecTree(tex->nodetree);
-                       }
-               }
-       }
-
-}
-
-/* optimized tree execute test for compositing */
-void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
-{
-       bNode *node;
-       ListBase threads;
-       ThreadData thdata;
-       int totnode, curnode, rendering= 1;
-       
-       if(ntree==NULL) return;
-       
-       if(do_preview)
-               ntreeInitPreview(ntree, 0, 0);
-       
-       ntreeBeginExecTree(ntree);
-       ntree_composite_texnode(ntree, 1);
-       
-       /* prevent unlucky accidents */
-       if(G.background)
-               rd->scemode &= ~R_COMP_CROP;
-       
-       /* setup callerdata for thread callback */
-       thdata.rd= rd;
-       thdata.stack= ntree->stack;
-       
-       /* fixed seed, for example noise texture */
-       BLI_srandom(rd->cfra);
-
-       /* sets need_exec tags in nodes */
-       curnode = totnode= setExecutableNodes(ntree, &thdata);
-
-       BLI_init_threads(&threads, exec_composite_node, rd->threads);
-       
-       while(rendering) {
-               
-               if(BLI_available_threads(&threads)) {
-                       node= getExecutableNode(ntree);
-                       if(node) {
-                               if(ntree->progress && totnode)
-                                       ntree->progress(ntree->prh, (1.0f - curnode/(float)totnode));
-                               if(ntree->stats_draw) {
-                                       char str[64];
-                                       sprintf(str, "Compositing %d %s", curnode, node->name);
-                                       ntree->stats_draw(ntree->sdh, str);
-                               }
-                               curnode--;
-                               
-                               node->threaddata = &thdata;
-                               node->exec= NODE_PROCESSING;
-                               BLI_insert_thread(&threads, node);
-                       }
-                       else
-                               PIL_sleep_ms(50);
-               }
-               else
-                       PIL_sleep_ms(50);
-               
-               rendering= 0;
-               /* test for ESC */
-               if(ntree->test_break && ntree->test_break(ntree->tbh)) {
-                       for(node= ntree->nodes.first; node; node= node->next)
-                               node->exec |= NODE_READY;
-               }
-               
-               /* check for ready ones, and if we need to continue */
-               for(node= ntree->nodes.first; node; node= node->next) {
-                       if(node->exec & NODE_READY) {
-                               if((node->exec & NODE_FINISHED)==0) {
-                                       BLI_remove_thread(&threads, node); /* this waits for running thread to finish btw */
-                                       node->exec |= NODE_FINISHED;
-                                       
-                                       /* freeing unused buffers */
-                                       if(rd->scemode & R_COMP_FREE)
-                                               freeExecutableNode(ntree);
-                               }
-                       }
-                       else rendering= 1;
-               }
-       }
-       
-       BLI_end_threads(&threads);
-       
-       ntreeEndExecTree(ntree);
-}
-
-
-/* ********** copy composite tree entirely, to allow threaded exec ******************* */
-/* ***************** do NOT execute this in a thread!               ****************** */
-
-/* returns localized tree for execution in threads */
-/* local tree then owns all compbufs (for composite) */
-bNodeTree *ntreeLocalize(bNodeTree *ntree)
-{
-       bNodeTree *ltree;
-       bNode *node;
-       bNodeSocket *sock;
-       
-       bAction *action_backup= NULL, *tmpact_backup= NULL;
-       
-       /* Workaround for copying an action on each render!
-        * set action to NULL so animdata actions dont get copied */
-       AnimData *adt= BKE_animdata_from_id(&ntree->id);
-
-       if(adt) {
-               action_backup= adt->action;
-               tmpact_backup= adt->tmpact;
-
-               adt->action= NULL;
-               adt->tmpact= NULL;
-       }
-
-       /* node copy func */
-       ltree= ntreeCopyTree(ntree);
-
-       if(adt) {
-               AnimData *ladt= BKE_animdata_from_id(&ltree->id);
-
-               adt->action= ladt->action= action_backup;
-               adt->tmpact= ladt->tmpact= tmpact_backup;
-
-               if(action_backup) action_backup->id.us++;
-               if(tmpact_backup) tmpact_backup->id.us++;
-               
-       }
-       /* end animdata uglyness */
-
-       /* ensures only a single output node is enabled */
-       ntreeSetOutput(ltree);
-
-       for(node= ntree->nodes.first; node; node= node->next) {
-               
-               /* store new_node pointer to original */
-               node->new_node->new_node= node;
-               
-               if(ntree->type==NTREE_COMPOSIT) {
-                       /* ensure new user input gets handled ok, only composites (texture nodes will break, for painting since it uses no tags) */
-                       node->need_exec= 0;
-                       
-                       /* move over the compbufs */
-                       /* right after ntreeCopyTree() oldsock pointers are valid */
-                       
-                       if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
-                               if(node->id) {
-                                       if(node->flag & NODE_DO_OUTPUT)
-                                               node->new_node->id= (ID *)copy_image((Image *)node->id);
-                                       else
-                                               node->new_node->id= NULL;
-                               }
-                       }
-                       
-                       for(sock= node->outputs.first; sock; sock= sock->next) {
-                               
-                               sock->new_sock->ns.data= sock->ns.data;
-                               compbuf_set_node(sock->new_sock->ns.data, node->new_node);
-                               
-                               sock->ns.data= NULL;
-                               sock->new_sock->new_sock= sock;
-                       }
-               }
-       }
-       
-       return ltree;
-}
-
-static int node_exists(bNodeTree *ntree, bNode *testnode)
-{
-       bNode *node= ntree->nodes.first;
-       for(; node; node= node->next)
-               if(node==testnode)
-                       return 1;
-       return 0;
-}
-
-static int outsocket_exists(bNode *node, bNodeSocket *testsock)
-{
-       bNodeSocket *sock= node->outputs.first;
-       for(; sock; sock= sock->next)
-               if(sock==testsock)
-                       return 1;
-       return 0;
-}
-
-
-/* sync local composite with real tree */
-/* local composite is supposed to be running, be careful moving previews! */
-/* is called by jobs manager, outside threads, so it doesnt happen during draw */
-void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
-{
-       bNode *lnode;
-       
-       if(ntree->type==NTREE_COMPOSIT) {
-               /* move over the compbufs and previews */
-               for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
-                       if( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) {
-                               if(node_exists(ntree, lnode->new_node)) {
-                                       
-                                       if(lnode->preview && lnode->preview->rect) {
-                                               node_free_preview(lnode->new_node);
-                                               lnode->new_node->preview= lnode->preview;
-                                               lnode->preview= NULL;
-                                       }
-                               }
-                       }
-               }
-       }
-       else if(ELEM(ntree->type, NTREE_SHADER, NTREE_TEXTURE)) {
-               /* copy over contents of previews */
-               for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
-                       if(node_exists(ntree, lnode->new_node)) {
-                               bNode *node= lnode->new_node;
-                               
-                               if(node->preview && node->preview->rect) {
-                                       if(lnode->preview && lnode->preview->rect) {
-                                               int xsize= node->preview->xsize;
-                                               int ysize= node->preview->ysize;
-                                               memcpy(node->preview->rect, lnode->preview->rect, 4*xsize + xsize*ysize*sizeof(char)*4);
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-/* merge local tree results back, and free local tree */
-/* we have to assume the editor already changed completely */
-void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
-{
-       bNode *lnode;
-       bNodeSocket *lsock;
-       
-       /* move over the compbufs and previews */
-       for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
-               if(node_exists(ntree, lnode->new_node)) {
-                       
-                       if(lnode->preview && lnode->preview->rect) {
-                               node_free_preview(lnode->new_node);
-                               lnode->new_node->preview= lnode->preview;
-                               lnode->preview= NULL;
-                       }
-                       
-                       if(ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
-                               if(lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
-                                       /* image_merge does sanity check for pointers */
-                                       BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id);
-                               }
-                       }
-                       
-                       for(lsock= lnode->outputs.first; lsock; lsock= lsock->next) {
-                               if(outsocket_exists(lnode->new_node, lsock->new_sock)) {
-                                       lsock->new_sock->ns.data= lsock->ns.data;
-                                       compbuf_set_node(lsock->new_sock->ns.data, lnode->new_node);
-                                       lsock->ns.data= NULL;
-                                       lsock->new_sock= NULL;
-                               }
-                       }
-               }
-       }
-       ntreeFreeTree(localtree);
-       MEM_freeN(localtree);
+       }
+       
+       node->flag |= NODE_ACTIVE;
+       if(node->id)
+               node->flag |= NODE_ACTIVE_ID;
 }
 
-/* *********************************************** */
-
-/* GPU material from shader nodes */
-
-static void gpu_from_node_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
+/* use flags are not persistant yet, groups might need different tagging, so we do it each time
+   when we need to get this info */
+void ntreeSocketUseFlags(bNodeTree *ntree)
 {
+       bNode *node;
        bNodeSocket *sock;
-       int i;
-
-       for (sock=sockets->first, i=0; sock; sock=sock->next, i++) {
-               memset(&gs[i], 0, sizeof(gs[i]));
-
-               QUATCOPY(gs[i].vec, ns[i]->vec);
-               gs[i].link= ns[i]->data;
-
-               if (sock->type == SOCK_VALUE)
-                       gs[i].type= GPU_FLOAT;
-               else if (sock->type == SOCK_VECTOR)
-                       gs[i].type= GPU_VEC3;
-               else if (sock->type == SOCK_RGBA)
-                       gs[i].type= GPU_VEC4;
-               else
-                       gs[i].type= GPU_NONE;
-
-               gs[i].name = "";
-               gs[i].hasinput= ns[i]->hasinput && ns[i]->data;
-               gs[i].hasoutput= ns[i]->hasoutput && ns[i]->data;
-               gs[i].sockettype= ns[i]->sockettype;
+       bNodeLink *link;
+       
+       /* clear flags */
+       for(node= ntree->nodes.first; node; node= node->next) {
+               for(sock= node->inputs.first; sock; sock= sock->next)
+                       sock->flag &= ~SOCK_IN_USE;
+               for(sock= node->outputs.first; sock; sock= sock->next)
+                       sock->flag &= ~SOCK_IN_USE;
+       }
+       
+       /* tag all thats in use */
+       for(link= ntree->links.first; link; link= link->next) {
+       
+               if(link->fromsock) // FIXME, see below
+                       link->fromsock->flag |= SOCK_IN_USE;
+               if(link->tosock) // FIXME This can be NULL, when dragging a new link in the UI, should probably copy the node tree for preview render - campbell
+                       link->tosock->flag |= SOCK_IN_USE;
        }
-
-       gs[i].type= GPU_NONE;
 }
 
-static void data_from_gpu_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
+/* ************** dependency stuff *********** */
+
+/* node is guaranteed to be not checked before */
+static int node_get_deplist_recurs(bNode *node, bNode ***nsort)
 {
+       bNode *fromnode;
        bNodeSocket *sock;
-       int i;
-
-       for (sock=sockets->first, i=0; sock; sock=sock->next, i++) {
-               ns[i]->data= gs[i].link;
-               ns[i]->sockettype= gs[i].sockettype;
+       int level = 0xFFF;
+       
+       node->done= 1;
+       
+       /* check linked nodes */
+       for(sock= node->inputs.first; sock; sock= sock->next) {
+               if(sock->link) {
+                       fromnode= sock->link->fromnode;
+                       if(fromnode) {
+                               if (fromnode->done==0)
+                                       fromnode->level= node_get_deplist_recurs(fromnode, nsort);
+                               if (fromnode->level <= level)
+                                       level = fromnode->level - 1;
+                       }
+               }
+       }
+       
+       /* check parent node */
+       if (node->parent) {
+               if (node->parent->done==0)
+                       node->parent->level= node_get_deplist_recurs(node->parent, nsort);
+               if (node->parent->level <= level)
+                       level = node->parent->level - 1;
+       }
+       
+       if (nsort) {
+               **nsort= node;
+               (*nsort)++;
        }
+       
+       return level;
 }
 
-static void gpu_node_group_execute(bNodeStack *stack, GPUMaterial *mat, bNode *gnode, bNodeStack **in)
+void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes)
 {
-       bNode *node;
-       bNodeTree *ntree= (bNodeTree *)gnode->id;
-       bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
-       bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
-       GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
-       int doit = 0;
+       bNode *node, **nsort;
        
-       if(ntree==NULL) return;
+       *totnodes=0;
        
-       stack+= gnode->stack_index;
-               
+       /* first clear data */
        for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->typeinfo->gpufunc) {
-                       node_get_stack(node, stack, nsin, nsout, in);
-
-                       doit = 0;
-                       
-                       /* for groups, only execute outputs for edited group */
-                       if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
-                               if(gnode->flag & NODE_GROUP_EDIT)
-                                       if(node->flag & NODE_DO_OUTPUT)
-                                               doit = 1;
-                       }
-                       else
-                               doit = 1;
-
-                       if(doit)  {
-                               gpu_from_node_stack(&node->inputs, nsin, gpuin);
-                               gpu_from_node_stack(&node->outputs, nsout, gpuout);
-                               if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
-                                       data_from_gpu_stack(&node->outputs, nsout, gpuout);
-                       }
+               node->done= 0;
+               (*totnodes)++;
+       }
+       if(*totnodes==0) {
+               *deplist = NULL;
+               return;
+       }
+       
+       nsort= *deplist= MEM_callocN((*totnodes)*sizeof(bNode*), "sorted node array");
+       
+       /* recursive check */
+       for(node= ntree->nodes.first; node; node= node->next) {
+               if(node->done==0) {
+                       node->level= node_get_deplist_recurs(node, &nsort);
                }
        }
 }
 
-void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat)
+static void ntree_update_link_pointers(bNodeTree *ntree)
 {
        bNode *node;
-       bNodeStack *stack;
-       bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
-       bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
-       GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
-
-       if((ntree->init & NTREE_EXEC_INIT)==0)
-               ntreeBeginExecTree(ntree);
-
-       stack= ntree->stack;
-
+       bNodeSocket *sock;
+       bNodeLink *link;
+       
+       /* first clear data */
        for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->typeinfo->gpufunc) {
-                       node_get_stack(node, stack, nsin, nsout, NULL);
-                       gpu_from_node_stack(&node->inputs, nsin, gpuin);
-                       gpu_from_node_stack(&node->outputs, nsout, gpuout);
-                       if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
-                               data_from_gpu_stack(&node->outputs, nsout, gpuout);
-               }
-               else if(node->type==NODE_GROUP && node->id) {
-                       node_get_stack(node, stack, nsin, nsout, NULL);
-                       gpu_node_group_execute(stack, mat, node, nsin);
-               }
+               for(sock= node->inputs.first; sock; sock= sock->next)
+                       sock->link= NULL;
        }
+       /* clear socket links */
+       for(sock= ntree->outputs.first; sock; sock= sock->next)
+               sock->link= NULL;
 
-       ntreeEndExecTree(ntree);
+       for(link= ntree->links.first; link; link= link->next) {
+               if (link->tosock)
+                       link->tosock->link= link;
+       }
 }
 
-/* **************** call to switch lamploop for material node ************ */
-
-void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *);
-
-void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult *))
+void ntree_validate_links(bNodeTree *ntree)
 {
-       node_shader_lamp_loop= lamp_loop_func;
+       bNodeTreeType *ntreetype = ntreeGetType(ntree->type);
+       bNodeLink *link;
+       
+       for (link = ntree->links.first; link; link = link->next) {
+               link->flag |= NODE_LINK_VALID;
+               if (link->fromnode && link->tonode && link->fromnode->level <= link->tonode->level)
+                       link->flag &= ~NODE_LINK_VALID;
+               else if (ntreetype->validate_link) {
+                       if (!ntreetype->validate_link(ntree, link))
+                               link->flag &= ~NODE_LINK_VALID;
+               }
+       }
 }
 
-/* clumsy checking... should do dynamic outputs once */
-static void force_hidden_passes(bNode *node, int passflag)
-{
-       bNodeSocket *sock;
-       
-       for(sock= node->outputs.first; sock; sock= sock->next)
-               sock->flag &= ~SOCK_UNAVAIL;
-       
-       sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
-       if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
-       if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
-       if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
-       if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
-       if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
-       if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
-       if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
-       if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
-       if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
-       if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
-       if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_INDIRECT);
-       if(!(passflag & SCE_PASS_INDIRECT)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
-       if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXMA);
-       if(!(passflag & SCE_PASS_INDEXMA)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_MIST);
-       if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_EMIT);
-       if(!(passflag & SCE_PASS_EMIT)) sock->flag |= SOCK_UNAVAIL;
-       sock= BLI_findlink(&node->outputs, RRES_OUT_ENV);
-       if(!(passflag & SCE_PASS_ENVIRONMENT)) sock->flag |= SOCK_UNAVAIL;
-       
-}
-
-/* based on rules, force sockets hidden always */
-void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene)
+static void ntree_verify_nodes_cb(void *calldata, struct ID *UNUSED(owner_id), struct bNodeTree *ntree)
 {
+       ID *id= (ID*)calldata;
        bNode *node;
        
-       if(ntree==NULL) return;
-       
-       for(node= ntree->nodes.first; node; node= node->next) {
-               if( node->type==CMP_NODE_R_LAYERS) {
-                       Scene *sce= node->id?(Scene *)node->id:curscene;
-                       SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
-                       if(srl)
-                               force_hidden_passes(node, srl->passflag);
-               }
-               else if( node->type==CMP_NODE_IMAGE) {
-                       Image *ima= (Image *)node->id;
-                       if(ima) {
-                               if(ima->rr) {
-                                       ImageUser *iuser= node->storage;
-                                       RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
-                                       if(rl)
-                                               force_hidden_passes(node, rl->passflag);
-                                       else
-                                               force_hidden_passes(node, 0);
-                               }
-                               else if(ima->type!=IMA_TYPE_MULTILAYER) {       /* if ->rr not yet read we keep inputs */
-                                       force_hidden_passes(node, RRES_OUT_Z);
-                               }
-                               else
-                                       force_hidden_passes(node, 0);
-                       }
-                       else
-                               force_hidden_passes(node, 0);
-               }
-       }
-
+       for (node=ntree->nodes.first; node; node=node->next)
+               if (node->typeinfo->verifyfunc)
+                       node->typeinfo->verifyfunc(ntree, node, id);
 }
 
-/* called from render pipeline, to tag render input and output */
-/* need to do all scenes, to prevent errors when you re-render 1 scene */
-void ntreeCompositTagRender(Scene *curscene)
+void ntreeVerifyNodes(struct Main *main, struct ID *id)
 {
-       Scene *sce;
+       bNodeTreeType *ntreetype;
+       bNodeTree *ntree;
+       int n;
        
-       for(sce= G.main->scene.first; sce; sce= sce->id.next) {
-               if(sce->nodetree) {
-                       bNode *node;
-                       
-                       for(node= sce->nodetree->nodes.first; node; node= node->next) {
-                               if(node->id==(ID *)curscene || node->type==CMP_NODE_COMPOSITE)
-                                       NodeTagChanged(sce->nodetree, node);
-                               else if(node->type==CMP_NODE_TEXTURE) /* uses scene sizex/sizey */
-                                       NodeTagChanged(sce->nodetree, node);
-                       }
-               }
+       for (n=0; n < NUM_NTREE_TYPES; ++n) {
+               ntreetype= ntreeGetType(n);
+               if (ntreetype && ntreetype->foreach_nodetree)
+                       ntreetype->foreach_nodetree(main, id, ntree_verify_nodes_cb);
        }
+       for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next)
+               ntree_verify_nodes_cb(id, NULL, ntree);
 }
 
-static int node_animation_properties(bNodeTree *ntree, bNode *node)
+void ntreeUpdateTree(bNodeTree *ntree)
 {
-       bNodeSocket *sock;
-       const ListBase *lb;
-       Link *link;
-       PointerRNA ptr;
-       PropertyRNA *prop;
-       
-       /* check to see if any of the node's properties have fcurves */
-       RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
-       lb = RNA_struct_type_properties(ptr.type);
-       
-       for (link=lb->first; link; link=link->next) {
-               int driven, len=1, index;
-               prop = (PropertyRNA *)link;
-               
-               if (RNA_property_array_check(prop))
-                       len = RNA_property_array_length(&ptr, prop);
-               
-               for (index=0; index<len; index++) {
-                       if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
-                               NodeTagChanged(ntree, node);
-                               return 1;
-                       }
-               }
-       }
+       bNodeTreeType *ntreetype= ntreeGetType(ntree->type);
+       bNode *node;
+       bNode **deplist;
+       int totnodes, n;
+       
+       ntree_update_link_pointers(ntree);
+       
+       /* also updates the node level! */
+       ntreeGetDependencyList(ntree, &deplist, &totnodes);
        
-       /* now check node sockets */
-       for (sock = node->inputs.first; sock; sock=sock->next) {
-               int driven, len=1, index;
+       if (deplist) {
+               /* update individual nodes */
+               for (n=0; n < totnodes; ++n) {
+                       node = deplist[n];
+                       if (ntreetype->update_node)
+                               ntreetype->update_node(ntree, node);
+                       else if (node->typeinfo->updatefunc)
+                               node->typeinfo->updatefunc(ntree, node);
+               }
                
-               RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
-               prop = RNA_struct_find_property(&ptr, "default_value");
+               MEM_freeN(deplist);
                
-               if (RNA_property_array_check(prop))
-                       len = RNA_property_array_length(&ptr, prop);
+               /* ensures only a single output node is enabled, texnode allows multiple though */
+               if(ntree->type!=NTREE_TEXTURE)
+                       ntreeSetOutput(ntree);
                
-               for (index=0; index<len; index++) {
-                       if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
-                               NodeTagChanged(ntree, node);
-                               return 1;
-                       }
-               }
        }
+       
+       /* general tree updates */
+       if (ntree->update & (NTREE_UPDATE_LINKS|NTREE_UPDATE_NODES)) {
+               ntree_validate_links(ntree);
+       }
+       
+       /* update tree */
+       if (ntreetype->update)
+               ntreetype->update(ntree);
+       else {
+               bNodeType *ntype= node_get_type(ntree, ntree->nodetype);
+               if (ntype && ntype->updatetreefunc)
+                       ntype->updatetreefunc(ntree);
+       }
+       
+       /* XXX hack, should be done by depsgraph!! */
+       ntreeVerifyNodes(G.main, &ntree->id);
+       
+       /* clear the update flag */
+       ntree->update = 0;
+}
 
-       return 0;
+void NodeTagChanged(bNodeTree *ntree, bNode *node)
+{
+       bNodeTreeType *ntreetype = ntreeGetType(ntree->type);
+       
+       /* extra null pointer checks here because this is called when unlinking
+          unknown nodes on file load, so typeinfo pointers may not be set */
+       if (ntreetype && ntreetype->update_node)
+               ntreetype->update_node(ntree, node);
+       else if (node->typeinfo && node->typeinfo->updatefunc)
+               node->typeinfo->updatefunc(ntree, node);
 }
 
-/* tags nodes that have animation capabilities */
-int ntreeCompositTagAnimated(bNodeTree *ntree)
+int NodeTagIDChanged(bNodeTree *ntree, ID *id)
 {
+       bNodeTreeType *ntreetype;
        bNode *node;
-       int tagged= 0;
+       int change = FALSE;
+
+       if(ELEM(NULL, id, ntree))
+               return change;
        
-       if(ntree==NULL) return 0;
+       ntreetype = ntreeGetType(ntree->type);
        
-       for(node= ntree->nodes.first; node; node= node->next) {
-               
-               tagged = node_animation_properties(ntree, node);
-               
-               /* otherwise always tag these node types */
-               if(node->type==CMP_NODE_IMAGE) {
-                       Image *ima= (Image *)node->id;
-                       if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
-                               NodeTagChanged(ntree, node);
-                               tagged= 1;
+       if (ntreetype->update_node) {
+               for(node= ntree->nodes.first; node; node= node->next) {
+                       if(node->id==id) {
+                               change = TRUE;
+                               ntreetype->update_node(ntree, node);
                        }
                }
-               else if(node->type==CMP_NODE_TIME) {
-                       NodeTagChanged(ntree, node);
-                       tagged= 1;
-               }
-               /* here was tag render layer, but this is called after a render, so re-composites fail */
-               else if(node->type==NODE_GROUP) {
-                       if( ntreeCompositTagAnimated((bNodeTree *)node->id