Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2011-09-20 16:01:16 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2011-09-20 16:01:16 +0400
commit7172316b945c62797e6beba953ff203766614531 (patch)
tree640ac56fadded9c7686399b5a1f1c64f1a135700
parent2015eefef70350382931881dd65ed2da09f8f2cd (diff)
parent78d4260144dbf01166fac8bc9303e6d5aa022f71 (diff)
Merging r40366 through r40392 from trunk into soc-2011-garlicsoc-2011-garlic
-rw-r--r--GNUmakefile17
-rw-r--r--build_files/cmake/cmake_static_check_splint.py4
-rw-r--r--build_files/scons/config/win64-vc-config.py5
-rw-r--r--doc/python_api/sphinx_doc_gen.py8
-rw-r--r--intern/smoke/CMakeLists.txt5
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py51
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py31
-rw-r--r--release/scripts/startup/bl_ui/space_info.py1
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py1
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py2
-rw-r--r--source/blender/blenkernel/BKE_armature.h2
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h3
-rw-r--r--source/blender/blenkernel/BKE_material.h18
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/BKE_paint.h1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c110
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c4
-rw-r--r--source/blender/blenkernel/intern/armature.c30
-rw-r--r--source/blender/blenkernel/intern/blender.c6
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c54
-rw-r--r--source/blender/blenkernel/intern/customdata.c2
-rw-r--r--source/blender/blenkernel/intern/image.c17
-rw-r--r--source/blender/blenkernel/intern/material.c508
-rw-r--r--source/blender/blenkernel/intern/mesh.c6
-rw-r--r--source/blender/blenkernel/intern/node.c10
-rw-r--r--source/blender/blenkernel/intern/paint.c4
-rw-r--r--source/blender/blenkernel/intern/sound.c2
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c22
-rw-r--r--source/blender/blenloader/intern/readfile.c27
-rw-r--r--source/blender/collada/GeometryExporter.cpp2
-rw-r--r--source/blender/collada/GeometryExporter.h2
-rw-r--r--source/blender/collada/MeshImporter.cpp2
-rw-r--r--source/blender/collada/MeshImporter.h2
-rw-r--r--source/blender/editors/armature/editarmature.c20
-rw-r--r--source/blender/editors/armature/meshlaplacian.c33
-rw-r--r--source/blender/editors/include/ED_mesh.h2
-rw-r--r--source/blender/editors/include/ED_view3d.h1
-rw-r--r--source/blender/editors/interface/interface_templates.c12
-rw-r--r--source/blender/editors/interface/view2d.c8
-rw-r--r--source/blender/editors/mesh/editmesh.c98
-rw-r--r--source/blender/editors/mesh/editmesh_mods.c6
-rw-r--r--source/blender/editors/mesh/mesh_data.c3
-rw-r--r--source/blender/editors/mesh/meshtools.c4
-rw-r--r--source/blender/editors/object/object_intern.h2
-rw-r--r--source/blender/editors/object/object_ops.c2
-rw-r--r--source/blender/editors/object/object_vgroup.c564
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h5
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c15
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c45
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c865
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_action/action_select.c4
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_logic/logic_ops.c37
-rw-r--r--source/blender/editors/space_nla/nla_select.c8
-rw-r--r--source/blender/editors/space_node/drawnode.c6
-rw-r--r--source/blender/editors/space_node/node_edit.c7
-rw-r--r--source/blender/editors/space_node/node_select.c4
-rw-r--r--source/blender/editors/space_node/node_state.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c10
-rw-r--r--source/blender/editors/space_text/text_draw.c4
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c133
-rw-r--r--source/blender/editors/space_view3d/drawobject.c110
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c5
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c194
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c2
-rw-r--r--source/blender/editors/transform/transform.c6
-rw-r--r--source/blender/editors/transform/transform_conversions.c18
-rw-r--r--source/blender/editors/transform/transform_manipulator.c4
-rw-r--r--source/blender/editors/transform/transform_ops.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c6
-rw-r--r--source/blender/gpu/GPU_draw.h6
-rw-r--r--source/blender/gpu/GPU_material.h5
-rw-r--r--source/blender/gpu/intern/gpu_draw.c80
-rw-r--r--source/blender/gpu/intern/gpu_material.c2
-rw-r--r--source/blender/makesdna/DNA_material_types.h40
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h2
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h2
-rw-r--r--source/blender/makesdna/DNA_object_types.h5
-rw-r--r--source/blender/makesdna/DNA_scene_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_curve.c3
-rw-r--r--source/blender/makesrna/intern/rna_material.c63
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c32
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c2
-rw-r--r--source/blender/makesrna/intern/rna_object.c5
-rw-r--r--source/blender/makesrna/intern/rna_scene.c32
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c1
-rw-r--r--source/blender/nodes/composite/node_composite_util.h4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorSpill.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_diffMatte.c4
-rw-r--r--source/blender/nodes/intern/node_common.c8
-rw-r--r--source/blender/render/intern/source/convertblender.c11
-rw-r--r--source/blender/render/intern/source/pixelshading.c4
-rw-r--r--source/blender/render/intern/source/pointdensity.c6
-rw-r--r--source/blender/render/intern/source/render_texture.c4
-rw-r--r--source/blender/render/intern/source/rendercore.c8
-rw-r--r--source/blender/render/intern/source/shadeoutput.c4
-rw-r--r--source/blender/render/intern/source/zbuf.c3
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c4
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp183
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.cpp8
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.h4
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp3
-rw-r--r--source/gameengine/Ketsji/BL_Material.h9
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp87
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h3
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp26
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.h4
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp49
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h25
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h14
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp36
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h4
120 files changed, 3297 insertions, 755 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 7da60ce951b..d587668cf0c 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -36,7 +36,7 @@ OS_NCASE:=$(shell uname -s | tr '[A-Z]' '[a-z]')
BLENDER_DIR:=$(shell pwd -P)
BUILD_DIR:=$(shell dirname $(BLENDER_DIR))/build/$(OS_NCASE)
BUILD_TYPE:=Release
-BUILD_CMAKE_ARGS:=""
+BUILD_CMAKE_ARGS:=
# -----------------------------------------------------------------------------
@@ -77,6 +77,16 @@ ifeq ($(OS), NetBSD)
NPROCS:=$(shell sysctl -a | grep "hw.ncpu " | cut -d" " -f3 )
endif
+
+# -----------------------------------------------------------------------------
+# Macro for configuring cmake
+
+CMAKE_CONFIG = cmake $(BUILD_CMAKE_ARGS) \
+ -H$(BLENDER_DIR) \
+ -B$(BUILD_DIR) \
+ -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE)
+
+
# -----------------------------------------------------------------------------
# Build Blender
all:
@@ -84,7 +94,7 @@ all:
@echo Configuring Blender ...
if test ! -f $(BUILD_DIR)/CMakeCache.txt ; then \
- cmake $(BUILD_CMAKE_ARGS) -H$(BLENDER_DIR) -B$(BUILD_DIR) -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE); \
+ $(CMAKE_CONFIG); \
fi
@echo
@@ -186,12 +196,15 @@ project_eclipse:
#
check_cppcheck:
+ $(CMAKE_CONFIG)
cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py
check_splint:
+ $(CMAKE_CONFIG)
cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py
check_sparse:
+ $(CMAKE_CONFIG)
cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py
diff --git a/build_files/cmake/cmake_static_check_splint.py b/build_files/cmake/cmake_static_check_splint.py
index 7827d3a5120..3614ab48cf8 100644
--- a/build_files/cmake/cmake_static_check_splint.py
+++ b/build_files/cmake/cmake_static_check_splint.py
@@ -58,6 +58,10 @@ CHECKER_ARGS = [
# re-definitions, rna causes most of these
"-redef",
"-syntax",
+
+ # dummy, witjout this splint complains with:
+ # /usr/include/bits/confname.h:31:27: *** Internal Bug at cscannerHelp.c:2428: Unexpanded macro not function or constant: int _PC_MAX_CANON
+ "-D_PC_MAX_CANON=0",
]
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index 3e22e9a634f..11e3155e5f4 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -188,11 +188,6 @@ CXX_WARN = []
LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid']
-if BF_DEBUG:
- BF_NUMJOBS=1
-else:
- BF_NUMJOBS=6
-
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/STACK:2097152','/OPT:NOREF','/INCREMENTAL:NO', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib']
BF_BUILDDIR = '..\\build\\blender25-win64-vc'
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 91248c08406..1792cb00210 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -1036,8 +1036,12 @@ def rna2sphinx(BASEPATH):
fw("copyright = u'Blender Foundation'\n")
fw("version = '%s - API'\n" % version_string)
fw("release = '%s - API'\n" % version_string)
- fw("html_theme = 'blender-org'\n")
- fw("html_theme_path = ['../']\n")
+
+ # until we get a theme for 'Naiad'
+ if 0:
+ fw("html_theme = 'blender-org'\n")
+ fw("html_theme_path = ['../']\n")
+
fw("html_favicon = 'favicon.ico'\n")
# not helpful since the source us generated, adds to upload size.
fw("html_copy_source = False\n")
diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt
index 228ff6ec389..6e1d3eb0ab4 100644
--- a/intern/smoke/CMakeLists.txt
+++ b/intern/smoke/CMakeLists.txt
@@ -83,8 +83,13 @@ set(SRC
intern/tnt/tnt_version.h
)
+# quiet -Wundef
+add_definitions(-DDDF_DEBUG=0)
+
if(WITH_OPENMP)
add_definitions(-DPARALLEL=1)
+else()
+ add_definitions(-DPARALLEL=0)
endif()
if(WITH_FFTW3)
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index b74c89bb67e..37c91370979 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -35,6 +35,10 @@ class MESH_MT_vertex_group_specials(Menu):
layout.operator("object.vertex_group_copy_to_selected", icon='LINK_AREA')
layout.operator("object.vertex_group_mirror", icon='ARROW_LEFTRIGHT')
layout.operator("object.vertex_group_remove", icon='X', text=_("Delete All")).all = True
+ layout.separator()
+ layout.operator("object.vertex_group_lock", icon='LOCK', text="Lock All").action = 'SELECT'
+ layout.operator("object.vertex_group_lock", icon='UNLOCK', text="UnLock All").action = 'DESELECT'
+ layout.operator("object.vertex_group_lock", icon='LOCK', text="Lock Invert All").action = 'INVERT'
class MESH_MT_shape_key_specials(Menu):
@@ -285,53 +289,6 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
layout.prop(lay, "name")
-class DATA_PT_texface(MeshButtonsPanel, Panel):
- bl_label = "Texture Face"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
-
- @classmethod
- def poll(cls, context):
- obj = context.object
- return (context.mode == 'EDIT_MESH') and obj and obj.type == 'MESH'
-
- def draw(self, context):
- layout = self.layout
- col = layout.column()
-
- me = context.mesh
-
- tf = me.faces.active_tface
-
- if tf:
- if context.scene.render.engine != 'BLENDER_GAME':
- col.label(text=_("Options only supported in Game Engine"))
-
- split = layout.split()
- col = split.column()
-
- col.prop(tf, "use_image")
- col.prop(tf, "use_light")
- col.prop(tf, "hide")
- col.prop(tf, "use_collision")
-
- col.prop(tf, "use_blend_shared")
- col.prop(tf, "use_twoside")
- col.prop(tf, "use_object_color")
-
- col = split.column()
-
- col.prop(tf, "use_halo")
- col.prop(tf, "use_billboard")
- col.prop(tf, "use_shadow_cast")
- col.prop(tf, "use_bitmap_text")
- col.prop(tf, "use_alpha_sort")
-
- col = layout.column()
- col.prop(tf, "blend_type")
- else:
- col.label(text=_("No UV Texture"))
-
-
class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
bl_label = "Vertex Colors"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index dda6610933d..7b04c990c6a 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -612,9 +612,37 @@ class MATERIAL_PT_flare(MaterialButtonsPanel, Panel):
col.prop(halo, "flare_subflare_size", text=_("Subsize"))
-class MATERIAL_PT_physics(MaterialButtonsPanel, Panel):
+class MATERIAL_PT_game_settings(MaterialButtonsPanel, bpy.types.Panel):
+ bl_label = "Game Settings"
+ COMPAT_ENGINES = {'BLENDER_GAME'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.material and (context.scene.render.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+ game = context.material.game_settings # dont use node material
+
+ row = layout.row()
+ row.prop(game, "back_culling")
+ row.prop(game, "invisible")
+ row.prop(game, "text")
+
+ row = layout.row()
+ row.label(text="Alpha Blend:")
+ row.label(text="Face Orientation:")
+ row = layout.row()
+ row.prop(game,"alpha_blend",text="")
+ row.prop(game,"face_orientation",text="")
+
+class MATERIAL_PT_physics(MaterialButtonsPanel, bpy.types.Panel):
bl_label = "Physics"
COMPAT_ENGINES = {'BLENDER_GAME'}
+
+ def draw_header(self, context):
+ game = context.material.game_settings
+ self.layout.prop(game, "physics", text="")
@classmethod
def poll(cls, context):
@@ -622,6 +650,7 @@ class MATERIAL_PT_physics(MaterialButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.active = context.material.game_settings.physics
phys = context.material.physics # dont use node material
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 99ee24406ac..3e6abaa8ea3 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -381,6 +381,7 @@ class INFO_MT_help(Menu):
layout.operator("wm.console_toggle", icon='CONSOLE')
layout.separator()
layout.operator("anim.update_data_paths", text=_("FCurve/Driver Version fix"), icon='HELP')
+ layout.operator("logic.texface_convert", text="TexFace to Material Convert", icon='GAME')
layout.separator()
layout.operator("wm.splash", icon='BLENDER')
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 69dd18d7a60..2e86e875bab 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1073,6 +1073,7 @@ class VIEW3D_MT_paint_weight(Menu):
layout.operator("object.vertex_group_invert", text=_("Invert"))
layout.operator("object.vertex_group_clean", text=_("Clean"))
layout.operator("object.vertex_group_levels", text=_("Levels"))
+ layout.operator("object.vertex_group_fix", text="Fix Deforms")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 7ac2df7b5d5..6bd2168dab9 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -647,6 +647,7 @@ class VIEW3D_PT_tools_brush(PaintPanel, Panel):
elif context.weight_paint_object and brush:
layout.prop(context.tool_settings, "vertex_group_weight", text="Weight", slider=True)
layout.prop(context.tool_settings, "use_auto_normalize", text="Auto Normalize")
+ layout.prop(context.tool_settings, "use_multipaint", text="Multi-Paint")
col = layout.column()
@@ -1059,6 +1060,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
col.operator("object.vertex_group_invert", text="Invert")
col.operator("object.vertex_group_clean", text="Clean")
col.operator("object.vertex_group_levels", text="Levels")
+ col.operator("object.vertex_group_fix", text="Fix Deforms")
class VIEW3D_PT_tools_weightpaint_options(View3DPanel, Panel):
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 7d60c00156d..8836999bc9b 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -100,6 +100,8 @@ void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[]
void vec_roll_to_mat3(float *vec, float roll, float mat[][3]);
void mat3_to_vec_roll(float mat[][3], float *vec, float *roll);
+int get_selected_defgroups(struct Object *ob, char *defbase_sel, int defbase_len);
+
/* Common Conversions Between Co-ordinate Spaces */
void armature_mat_world_to_pose(struct Object *ob, float inmat[][4], float outmat[][4]);
void armature_loc_world_to_pose(struct Object *ob, float *inloc, float *outloc);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 742240d53b5..333c00c3f2a 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -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 2
+#define BLENDER_SUBVERSION 3
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 0c31083a266..8181ad6421c 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -168,6 +168,9 @@ struct Image *copy_image(struct Image *ima);
/* merge source into dest, and free source */
void BKE_image_merge(struct Image *dest, struct Image *source);
+/* check if texture has alpha (depth=32) */
+int BKE_image_has_alpha(struct Image *image);
+
/* image_gen.c */
void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, float color[4]);
void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int height, int width);
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 85b6f8f78fb..cb6a0b9ab37 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -42,6 +42,8 @@ struct Main;
struct Material;
struct ID;
struct Object;
+struct Mesh;
+struct MTFace;
/* materials */
@@ -50,6 +52,7 @@ void free_material(struct Material *sc);
void test_object_materials(struct ID *id);
void resize_object_material(struct Object *ob, const short totcol);
void init_material(struct Material *ma);
+struct Material *add_material_main(struct Main *main, const char *name);
struct Material *add_material(const char *name);
struct Material *copy_material(struct Material *ma);
struct Material *localize_material(struct Material *ma);
@@ -66,19 +69,19 @@ short *give_totcolp(struct Object *ob);
struct Material ***give_matarar_id(struct ID *id); /* same but for ID's */
short *give_totcolp_id(struct ID *id);
-struct Material *give_current_material(struct Object *ob, int act);
-struct ID *material_from(struct Object *ob, int act);
-void assign_material(struct Object *ob, struct Material *ma, int act);
-void assign_matarar(struct Object *ob, struct Material ***matar, int totcol);
+struct Material *give_current_material(struct Object *ob, short act);
+struct ID *material_from(struct Object *ob, short act);
+void assign_material(struct Object *ob, struct Material *ma, short act);
+void assign_matarar(struct Object *ob, struct Material ***matar, short totcol);
-int find_material_index(struct Object *ob, struct Material *ma);
+short find_material_index(struct Object *ob, struct Material *ma);
int object_add_material_slot(struct Object *ob);
int object_remove_material_slot(struct Object *ob);
/* rna api */
void material_append_id(struct ID *id, struct Material *ma);
-struct Material *material_pop_id(struct ID *id, int index, int remove_material_slot);
+struct Material *material_pop_id(struct ID *id, int index, int remove_material_slot); /* index is an int because of RNA */
/* rendering */
@@ -101,6 +104,9 @@ void clear_mat_mtex_copybuf(void);
void copy_mat_mtex_copybuf(struct ID *id);
void paste_mat_mtex_copybuf(struct ID *id);
+/* handle backward compatibility for tface/materials called from doversion (fileload=1) or Help Menu (fileload=0) */
+int do_version_tface(struct Main *main, int fileload);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 08c150e30e3..95490b1aff6 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -84,7 +84,7 @@ void nurbs_to_mesh(struct Object *ob);
void mesh_to_curve(struct Scene *scene, struct Object *ob);
void free_dverts(struct MDeformVert *dvert, int totvert);
void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */
-void mesh_delete_material_index(struct Mesh *me, int index);
+void mesh_delete_material_index(struct Mesh *me, short index);
void mesh_set_smooth_flag(struct Object *meshOb, int enableSmooth);
struct BoundBox *mesh_get_bb(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 0400f229083..2578a90808a 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -59,6 +59,7 @@ void paint_brush_set(struct Paint *paint, struct Brush *br);
* Texture paint could be removed since selected faces are not used
* however hiding faces is useful */
int paint_facesel_test(struct Object *ob);
+int paint_vertsel_test(struct Object *ob);
/* Session data (mode-specific) */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 7a02da57350..0b3bb4cc7cd 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -40,6 +40,7 @@
#include "DNA_cloth_types.h"
#include "DNA_key_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_armature_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h" // N_T
@@ -59,6 +60,7 @@
#include "BKE_paint.h"
#include "BKE_texture.h"
#include "BKE_multires.h"
+#include "BKE_armature.h"
#include "BLO_sys_types.h" // for intptr_t support
@@ -986,17 +988,14 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
EditFace *efa;
DMVertexAttribs attribs= {{{0}}};
GPUVertexAttribs gattribs;
- MTFace *tf;
- int transp, new_transp, orig_transp, tfoffset;
- int i, b, matnr, new_matnr, dodraw, layer;
+ /* int tfoffset; */ /* UNUSED */
+ int i, b, matnr, new_matnr, dodraw /* , layer */ /* UNUSED */;
dodraw = 0;
matnr = -1;
- transp = GPU_get_material_blend_mode();
- orig_transp = transp;
- layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE);
- tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset;
+ /* layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); */ /* UNUSED */
+ /* tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; */ /* UNUSED */
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
glShadeModel(GL_SMOOTH);
@@ -1038,19 +1037,6 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
}
- if(tfoffset != -1) {
- tf = (MTFace*)((char*)efa->data)+tfoffset;
- new_transp = tf->transp;
-
- if(new_transp != transp) {
- if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
- GPU_set_material_blend_mode(orig_transp);
- else
- GPU_set_material_blend_mode(new_transp);
- transp = new_transp;
- }
- }
-
if(dodraw) {
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
if (!drawSmooth) {
@@ -1673,20 +1659,64 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb)
}
}
-static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col)
+/* draw_flag's for calc_weightpaint_vert_color */
+enum {
+ CALC_WP_MULTIPAINT= (1<<0),
+ CALC_WP_AUTO_NORMALIZE= (1<<1),
+};
+
+static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col, char *dg_flags, int selected, int UNUSED(unselected), const int draw_flag)
{
Mesh *me = ob->data;
float colf[4], input = 0.0f;
int i;
+
+ int make_black= FALSE;
+
if (me->dvert) {
- for (i=0; i<me->dvert[vert].totweight; i++)
- if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
- input+=me->dvert[vert].dw[i].weight;
- }
+ if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
+
+ int was_a_nonzero= FALSE;
+ for (i=0; i<me->dvert[vert].totweight; i++) {
+ /* in multipaint, get the average if auto normalize is inactive
+ * get the sum if it is active */
+ if(dg_flags[me->dvert[vert].dw[i].def_nr]) {
+ if(me->dvert[vert].dw[i].weight) {
+ input+= me->dvert[vert].dw[i].weight;
+ was_a_nonzero= TRUE;
+ }
+ }
+ }
- CLAMP(input, 0.0f, 1.0f);
+ /* make it black if the selected groups have no weight on a vertex */
+ if(was_a_nonzero == FALSE) {
+ make_black = TRUE;
+ }
+ else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) {
+ input /= selected; /* get the average */
+ }
+ }
+ else {
+ /* default, non tricky behavior */
+ for (i=0; i<me->dvert[vert].totweight; i++) {
+ if (me->dvert[vert].dw[i].def_nr==ob->actdef-1) {
+ input+=me->dvert[vert].dw[i].weight;
+ }
+ }
+ }
+ }
+ if (make_black) {
+ col[3] = 0;
+ col[2] = 0;
+ col[1] = 0;
+ col[0] = 255;
+ return;
+ }
+
+ CLAMP(input, 0.0f, 1.0f);
+
if(coba)
do_colorband(coba, input, colf);
else
@@ -1705,7 +1735,7 @@ void vDM_ColorBand_store(ColorBand *coba)
stored_cb= coba;
}
-static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm)
+static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
{
Mesh *me = ob->data;
MFace *mf = me->mface;
@@ -1713,17 +1743,24 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm)
unsigned char *wtcol;
int i;
+ int defbase_len = BLI_countlist(&ob->defbase);
+ char *defbase_sel = MEM_mallocN(defbase_len * sizeof(char), __func__);
+ int selected = get_selected_defgroups(ob, defbase_sel, defbase_len);
+ int unselected = defbase_len - selected;
+
wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
for (i=0; i<me->totface; i++, mf++) {
- calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]);
- calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]);
- calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]);
+ calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag);
+ calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag);
+ calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4], defbase_sel, selected, unselected, draw_flag);
if (mf->v4)
- calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]);
+ calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag);
}
+ MEM_freeN(defbase_sel);
+
CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
}
@@ -1751,6 +1788,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
int has_multires = mmd != NULL, multires_applied = 0;
int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
+ int draw_flag= ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) |
+ (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0));
+
if(mmd && !mmd->sculptlvl)
has_multires = 0;
@@ -1930,7 +1970,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
- add_weight_mcol_dm(ob, dm);
+ add_weight_mcol_dm(ob, dm, draw_flag);
/* Constructive modifiers need to have an origindex
* otherwise they wont have anywhere to copy the data from.
@@ -2042,7 +2082,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
CDDM_calc_normals(finaldm);
if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
- add_weight_mcol_dm(ob, finaldm);
+ add_weight_mcol_dm(ob, finaldm, draw_flag);
} else if(dm) {
finaldm = dm;
} else {
@@ -2054,7 +2094,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
- add_weight_mcol_dm(ob, finaldm);
+ add_weight_mcol_dm(ob, finaldm, draw_flag);
}
/* add an orco layer if needed */
@@ -2327,7 +2367,7 @@ static void clear_mesh_caches(Object *ob)
static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
{
Object *obact = scene->basact?scene->basact->object:NULL;
- int editing = paint_facesel_test(ob);
+ int editing = paint_facesel_test(ob) || paint_vertsel_test(ob);/* paint_vertsel_test */
/* weight paint and face select need original indices because of selection buffer drawing */
int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT)));
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index b690c9b4a91..5d01db87422 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -1557,7 +1557,7 @@ static NlaEvalChannel *nlaevalchan_verify (PointerRNA *ptr, ListBase *channels,
PropertyRNA *prop;
PointerRNA new_ptr;
char *path = NULL;
- short free_path=0;
+ /* short free_path=0; */
/* sanity checks */
if (channels == NULL)
@@ -1565,7 +1565,7 @@ static NlaEvalChannel *nlaevalchan_verify (PointerRNA *ptr, ListBase *channels,
/* get RNA pointer+property info from F-Curve for more convenient handling */
/* get path, remapped as appropriate to work in its new environment */
- free_path= animsys_remap_path(strip->remap, fcu->rna_path, &path);
+ /* free_path= */ /* UNUSED */ animsys_remap_path(strip->remap, fcu->rna_path, &path);
/* a valid property must be available, and it must be animateable */
if (RNA_path_resolve(ptr, path, &new_ptr, &prop) == 0) {
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 08a95477c2e..1149d8eee25 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -2464,3 +2464,33 @@ void where_is_pose (Scene *scene, Object *ob)
}
}
}
+
+
+/* Returns total selected vgroups,
+ * wpi.defbase_sel is assumed malloc'd, all values are set */
+int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_len)
+{
+ bDeformGroup *defgroup;
+ unsigned int i;
+ Object *armob= object_pose_armature_get(ob);
+ int dg_flags_sel_tot= 0;
+
+ if(armob) {
+ bPose *pose= armob->pose;
+ for (i= 0, defgroup= ob->defbase.first; i < defbase_len && defgroup; defgroup = defgroup->next, i++) {
+ bPoseChannel *pchan= get_pose_channel(pose, defgroup->name);
+ if(pchan && (pchan->bone->flag & BONE_SELECTED)) {
+ dg_selection[i]= TRUE;
+ dg_flags_sel_tot++;
+ }
+ else {
+ dg_selection[i]= FALSE;
+ }
+ }
+ }
+ else {
+ memset(dg_selection, FALSE, sizeof(char) * defbase_len);
+ }
+
+ return dg_flags_sel_tot;
+}
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 2b6261b1c81..218b83fc52a 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -500,7 +500,7 @@ static int read_undosave(bContext *C, UndoElem *uel)
void BKE_write_undo(bContext *C, const char *name)
{
uintptr_t maxmem, totmem, memused;
- int nr, success;
+ int nr /*, success */ /* UNUSED */;
UndoElem *uel;
if( (U.uiflag & USER_GLOBALUNDO)==0) return;
@@ -552,7 +552,7 @@ void BKE_write_undo(bContext *C, const char *name)
BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter);
BLI_make_file_string("/", filepath, btempdir, numstr);
- success= BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
+ /* success= */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
BLI_strncpy(curundo->str, filepath, sizeof(curundo->str));
}
@@ -562,7 +562,7 @@ void BKE_write_undo(bContext *C, const char *name)
if(curundo->prev) prevfile= &(curundo->prev->memfile);
memused= MEM_get_memory_in_use();
- success= BLO_write_file_mem(CTX_data_main(C), prevfile, &curundo->memfile, G.fileflags);
+ /* success= */ /* UNUSED */ BLO_write_file_mem(CTX_data_main(C), prevfile, &curundo->memfile, G.fileflags);
curundo->undosize= MEM_get_memory_in_use() - memused;
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 44359a142c9..e1939335268 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1060,18 +1060,15 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
DMVertexAttribs attribs;
MVert *mvert = cddm->mvert;
MFace *mface = cddm->mface;
- MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
+ /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
int a, b, dodraw, matnr, new_matnr;
- int transp, new_transp, orig_transp;
int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
cdDM_update_normals_from_pbvh(dm);
matnr = -1;
dodraw = 0;
- transp = GPU_get_material_blend_mode();
- orig_transp = transp;
glShadeModel(GL_SMOOTH);
@@ -1111,22 +1108,6 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
continue;
}
- if(tf) {
- new_transp = tf[a].transp;
-
- if(new_transp != transp) {
- glEnd();
-
- if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
- GPU_set_material_blend_mode(orig_transp);
- else
- GPU_set_material_blend_mode(new_transp);
- transp = new_transp;
-
- glBegin(GL_QUADS);
- }
- }
-
if(!smoothnormal) {
if(nors) {
glNormal3fv(nors[a]);
@@ -1158,7 +1139,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
GPUBuffer *buffer = NULL;
char *varray = NULL;
int numdata = 0, elementsize = 0, offset;
- int start = 0, numfaces = 0, prevdraw = 0, curface = 0;
+ int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
int i;
MFace *mf = mface;
@@ -1202,7 +1183,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
}
numdata = 0;
start = curface;
- prevdraw = dodraw;
+ /* prevdraw = dodraw; */ /* UNUSED */
dodraw = setMaterial(matnr = new_matnr, &gattribs);
if(dodraw) {
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
@@ -1250,7 +1231,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
else {
/* if the buffer was set, dont use it again.
* prevdraw was assumed true but didnt run so set to false - [#21036] */
- prevdraw= 0;
+ /* prevdraw= 0; */ /* UNUSED */
buffer= NULL;
}
}
@@ -1259,33 +1240,6 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
continue;
}
- if(tf) {
- new_transp = tf[a].transp;
-
- if(new_transp != transp) {
- numfaces = curface - start;
- if( numfaces > 0 ) {
- if( dodraw ) {
- if( numdata != 0 ) {
- GPU_buffer_unlock(buffer);
- GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
- }
- glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
- if( numdata != 0 ) {
- varray = GPU_buffer_lock_stream(buffer);
- }
- }
- }
- start = curface;
-
- if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
- GPU_set_material_blend_mode(orig_transp);
- else
- GPU_set_material_blend_mode(new_transp);
- transp = new_transp;
- }
- }
-
if( numdata != 0 ) {
offset = 0;
if(attribs.totorco) {
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 883f67c3061..30da2e01011 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -326,7 +326,7 @@ static void layerSwap_tface(void *data, const int *corner_indices)
static void layerDefault_tface(void *data, int count)
{
static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL,
- 0, 0, TF_DYNAMIC, 0, 0};
+ 0, 0, TF_DYNAMIC|TF_CONVERTED, 0, 0};
MTFace *tf = (MTFace*)data;
int i;
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 002cfdbf41a..d764826cd47 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2290,3 +2290,20 @@ void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr)
iuser->framenr= framenr;
if(iuser->ok==0) iuser->ok= 1;
}
+
+int BKE_image_has_alpha(struct Image *image)
+{
+ ImBuf *ibuf;
+ void *lock;
+ int depth;
+
+ ibuf= BKE_image_acquire_ibuf(image, NULL, &lock);
+ depth = (ibuf?ibuf->depth:0);
+ BKE_image_release_ibuf(image, lock);
+
+ if (depth == 32)
+ return 1;
+ else
+ return 0;
+}
+
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 2a9e786d139..f5df6efd622 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -37,12 +37,16 @@
#include <string.h>
#include <math.h>
+#include <stddef.h>
#include "MEM_guardedalloc.h"
#include "DNA_curve_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_customdata_types.h"
+#include "DNA_ID.h"
#include "DNA_meta_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -56,6 +60,7 @@
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_icons.h"
+#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -188,6 +193,10 @@ void init_material(Material *ma)
ma->vol.ms_diff = 1.f;
ma->vol.ms_intensity = 1.f;
+ ma->game.flag=0;
+ ma->game.alpha_blend=0;
+ ma->game.face_orientation=0;
+
ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RAYBIAS|MA_TANGENT_STR|MA_ZTRANSP;
ma->shade_flag= MA_APPROX_OCCLUSION;
ma->preview = NULL;
@@ -515,7 +524,7 @@ short *give_totcolp_id(ID *id)
return NULL;
}
-static void data_delete_material_index_id(ID *id, int index)
+static void data_delete_material_index_id(ID *id, short index)
{
switch(GS(id->name)) {
case ID_ME:
@@ -547,8 +556,9 @@ void material_append_id(ID *id, Material *ma)
}
}
-Material *material_pop_id(ID *id, int index, int remove_material_slot)
+Material *material_pop_id(ID *id, int index_i, int remove_material_slot)
{
+ short index= (short)index_i;
Material *ret= NULL;
Material ***matar;
if((matar= give_matarar_id(id))) {
@@ -591,7 +601,7 @@ Material *material_pop_id(ID *id, int index, int remove_material_slot)
return ret;
}
-Material *give_current_material(Object *ob, int act)
+Material *give_current_material(Object *ob, short act)
{
Material ***matarar, *ma;
short *totcolp;
@@ -629,7 +639,7 @@ Material *give_current_material(Object *ob, int act)
return ma;
}
-ID *material_from(Object *ob, int act)
+ID *material_from(Object *ob, short act)
{
if(ob==NULL) return NULL;
@@ -713,7 +723,7 @@ void test_object_materials(ID *id)
}
}
-void assign_material(Object *ob, Material *ma, int act)
+void assign_material(Object *ob, Material *ma, short act)
{
Material *mao, **matar, ***matarar;
char *matbits;
@@ -784,9 +794,10 @@ void assign_material(Object *ob, Material *ma, int act)
}
/* XXX - this calls many more update calls per object then are needed, could be optimized */
-void assign_matarar(struct Object *ob, struct Material ***matar, int totcol)
+void assign_matarar(struct Object *ob, struct Material ***matar, short totcol)
{
- int i, actcol_orig= ob->actcol;
+ int actcol_orig= ob->actcol;
+ short i;
while(object_remove_material_slot(ob)) {};
@@ -801,7 +812,7 @@ void assign_matarar(struct Object *ob, struct Material ***matar, int totcol)
}
-int find_material_index(Object *ob, Material *ma)
+short find_material_index(Object *ob, Material *ma)
{
Material ***matarar;
short a, *totcolp;
@@ -1053,7 +1064,7 @@ int object_remove_material_slot(Object *ob)
Material *mao, ***matarar;
Object *obt;
short *totcolp;
- int a, actcol;
+ short a, actcol;
if(ob==NULL || ob->totcol==0) return FALSE;
@@ -1468,3 +1479,482 @@ void paste_matcopybuf(Material *ma)
ma->nodetree= ntreeCopyTree(matcopybuf.nodetree);
}
+
+
+/*********************** texface to material convert functions **********************/
+/* encode all the TF information into a single int */
+static int encode_tfaceflag(MTFace *tf, int convertall)
+{
+ /* calculate the flag */
+ int flag = tf->mode;
+
+ /* options that change the material offline render */
+ if (!convertall) {
+ flag &= ~TF_OBCOL;
+ }
+
+ /* clean flags that are not being converted */
+ flag &= ~TF_TEX;
+ flag &= ~TF_SHAREDVERT;
+ flag &= ~TF_SHAREDCOL;
+ flag &= ~TF_CONVERTED;
+
+ /* light tface flag is ignored in GLSL mode */
+ flag &= ~TF_LIGHT;
+
+ /* 15 is how big the flag can be - hardcoded here and in decode_tfaceflag() */
+ flag |= tf->transp << 15;
+
+ /* increase 1 so flag 0 is different than no flag yet */
+ return flag + 1;
+}
+
+/* set the material options based in the tface flag */
+static void decode_tfaceflag(Material *ma, int flag, int convertall)
+{
+ int alphablend;
+ GameSettings *game= &ma->game;
+
+ /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
+ flag -= 1;
+
+ alphablend = flag >> 15; //encoded in the encode_tfaceflag function
+ (*game).flag = 0;
+
+ /* General Material Options */
+ if ((flag & TF_DYNAMIC)==0) (*game).flag |= GEMAT_NOPHYSICS;
+
+ /* Material Offline Rendering Properties */
+ if (convertall) {
+ if (flag & TF_OBCOL) ma->shade_flag |= MA_OBCOLOR;
+ }
+
+ /* Special Face Properties */
+ if ((flag & TF_TWOSIDE)==0) (*game).flag |= GEMAT_BACKCULL;
+ if (flag & TF_INVISIBLE)(*game).flag |= GEMAT_INVISIBLE;
+ if (flag & TF_BMFONT) (*game).flag |= GEMAT_TEXT;
+
+ /* Face Orientation */
+ if (flag & TF_BILLBOARD) (*game).face_orientation |= GEMAT_HALO;
+ else if (flag & TF_BILLBOARD2) (*game).face_orientation |= GEMAT_BILLBOARD;
+ else if (flag & TF_SHADOW) (*game).face_orientation |= GEMAT_SHADOW;
+
+ /* Alpha Blend */
+ if (flag & TF_ALPHASORT && ELEM(alphablend, TF_ALPHA, TF_ADD)) (*game).alpha_blend = GEMAT_ALPHA_SORT;
+ else if (alphablend & TF_ALPHA) (*game).alpha_blend = GEMAT_ALPHA;
+ else if (alphablend & TF_ADD) (*game).alpha_blend = GEMAT_ADD;
+ else if (alphablend & TF_CLIP) (*game).alpha_blend = GEMAT_CLIP;
+}
+
+/* boolean check to see if the mesh needs a material */
+static int check_tfaceneedmaterial(int flag)
+{
+ // check if the flags we have are not deprecated != than default material options
+ // also if only flags are visible and collision see if all objects using this mesh have this option in physics
+
+ /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
+ flag -=1;
+
+ // deprecated flags
+ flag &= ~TF_OBCOL;
+ flag &= ~TF_SHAREDVERT;
+ flag &= ~TF_SHAREDCOL;
+
+ /* light tface flag is ignored in GLSL mode */
+ flag &= ~TF_LIGHT;
+
+ // automatic detected if tex image has alpha
+ flag &= ~(TF_ALPHA << 15);
+ // automatic detected if using texture
+ flag &= ~TF_TEX;
+
+ // settings for the default NoMaterial
+ if (flag == TF_DYNAMIC)
+ return 0;
+
+ else
+ return 1;
+}
+
+/* return number of digits of an integer */
+// XXX to be optmized or replaced by an equivalent blender internal function
+static int integer_getdigits(int number)
+{
+ int i=0;
+ if (number == 0) return 1;
+
+ while (number != 0){
+ number = (int)(number/10);
+ i++;
+ }
+ return i;
+}
+
+static void calculate_tface_materialname(char *matname, char *newname, int flag)
+{
+ // if flag has only light and collision and material matches those values
+ // you can do strcpy(name, mat_name);
+ // otherwise do:
+ int digits = integer_getdigits(flag);
+ /* clamp the old name, remove the MA prefix and add the .TF.flag suffix
+ e.g. matname = "MALoooooooooooooongName"; newname = "Loooooooooooooon.TF.2" */
+ sprintf(newname, "%.*s.TF.%0*d", MAX_ID_NAME-(digits+5), matname, digits, flag);
+}
+
+/* returns -1 if no match */
+static short mesh_getmaterialnumber(Mesh *me, Material *ma)
+{
+ short a;
+
+ for (a=0; a<me->totcol; a++) {
+ if (me->mat[a] == ma) {
+ return a;
+ }
+ }
+
+ return -1;
+}
+
+/* append material */
+static short mesh_addmaterial(Mesh *me, Material *ma)
+{
+ material_append_id(&me->id, NULL);
+ me->mat[me->totcol-1]= ma;
+
+ id_us_plus(&ma->id);
+
+ return me->totcol-1;
+}
+
+static void set_facetexture_flags(Material *ma, Image *image)
+{
+ if(image) {
+ ma->mode |= MA_FACETEXTURE;
+ /* we could check if the texture has alpha, but then more meshes sharing the same
+ * material may need it. Let's make it simple. */
+ if(BKE_image_has_alpha(image))
+ ma->mode |= MA_FACETEXTURE_ALPHA;
+ }
+}
+
+/* returns material number */
+static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag)
+{
+ Material *ma;
+ char idname[MAX_ID_NAME];
+ short mat_nr= -1;
+
+ /* new material, the name uses the flag*/
+ sprintf(idname, "MAMaterial.TF.%0*d", integer_getdigits(flag), flag);
+
+ if ((ma= BLI_findstring(&main->mat, idname+2, offsetof(ID, name)+2))) {
+ mat_nr= mesh_getmaterialnumber(me, ma);
+ /* assign the material to the mesh */
+ if(mat_nr == -1) mat_nr= mesh_addmaterial(me, ma);
+
+ /* if needed set "Face Textures [Alpha]" Material options */
+ set_facetexture_flags(ma, tf->tpage);
+ }
+ /* create a new material */
+ else {
+ ma= add_material(idname+2);
+
+ if(ma){
+ printf("TexFace Convert: Material \"%s\" created.\n", idname+2);
+ mat_nr= mesh_addmaterial(me, ma);
+
+ /* if needed set "Face Textures [Alpha]" Material options */
+ set_facetexture_flags(ma, tf->tpage);
+
+ decode_tfaceflag(ma, flag, 1);
+ // the final decoding will happen after, outside the main loop
+ // for now store the flag into the material and change light/tex/collision
+ // store the flag as a negative number
+ ma->game.flag = -flag;
+ id_us_min((ID *)ma);
+ }
+ else printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname+2, me->id.name+2);
+ }
+
+ /* set as converted, no need to go bad to this face */
+ tf->mode |= TF_CONVERTED;
+ return mat_nr;
+}
+
+/* Function to fully convert materials */
+static void convert_tfacematerial(Main *main, Material *ma)
+{
+ Mesh *me;
+ Material *mat_new;
+ MFace *mf;
+ MTFace *tf;
+ int flag, index;
+ int a;
+ short mat_nr;
+ CustomDataLayer *cdl;
+ char idname[MAX_ID_NAME];
+
+ for(me=main->mesh.first; me; me=me->id.next){
+ /* check if this mesh uses this material */
+ for(a=0;a<me->totcol;a++)
+ if(me->mat[a] == ma) break;
+
+ /* no material found */
+ if (a == me->totcol) continue;
+
+ /* get the active tface layer */
+ index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
+ cdl= (index == -1)? NULL: &me->fdata.layers[index];
+ if (!cdl) continue;
+
+ /* loop over all the faces and stop at the ones that use the material*/
+ for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
+ if(me->mat[mf->mat_nr] != ma) continue;
+
+ /* texface data for this face */
+ tf = ((MTFace*)cdl->data) + a;
+ flag = encode_tfaceflag(tf, 1);
+
+ /* the name of the new material */
+ calculate_tface_materialname(ma->id.name, (char *)&idname, flag);
+
+ if ((mat_new= BLI_findstring(&main->mat, idname+2, offsetof(ID, name)+2))) {
+ /* material already existent, see if the mesh has it */
+ mat_nr = mesh_getmaterialnumber(me, mat_new);
+ /* material is not in the mesh, add it */
+ if(mat_nr == -1) mat_nr= mesh_addmaterial(me, mat_new);
+ }
+ /* create a new material */
+ else {
+ mat_new=copy_material(ma);
+ if(mat_new){
+ /* rename the material*/
+ strcpy(mat_new->id.name, idname);
+ id_us_min((ID *)mat_new);
+
+ mat_nr= mesh_addmaterial(me, mat_new);
+ decode_tfaceflag(mat_new, flag, 1);
+ }
+ else {
+ printf("Error: Unable to create Material \"%s\" for Mesh \"%s.", idname+2, me->id.name+2);
+ mat_nr = mf->mat_nr;
+ continue;
+ }
+ }
+
+ /* if the material has a texture but no texture channel
+ * set "Face Textures [Alpha]" Material options
+ * actually we need to run it always, because of old behavior
+ * of using face texture if any texture channel was present (multitex) */
+ //if((!mat_new->mtex[0]) && (!mat_new->mtex[0]->tex))
+ set_facetexture_flags(mat_new, tf->tpage);
+
+ /* set the material number to the face*/
+ mf->mat_nr = mat_nr;
+ }
+ /* remove material from mesh */
+ for(a=0;a<me->totcol;)
+ if(me->mat[a] == ma) material_pop_id(&me->id, a, 1);else a++;
+ }
+}
+
+
+#define MAT_BGE_DISPUTED -99999
+
+int do_version_tface(Main *main, int fileload)
+{
+ Mesh *me;
+ Material *ma;
+ MFace *mf;
+ MTFace *tf;
+ CustomDataLayer *cdl;
+ int a;
+ int flag;
+ int index;
+
+ /* sometimes mesh has no materials but will need a new one. In those
+ * cases we need to ignore the mf->mat_nr and only look at the face
+ * mode because it can be zero as uninitialized or the 1st created material
+ */
+ int nomaterialslots;
+
+ /* alert to user to check the console */
+ int nowarning = 1;
+
+ /* mark all the materials to conversion with a flag
+ * if there is tface create a complete flag for that storing in flag
+ * if there is tface and flag > 0: creates a new flag based on this face
+ * if flags are different set flag to -1
+ */
+
+ /* 1st part: marking mesh materials to update */
+ for(me=main->mesh.first; me; me=me->id.next){
+ if (me->id.lib) continue;
+
+ /* get the active tface layer */
+ index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
+ cdl= (index == -1)? NULL: &me->fdata.layers[index];
+ if (!cdl) continue;
+
+ nomaterialslots = (me->totcol==0?1:0);
+
+ /* loop over all the faces*/
+ for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
+ /* texface data for this face */
+ tf = ((MTFace*)cdl->data) + a;
+
+ /* conversion should happen only once */
+ if (fileload)
+ tf->mode &= ~TF_CONVERTED;
+ else {
+ if((tf->mode & TF_CONVERTED)) continue;
+ else tf->mode |= TF_CONVERTED;
+ }
+
+ /* no material slots */
+ if(nomaterialslots) {
+ flag = encode_tfaceflag(tf, 1);
+
+ /* create/find a new material and assign to the face */
+ if (check_tfaceneedmaterial(flag)) {
+ mf->mat_nr= convert_tfacenomaterial(main, me, tf, flag);
+ }
+ /* else mark them as no-material to be reverted to 0 later */
+ else {
+ mf->mat_nr = -1;
+ }
+ }
+ else if(mf->mat_nr < me->totcol) {
+ ma= me->mat[mf->mat_nr];
+
+ /* no material create one if necessary */
+ if(!ma) {
+ /* find a new material and assign to the face */
+ flag = encode_tfaceflag(tf, 1);
+
+ /* create/find a new material and assign to the face */
+ if (check_tfaceneedmaterial(flag))
+ mf->mat_nr= convert_tfacenomaterial(main, me, tf, flag);
+
+ continue;
+ }
+
+ /* we can't read from this if it comes from a library,
+ * at doversion time: direct_link might not have happened on it,
+ * so ma->mtex is not pointing to valid memory yet.
+ * later we could, but it's better not */
+ else if(ma->id.lib)
+ continue;
+
+ /* material already marked as disputed */
+ else if(ma->game.flag == MAT_BGE_DISPUTED)
+ continue;
+
+ /* found a material */
+ else {
+ flag = encode_tfaceflag(tf, ((fileload)?0:1));
+
+ /* first time changing this material */
+ if (ma->game.flag == 0)
+ ma->game.flag= -flag;
+
+ /* mark material as disputed */
+ else if (ma->game.flag != -flag) {
+ ma->game.flag = MAT_BGE_DISPUTED;
+ continue;
+ }
+
+ /* material ok so far */
+ else {
+ ma->game.flag = -flag;
+
+ /* some people uses multitexture with TexFace by creating a texture
+ * channel which not neccessarly the tf->tpage image. But the game engine
+ * was enabling it. Now it's required to set "Face Texture [Alpha] in the
+ * material settings. */
+ if(!fileload)
+ set_facetexture_flags(ma, tf->tpage);
+ }
+ }
+ }
+ else
+ continue;
+ }
+
+ /* if we didn't have material slot and now we do, we need to
+ * make sure the materials are correct */
+ if(nomaterialslots) {
+ if (me->totcol>0) {
+ for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
+ if (mf->mat_nr == -1) {
+ /* texface data for this face */
+ tf = ((MTFace*)cdl->data) + a;
+ mf->mat_nr= convert_tfacenomaterial(main, me, tf, encode_tfaceflag(tf, 1));
+ }
+ }
+ }
+ else {
+ for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
+ mf->mat_nr=0;
+ }
+ }
+ }
+
+ }
+
+ /* 2nd part - conversion */
+ /* skip library files */
+
+ /* we shouldn't loop through the materials created in the loop. make the loop stop at its original length) */
+ for (ma= main->mat.first, a=0; ma; ma= ma->id.next, a++) {
+ if (ma->id.lib) continue;
+
+ /* disputed material */
+ if (ma->game.flag == MAT_BGE_DISPUTED) {
+ ma->game.flag = 0;
+ if (fileload) {
+ printf("Warning: material \"%s\" skipped - to convert old game texface to material go to the Help menu.\n", ma->id.name+2);
+ nowarning = 0;
+ }
+ else
+ convert_tfacematerial(main, ma);
+ continue;
+ }
+
+ /* no conflicts in this material - 90% of cases
+ * convert from tface system to material */
+ else if (ma->game.flag < 0) {
+ decode_tfaceflag(ma, -(ma->game.flag), 1);
+
+ /* material is good make sure all faces using
+ * this material are set to converted */
+ if (fileload) {
+ for(me=main->mesh.first; me; me=me->id.next){
+ /* check if this mesh uses this material */
+ for(a=0;a<me->totcol;a++)
+ if(me->mat[a] == ma) break;
+
+ /* no material found */
+ if (a == me->totcol) continue;
+
+ /* get the active tface layer */
+ index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
+ cdl= (index == -1)? NULL: &me->fdata.layers[index];
+ if (!cdl) continue;
+
+ /* loop over all the faces and stop at the ones that use the material*/
+ for (a=0, mf=me->mface; a<me->totface; a++, mf++) {
+ if (me->mat[mf->mat_nr] == ma) {
+ /* texface data for this face */
+ tf = ((MTFace*)cdl->data) + a;
+ tf->mode |= TF_CONVERTED;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return nowarning;
+}
+
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 32819226361..810e7c285e8 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -917,7 +917,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
mface->v2= startvert+index[2];
mface->v3= startvert+index[1];
mface->v4= 0;
- mface->mat_nr= (unsigned char)dl->col;
+ mface->mat_nr= dl->col;
test_index_face(mface, NULL, 0, 3);
if(smooth) mface->flag |= ME_SMOOTH;
@@ -966,7 +966,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
mface->v2= p3;
mface->v3= p4;
mface->v4= p2;
- mface->mat_nr= (unsigned char)dl->col;
+ mface->mat_nr= dl->col;
test_index_face(mface, NULL, 0, 4);
if(smooth) mface->flag |= ME_SMOOTH;
@@ -1252,7 +1252,7 @@ void mesh_to_curve(Scene *scene, Object *ob)
}
}
-void mesh_delete_material_index(Mesh *me, int index)
+void mesh_delete_material_index(Mesh *me, short index)
{
MFace *mf;
int i;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 89fd3ff9c13..524a63a8a95 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -295,12 +295,12 @@ int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockin
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
{
bNodeSocketTemplate *sockdef;
- bNodeSocket *sock;
+ /* bNodeSocket *sock; */ /* UNUSED */
if(ntype->inputs) {
sockdef= ntype->inputs;
while(sockdef->type != -1) {
- sock = node_add_input_from_template(ntree, node, sockdef);
+ /* sock = */ node_add_input_from_template(ntree, node, sockdef);
sockdef++;
}
@@ -308,7 +308,7 @@ static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType
if(ntype->outputs) {
sockdef= ntype->outputs;
while(sockdef->type != -1) {
- sock = node_add_output_from_template(ntree, node, sockdef);
+ /* sock = */ node_add_output_from_template(ntree, node, sockdef);
sockdef++;
}
@@ -620,7 +620,7 @@ bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
bNodeTree *ntreeCopyTree(bNodeTree *ntree)
{
bNodeTree *newtree;
- bNode *node, *nnode, *last;
+ bNode *node /*, *nnode */ /* UNUSED */, *last;
bNodeLink *link;
bNodeSocket *gsock, *oldgsock;
@@ -647,7 +647,7 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree)
last = ntree->nodes.last;
for(node= ntree->nodes.first; node; node= node->next) {
node->new_node= NULL;
- nnode= nodeCopyNode(newtree, node); /* sets node->new */
+ /* nnode= */ nodeCopyNode(newtree, node); /* sets node->new */
/* make sure we don't copy new nodes again! */
if (node==last)
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d00eb6192da..ddeb42d608e 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -97,6 +97,10 @@ int paint_facesel_test(Object *ob)
return (ob && ob->type==OB_MESH && ob->data && (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_MASK) && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)));
}
+int paint_vertsel_test(Object *ob)
+{
+ return (ob && ob->type==OB_MESH && ob->data && (((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) && (ob->mode & OB_MODE_WEIGHT_PAINT));
+}
void paint_init(Paint *p, const char col[3])
{
Brush *brush;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index d17b769888b..73d0d70778f 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -1,5 +1,5 @@
/*
- * $Id:
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 2ff555b5b22..36263746228 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -968,8 +968,9 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
for(index = 0; index < totface; index++) {
CCGFace *f = ccgdm->faceMap[index].face;
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
- int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
- int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
+ /* keep types in sync with MFace, avoid many conversions */
+ char flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
+ short mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
for(S = 0; S < numVerts; S++) {
for(y = 0; y < gridSize - 1; y++) {
@@ -1374,11 +1375,10 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
GPUVertexAttribs gattribs;
DMVertexAttribs attribs= {{{NULL}}};
- MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
+ /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
int gridSize = ccgSubSurf_getGridSize(ss);
int gridFaces = gridSize - 1;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int transp, orig_transp, new_transp;
char *faceFlags = ccgdm->faceFlags;
int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
@@ -1386,8 +1386,6 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v
doDraw = 0;
matnr = -1;
- transp = GPU_get_material_blend_mode();
- orig_transp = transp;
#define PASSATTRIB(dx, dy, vert) { \
if(attribs.totorco) { \
@@ -1439,18 +1437,6 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v
continue;
}
- if(tf) {
- new_transp = tf[i].transp;
-
- if(new_transp != transp) {
- if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
- GPU_set_material_blend_mode(orig_transp);
- else
- GPU_set_material_blend_mode(new_transp);
- transp = new_transp;
- }
- }
-
glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
for (S=0; S<numVerts; S++) {
DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 38454547f48..497ac415ebb 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -238,6 +238,7 @@ typedef struct OldNewMap {
/* local prototypes */
static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(FileData *fd, ListBase *lb);
+static void convert_tface_mt(FileData *fd, Main *main);
static OldNewMap *oldnewmap_new(void)
{
@@ -3478,6 +3479,9 @@ static void lib_link_mesh(FileData *fd, Main *main)
}
me= me->id.next;
}
+
+ /* convert texface options to material */
+ convert_tface_mt(fd, main);
}
static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts)
@@ -6358,7 +6362,7 @@ static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
/* if we do, set alpha sort if the game engine did it before */
for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
if(mf->mat_nr < me->totcol) {
- ma= newlibadr(fd, lib, me->mat[(int)mf->mat_nr]);
+ ma= newlibadr(fd, lib, me->mat[mf->mat_nr]);
texalpha = 0;
/* we can't read from this if it comes from a library,
@@ -7038,6 +7042,27 @@ static void do_versions_nodetree_dynamic_sockets(bNodeTree *ntree)
sock->flag |= SOCK_DYNAMIC;
}
+void convert_tface_mt(FileData *fd, Main *main)
+{
+ Main *gmain;
+
+ /* this is a delayed do_version (so it can create new materials) */
+ if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 3)) {
+
+ //XXX hack, material.c uses G.main all over the place, instead of main
+ // temporarily set G.main to the current main
+ gmain = G.main;
+ G.main = main;
+
+ if(!(do_version_tface(main, 1))) {
+ BKE_report(fd->reports, RPT_ERROR, "Texface conversion problem. Error in console");
+ }
+
+ //XXX hack, material.c uses G.main allover the place, instead of main
+ G.main = gmain;
+ }
+}
+
static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index 4da0a4c6e1f..4892955fd3c 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -129,7 +129,7 @@ void GeometryExporter::operator()(Object *ob)
}
// powerful because it handles both cases when there is material and when there's not
-void GeometryExporter::createPolylist(int material_index,
+void GeometryExporter::createPolylist(short material_index,
bool has_uvs,
bool has_color,
Object *ob,
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index 64c51b6324e..532a439eba7 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -67,7 +67,7 @@ public:
void operator()(Object *ob);
// powerful because it handles both cases when there is material and when there's not
- void createPolylist(int material_index,
+ void createPolylist(short material_index,
bool has_uvs,
bool has_color,
Object *ob,
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index 15bd9c48f12..2f5d9e54e50 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -778,7 +778,7 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
Object *ob, const COLLADAFW::UniqueId *geom_uid,
MTex **color_texture, char *layername, MTFace *texture_face,
- std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, int mat_index)
+ std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
{
Mesh *me = (Mesh*)ob->data;
const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index 88ee0e46c33..208ba4d65c0 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -141,7 +141,7 @@ public:
std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
Object *ob, const COLLADAFW::UniqueId *geom_uid,
MTex **color_texture, char *layername, MTFace *texture_face,
- std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, int mat_index);
+ std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 53e0fd92eeb..566ff09c366 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -4290,10 +4290,15 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor
/* if the bone cannot be affected, don't do anything */
if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
+ Object *ob_act= OBACT;
bArmature *arm= ob->data;
- /* since we do unified select, we don't shift+select a bone if the armature object was not active yet */
- if (!(extend) || (base != scene->basact)) {
+ /* since we do unified select, we don't shift+select a bone if the
+ * armature object was not active yet.
+ * note, special exception for armature mode so we can do multi-select
+ * we could check for multi-select explicitly but think its fine to
+ * always give pradictable behavior in weight paint mode - campbell */
+ if (!(extend) || ((ob_act && ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0)) {
ED_pose_deselectall(ob, 0);
nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
arm->act_bone= nearBone;
@@ -4324,7 +4329,7 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor
}
/* in weightpaint we select the associated vertex group too */
- if (OBACT && OBACT->mode & OB_MODE_WEIGHT_PAINT) {
+ if (ob_act && ob_act->mode & OB_MODE_WEIGHT_PAINT) {
if (nearBone == arm->act_bone) {
ED_vgroup_select_by_name(OBACT, nearBone->name);
DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
@@ -5061,6 +5066,10 @@ void POSE_OT_select_inverse(wmOperatorType *ot)
static int pose_de_select_all_exec(bContext *C, wmOperator *op)
{
int action = RNA_enum_get(op->ptr, "action");
+
+ Object *ob = NULL;
+ Scene *scene= CTX_data_scene(C);
+ int multipaint = scene->toolsettings->multipaint;
if (action == SEL_TOGGLE) {
action= CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT : SEL_SELECT;
@@ -5091,6 +5100,11 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL);
+ if(multipaint) {
+ ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 806e288798f..6c721660e9c 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -657,22 +657,41 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
int *vertsflipped = NULL, *mask= NULL;
int a, totface, j, bbone, firstsegment, lastsegment;
+ MVert *mvert = me->mvert;
+ int use_vert_sel= FALSE;
+ int use_face_sel= FALSE;
+
*err_str= NULL;
/* count triangles and create mask */
- if(me->editflag & ME_EDIT_PAINT_MASK)
+ if( (use_face_sel= (me->editflag & ME_EDIT_PAINT_MASK) != 0) ||
+ (use_vert_sel= ((me->editflag & ME_EDIT_VERT_SEL) != 0)))
+ {
mask= MEM_callocN(sizeof(int)*me->totvert, "heat_bone_weighting mask");
+ }
for(totface=0, a=0, mface=me->mface; a<me->totface; a++, mface++) {
totface++;
if(mface->v4) totface++;
- if(mask && (mface->flag & ME_FACE_SEL)) {
- mask[mface->v1]= 1;
- mask[mface->v2]= 1;
- mask[mface->v3]= 1;
- if(mface->v4)
- mask[mface->v4]= 1;
+ /* (added selectedVerts content for vertex mask, they used to just equal 1) */
+ if(use_vert_sel) {
+ mask[mface->v1]= (mvert[mface->v1].flag & SELECT) != 0;
+ mask[mface->v2]= (mvert[mface->v2].flag & SELECT) != 0;
+ mask[mface->v3]= (mvert[mface->v3].flag & SELECT) != 0;
+ if(mface->v4) {
+ mask[mface->v4]= (mvert[mface->v4].flag & SELECT) != 0;
+ }
+ }
+ else {
+ if(use_face_sel) {
+ mask[mface->v1]= 1;
+ mask[mface->v2]= 1;
+ mask[mface->v3]= 1;
+ if(mface->v4) {
+ mask[mface->v4]= 1;
+ }
+ }
}
}
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 8bb77ad43a0..9709979ff6a 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -123,6 +123,8 @@ int EM_vertColorCheck(struct EditMesh *em);
void undo_push_mesh(struct bContext *C, const char *name);
+void paintvert_flush_flags(struct Object *ob);
+void paintvert_deselect_all_visible(struct Object *ob, int action, short flush_flags);
/* editmesh_lib.c */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index f8682d3935b..d574ddd3030 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -53,6 +53,7 @@ struct Scene;
struct View3D;
struct ViewContext;
struct wmWindow;
+struct MVert;
/* for derivedmesh drawing callbacks, for view3d_select, .... */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 095c90797f1..af515bf8061 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2138,6 +2138,18 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
//uiItemR(row, itemptr, "mute", 0, "", ICON_MUTE_IPO_OFF);
uiBlockSetEmboss(block, UI_EMBOSS);
}
+ else if(itemptr->type == &RNA_VertexGroup) {
+ bDeformGroup *dg= (bDeformGroup *)itemptr->data;
+ uiItemL(sub, name, icon);
+ /* RNA does not allow nice lock icons, use lower level buttons */
+#if 0
+ uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "lock_weight", 0, 0, 0, 0, 0, NULL);
+#else
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ uiDefIconButBitC(block, TOG, DG_LOCK_WEIGHT, 0, (dg->flag & DG_LOCK_WEIGHT) ? ICON_LOCKED : ICON_UNLOCKED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &dg->flag, 0, 0, 0, 0, "Maintain relative weights while painting");
+ uiBlockSetEmboss(block, UI_EMBOSS);
+#endif
+ }
else if(itemptr->type == &RNA_KeyingSetPath) {
KS_Path *ksp = (KS_Path*)itemptr->data;
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 3f5bc21814d..18db1c8c894 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -420,8 +420,8 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize)
/* check if we should restore aspect ratio (if view size changed) */
if (v2d->keepzoom & V2D_KEEPASPECT) {
- short do_x=0, do_y=0, do_cur, do_win;
- float curRatio, winRatio;
+ short do_x=0, do_y=0, do_cur /* , do_win */ /* UNUSED */;
+ float /* curRatio, */ /* UNUSED */ winRatio;
/* when a window edge changes, the aspect ratio can't be used to
* find which is the best new 'cur' rect. thats why it stores 'old'
@@ -429,7 +429,7 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize)
if (winx != v2d->oldwinx) do_x= 1;
if (winy != v2d->oldwiny) do_y= 1;
- curRatio= height / width;
+ /* curRatio= height / width; */ /* UNUSED */
winRatio= winy / winx;
/* both sizes change (area/region maximised) */
@@ -443,7 +443,7 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize)
else do_x= 1;
}
do_cur= do_x;
- do_win= do_y;
+ /* do_win= do_y; */ /* UNUSED */
if (do_cur) {
if ((v2d->keeptot == V2D_KEEPTOT_STRICT) && (winx != v2d->oldwinx)) {
diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c
index c56a4238239..6a263fca915 100644
--- a/source/blender/editors/mesh/editmesh.c
+++ b/source/blender/editors/mesh/editmesh.c
@@ -1958,3 +1958,101 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc)
vc->em= me->edit_mesh;
}
}
+
+
+/* (similar to void paintface_flush_flags(Object *ob))
+ * copy the vertex flags, most importantly selection from the mesh to the final derived mesh,
+ * use in object mode when selecting vertices (while painting) */
+void paintvert_flush_flags(Object *ob)
+{
+ Mesh *me= get_mesh(ob);
+ DerivedMesh *dm= ob->derivedFinal;
+ MVert *dm_mvert, *dm_mv;
+ int *index_array = NULL;
+ int totvert;
+ int i;
+
+ if(me==NULL || dm==NULL)
+ return;
+
+ index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
+
+ dm_mvert = dm->getVertArray(dm);
+ totvert = dm->getNumVerts(dm);
+
+ dm_mv= dm_mvert;
+
+ if(index_array) {
+ int orig_index;
+ for (i= 0; i<totvert; i++, dm_mv++) {
+ orig_index= index_array[i];
+ if(orig_index != ORIGINDEX_NONE) {
+ dm_mv->flag= me->mvert[index_array[i]].flag;
+ }
+ }
+ }
+ else {
+ for (i= 0; i<totvert; i++, dm_mv++) {
+ dm_mv->flag= me->mvert[i].flag;
+ }
+ }
+}
+/* note: if the caller passes FALSE to flush_flags, then they will need to run paintvert_flush_flags(ob) themselves */
+void paintvert_deselect_all_visible(Object *ob, int action, short flush_flags)
+{
+ Mesh *me;
+ MVert *mvert;
+ int a;
+
+ me= get_mesh(ob);
+ if(me==NULL) return;
+
+ if(action == SEL_INVERT) {
+ mvert= me->mvert;
+ a= me->totvert;
+ while(a--) {
+ if((mvert->flag & ME_HIDE) == 0) {
+ mvert->flag ^= SELECT;
+ }
+ mvert++;
+ }
+ }
+ else {
+ if (action == SEL_TOGGLE) {
+ action = SEL_SELECT;
+
+ mvert= me->mvert;
+ a= me->totvert;
+ while(a--) {
+ if((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
+ action = SEL_DESELECT;
+ break;
+ }
+ mvert++;
+ }
+ }
+
+ mvert= me->mvert;
+ a= me->totvert;
+ while(a--) {
+ if((mvert->flag & ME_HIDE) == 0) {
+ switch (action) {
+ case SEL_SELECT:
+ mvert->flag |= SELECT;
+ break;
+ case SEL_DESELECT:
+ mvert->flag &= ~SELECT;
+ break;
+ case SEL_INVERT:
+ mvert->flag ^= SELECT;
+ break;
+ }
+ }
+ mvert++;
+ }
+ }
+
+ if(flush_flags) {
+ paintvert_flush_flags(ob);
+ }
+}
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index 9783f25466e..8c035ca46fd 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -266,6 +266,7 @@ int EM_mask_init_backbuf_border(ViewContext *vc, int mcords[][2], short tot, sho
/* method in use for face selecting too */
if(vc->obedit==NULL) {
if(paint_facesel_test(vc->obact));
+ else if(paint_vertsel_test(vc->obact));
else return 0;
}
else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
@@ -328,6 +329,7 @@ int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
/* method in use for face selecting too */
if(vc->obedit==NULL) {
if(paint_facesel_test(vc->obact));
+ else if (paint_vertsel_test(vc->obact));
else return 0;
}
else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
@@ -1471,10 +1473,8 @@ static void EM_mesh_copy_face(EditMesh *em, wmOperator *op, short type)
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if (tf_act->tpage) {
tf->tpage = tf_act->tpage;
- tf->mode |= TF_TEX;
} else {
tf->tpage = NULL;
- tf->mode &= ~TF_TEX;
}
tf->tile= tf_act->tile;
change = 1;
@@ -1654,10 +1654,8 @@ void EM_mesh_copy_face_layer(EditMesh *em, wmOperator *op, short type)
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if (tf_from->tpage) {
tf->tpage = tf_from->tpage;
- tf->mode |= TF_TEX;
} else {
tf->tpage = NULL;
- tf->mode &= ~TF_TEX;
}
tf->tile= tf_from->tile;
change = 1;
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 5411f01bee4..ef52d9be0c3 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -238,7 +238,6 @@ int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mesh *me, const char *name, int active_set)
{
EditMesh *em;
- MCol *mcol;
int layernum;
if(me->edit_mesh) {
@@ -261,8 +260,6 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
if(layernum >= MAX_MCOL)
return 0;
- mcol= me->mcol;
-
if(me->mcol)
CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name);
else
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 32e52916b77..526bf177ab7 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -217,7 +217,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
if(me->totvert) {
/* Add this object's materials to the base one's if they don't exist already (but only if limits not exceeded yet) */
- if(totcol < MAXMAT-1) {
+ if(totcol < MAXMAT) {
for(a=1; a<=base->object->totcol; a++) {
ma= give_current_material(base->object, a);
@@ -231,7 +231,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
totcol++;
}
- if(totcol>=MAXMAT-1)
+ if(totcol >= MAXMAT)
break;
}
}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 3da0723ec18..434111c1227 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -200,6 +200,8 @@ void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_lock(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 57efc8c7dc9..452d1aded51 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -174,6 +174,8 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_copy);
WM_operatortype_append(OBJECT_OT_vertex_group_normalize);
WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all);
+ WM_operatortype_append(OBJECT_OT_vertex_group_lock);
+ WM_operatortype_append(OBJECT_OT_vertex_group_fix);
WM_operatortype_append(OBJECT_OT_vertex_group_invert);
WM_operatortype_append(OBJECT_OT_vertex_group_levels);
WM_operatortype_append(OBJECT_OT_vertex_group_blend);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 592205d2a31..797cf428969 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -49,6 +49,7 @@
#include "DNA_scene_types.h"
#include "DNA_particle_types.h"
+#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BLI_utildefines.h"
@@ -60,6 +61,7 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_report.h"
+#include "BKE_DerivedMesh.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -701,6 +703,10 @@ static void vgroup_normalize(Object *ob)
MDeformWeight *dw;
MDeformVert *dvert, **dvert_array=NULL;
int i, def_nr, dvert_tot=0;
+
+ Mesh *me = ob->data;
+ MVert *mvert = me->mvert;
+ const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
@@ -712,6 +718,11 @@ static void vgroup_normalize(Object *ob)
def_nr= ob->actdef-1;
for(i = 0; i < dvert_tot; i++) {
+
+ if(use_vert_sel && !(mvert[i].flag & SELECT)) {
+ continue;
+ }
+
dvert = dvert_array[i];
dw = defvert_find_index(dvert, def_nr);
if(dw) {
@@ -721,6 +732,11 @@ static void vgroup_normalize(Object *ob)
if(weight_max > 0.0f) {
for(i = 0; i < dvert_tot; i++) {
+
+ if(use_vert_sel && !(mvert[i].flag & SELECT)) {
+ continue;
+ }
+
dvert = dvert_array[i];
dw = defvert_find_index(dvert, def_nr);
if(dw) {
@@ -736,6 +752,401 @@ static void vgroup_normalize(Object *ob)
if (dvert_array) MEM_freeN(dvert_array);
}
+/* This adds the indices of vertices to a list if they are not already present
+It returns the number that it added (0-2)
+It relies on verts having -1 for unassigned indices
+*/
+static int tryToAddVerts(int *verts, int length, int a, int b) {
+ char containsA = FALSE;
+ char containsB = FALSE;
+ int added = 0;
+ int i;
+ for(i = 0; i < length && (!containsA || !containsB); i++) {
+ if(verts[i] == a) {
+ containsA = TRUE;
+ } else if(verts[i] == b) {
+ containsB = TRUE;
+ } else if(verts[i] == -1) {
+ if(!containsA) {
+ verts[i] = a;
+ containsA = TRUE;
+ added++;
+ } else if(!containsB){
+ verts[i] = b;
+ containsB = TRUE;
+ added++;
+ }
+ }
+ }
+ return added;
+}
+
+/* This finds all of the vertices connected to vert by an edge
+and returns an array of indices of size count
+
+count is an int passed by reference so it can be assigned the value of the length here.
+*/
+static int* getSurroundingVerts(Mesh *me, int vert, int *count) {
+ int length = 0;
+ int *tverts;
+ int *verts = NULL;
+ MFace *mf = me->mface;
+ int totface = me->totface;
+ int found = 0;
+ int i;
+ for(i = 0; i < totface; i++, mf++) {
+ if(vert == mf->v1 || vert == mf->v2 || vert == mf->v3 || (mf->v4 &&vert == mf->v4)) {
+ length+=2;
+ }
+ }
+ if(!length) {
+ return 0;
+ }
+ tverts = MEM_mallocN(sizeof(int)*length, "tempSurroundingVerts");
+ mf = me->mface;
+ for(i = 0; i < length; i++) {
+ tverts[i] = -1;
+ }
+ for(i = 0; i < totface; i++, mf++) {
+ int a=-1, b=-1;
+ if(mf->v1 == vert) {
+ a = mf->v2;
+ if(mf->v4) {
+ b = mf->v4;
+ } else {
+ b = mf->v3;
+ }
+ } else if(mf->v2 == vert) {
+ a = mf->v1;
+ b = mf->v3;
+ } else if(mf->v3 == vert) {
+ a = mf->v2;
+ if(mf->v4) {
+ b = mf->v4;
+ } else {
+ b = mf->v1;
+ }
+ } else if (mf->v4 && mf->v4 == vert){
+ a = mf->v1;
+ b = mf->v3;
+ } else {
+ continue;
+ }
+ found += tryToAddVerts(tverts, length, a, b);
+ }
+ if(found) {
+ verts = MEM_mallocN(sizeof(int)* found, "surroundingVerts");
+ for(i = 0; i < found; i++) {
+ verts[i] = tverts[i];
+ }
+ *count = found;
+ }
+ MEM_freeN(tverts);
+ return verts;
+}
+
+/* get a single point in space by averaging a point cloud (vectors of size 3)
+coord is the place the average is stored, points is the point cloud, count is the number of points in the cloud
+*/
+static void getSingleCoordinate(MVert *points, int count, float coord[3]) {
+ int i;
+ zero_v3(coord);
+ for(i = 0; i < count; i++) {
+ add_v3_v3(coord, points[i].co);
+ }
+ mul_v3_fl(coord, 1.0f/count);
+}
+
+/* find the closest point on a plane to another point and store it in dst */
+/* coord is a point on the plane */
+/* point is the point that you want the nearest of */
+/* norm is the plane's normal, and d is the last number in the plane equation 0 = ax + by + cz + d */
+static void getNearestPointOnPlane(const float norm[3], const float coord[3], const float point[3], float dst_r[3])
+{
+ float temp[3];
+ float dotprod;
+
+ sub_v3_v3v3(temp, point, coord);
+ dotprod= dot_v3v3(temp, norm);
+
+ dst_r[0] = point[0] - (norm[0] * dotprod);
+ dst_r[1] = point[1] - (norm[1] * dotprod);
+ dst_r[2] = point[2] - (norm[2] * dotprod);
+}
+
+/* distance of two vectors a and b of size length */
+static float distance(float* a, float *b, int length) {
+ int i;
+ float sum = 0;
+ for(i = 0; i < length; i++) {
+ sum += (b[i]-a[i])*(b[i]-a[i]);
+ }
+ return sqrt(sum);
+}
+
+/* given a plane and a start and end position,
+compute the amount of vertical distance relative to the plane and store it in dists,
+then get the horizontal and vertical change and store them in changes
+*/
+static void getVerticalAndHorizontalChange(float *norm, float d, float *coord, float *start, float distToStart, float *end, float (*changes)[2], float *dists, int index) {
+ // A=Q-((Q-P).N)N
+ // D = (a*x0 + b*y0 +c*z0 +d)
+ float projA[3] = {0}, projB[3] = {0};
+
+ getNearestPointOnPlane(norm, coord, start, projA);
+ getNearestPointOnPlane(norm, coord, end, projB);
+ // (vertical and horizontal refer to the plane's y and xz respectively)
+ // vertical distance
+ dists[index] = norm[0]*end[0] + norm[1]*end[1] + norm[2]*end[2] + d;
+ // vertical change
+ changes[index][0] = dists[index] - distToStart;
+ //printf("vc %f %f\n", distance(end, projB, 3)-distance(start, projA, 3), changes[index][0]);
+ // horizontal change
+ changes[index][1] = distance(projA, projB, 3);
+}
+
+// I need the derived mesh to be forgotten so the positions are recalculated with weight changes (see dm_deform_recalc)
+static void dm_deform_clear(DerivedMesh *dm, Object *ob) {
+ if(ob->derivedDeform && (ob->derivedDeform)==dm) {
+ ob->derivedDeform->needsFree = 1;
+ ob->derivedDeform->release(ob->derivedDeform);
+ ob->derivedDeform = NULL;
+ }
+ else if(dm) {
+ dm->needsFree = 1;
+ dm->release(dm);
+ }
+}
+
+// recalculate the deformation
+static DerivedMesh* dm_deform_recalc(Scene *scene, Object *ob) {
+ return mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+}
+
+/* by changing nonzero weights, try to move a vertex in me->mverts with index 'index' to distToBe distance away from the provided plane
+strength can change distToBe so that it moves towards distToBe by that percentage
+cp changes how much the weights are adjusted to check the distance
+
+index is the index of the vertex being moved
+norm and d are the plane's properties for the equation: ax + by + cz + d = 0
+coord is a point on the plane
+*/
+static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, int index, float norm[3], float coord[3], float d, float distToBe, float strength, float cp) {
+ DerivedMesh *dm;
+ MDeformWeight *dw;
+ MVert m;
+ MDeformVert *dvert = me->dvert+index;
+ int totweight = dvert->totweight;
+ float oldw = 0;
+ float oldPos[3] = {0};
+ float vc, hc, dist;
+ int i, k;
+ float (*changes)[2] = MEM_mallocN(sizeof(float *)*totweight*2, "vertHorzChange");
+ float *dists = MEM_mallocN(sizeof(float)*totweight, "distance");
+ int *upDown = MEM_callocN(sizeof(int)*totweight, "upDownTracker");// track if up or down moved it closer for each bone
+ int *dwIndices = MEM_callocN(sizeof(int)*totweight, "dwIndexTracker");
+ float distToStart;
+ int bestIndex = 0;
+ char wasChange;
+ char wasUp;
+ int lastIndex = -1;
+ float originalDistToBe = distToBe;
+ do {
+ wasChange = FALSE;
+ dm = dm_deform_recalc(scene, ob);
+ dm->getVert(dm, index, &m);
+ oldPos[0] = m.co[0];
+ oldPos[1] = m.co[1];
+ oldPos[2] = m.co[2];
+ distToStart = norm[0]*oldPos[0] + norm[1]*oldPos[1] + norm[2]*oldPos[2] + d;
+
+ if(distToBe == originalDistToBe) {
+ distToBe += distToStart - distToStart*strength;
+ }
+ for(i = 0; i < totweight; i++) {
+ dwIndices[i] = i;
+ dw = (dvert->dw+i);
+ vc = hc = 0;
+ if(!dw->weight) {
+ changes[i][0] = 0;
+ changes[i][1] = 0;
+ dists[i] = distToStart;
+ continue;
+ }
+ for(k = 0; k < 2; k++) {
+ if(dm) {
+ dm_deform_clear(dm, ob); dm = NULL;
+ }
+ oldw = dw->weight;
+ if(k) {
+ dw->weight *= 1+cp;
+ } else {
+ dw->weight /= 1+cp;
+ }
+ if(dw->weight == oldw) {
+ changes[i][0] = 0;
+ changes[i][1] = 0;
+ dists[i] = distToStart;
+ break;
+ }
+ if(dw->weight > 1) {
+ dw->weight = 1;
+ }
+ dm = dm_deform_recalc(scene, ob);
+ dm->getVert(dm, index, &m);
+ getVerticalAndHorizontalChange(norm, d, coord, oldPos, distToStart, m.co, changes, dists, i);
+ dw->weight = oldw;
+ if(!k) {
+ vc = changes[i][0];
+ hc = changes[i][1];
+ dist = dists[i];
+ } else {
+ if(fabs(dist - distToBe) < fabs(dists[i] - distToBe)) {
+ upDown[i] = 0;
+ changes[i][0] = vc;
+ changes[i][1] = hc;
+ dists[i] = dist;
+ } else {
+ upDown[i] = 1;
+ }
+ if(fabs(dists[i] - distToBe) > fabs(distToStart - distToBe)) {
+ changes[i][0] = 0;
+ changes[i][1] = 0;
+ dists[i] = distToStart;
+ }
+ }
+ }
+ }
+ // sort the changes by the vertical change
+ for(k = 0; k < totweight; k++) {
+ float tf;
+ int ti;
+ bestIndex = k;
+ for(i = k+1; i < totweight; i++) {
+ dist = dists[i];
+
+ if(fabs(dist) > fabs(dists[i])) {
+ bestIndex = i;
+ }
+ }
+ // switch with k
+ if(bestIndex != k) {
+ ti = upDown[k];
+ upDown[k] = upDown[bestIndex];
+ upDown[bestIndex] = ti;
+
+ ti = dwIndices[k];
+ dwIndices[k] = dwIndices[bestIndex];
+ dwIndices[bestIndex] = ti;
+
+ tf = changes[k][0];
+ changes[k][0] = changes[bestIndex][0];
+ changes[bestIndex][0] = tf;
+
+ tf = changes[k][1];
+ changes[k][1] = changes[bestIndex][1];
+ changes[bestIndex][1] = tf;
+
+ tf = dists[k];
+ dists[k] = dists[bestIndex];
+ dists[bestIndex] = tf;
+ }
+ }
+ bestIndex = -1;
+ // find the best change with an acceptable horizontal change
+ for(i = 0; i < totweight; i++) {
+ if(fabs(changes[i][0]) > fabs(changes[i][1]*2.0f)) {
+ bestIndex = i;
+ break;
+ }
+ }
+ if(bestIndex != -1) {
+ wasChange = TRUE;
+ // it is a good place to stop if it tries to move the opposite direction
+ // (relative to the plane) of last time
+ if(lastIndex != -1) {
+ if(wasUp != upDown[bestIndex]) {
+ wasChange = FALSE;
+ }
+ }
+ lastIndex = bestIndex;
+ wasUp = upDown[bestIndex];
+ dw = (dvert->dw+dwIndices[bestIndex]);
+ oldw = dw->weight;
+ if(upDown[bestIndex]) {
+ dw->weight *= 1+cp;
+ } else {
+ dw->weight /= 1+cp;
+ }
+ if(dw->weight > 1) {
+ dw->weight = 1;
+ }
+ if(oldw == dw->weight) {
+ wasChange = FALSE;
+ }
+ if(dm) {
+ dm_deform_clear(dm, ob); dm = NULL;
+ }
+ }
+ }while(wasChange && (distToStart-distToBe)/fabs(distToStart-distToBe) == (dists[bestIndex]-distToBe)/fabs(dists[bestIndex]-distToBe));
+ MEM_freeN(upDown);
+ MEM_freeN(changes);
+ MEM_freeN(dists);
+ MEM_freeN(dwIndices);
+}
+
+/* this is used to try to smooth a surface by only adjusting the nonzero weights of a vertex
+but it could be used to raise or lower an existing 'bump.' */
+static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength, float cp)
+{
+ int i;
+
+ Mesh *me = ob->data;
+ MVert *mvert = me->mvert;
+ const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
+ int *verts = NULL;
+ for(i = 0; i < me->totvert && mvert; i++, mvert++) {
+
+ if(use_vert_sel && (mvert->flag & SELECT)) {
+
+ int count=0;
+ if((verts = getSurroundingVerts(me, i, &count))) {
+ MVert m;
+ MVert *p = MEM_callocN(sizeof(MVert)*(count), "deformedPoints");
+ int k;
+
+ DerivedMesh *dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+ for(k = 0; k < count; k++) {
+ dm->getVert(dm, verts[k], &m);
+ p[k] = m;
+ }
+
+ if(count >= 3) {
+ float d /*, dist */ /* UNUSED */, mag;
+ float coord[3] = {0};
+ float norm[3] = {0};
+ getSingleCoordinate(p, count, coord);
+ dm->getVert(dm, i, &m);
+ norm[0] = m.co[0]-coord[0];
+ norm[1] = m.co[1]-coord[1];
+ norm[2] = m.co[2]-coord[2];
+ mag = sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
+ if(mag) {// zeros fix
+ mul_v3_fl(norm, 1.0f/mag);
+
+ d = -norm[0]*coord[0] -norm[1]*coord[1] -norm[2]*coord[2];
+ /* dist = (norm[0]*m.co[0] + norm[1]*m.co[1] + norm[2]*m.co[2] + d); */ /* UNUSED */
+ moveCloserToDistanceFromPlane(scene, ob, me, i, norm, coord, d, distToBe, strength, cp);
+ }
+ }
+
+ MEM_freeN(verts);
+ MEM_freeN(p);
+ }
+ }
+ }
+}
+
static void vgroup_levels(Object *ob, float offset, float gain)
{
bDeformGroup *dg;
@@ -743,6 +1154,10 @@ static void vgroup_levels(Object *ob, float offset, float gain)
MDeformVert *dvert, **dvert_array=NULL;
int i, def_nr, dvert_tot=0;
+ Mesh *me = ob->data;
+ MVert *mvert = me->mvert;
+ const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
+
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
dg = BLI_findlink(&ob->defbase, (ob->actdef-1));
@@ -751,6 +1166,11 @@ static void vgroup_levels(Object *ob, float offset, float gain)
def_nr= ob->actdef-1;
for(i = 0; i < dvert_tot; i++) {
+
+ if(use_vert_sel && !(mvert[i].flag & SELECT)) {
+ continue;
+ }
+
dvert = dvert_array[i];
dw = defvert_find_index(dvert, def_nr);
if(dw) {
@@ -772,6 +1192,11 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
int i, dvert_tot=0;
float tot_weight;
+
+ Mesh *me = ob->data;
+ MVert *mvert = me->mvert;
+ const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
+
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
if(dvert_array) {
@@ -781,6 +1206,10 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
for(i = 0; i < dvert_tot; i++) {
float lock_iweight= 1.0f;
int j;
+
+ if(use_vert_sel && !(mvert[i].flag & SELECT)) {
+ continue;
+ }
tot_weight= 0.0f;
dw_act= NULL;
@@ -821,6 +1250,11 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
else {
for(i = 0; i < dvert_tot; i++) {
int j;
+
+ if(use_vert_sel && !(mvert[i].flag & SELECT)) {
+ continue;
+ }
+
tot_weight= 0.0f;
dvert = dvert_array[i];
@@ -848,12 +1282,45 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
}
+static void vgroup_lock_all(Object *ob, int action)
+{
+ bDeformGroup *dg;
+
+ if(action == SEL_TOGGLE) {
+ action= SEL_SELECT;
+ for(dg= ob->defbase.first; dg; dg= dg->next) {
+ if(dg->flag & DG_LOCK_WEIGHT) {
+ action= SEL_DESELECT;
+ break;
+ }
+ }
+ }
+
+ for(dg= ob->defbase.first; dg; dg= dg->next) {
+ switch(action) {
+ case SEL_SELECT:
+ dg->flag |= DG_LOCK_WEIGHT;
+ break;
+ case SEL_DESELECT:
+ dg->flag &= ~DG_LOCK_WEIGHT;
+ break;
+ case SEL_INVERT:
+ dg->flag ^= DG_LOCK_WEIGHT;
+ break;
+ }
+ }
+}
+
static void vgroup_invert(Object *ob, int auto_assign, int auto_remove)
{
bDeformGroup *dg;
MDeformWeight *dw;
MDeformVert *dvert, **dvert_array=NULL;
int i, def_nr, dvert_tot=0;
+
+ Mesh *me = ob->data;
+ MVert *mvert = me->mvert;
+ const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
@@ -864,6 +1331,10 @@ static void vgroup_invert(Object *ob, int auto_assign, int auto_remove)
for(i = 0; i < dvert_tot; i++) {
+
+ if(use_vert_sel && !(mvert[i].flag & SELECT)) {
+ continue;
+ }
dvert = dvert_array[i];
if(auto_assign) {
@@ -976,6 +1447,10 @@ static void vgroup_clean(Object *ob, float eul, int keep_single)
MDeformWeight *dw;
MDeformVert *dvert, **dvert_array=NULL;
int i, def_nr, dvert_tot=0;
+
+ Mesh *me = ob->data;
+ MVert *mvert = me->mvert;
+ const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
@@ -985,6 +1460,10 @@ static void vgroup_clean(Object *ob, float eul, int keep_single)
def_nr= ob->actdef-1;
for(i = 0; i < dvert_tot; i++) {
+
+ if(use_vert_sel && !(mvert[i].flag & SELECT)) {
+ continue;
+ }
dvert = dvert_array[i];
dw= defvert_find_index(dvert, def_nr);
@@ -1006,12 +1485,21 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single)
MDeformWeight *dw;
MDeformVert *dvert, **dvert_array=NULL;
int i, dvert_tot=0;
+
+ Mesh *me = ob->data;
+ MVert *mvert = me->mvert;
+ const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
if(dvert_array) {
for(i = 0; i < dvert_tot; i++) {
int j;
+
+ if(use_vert_sel && !(mvert[i].flag & SELECT)) {
+ continue;
+ }
+
dvert = dvert_array[i];
j= dvert->totweight;
@@ -1832,6 +2320,82 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "lock_active", TRUE, "Lock Active", "Keep the values of the active group while normalizing others");
}
+static int vertex_group_fix_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_active_object(C);
+ Scene *scene= CTX_data_scene(C);
+
+ float distToBe= RNA_float_get(op->ptr, "dist");
+ float strength= RNA_float_get(op->ptr, "strength");
+ float cp= RNA_float_get(op->ptr, "accuracy");
+ ModifierData *md= ob->modifiers.first;
+
+ while(md) {
+ if(md->type == eModifierType_Mirror && (md->mode&eModifierMode_Realtime)) {
+ break;
+ }
+ md = md->next;
+ }
+
+ if(md && md->type == eModifierType_Mirror) {
+ BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "This operator does not support an active mirror modifier");
+ return OPERATOR_CANCELLED;
+ }
+ vgroup_fix(scene, ob, distToBe, strength, cp);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_fix(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Fix Vertex Group Deform";
+ ot->idname= "OBJECT_OT_vertex_group_fix";
+ ot->description= "Modify the position of selected vertices by changing only their respective groups' weights (this tool may be slow for many vertices).";
+
+ /* api callbacks */
+ ot->poll= vertex_group_poll;
+ ot->exec= vertex_group_fix_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+ RNA_def_float(ot->srna, "dist", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "The distance to move to.", -10.0f, 10.0f);
+ RNA_def_float(ot->srna, "strength", 1.f, -2.0f, FLT_MAX, "Strength", "The distance moved can be changed by this multiplier.", -2.0f, 2.0f);
+ RNA_def_float(ot->srna, "accuracy", 1.0f, 0.05f, FLT_MAX, "Change Sensitivity", "Changes the amount weights are altered with each iteration: lower values are slower.", 0.05f, 1.f);
+}
+
+
+static int vertex_group_lock_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_active_object(C);
+
+ int action = RNA_enum_get(op->ptr, "action");
+
+ vgroup_lock_all(ob, action);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_lock(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Change the Lock On Vertex Groups";
+ ot->idname= "OBJECT_OT_vertex_group_lock";
+
+ /* api callbacks */
+ ot->poll= vertex_group_poll;
+ ot->exec= vertex_group_lock_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ WM_operator_properties_select_all(ot);
+}
+
static int vertex_group_invert_exec(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 37c720ea43b..eb919261127 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -5409,6 +5409,15 @@ int facemask_paint_poll(bContext *C)
return paint_facesel_test(CTX_data_active_object(C));
}
+int vert_paint_poll(bContext *C)
+{
+ return paint_vertsel_test(CTX_data_active_object(C));
+}
+
+int mask_paint_poll(bContext *C)
+{
+ return paint_facesel_test(CTX_data_active_object(C)) || paint_vertsel_test(CTX_data_active_object(C));
+}
/* use project paint to re-apply an image */
static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
{
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 5a0ee19d6c9..f671b7b1713 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -122,6 +122,11 @@ void PAINT_OT_face_select_inverse(struct wmOperatorType *ot);
void PAINT_OT_face_select_hide(struct wmOperatorType *ot);
void PAINT_OT_face_select_reveal(struct wmOperatorType *ot);
+void PAINT_OT_vert_select_all(struct wmOperatorType *ot);
+void PAINT_OT_vert_select_inverse(struct wmOperatorType *ot);
+int vert_paint_poll(struct bContext *C);
+int mask_paint_poll(struct bContext *C);
+
int facemask_paint_poll(struct bContext *C);
/* stroke operator */
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 69af50415cc..287d204115c 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -373,6 +373,10 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_weight_sample);
WM_operatortype_append(PAINT_OT_weight_sample_group);
+ /* vertex selection */
+ WM_operatortype_append(PAINT_OT_vert_select_all);
+ WM_operatortype_append(PAINT_OT_vert_select_inverse);
+
/* vertex */
WM_operatortype_append(PAINT_OT_vertex_paint_toggle);
WM_operatortype_append(PAINT_OT_vertex_paint);
@@ -607,6 +611,17 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "PAINT_OT_weight_from_bones", WKEY, KM_PRESS, 0, 0);
+
+ /*Weight paint's Vertex Selection Mode */
+ keymap= WM_keymap_find(keyconf, "Weight Paint Vertex Selection", 0, 0);
+ keymap->poll= vert_paint_poll;
+ WM_keymap_add_item(keymap, "PAINT_OT_vert_select_all", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PAINT_OT_vert_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "deselect", 1);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0);
+
/* Image/Texture Paint mode */
keymap= WM_keymap_find(keyconf, "Image Paint", 0, 0);
keymap->poll= image_texture_paint_poll;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 33b8a7ca686..d332dc6ec0d 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -1,5 +1,5 @@
/*
- * $Id:
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -387,6 +387,49 @@ void PAINT_OT_face_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
+
+static int vert_select_all_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_active_object(C);
+ paintvert_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), TRUE);
+ ED_region_tag_redraw(CTX_wm_region(C));
+ return OPERATOR_FINISHED;
+}
+
+
+void PAINT_OT_vert_select_all(wmOperatorType *ot)
+{
+ ot->name= "Vertex Selection";
+ ot->description= "Change selection for all vertices";
+ ot->idname= "PAINT_OT_vert_select_all";
+
+ ot->exec= vert_select_all_exec;
+ ot->poll= vert_paint_poll;
+
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ WM_operator_properties_select_all(ot);
+}
+
+static int vert_select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob= CTX_data_active_object(C);
+ paintvert_deselect_all_visible(ob, SEL_INVERT, TRUE);
+ ED_region_tag_redraw(CTX_wm_region(C));
+ return OPERATOR_FINISHED;
+}
+
+void PAINT_OT_vert_select_inverse(wmOperatorType *ot)
+{
+ ot->name= "Vertex Select Invert";
+ ot->description= "Invert selection of vertices";
+ ot->idname= "PAINT_OT_vert_select_inverse";
+
+ ot->exec= vert_select_inverse_exec;
+ ot->poll= vert_paint_poll;
+
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
static int face_select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob= CTX_data_active_object(C);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index b2aa1be3b9f..11a46bb373b 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -64,6 +64,7 @@
#include "RNA_enum_types.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_armature.h"
#include "BKE_action.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -390,25 +391,27 @@ void vpaint_fill(Object *ob, unsigned int paintcol)
void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
{
Mesh *me;
- MFace *mface;
MDeformWeight *dw, *uw;
int *indexar;
- int index, vgroup;
- unsigned int faceverts[5]={0,0,0,0,0};
- unsigned char i;
- int vgroup_mirror= -1;
+ unsigned int index;
+ int vgroup, vgroup_mirror= -1;
int selected;
+ int use_vert_sel;
+
me= ob->data;
if(me==NULL || me->totface==0 || me->dvert==NULL || !me->mface) return;
selected= (me->editflag & ME_EDIT_PAINT_MASK);
+
+ use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
indexar= get_indexarray(me);
if(selected) {
- for(index=0, mface=me->mface; index<me->totface; index++, mface++) {
- if((mface->flag & ME_FACE_SEL)==0)
+ MFace *mf;
+ for(index=0, mf= me->mface; index<me->totface; index++, mf++) {
+ if((mf->flag & ME_FACE_SEL)==0)
indexar[index]= 0;
else
indexar[index]= index+1;
@@ -430,22 +433,25 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
for(index=0; index<me->totface; index++) {
if(indexar[index] && indexar[index]<=me->totface) {
- mface= me->mface + (indexar[index]-1);
- /* just so we can loop through the verts */
- faceverts[0]= mface->v1;
- faceverts[1]= mface->v2;
- faceverts[2]= mface->v3;
- faceverts[3]= mface->v4;
- for (i=0; i<3 || faceverts[i]; i++) {
- if(!((me->dvert+faceverts[i])->flag)) {
- dw= defvert_verify_index(me->dvert+faceverts[i], vgroup);
+ MFace *mf= &me->mface[indexar[index]-1];
+ unsigned int fidx= mf->v4 ? 3:2;
+
+ do {
+ unsigned int vidx= *(&mf->v1 + fidx);
+
+ if(!me->dvert[vidx].flag) {
+ if(use_vert_sel && !(me->mvert[vidx].flag & SELECT)) {
+ continue;
+ }
+
+ dw= defvert_verify_index(&me->dvert[vidx], vgroup);
if(dw) {
- uw= defvert_verify_index(wp->wpaint_prev+faceverts[i], vgroup);
+ uw= defvert_verify_index(wp->wpaint_prev+vidx, vgroup);
uw->weight= dw->weight; /* set the undo weight */
dw->weight= paintweight;
-
+
if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */
- int j= mesh_get_x_mirror_vert(ob, faceverts[i]);
+ int j= mesh_get_x_mirror_vert(ob, vidx);
if(j>=0) {
/* copy, not paint again */
if(vgroup_mirror != -1) {
@@ -460,16 +466,19 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
}
}
}
- (me->dvert+faceverts[i])->flag= 1;
+ me->dvert[vidx].flag= 1;
}
- }
+
+
+ } while (fidx--);
}
}
-
- index=0;
- while (index<me->totvert) {
- (me->dvert+index)->flag= 0;
- index++;
+
+ {
+ MDeformVert *dv= me->dvert;
+ for(index= me->totvert; index != 0; index--, dv++) {
+ dv->flag= 0;
+ }
}
MEM_freeN(indexar);
@@ -792,7 +801,7 @@ static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, float vpimat[][3], fl
return alpha;
}
-static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval, int flip)
+static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval, int flip, int multipaint)
{
Brush *brush = paint_brush(&wp->paint);
int tool = brush->vertexpaint_tool;
@@ -830,7 +839,10 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float
if (dw->weight > paintval)
dw->weight = paintval*alpha + dw->weight*(1.0f-alpha);
}
- CLAMP(dw->weight, 0.0f, 1.0f);
+ /* delay clamping until the end so multi-paint can function when the active group is at the limits */
+ if(multipaint == FALSE) {
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
/* if no spray, clip result with orig weight & orig alpha */
if((wp->flag & VP_SPRAY)==0) {
@@ -857,15 +869,17 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float
else
testw = uw->weight;
}
- CLAMP(testw, 0.0f, 1.0f);
-
- if( testw<uw->weight ) {
- if(dw->weight < testw) dw->weight= testw;
- else if(dw->weight > uw->weight) dw->weight= uw->weight;
- }
- else {
- if(dw->weight > testw) dw->weight= testw;
- else if(dw->weight < uw->weight) dw->weight= uw->weight;
+
+ if(multipaint == FALSE) {
+ CLAMP(testw, 0.0f, 1.0f);
+ if( testw<uw->weight ) {
+ if(dw->weight < testw) dw->weight= testw;
+ else if(dw->weight > uw->weight) dw->weight= uw->weight;
+ }
+ else {
+ if(dw->weight > testw) dw->weight= testw;
+ else if(dw->weight < uw->weight) dw->weight= uw->weight;
+ }
}
}
@@ -980,7 +994,7 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
const int totgroup= BLI_countlist(&vc.obact->defbase);
if(totgroup) {
MFace *mf= ((MFace *)me->mface) + index-1;
- int fidx= mf->v4 ? 3:2;
+ unsigned int fidx= mf->v4 ? 3:2;
int *groups= MEM_callocN(totgroup*sizeof(int), "groups");
int found= FALSE;
@@ -1062,6 +1076,7 @@ void PAINT_OT_weight_sample_group(wmOperatorType *ot)
}
+#if 0 /* UNUSED */
static void do_weight_paint_auto_normalize(MDeformVert *dvert,
int paint_nr, char *map)
{
@@ -1096,41 +1111,600 @@ static void do_weight_paint_auto_normalize(MDeformVert *dvert,
}
}
}
+#endif
+
+/* the active group should be involved in auto normalize */
+static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, char *map, char do_auto_normalize)
+{
+// MDeformWeight *dw = dvert->dw;
+ float sum=0.0f, fac=0.0f;
+ int i, tot=0;
+
+ if (do_auto_normalize == FALSE)
+ return;
+
+ for (i=0; i<dvert->totweight; i++) {
+ if (map[dvert->dw[i].def_nr]) {
+ tot += 1;
+ sum += dvert->dw[i].weight;
+ }
+ }
+
+ if (!tot || sum == 1.0f)
+ return;
+
+ fac = sum;
+ fac = fac==0.0f ? 1.0f : 1.0f / fac;
+
+ for (i=0; i<dvert->totweight; i++) {
+ if (map[dvert->dw[i].def_nr]) {
+ dvert->dw[i].weight *= fac;
+ }
+ }
+}
+
+/*
+See if the current deform vertex has a locked group
+*/
+static char has_locked_group(MDeformVert *dvert, const char *lock_flags)
+{
+ int i;
+ for(i = 0; i < dvert->totweight; i++) {
+ if(lock_flags[dvert->dw[i].def_nr] && dvert->dw[i].weight > 0.0f) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+/*
+ * gen_lck_flags gets the status of "flag" for each bDeformGroup
+ *in ob->defbase and returns an array containing them
+ */
+static char *gen_lock_flags(Object* ob, int defbase_tot)
+{
+ char is_locked = FALSE;
+ int i;
+ //int defbase_tot = BLI_countlist(&ob->defbase);
+ char *lock_flags = MEM_mallocN(defbase_tot*sizeof(char), "defflags");
+ bDeformGroup *defgroup;
+
+ for(i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
+ lock_flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0);
+ is_locked |= lock_flags[i];
+ }
+ if(is_locked){
+ return lock_flags;
+ }
+
+ MEM_freeN(lock_flags);
+ return NULL;
+}
+
+static int has_locked_group_selected(int defbase_tot, char *defbase_sel, char *lock_flags)
+{
+ int i;
+ for(i = 0; i < defbase_tot; i++) {
+ if(defbase_sel[i] && lock_flags[i]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+#if 0 /* UNUSED */
+static int has_unselected_unlocked_bone_group(int defbase_tot, char *defbase_sel, int selected, char *lock_flags, char *vgroup_validmap)
+{
+ int i;
+ if(defbase_tot == selected) {
+ return FALSE;
+ }
+ for(i = 0; i < defbase_tot; i++) {
+ if(vgroup_validmap[i] && !defbase_sel[i] && !lock_flags[i]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+#endif
+
+
+static void multipaint_selection(MDeformVert *dvert, float change, char *defbase_sel, int defbase_tot)
+{
+ int i;
+ MDeformWeight *dw;
+ float val;
+ /* make sure they are all at most 1 after the change */
+ for(i = 0; i < defbase_tot; i++) {
+ if(defbase_sel[i]) {
+ dw = defvert_find_index(dvert, i);
+ if(dw && dw->weight) {
+ val = dw->weight * change;
+ if(val > 1) {
+ /* TODO: when the change is reduced, you need to recheck
+ * the earlier values to make sure they are not 0
+ * (precision error) */
+ change = 1.0f/dw->weight;
+ }
+ /* the value should never reach zero while multi-painting if it
+ * was nonzero beforehand */
+ if(val <= 0) {
+ return;
+ }
+ }
+ }
+ }
+ /* apply the valid change */
+ for(i = 0; i < defbase_tot; i++) {
+ if(defbase_sel[i]) {
+ dw = defvert_find_index(dvert, i);
+ if(dw && dw->weight) {
+ dw->weight = dw->weight * change;
+ }
+ }
+ }
+}
+
+/* move all change onto valid, unchanged groups. If there is change left over,
+ * then return it.
+ * assumes there are valid groups to shift weight onto */
+static float redistribute_change(MDeformVert *ndv, char *change_status, int changeme, int changeto, float totchange, float total_valid, char do_auto_normalize)
+{
+ float was_change;
+ float change;
+ float oldval;
+ MDeformWeight *ndw;
+ int i;
+ do {
+ /* assume there is no change until you see one */
+ was_change = FALSE;
+ /* change each group by the same amount each time */
+ change = totchange/total_valid;
+ for(i = 0; i < ndv->totweight && total_valid && totchange; i++) {
+ ndw = (ndv->dw+i);
+ /* change only the groups with a valid status */
+ if(change_status[ndw->def_nr] == changeme) {
+ oldval = ndw->weight;
+ /* if auto normalize is active, don't worry about upper bounds */
+ if(do_auto_normalize == FALSE && ndw->weight + change > 1) {
+ totchange -= 1-ndw->weight;
+ ndw->weight = 1;
+ /* stop the changes to this group */
+ change_status[ndw->def_nr] = changeto;
+ total_valid--;
+ }
+ else if(ndw->weight + change < 0) { /* check the lower bound */
+ totchange -= ndw->weight;
+ ndw->weight = 0;
+ change_status[ndw->def_nr] = changeto;
+ total_valid--;
+ }
+ else {/* a perfectly valid change occurred to ndw->weight */
+ totchange -= change;
+ ndw->weight += change;
+ }
+ /* see if there was a change */
+ if(oldval != ndw->weight) {
+ was_change = TRUE;
+ }
+ }
+ }
+ /* don't go again if there was no change, if there is no valid group,
+ * or there is no change left */
+ } while(was_change && total_valid && totchange);
+ /* left overs */
+ return totchange;
+}
+
+/* observe the changes made to the weights of groups.
+ * make sure all locked groups on the vertex have the same deformation
+ * by moving the changes made to groups onto other unlocked groups */
+static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defbase_tot,
+ const char *lock_flags, const char *vgroup_validmap, char do_auto_normalize)
+{
+ float totchange = 0.0f;
+ float totchange_allowed = 0.0f;
+ float left_over;
+
+ int total_valid = 0;
+ int total_changed = 0;
+ unsigned int i;
+ MDeformWeight *ndw;
+ MDeformWeight *odw;
+ MDeformWeight *ndw2;
+ MDeformWeight *odw2;
+ int designatedw = -1;
+ int designatedw_changed = FALSE;
+ float storedw;
+ char *change_status;
+ char new_weight_has_zero = FALSE;
+
+ if(!lock_flags || !has_locked_group(ndv, lock_flags)) {
+ return;
+ }
+ /* record if a group was changed, unlocked and not changed, or locked */
+ change_status = MEM_callocN(sizeof(char)*defbase_tot, "unlocked_unchanged");
+
+ for(i = 0; i < defbase_tot; i++) {
+ ndw = defvert_find_index(ndv, i);
+ odw = defvert_find_index(odv, i);
+ /* the weights are zero, so we can assume a lot */
+ if(!ndw || !odw) {
+ if (!lock_flags[i] && vgroup_validmap[i]){
+ defvert_verify_index(odv, i);
+ defvert_verify_index(ndv, i);
+ total_valid++;
+ change_status[i] = 1; /* can be altered while redistributing */
+ }
+ continue;
+ }
+ /* locked groups should not be changed */
+ if(lock_flags[i]) {
+ ndw->weight = odw->weight;
+ }
+ else if(ndw->weight != odw->weight) { /* changed groups are handled here */
+ totchange += ndw->weight - odw->weight;
+ change_status[i] = 2; /* was altered already */
+ total_changed++;
+ if(ndw->weight == 0) {
+ new_weight_has_zero = TRUE;
+ }
+ else if(designatedw == -1){
+ designatedw = i;
+ }
+ } /* unchanged, unlocked bone groups are handled here */
+ else if (vgroup_validmap[i]){
+ totchange_allowed += ndw->weight;
+ total_valid++;
+ change_status[i] = 1; /* can be altered while redistributing */
+ }
+ }
+ /* if there was any change, redistribute it */
+ if(total_changed) {
+ /* auto normalize will allow weights to temporarily go above 1 in redistribution */
+ if(vgroup_validmap && total_changed < 0 && total_valid) {
+ totchange_allowed = total_valid;
+ }
+ /* there needs to be change allowed, or you should not bother */
+ if(totchange_allowed) {
+ /* the way you modify the unlocked+unchanged groups is different depending
+ * on whether or not you are painting the weight(s) up or down */
+ if(totchange < 0) {
+ totchange_allowed = total_valid - totchange_allowed;
+ }
+ else {
+ totchange_allowed *= -1;
+ }
+ left_over = 0;
+ if(fabsf(totchange_allowed) < fabsf(totchange)) {
+ /* this amount goes back onto the changed, unlocked weights */
+ left_over = fabsf(fabsf(totchange) - fabsf(totchange_allowed));
+ if(totchange > 0) {
+ left_over *= -1;
+ }
+ }
+ else {
+ /* all of the change will be permitted */
+ totchange_allowed = -totchange;
+ }
+ /* move the weight evenly between the allowed groups, move excess back onto the used groups based on the change */
+ totchange_allowed = redistribute_change(ndv, change_status, 1, -1, totchange_allowed, total_valid, do_auto_normalize);
+ left_over += totchange_allowed;
+ if(left_over) {
+ /* more than one nonzero weights were changed with the same ratio, so keep them changed that way! */
+ if(total_changed > 1 && !new_weight_has_zero && designatedw >= 0) {
+ /* this dw is special, it is used as a base to determine how to change the others */
+ ndw = defvert_find_index(ndv, designatedw);
+ odw = defvert_find_index(odv, designatedw);
+ storedw = ndw->weight;
+ for(i = 0; i < ndv->totweight; i++) {
+ if(change_status[ndw->def_nr] == 2) {
+ odw2 = &odv->dw[i];
+ ndw2 = &ndv->dw[i];
+ if(!designatedw_changed) {
+ ndw->weight = (totchange_allowed + odw->weight + odw2->weight)/(1.0f + ndw2->weight/ndw->weight);
+ designatedw_changed = TRUE;
+ }
+ ndw2->weight = ndw->weight * ndw2->weight / storedw;
+ }
+ }
+ }
+ /* a weight was changed to zero, only one weight was changed,
+ * or designatedw is still -1 put weight back as evenly as possible */
+ else {
+ redistribute_change(ndv, change_status, 2, -2, left_over, total_changed, do_auto_normalize);
+ }
+ }
+ }
+ else {
+ /* reset the weights */
+ unsigned int i;
+ MDeformWeight *dw_old= odv->dw;
+ MDeformWeight *dw_new= ndv->dw;
+
+ for (i= odv->totweight; i != 0; i--, dw_old++, dw_new++) {
+ dw_new->weight= dw_old->weight;
+ }
+ }
+ }
+
+ MEM_freeN(change_status);
+}
-static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index,
- float alpha, float paintweight, int flip,
- int vgroup_mirror, char *validmap)
+/* multi-paint's initial, potential change is computed here based on the user's stroke */
+static float get_mp_change(MDeformVert *odv, char *defbase_sel, float brush_change)
+{
+ float selwsum = 0.0f;
+ unsigned int i;
+ MDeformWeight *dw= odv->dw;
+
+ for (i= odv->totweight; i != 0; i--, dw++) {
+ if(defbase_sel[dw->def_nr]) {
+ selwsum += dw->weight;
+ }
+ }
+ if(selwsum && selwsum+brush_change > 0) {
+ return (selwsum+brush_change)/selwsum;
+ }
+ return 0.0f;
+}
+
+/* change the weights back to the wv's weights
+ * it assumes you already have the correct pointer index */
+static void reset_to_prev(MDeformVert *wv, MDeformVert *dvert)
+{
+ MDeformWeight *dw= dvert->dw;
+ MDeformWeight *w;
+ unsigned int i;
+ for (i= dvert->totweight; i != 0; i--, dw++) {
+ w= defvert_find_index(wv, dw->def_nr);
+ /* if there was no w when there is a d, then the old weight was 0 */
+ dw->weight = w ? w->weight : 0.0f;
+ }
+}
+
+static void clamp_weights(MDeformVert *dvert)
+{
+ MDeformWeight *dw= dvert->dw;
+ unsigned int i;
+ for (i= dvert->totweight; i != 0; i--, dw++) {
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
+}
+
+/* struct to avoid passing many args each call to do_weight_paint_vertex()
+ * this _could_ be made a part of the operators 'WPaintData' struct, or at
+ * least a member, but for now keep its own struct, initialized on every
+ * paint stroke update - campbell */
+typedef struct WeightPaintInfo {
+
+ int defbase_tot;
+
+ /* both must add up to 'defbase_tot' */
+ int defbase_tot_sel;
+ int defbase_tot_unsel;
+
+ int vgroup_mirror; /* mirror group or -1 */
+
+ char *lock_flags; /* boolean array for locked bones,
+ * length of defbase_tot */
+ char *defbase_sel; /* boolean array for selected bones,
+ * length of defbase_tot */
+
+ char *vgroup_validmap; /* same as WeightPaintData.vgroup_validmap,
+ * only added here for convenience */
+
+ char do_flip;
+ char do_multipaint;
+ char do_auto_normalize;
+} WeightPaintInfo;
+
+/* fresh start to make multi-paint and locking modular */
+/* returns TRUE if it thinks you need to reset the weights due to
+ * normalizing while multi-painting */
+static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi,
+ const unsigned int index,
+ MDeformWeight *dw, MDeformWeight *tdw,
+ float change, float oldChange,
+ float oldw, float neww)
+{
+ MDeformVert *dv= &me->dvert[index];
+ MDeformVert dv_test= {NULL};
+
+ dv_test.dw= MEM_dupallocN(dv->dw);
+ dv_test.flag = dv->flag;
+ dv_test.totweight = dv->totweight;
+ /* do not multi-paint if a locked group is selected or the active group is locked
+ * !lock_flags[dw->def_nr] helps if nothing is selected, but active group is locked */
+ if( (wpi->lock_flags == NULL) ||
+ ((wpi->lock_flags[dw->def_nr] == FALSE) &&
+ has_locked_group_selected(wpi->defbase_tot, wpi->defbase_sel, wpi->lock_flags) == FALSE))
+ {
+ if(wpi->do_multipaint && wpi->defbase_tot_sel > 1) {
+ if(change && change!=1) {
+ multipaint_selection(dv, change, wpi->defbase_sel, wpi->defbase_tot);
+ }
+ }
+ else { /* this lets users paint normally, but don't let them paint locked groups */
+ dw->weight = neww;
+ }
+ }
+ clamp_weights(dv);
+
+ enforce_locks(&dv_test, dv, wpi->defbase_tot, wpi->lock_flags, wpi->vgroup_validmap, wpi->do_auto_normalize);
+
+ do_weight_paint_auto_normalize_all_groups(dv, wpi->vgroup_validmap, wpi->do_auto_normalize);
+
+ if(oldChange && wpi->do_multipaint && wpi->defbase_tot_sel > 1) {
+ if(tdw->weight != oldw) {
+ if(neww > oldw) {
+ if(tdw->weight <= oldw) {
+ MEM_freeN(dv_test.dw);
+ return TRUE;
+ }
+ }
+ else {
+ if(tdw->weight >= oldw) {
+ MEM_freeN(dv_test.dw);
+ return TRUE;
+ }
+ }
+ }
+ }
+ MEM_freeN(dv_test.dw);
+ return FALSE;
+}
+
+/* within the current dvert index, get the dw that is selected and has a weight
+ * above 0, this helps multi-paint */
+static int get_first_selected_nonzero_weight(MDeformVert *dvert, char *defbase_sel)
+{
+ int i;
+ MDeformWeight *dw= dvert->dw;
+ for(i=0; i< dvert->totweight; i++, dw++) {
+ if(defbase_sel[dw->def_nr] && dw->weight > 0.0f) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+static char *wpaint_make_validmap(Object *ob);
+
+
+static void do_weight_paint_vertex( /* vars which remain the same for every vert */
+ VPaint *wp, Object *ob, const WeightPaintInfo *wpi,
+ /* vars which change on each stroke */
+ const unsigned int index, float alpha, float paintweight
+ )
{
Mesh *me= ob->data;
+
MDeformWeight *dw, *uw;
int vgroup= ob->actdef-1;
-
+
if(wp->flag & VP_ONLYVGROUP) {
- dw= defvert_find_index(me->dvert+index, vgroup);
+ dw= defvert_find_index(&me->dvert[index], vgroup);
uw= defvert_find_index(wp->wpaint_prev+index, vgroup);
}
else {
- dw= defvert_verify_index(me->dvert+index, vgroup);
+ dw= defvert_verify_index(&me->dvert[index], vgroup);
uw= defvert_verify_index(wp->wpaint_prev+index, vgroup);
}
if(dw==NULL || uw==NULL)
return;
-
- wpaint_blend(wp, dw, uw, alpha, paintweight, flip);
- do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap);
- if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */
- int j= mesh_get_x_mirror_vert(ob, index);
- if(j>=0) {
- /* copy, not paint again */
- if(vgroup_mirror != -1)
- uw= defvert_verify_index(me->dvert+j, vgroup_mirror);
- else
- uw= defvert_verify_index(me->dvert+j, vgroup);
-
- uw->weight= dw->weight;
+ /* TODO: De-duplicate the simple weight paint - jason */
+ /* ... or not, since its <10 SLOC - campbell */
+
+ /* If there are no locks or multipaint,
+ * then there is no need to run the more complicated checks */
+ if( (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) &&
+ (wpi->lock_flags == NULL || has_locked_group(&me->dvert[index], wpi->lock_flags) == FALSE))
+ {
+ wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, FALSE);
+ do_weight_paint_auto_normalize_all_groups(&me->dvert[index], wpi->vgroup_validmap, wpi->do_auto_normalize);
+
+ if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */
+ int j= mesh_get_x_mirror_vert(ob, index);
+ if(j>=0) {
+ /* copy, not paint again */
+ uw= defvert_verify_index(me->dvert+j, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup);
+
+ uw->weight= dw->weight;
- do_weight_paint_auto_normalize(me->dvert+j, vgroup, validmap);
+ do_weight_paint_auto_normalize_all_groups(me->dvert+j, wpi->vgroup_validmap, wpi->do_auto_normalize);
+ }
+ }
+ }
+ else {
+ /* use locks and/or multipaint */
+ float oldw;
+ float neww;
+ float testw=0;
+ float change = 0;
+ float oldChange = 0;
+ int i;
+ MDeformWeight *tdw = NULL, *tuw;
+ MDeformVert dv= {NULL};
+
+ oldw = dw->weight;
+ wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, wpi->do_multipaint && wpi->defbase_tot_sel >1);
+ neww = dw->weight;
+ dw->weight = oldw;
+
+ /* setup multi-paint */
+ if(wpi->defbase_tot_sel > 1 && wpi->do_multipaint) {
+ dv.dw= MEM_dupallocN(me->dvert[index].dw);
+ dv.flag = me->dvert[index].flag;
+ dv.totweight = me->dvert[index].totweight;
+ tdw = dw;
+ tuw = uw;
+ change = get_mp_change(wp->wpaint_prev+index, wpi->defbase_sel, neww - oldw);
+ if(change) {
+ if(!tdw->weight) {
+ i = get_first_selected_nonzero_weight(&me->dvert[index], wpi->defbase_sel);
+ if(i>=0) {
+ tdw = &(me->dvert[index].dw[i]);
+ tuw = defvert_verify_index(wp->wpaint_prev+index, tdw->def_nr);
+ }
+ else {
+ change = 0;
+ }
+ }
+ if(change && tuw->weight && tuw->weight * change) {
+ if(tdw->weight != tuw->weight) {
+ oldChange = tdw->weight/tuw->weight;
+ testw = tuw->weight*change;
+ if( testw > tuw->weight ) {
+ if(change > oldChange) {
+ /* reset the weights and use the new change */
+ reset_to_prev(wp->wpaint_prev+index, &me->dvert[index]);
+ }
+ else {
+ /* the old change was more significant, so set
+ * the change to 0 so that it will not do another multi-paint */
+ change = 0;
+ }
+ }
+ else {
+ if(change < oldChange) {
+ reset_to_prev(wp->wpaint_prev+index, &me->dvert[index]);
+ }
+ else {
+ change = 0;
+ }
+ }
+ }
+ }
+ else {
+ change = 0;
+ }
+ }
+ }
+
+ if(apply_mp_locks_normalize(me, wpi, index, dw, tdw, change, oldChange, oldw, neww)) {
+ reset_to_prev(&dv, &me->dvert[index]);
+ change = 0;
+ oldChange = 0;
+ }
+ if(dv.dw) {
+ MEM_freeN(dv.dw);
+ }
+ /* dvert may have been altered greatly */
+ dw = defvert_find_index(&me->dvert[index], vgroup);
+
+ if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */
+ int j= mesh_get_x_mirror_vert(ob, index);
+ if(j>=0) {
+ /* copy, not paint again */
+ uw= defvert_verify_index(me->dvert+j, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup);
+
+ //uw->weight= dw->weight;
+
+ apply_mp_locks_normalize(me, wpi, j, uw, tdw, change, oldChange, oldw, neww);
+ }
}
}
}
@@ -1227,16 +1801,15 @@ struct WPaintData {
/*variables for auto normalize*/
int auto_normalize;
char *vgroup_validmap; /*stores if vgroups tie to deforming bones or not*/
+ char *lock_flags;
+ int defbase_tot;
};
static char *wpaint_make_validmap(Object *ob)
{
bDeformGroup *dg;
ModifierData *md;
- char *validmap;
- bPose *pose;
- bPoseChannel *chan;
- ArmatureModifierData *amd;
+ char *vgroup_validmap;
GHash *gh = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wpaint_make_validmap gh");
int i = 0, step1=1;
@@ -1248,7 +1821,7 @@ static char *wpaint_make_validmap(Object *ob)
if (!i)
return NULL;
- validmap = MEM_callocN(i, "wpaint valid map");
+ vgroup_validmap= MEM_callocN(i, "wpaint valid map");
/*now loop through the armature modifiers and identify deform bones*/
for (md = ob->modifiers.first; md; md= !md->next && step1 ? (step1=0), modifiers_getVirtualModifierList(ob) : md->next) {
@@ -1257,10 +1830,11 @@ static char *wpaint_make_validmap(Object *ob)
if (md->type == eModifierType_Armature)
{
- amd = (ArmatureModifierData*) md;
+ ArmatureModifierData *amd= (ArmatureModifierData*) md;
if(amd->object && amd->object->pose) {
- pose = amd->object->pose;
+ bPose *pose= amd->object->pose;
+ bPoseChannel *chan;
for (chan=pose->chanbase.first; chan; chan=chan->next) {
if (chan->bone->flag & BONE_NO_DEFORM)
@@ -1278,13 +1852,13 @@ static char *wpaint_make_validmap(Object *ob)
/*add all names to a hash table*/
for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
if (BLI_ghash_lookup(gh, dg->name) != NULL) {
- validmap[i] = 1;
+ vgroup_validmap[i] = TRUE;
}
}
BLI_ghash_free(gh, NULL, NULL);
- return validmap;
+ return vgroup_validmap;
}
static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
@@ -1318,7 +1892,9 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
/*set up auto-normalize, and generate map for detecting which
vgroups affect deform bones*/
wpd->auto_normalize = ts->auto_normalize;
- if (wpd->auto_normalize)
+ wpd->defbase_tot = BLI_countlist(&ob->defbase);
+ wpd->lock_flags = gen_lock_flags(ob, wpd->defbase_tot);
+ if (wpd->auto_normalize || ts->multipaint || wpd->lock_flags)
wpd->vgroup_validmap = wpaint_make_validmap(ob);
// if(qual & LR_CTRLKEY) {
@@ -1385,14 +1961,19 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
float mat[4][4];
float paintweight;
int *indexar;
- int totindex, index, totw, flip;
+ int totw;
+ unsigned int index, totindex;
float alpha;
float mval[2], pressure;
-
+ int use_vert_sel;
+
+ /* intentionally dont initialize as NULL, make sure we initialize all members below */
+ WeightPaintInfo wpi;
+
/* cannot paint if there is no stroke data */
if (wpd == NULL) {
- // XXX: force a redraw here, since even though we can't paint,
- // at least view won't freeze until stroke ends
+ /* XXX: force a redraw here, since even though we can't paint,
+ * at least view won't freeze until stroke ends */
ED_region_tag_redraw(CTX_wm_region(C));
return;
}
@@ -1407,17 +1988,39 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* load projection matrix */
mul_m4_m4m4(mat, ob->obmat, vc->rv3d->persmat);
- flip = RNA_boolean_get(itemptr, "pen_flip");
pressure = RNA_float_get(itemptr, "pressure");
RNA_float_get_array(itemptr, "mouse", mval);
mval[0]-= vc->ar->winrct.xmin;
mval[1]-= vc->ar->winrct.ymin;
-
+
+
+
+ /* *** setup WeightPaintInfo - pass onto do_weight_paint_vertex *** */
+ wpi.defbase_tot= wpd->defbase_tot;
+ wpi.defbase_sel= MEM_mallocN(wpi.defbase_tot*sizeof(char), "wpi.defbase_sel");
+ wpi.defbase_tot_sel= get_selected_defgroups(ob, wpi.defbase_sel, wpi.defbase_tot);
+ if(wpi.defbase_tot_sel == 0 && ob->actdef) wpi.defbase_tot_sel = 1;
+ wpi.defbase_tot_unsel= wpi.defbase_tot - wpi.defbase_tot_sel;
+ wpi.vgroup_mirror= wpd->vgroup_mirror;
+ wpi.lock_flags= wpd->lock_flags;
+ wpi.vgroup_validmap= wpd->vgroup_validmap;
+ wpi.do_flip= RNA_boolean_get(itemptr, "pen_flip");
+ wpi.do_multipaint= (ts->multipaint != 0);
+ wpi.do_auto_normalize= (ts->auto_normalize != 0);
+ /* *** done setting up WeightPaintInfo *** */
+
+
+
swap_m4m4(wpd->vc.rv3d->persmat, mat);
-
+
+ use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
+
/* which faces are involved */
if(wp->flag & VP_AREA) {
+ /* Ugly hack, to avoid drawing vertex index when getting the face index buffer - campbell */
+ me->editflag &= ~ME_EDIT_VERT_SEL;
totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size(brush));
+ me->editflag |= use_vert_sel ? ME_EDIT_VERT_SEL : 0;
}
else {
indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]);
@@ -1460,30 +2063,40 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
for(index=0; index<totindex; index++) {
if(indexar[index] && indexar[index]<=me->totface) {
MFace *mface= me->mface + (indexar[index]-1);
-
- (me->dvert+mface->v1)->flag= 1;
- (me->dvert+mface->v2)->flag= 1;
- (me->dvert+mface->v3)->flag= 1;
- if(mface->v4) (me->dvert+mface->v4)->flag= 1;
+
+ if(use_vert_sel) {
+ me->dvert[mface->v1].flag = (me->mvert[mface->v1].flag & SELECT);
+ me->dvert[mface->v2].flag = (me->mvert[mface->v2].flag & SELECT);
+ me->dvert[mface->v3].flag = (me->mvert[mface->v3].flag & SELECT);
+ if(mface->v4) me->dvert[mface->v4].flag = (me->mvert[mface->v4].flag & SELECT);
+ }
+ else {
+ me->dvert[mface->v1].flag= 1;
+ me->dvert[mface->v2].flag= 1;
+ me->dvert[mface->v3].flag= 1;
+ if(mface->v4) me->dvert[mface->v4].flag= 1;
+ }
if(brush->vertexpaint_tool==VP_BLUR) {
MDeformWeight *dw, *(*dw_func)(MDeformVert *, const int);
+ unsigned int fidx= mface->v4 ? 3:2;
if(wp->flag & VP_ONLYVGROUP)
dw_func= (MDeformWeight *(*)(MDeformVert *, const int))defvert_find_index;
else
dw_func= defvert_verify_index;
-
- dw= dw_func(me->dvert+mface->v1, ob->actdef-1);
- if(dw) {paintweight+= dw->weight; totw++;}
- dw= dw_func(me->dvert+mface->v2, ob->actdef-1);
- if(dw) {paintweight+= dw->weight; totw++;}
- dw= dw_func(me->dvert+mface->v3, ob->actdef-1);
- if(dw) {paintweight+= dw->weight; totw++;}
- if(mface->v4) {
- dw= dw_func(me->dvert+mface->v4, ob->actdef-1);
- if(dw) {paintweight+= dw->weight; totw++;}
- }
+
+ do {
+ unsigned int vidx= *(&mface->v1 + fidx);
+
+ dw= dw_func(me->dvert+vidx, ob->actdef-1);
+ if(dw) {
+ paintweight+= dw->weight;
+ totw++;
+ }
+
+ } while (fidx--);
+
}
}
}
@@ -1494,52 +2107,28 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
for(index=0; index<totindex; index++) {
if(indexar[index] && indexar[index]<=me->totface) {
- MFace *mface= me->mface + (indexar[index]-1);
-
- if((me->dvert+mface->v1)->flag) {
- alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v1, mval, pressure);
- if(alpha) {
- do_weight_paint_vertex(wp, ob, mface->v1,
- alpha, paintweight, flip, wpd->vgroup_mirror,
- wpd->vgroup_validmap);
- }
- (me->dvert+mface->v1)->flag= 0;
- }
-
- if((me->dvert+mface->v2)->flag) {
- alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v2, mval, pressure);
- if(alpha) {
- do_weight_paint_vertex(wp, ob, mface->v2,
- alpha, paintweight, flip, wpd->vgroup_mirror,
- wpd->vgroup_validmap);
- }
- (me->dvert+mface->v2)->flag= 0;
- }
-
- if((me->dvert+mface->v3)->flag) {
- alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v3, mval, pressure);
- if(alpha) {
- do_weight_paint_vertex(wp, ob, mface->v3,
- alpha, paintweight, flip, wpd->vgroup_mirror,
- wpd->vgroup_validmap);
- }
- (me->dvert+mface->v3)->flag= 0;
- }
-
- if((me->dvert+mface->v4)->flag) {
- if(mface->v4) {
- alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v4, mval, pressure);
+ MFace *mf= me->mface + (indexar[index]-1);
+ unsigned int fidx= mf->v4 ? 3:2;;
+ do {
+ unsigned int vidx= *(&mf->v1 + fidx);
+
+ if(me->dvert[vidx].flag) {
+ alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*vidx, mval, pressure);
if(alpha) {
- do_weight_paint_vertex(wp, ob, mface->v4,
- alpha, paintweight, flip, wpd->vgroup_mirror,
- wpd->vgroup_validmap);
+ do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight);
}
- (me->dvert+mface->v4)->flag= 0;
+ me->dvert[vidx].flag= 0;
}
- }
+ } while (fidx--);
}
}
-
+
+
+ /* *** free wpi members */
+ MEM_freeN(wpi.defbase_sel);
+ /* *** dont freeing wpi members */
+
+
swap_m4m4(vc->rv3d->persmat, mat);
DAG_id_tag_update(ob->data, 0);
@@ -1559,7 +2148,9 @@ static void wpaint_stroke_done(bContext *C, struct PaintStroke *stroke)
if (wpd->vgroup_validmap)
MEM_freeN(wpd->vgroup_validmap);
-
+ if(wpd->lock_flags)
+ MEM_freeN(wpd->lock_flags);
+
MEM_freeN(wpd);
}
@@ -1633,7 +2224,7 @@ static int weight_paint_set_exec(bContext *C, wmOperator *UNUSED(op))
Object *obact = CTX_data_active_object(C);
wpaint_fill(scene->toolsettings->wpaint, obact, scene->toolsettings->vgroup_weight);
- ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
+ ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */
return OPERATOR_FINISHED;
}
@@ -1645,7 +2236,7 @@ void PAINT_OT_weight_set(wmOperatorType *ot)
/* api callbacks */
ot->exec= weight_paint_set_exec;
- ot->poll= facemask_paint_poll;
+ ot->poll= mask_paint_poll; /* it was facemask_paint_poll */
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1781,12 +2372,12 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent
return 1;
}
-static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, int index, const float mval[2], float pressure, int UNUSED(flip))
+static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, const unsigned int index, const float mval[2], float pressure, int UNUSED(flip))
{
ViewContext *vc = &vpd->vc;
Brush *brush = paint_brush(&vp->paint);
Mesh *me = get_mesh(ob);
- MFace *mface= ((MFace*)me->mface) + index;
+ MFace *mface= &me->mface[index];
unsigned int *mcol= ((unsigned int*)me->mcol) + 4*index;
unsigned int *mcolorig= ((unsigned int*)vp->vpaint_prev) + 4*index;
float alpha;
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 539e975095e..5b72e87f95a 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -436,7 +436,7 @@ static void mixdown_draw(bContext *C, wmOperator *op)
}
#endif // WITH_AUDASPACE
-void SOUND_OT_mixdown(wmOperatorType *ot)
+static void SOUND_OT_mixdown(wmOperatorType *ot)
{
#ifdef WITH_AUDASPACE
static EnumPropertyItem format_items[] = {
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 32594e710a4..dc81fb1e8bc 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -1139,7 +1139,7 @@ static void mouse_action_keys (bAnimContext *ac, const int mval[2], short select
static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
bAnimContext ac;
- ARegion *ar;
+ /* ARegion *ar; */ /* UNUSED */
short selectmode, column;
/* get editor data */
@@ -1147,7 +1147,7 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *even
return OPERATOR_CANCELLED;
/* get useful pointers from animation context data */
- ar= ac.ar;
+ /* ar= ac.ar; */ /* UNUSED */
/* select mode is either replace (deselect all, then add) or add/extend */
if (RNA_boolean_get(op->ptr, "extend"))
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index afab4ede229..e345caf1359 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -595,7 +595,7 @@ static void image_refresh(const bContext *C, ScrArea *UNUSED(sa))
tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */
- if(tf && (tf->mode & TF_TEX)) {
+ if(tf) {
/* don't need to check for pin here, see above */
sima->image= tf->tpage;
diff --git a/source/blender/editors/space_logic/logic_ops.c b/source/blender/editors/space_logic/logic_ops.c
index 60e9595b77a..b7f9af09348 100644
--- a/source/blender/editors/space_logic/logic_ops.c
+++ b/source/blender/editors/space_logic/logic_ops.c
@@ -43,6 +43,7 @@
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_sca.h"
+#include "BKE_material.h" //for texface convert
#include "ED_logic.h"
#include "ED_object.h"
@@ -57,6 +58,11 @@
#include "logic_intern.h"
+// temporary new includes for texface functions
+#include "DNA_mesh_types.h"
+#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
+
/* ************* Generic Operator Helpers ************* */
static int edit_sensor_poll(bContext *C)
{
@@ -687,6 +693,36 @@ static void LOGIC_OT_actuator_move(wmOperatorType *ot)
RNA_def_enum(ot->srna, "direction", logicbricks_move_direction, 1, "Direction", "Move Up or Down");
}
+/* ************* TexFace Converter Operator ************* */
+static int texface_convert_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Main *bmain= CTX_data_main(C);
+ do_version_tface(bmain, 0);
+
+ return OPERATOR_FINISHED;
+}
+
+static int texface_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ return texface_convert_exec(C, op);
+}
+
+ static void LOGIC_OT_texface_convert(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "TexFace to Material Converter";
+ ot->description = "Convert old texface settings into material. It may create new materials if needed";
+ ot->idname= "LOGIC_OT_texface_convert";
+
+ /* api callbacks */
+ ot->invoke= texface_convert_invoke;
+ ot->exec= texface_convert_exec;
+// ot->poll= texface_convert_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
void ED_operatortypes_logic(void)
{
@@ -699,4 +735,5 @@ void ED_operatortypes_logic(void)
WM_operatortype_append(LOGIC_OT_actuator_remove);
WM_operatortype_append(LOGIC_OT_actuator_add);
WM_operatortype_append(LOGIC_OT_actuator_move);
+ WM_operatortype_append(LOGIC_OT_texface_convert);
}
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index 5ea7f357ecf..05d38a63109 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -606,8 +606,8 @@ static void mouse_nla_strips (bContext *C, bAnimContext *ac, const int mval[2],
static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
bAnimContext ac;
- Scene *scene;
- ARegion *ar;
+ /* Scene *scene; */ /* UNUSED */
+ /* ARegion *ar; */ /* UNUSED */
// View2D *v2d; /*UNUSED*/
short selectmode;
@@ -616,8 +616,8 @@ static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *even
return OPERATOR_CANCELLED;
/* get useful pointers from animation context data */
- scene= ac.scene;
- ar= ac.ar;
+ /* scene= ac.scene; */ /* UNUSED */
+ /* ar= ac.ar; */ /* UNUSED */
// v2d= &ar->v2d;
/* select mode is either replace (deselect all, then add) or add/extend */
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index cd521f7e8c7..f34cef4d2aa 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -179,6 +179,7 @@ static void node_socket_button_color(const bContext *C, uiBlock *block,
/* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */
+#if 0 /* UNUSED */
static void node_draw_socket_new(bNodeSocket *sock, float size)
{
float x=sock->locx, y=sock->locy;
@@ -216,6 +217,7 @@ static void node_draw_socket_new(bNodeSocket *sock, float size)
glDisable( GL_LINE_SMOOTH );
glDisable(GL_BLEND);
}
+#endif
/* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
@@ -894,14 +896,14 @@ static void node_browse_text_cb(bContext *C, void *ntree_v, void *node_v)
Main *bmain= CTX_data_main(C);
bNodeTree *ntree= ntree_v;
bNode *node= node_v;
- ID *oldid;
+ /* ID *oldid; */ /* UNUSED */
if(node->menunr<1) return;
if(node->id) {
node->id->us--;
}
- oldid= node->id;
+ /* oldid= node->id; */ /* UNUSED */
node->id= BLI_findlink(&bmain->text, node->menunr-1);
id_us_plus(node->id);
BLI_strncpy(node->name, node->id->name+2, sizeof(node->name));
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index a966caa4d70..7cb8351cd12 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -757,6 +757,8 @@ void ED_node_update_hierarchy(bContext *UNUSED(C), bNodeTree *ntree)
/* ***************** generic operator functions for nodes ***************** */
+#if 0 /* UNUSED */
+
static int edit_node_poll(bContext *C)
{
return ED_operator_node_active(C);
@@ -815,6 +817,7 @@ static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **r
if (rin_out)
*rin_out = in_out;
}
+#endif
/* ***************** Edit Group operator ************* */
@@ -902,7 +905,7 @@ static int node_group_socket_add_exec(bContext *C, wmOperator *op)
char name[32]= "";
int type= SOCK_FLOAT;
bNodeTree *ngroup= snode->edittree;
- bNodeSocket *sock;
+ /* bNodeSocket *sock; */ /* UNUSED */
ED_preview_kill_jobs(C);
@@ -918,7 +921,7 @@ static int node_group_socket_add_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
/* using placeholder subtype first */
- sock = node_group_add_socket(ngroup, name, type, in_out);
+ /* sock = */ /* UNUSED */ node_group_add_socket(ngroup, name, type, in_out);
ntreeUpdateTree(ngroup);
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index ca9ecf2c328..e2b0b9c65d0 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -109,7 +109,7 @@ static int node_select_exec(bContext *C, wmOperator *op)
ARegion *ar= CTX_wm_region(C);
int mval[2];
short extend;
- bNode *node= NULL;
+ /* bNode *node= NULL; */ /* UNUSED */
/* get settings from RNA properties for operator */
mval[0] = RNA_int_get(op->ptr, "mouse_x");
@@ -118,7 +118,7 @@ static int node_select_exec(bContext *C, wmOperator *op)
extend = RNA_boolean_get(op->ptr, "extend");
/* perform the select */
- node= node_mouse_select(bmain, snode, ar, mval, extend);
+ /* node= */ /* UNUSED*/ node_mouse_select(bmain, snode, ar, mval, extend);
/* send notifiers */
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
diff --git a/source/blender/editors/space_node/node_state.c b/source/blender/editors/space_node/node_state.c
index c4567bea648..13a5f3cb3dc 100644
--- a/source/blender/editors/space_node/node_state.c
+++ b/source/blender/editors/space_node/node_state.c
@@ -214,12 +214,11 @@ void NODE_OT_visibility_toggle(wmOperatorType *ot)
static void snode_home(ScrArea *UNUSED(sa), ARegion *ar, SpaceNode* snode)
{
bNode *node;
- rctf *cur, *tot;
+ rctf *cur;
float oldwidth, oldheight, width, height;
int first= 1;
cur= &ar->v2d.cur;
- tot= &ar->v2d.tot;
oldwidth= cur->xmax - cur->xmin;
oldheight= cur->ymax - cur->ymin;
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 68b2d3d586f..6bfe370d105 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -969,7 +969,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
ListBase hierarchy = {NULL, NULL};
LinkData *ld;
TreeElement *tem, *temnext, *temsub;
- TreeStoreElem *tse, *tsenext;
+ TreeStoreElem *tse /* , *tsenext */ /* UNUSED */;
PointerRNA *ptr, *nextptr;
PropertyRNA *prop;
char *newpath=NULL;
@@ -1018,7 +1018,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
char buf[128], *name;
temnext= (TreeElement*)(ld->next->data);
- tsenext= TREESTORE(temnext);
+ /* tsenext= TREESTORE(temnext); */ /* UNUSED */
nextptr= &temnext->rnaptr;
name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf));
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 0a1f7a3599d..9fe0ed0543f 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1151,7 +1151,7 @@ static int need_add_seq_dup(Sequence *seq)
static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *te, short index)
{
- TreeElement *ch;
+ /* TreeElement *ch; */ /* UNUSED */
Sequence *p;
p= seq;
@@ -1162,7 +1162,7 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t
}
if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name))
- ch= outliner_add_element(soops, &te->subtree, (void*)p, te, TSE_SEQUENCE, index);
+ /* ch= */ /* UNUSED */ outliner_add_element(soops, &te->subtree, (void*)p, te, TSE_SEQUENCE, index);
p= p->next;
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index da769184669..bd93a1270f6 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1483,9 +1483,13 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op)
sort_seq(scene);
}
- WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
-
- return OPERATOR_FINISHED;
+ if(changed) {
+ WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 3d49bc7ffa0..685b15aed50 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -1291,7 +1291,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
TextLine *tmp;
char *docs, buf[DOC_WIDTH+1], *p;
int i, br, lines;
- int boxw, boxh, l, x, y, top;
+ int boxw, boxh, l, x, y /* , top */ /* UNUSED */;
if(!st || !st->text) return;
if(!texttool_text_is_active(st->text)) return;
@@ -1314,7 +1314,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
x += SUGG_LIST_WIDTH*st->cwidth + 50;
}
- top= y= ar->winy - st->lheight*l - 2;
+ /* top= */ /* UNUSED */ y= ar->winy - st->lheight*l - 2;
boxw= DOC_WIDTH*st->cwidth + 20;
boxh= (DOC_HEIGHT+1)*st->lheight;
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 6e02ecbd5a8..b6e76885719 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -64,6 +64,7 @@
#include "GPU_buffers.h"
#include "GPU_extensions.h"
#include "GPU_draw.h"
+#include "GPU_material.h"
#include "ED_mesh.h"
@@ -207,44 +208,71 @@ static Material *give_current_material_or_def(Object *ob, int matnr)
return ma?ma:&defmaterial;
}
-static int set_draw_settings_cached(int clearcache, int textured, MTFace *texface, int lit, Object *litob, int litmatnr, int doublesided)
+/* Icky globals, fix with userdata parameter */
+
+static struct TextureDrawState {
+ Object *ob;
+ int islit, istex;
+ int color_profile;
+ unsigned char obcol[4];
+} Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
+
+static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
{
+ static Material *c_ma;
static int c_textured;
- static int c_lit;
- static int c_doublesided;
static MTFace *c_texface;
- static Object *c_litob;
- static int c_litmatnr;
+ static int c_backculled;
static int c_badtex;
+ static int c_lit;
+ Object *litob = NULL; //to get mode to turn off mipmap in painting mode
+ int backculled = 0;
+ int alphablend = 0;
+ int textured = 0;
+ int lit = 0;
+
if (clearcache) {
- c_textured= c_lit= c_doublesided= -1;
+ c_textured= c_lit= c_backculled= -1;
c_texface= (MTFace*) -1;
- c_litob= (Object*) -1;
- c_litmatnr= -1;
c_badtex= 0;
+ } else {
+ textured = gtexdraw.istex;
+ litob = gtexdraw.ob;
+ }
+
+ /* convert number of lights into boolean */
+ if (gtexdraw.islit) lit = 1;
+
+ if (ma) {
+ alphablend = ma->game.alpha_blend;
+ if (ma->mode & MA_SHLESS) lit = 0;
+ backculled = ma->game.flag & GEMAT_BACKCULL;
}
if (texface) {
- lit = lit && (lit==-1 || texface->mode&TF_LIGHT);
- textured = textured && (texface->mode&TF_TEX);
- doublesided = texface->mode&TF_TWOSIDE;
- } else {
- textured = 0;
+ textured = textured && (texface->tpage);
+
+ /* no material, render alpha if texture has depth=32 */
+ if (!ma && BKE_image_has_alpha(texface->tpage))
+ alphablend = GPU_BLEND_ALPHA;
}
- if (doublesided!=c_doublesided) {
- if (doublesided) glDisable(GL_CULL_FACE);
- else glEnable(GL_CULL_FACE);
+ else
+ textured = 0;
+
+ if (backculled!=c_backculled) {
+ if (backculled) glEnable(GL_CULL_FACE);
+ else glDisable(GL_CULL_FACE);
- c_doublesided= doublesided;
+ c_backculled= backculled;
}
if (textured!=c_textured || texface!=c_texface) {
if (textured ) {
- c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT));
+ c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
} else {
- GPU_set_tpage(NULL, 0);
+ GPU_set_tpage(NULL, 0, 0);
c_badtex= 0;
}
c_textured= textured;
@@ -252,10 +280,10 @@ static int set_draw_settings_cached(int clearcache, int textured, MTFace *texfac
}
if (c_badtex) lit= 0;
- if (lit!=c_lit || litob!=c_litob || litmatnr!=c_litmatnr) {
+ if (lit!=c_lit || ma!=c_ma) {
if (lit) {
- Material *ma= give_current_material_or_def(litob, litmatnr+1);
float spec[4];
+ if (!ma)ma= give_current_material_or_def(NULL, 0); //default material
spec[0]= ma->spec*ma->specr;
spec[1]= ma->spec*ma->specg;
@@ -273,22 +301,11 @@ static int set_draw_settings_cached(int clearcache, int textured, MTFace *texfac
glDisable(GL_COLOR_MATERIAL);
}
c_lit= lit;
- c_litob= litob;
- c_litmatnr= litmatnr;
}
return c_badtex;
}
-/* Icky globals, fix with userdata parameter */
-
-static struct TextureDrawState {
- Object *ob;
- int islit, istex;
- int color_profile;
- unsigned char obcol[4];
-} Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
-
static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
{
unsigned char obcol[4];
@@ -318,14 +335,14 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
Gtexdraw.istex = istex;
Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
- set_draw_settings_cached(1, 0, NULL, Gtexdraw.islit, NULL, 0, 0);
+ set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
glShadeModel(GL_SMOOTH);
}
static void draw_textured_end(void)
{
/* switch off textures */
- GPU_set_tpage(NULL, 0);
+ GPU_set_tpage(NULL, 0, 0);
glShadeModel(GL_FLAT);
glDisable(GL_CULL_FACE);
@@ -347,18 +364,22 @@ static void draw_textured_end(void)
static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr)
{
- if (tface && (tface->mode&TF_INVISIBLE)) return 0;
+ Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
+ int validtexture=0;
+
+ if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
+
+ validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
- if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
+ if (tface && validtexture) {
glColor3ub(0xFF, 0x00, 0xFF);
return 2; /* Don't set color */
- } else if (tface && tface->mode&TF_OBCOL) {
+ } else if (ma && ma->shade_flag&MA_OBCOLOR) {
glColor3ubv(Gtexdraw.obcol);
return 2; /* Don't set color */
} else if (!mcol) {
if (tface) glColor3f(1.0, 1.0, 1.0);
else {
- Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
if(ma) {
float col[3];
if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
@@ -375,9 +396,11 @@ static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr)
}
static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
{
- if (tface && (tface->mode&TF_INVISIBLE)) return 0;
+ Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
+
+ if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
- if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
+ if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
return 2; /* Don't set color */
} else if (tface && tface->mode&TF_OBCOL) {
return 2; /* Don't set color */
@@ -399,7 +422,9 @@ static void add_tface_color_layer(DerivedMesh *dm)
finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
for(i=0;i<dm->getNumFaces(dm);i++) {
- if (tface && (tface->mode&TF_INVISIBLE)) {
+ Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
+
+ if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
if( mcol )
memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
else
@@ -409,7 +434,7 @@ static void add_tface_color_layer(DerivedMesh *dm)
finalCol[i*4+j].r = 255;
}
}
- else if (tface && mface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, mface[i].mat_nr, TF_TWOSIDE)) {
+ else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
for(j=0;j<4;j++) {
finalCol[i*4+j].b = 255;
finalCol[i*4+j].g = 0;
@@ -494,10 +519,13 @@ static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmoot
{
Mesh *me = (Mesh*)userData;
- if ( (me->mface && me->mface[index].flag & ME_HIDE) ||
- (me->mtface && (me->mtface[index].mode & TF_INVISIBLE))
- ) {
- return 0;
+ if (me->mface) {
+ short matnr= me->mface[index].mat_nr;
+ Material *ma= me->mat[matnr];
+
+ if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
+ return 0;
+ }
}
*drawSmooth_r = 1;
@@ -523,17 +551,18 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
if(ob->mode & OB_MODE_EDIT)
return;
else if(ob==OBACT)
- if(paint_facesel_test(ob))
+ if(paint_facesel_test(ob) || paint_vertsel_test(ob))
return;
ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
- int mode= tface->mode;
- int matnr= mf->mat_nr;
+ short matnr= mf->mat_nr;
int mf_smooth= mf->flag & ME_SMOOTH;
+ Material *mat = me->mat[matnr];
+ int mode= mat->game.flag;
- if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) {
+ if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
float v1[3], v2[3], v3[3], v4[3];
char string[MAX_PROPSTRING];
int characters, i, glattrib= -1, badtex= 0;
@@ -549,7 +578,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
}
}
else {
- badtex = set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE);
+ badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
if (badtex) {
if (mcol) mcol+=4;
continue;
@@ -578,7 +607,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
glNormal3fv(nor);
}
- GPU_render_text(tface, tface->mode, string, characters,
+ GPU_render_text(tface, mode, string, characters,
(unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
}
if (mcol) {
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 0e8e6cdfee1..44d68ded679 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -220,16 +220,13 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID);
}
-static int check_material_alpha(Base *base, Mesh *me, int glsl)
+static int check_material_alpha(Base *base, int glsl)
{
if(base->flag & OB_FROMDUPLI)
return 0;
if(G.f & G_PICKSEL)
return 0;
-
- if(me->edit_mesh)
- return 0;
return (glsl || (base->object->dtx & OB_DRAWTRANSP));
}
@@ -1740,6 +1737,31 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe
dm->release(dm);
}
+/* draw callback */
+static void drawSelectedVertices__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
+{
+ MVert *mv = &((MVert *)userData)[index];
+
+ if(!(mv->flag & ME_HIDE)) {
+ const char sel= mv->flag & SELECT;
+
+ // TODO define selected color
+ if(sel) {
+ glColor3f(1.0f, 1.0f, 0.0f);
+ }
+ else {
+ glColor3f(0.0f, 0.0f, 0.0f);
+ }
+
+ glVertex3fv(co);
+ }
+}
+
+static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) {
+ glBegin(GL_POINTS);
+ dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, me->mvert);
+ glEnd();
+}
static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
{
struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData;
@@ -2924,7 +2946,16 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
bglPolygonOffset(rv3d->dist, 0.0);
}
}
-
+
+ if(paint_vertsel_test(ob)) {
+
+ glColor3f(0.0f, 0.0f, 0.0f);
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ drawSelectedVertices(dm, ob->data);
+
+ glPointSize(1.0f);
+ }
dm->release(dm);
}
@@ -2964,12 +2995,16 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
scene->customdata_mask);
if(dt>OB_WIRE) {
- // no transp in editmode, the fancy draw over goes bad then
glsl = draw_glsl_material(scene, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+ check_alpha = check_material_alpha(base, glsl);
+
+ GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
+ (check_alpha)? &do_alpha_pass: NULL);
}
- draw_em_fancy(scene, v3d, rv3d, ob, em, cageDM, finalDM, dt);
+ // transp in editmode makes the fancy draw over go bad
+ if (!do_alpha_pass)
+ draw_em_fancy(scene, v3d, rv3d, ob, em, cageDM, finalDM, dt);
GPU_end_object_materials();
@@ -2980,7 +3015,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
/* don't create boundbox here with mesh_get_bb(), the derived system will make it, puts deformed bb's OK */
if(me->totface<=4 || ED_view3d_boundbox_clip(rv3d, ob->obmat, (ob->bb)? ob->bb: me->bb)) {
glsl = draw_glsl_material(scene, ob, v3d, dt);
- check_alpha = check_material_alpha(base, me, glsl);
+ check_alpha = check_material_alpha(base, glsl);
if(dt==OB_SOLID || glsl) {
GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
@@ -4022,7 +4057,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(draw_as==PART_DRAW_PATH){
ParticleCacheKey **cache, *path;
- float *cd2=NULL,*cdata2=NULL;
+ float /* *cd2=NULL, */ /* UNUSED */ *cdata2=NULL;
/* setup gl flags */
if (1) { //ob_dt > OB_WIRE) {
@@ -4090,7 +4125,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(cdata2)
MEM_freeN(cdata2);
- cd2=cdata2=NULL;
+ /* cd2= */ /* UNUSED */ cdata2=NULL;
glLineWidth(1.0f);
@@ -6516,6 +6551,32 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
/* ***************** BACKBUF SEL (BBS) ********* */
+static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
+{
+ struct {void* offset; MVert *mvert;} *data = userData;
+ MVert *mv = &data->mvert[index];
+ int offset = (intptr_t) data->offset;
+
+ if (!(mv->flag & ME_HIDE)) {
+ WM_set_framebuffer_index_color(offset+index);
+ bglVertex3fv(co);
+ }
+}
+
+static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
+{
+ struct {void* offset; struct MVert *mvert;} data;
+ Mesh *me = ob->data;
+ MVert *mvert = me->mvert;
+ data.mvert = mvert;
+ data.offset = (void*)(intptr_t) offset;
+ glPointSize( UI_GetThemeValuef(TH_VERTEX_SIZE) );
+ bglBegin(GL_POINTS);
+ dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data);
+ bglEnd();
+ glPointSize(1.0);
+}
+
static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
{
int offset = (intptr_t) userData;
@@ -6614,6 +6675,17 @@ static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *UNUS
}
}
+// must have called WM_set_framebuffer_index_color beforehand
+static int bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index, int *UNUSED(drawSmooth_r))
+{
+ Mesh *me = userData;
+
+ if (!(me->mface[index].flag & ME_HIDE)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
static void bbs_mesh_solid(Scene *scene, Object *ob)
{
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
@@ -6672,7 +6744,21 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
EM_free_index_arrays();
}
else {
- bbs_mesh_solid(scene, ob);
+ Mesh *me= ob->data;
+ if(me->editflag & ME_EDIT_VERT_SEL) {
+ DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
+ glColor3ub(0, 0, 0);
+
+ dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, me, 0, GPU_enable_material, NULL);
+
+
+ bbs_obmode_mesh_verts(ob, dm, 1);
+ em_vertoffs = me->totvert+1;
+ dm->release(dm);
+ }
+ else {
+ bbs_mesh_solid(scene, ob);
+ }
}
break;
case OB_CURVE:
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index 8da6f49e089..e87ace19edb 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -183,7 +183,7 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3
float viewnormal[3];
int i, j, n, good_index;
- float d, d0, dd, ds;
+ float d /*, d0 */ /* UNUSED */, dd, ds;
float *points = NULL;
int numpoints = 0;
float cor[3] = {1.,1.,1.};
@@ -390,7 +390,8 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3
// (a,b,c), the plane normal, are given by viewdir
// d is the parameter along the view direction. the first d is given by
// inserting previously found vertex into the plane equation
- d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]);
+
+ /* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */
ds = (ABS(viewnormal[0])*size[0] + ABS(viewnormal[1])*size[1] + ABS(viewnormal[2])*size[2]);
dd = 0.05; // ds/512.0f;
n = 0;
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 6833dec2e43..c46b6b6d70b 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -371,6 +371,10 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
keymap= WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Weight Paint Vertex Selection", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
/* pose is not modal, operator poll checks for this */
keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 2f2e2c5c282..0854f9f3685 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -2786,7 +2786,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot)
ot->flag= 0;
RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "The Type of view");
- RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active objects axis");
+ RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis");
}
static EnumPropertyItem prop_view_orbit_items[] = {
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 55b30aec804..0776ca752a9 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -516,7 +516,15 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
PointerRNA meshptr;
RNA_pointer_create(&ob->id, &RNA_Mesh, ob->data, &meshptr);
- uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ if(ob->mode & (OB_MODE_TEXTURE_PAINT|OB_MODE_VERTEX_PAINT)) {
+ uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ }
+ else {
+
+ row= uiLayoutRow(layout, 1);
+ uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ }
} else {
const char *str_menu;
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 36ae6b65038..1c98397c7f6 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -54,6 +54,11 @@
#include "BLI_linklist.h"
#include "BLI_utildefines.h"
+/* vertex box select */
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "BKE_global.h"
+
#include "BKE_context.h"
#include "BKE_paint.h"
#include "BKE_armature.h"
@@ -198,6 +203,24 @@ static void EM_backbuf_checkAndSelectFaces(EditMesh *em, int select)
}
}
+
+/* object mode, EM_ prefix is confusing here, rename? */
+static void EM_backbuf_checkAndSelectVerts_obmode(Mesh *me, int select)
+{
+ MVert *mv = me->mvert;
+ int a;
+
+ if (mv) {
+ for(a=1; a<=me->totvert; a++, mv++) {
+ if(EM_check_backbuf(a)) {
+ if(!(mv->flag & ME_HIDE)) {
+ mv->flag = select?(mv->flag|SELECT):(mv->flag&~SELECT);
+ }
+ }
+ }
+ }
+}
+/* object mode, EM_ prefix is confusing here, rename? */
static void EM_backbuf_checkAndSelectTFaces(Mesh *me, int select)
{
MFace *mface = me->mface;
@@ -231,7 +254,7 @@ static int view3d_selectable_data(bContext *C)
if (ob->mode & OB_MODE_SCULPT) {
return 0;
}
- if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob)) {
+ if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob) && !paint_vertsel_test(ob)) {
return 0;
}
}
@@ -727,6 +750,88 @@ static void do_lasso_select_meta(ViewContext *vc, int mcords[][2], short moves,
}
}
+int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend)
+{
+ Mesh *me;
+ MVert *mvert;
+ struct ImBuf *ibuf;
+ unsigned int *rt;
+ int a, index;
+ char *selar;
+ int sx= rect->xmax-rect->xmin+1;
+ int sy= rect->ymax-rect->ymin+1;
+
+ me= vc->obact->data;
+
+ if(me==NULL || me->totvert==0 || sx*sy <= 0)
+ return OPERATOR_CANCELLED;
+
+ selar= MEM_callocN(me->totvert+1, "selar");
+
+ if (extend == 0 && select)
+ paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, FALSE);
+
+ view3d_validate_backbuf(vc);
+
+ ibuf = IMB_allocImBuf(sx,sy,32,IB_rect);
+ rt = ibuf->rect;
+ glReadPixels(rect->xmin+vc->ar->winrct.xmin, rect->ymin+vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ if(ENDIAN_ORDER==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
+
+ a= sx*sy;
+ while(a--) {
+ if(*rt) {
+ index= WM_framebuffer_to_index(*rt);
+ if(index<=me->totvert) selar[index]= 1;
+ }
+ rt++;
+ }
+
+ mvert= me->mvert;
+ for(a=1; a<=me->totvert; a++, mvert++) {
+ if(selar[a]) {
+ if(mvert->flag & ME_HIDE);
+ else {
+ if(select) mvert->flag |= SELECT;
+ else mvert->flag &= ~SELECT;
+ }
+ }
+ }
+
+ IMB_freeImBuf(ibuf);
+ MEM_freeN(selar);
+
+#ifdef __APPLE__
+ glReadBuffer(GL_BACK);
+#endif
+
+ paintvert_flush_flags(vc->obact);
+
+ return OPERATOR_FINISHED;
+}
+
+static void do_lasso_select_paintvert(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
+{
+ Object *ob= vc->obact;
+ Mesh *me= ob?ob->data:NULL;
+ rcti rect;
+
+ if(me==NULL || me->totvert==0)
+ return;
+
+ if(extend==0 && select)
+ paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */
+ em_vertoffs= me->totvert+1; /* max index array */
+
+ lasso_select_boundbox(&rect, mcords, moves);
+ EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+
+ EM_backbuf_checkAndSelectVerts_obmode(me, select);
+
+ EM_free_backbuf();
+
+ paintvert_flush_flags(ob);
+}
static void do_lasso_select_paintface(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
{
Object *ob= vc->obact;
@@ -789,6 +894,8 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, int mcords[][2], s
if(vc->obedit==NULL) { /* Object Mode */
if(paint_facesel_test(ob))
do_lasso_select_paintface(vc, mcords, moves, extend, select);
+ else if(paint_vertsel_test(ob))
+ do_lasso_select_paintvert(vc, mcords, moves, extend, select);
else if(ob && ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))
;
else if(ob && ob->mode & OB_MODE_PARTICLE_EDIT)
@@ -1798,6 +1905,9 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
else if(vc.obact && paint_facesel_test(vc.obact)) {
ret= do_paintface_box_select(&vc, &rect, select, extend);
}
+ else if(vc.obact && paint_vertsel_test(vc.obact)) {
+ ret= do_paintvert_box_select(&vc, &rect, select, extend);
+ }
else if(vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
ret= PE_border_select(C, &rect, select, extend);
}
@@ -1834,6 +1944,58 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
WM_operator_properties_gesture_border(ot, TRUE);
}
+/* much like facesel_face_pick()*/
+/* returns 0 if not found, otherwise 1 */
+static int vertsel_vert_pick(struct bContext *C, Mesh *me, const int mval[2], unsigned int *index, short rect)
+{
+ ViewContext vc;
+ view3d_set_viewcontext(C, &vc);
+
+ if (!me || me->totvert==0)
+ return 0;
+
+ if (rect) {
+ /* sample rect to increase changes of selecting, so that when clicking
+ on an face in the backbuf, we can still select a vert */
+
+ int dist;
+ *index = view3d_sample_backbuf_rect(&vc, mval, 3, 1, me->totvert+1, &dist,0,NULL, NULL);
+ }
+ else {
+ /* sample only on the exact position */
+ *index = view3d_sample_backbuf(&vc, mval[0], mval[1]);
+ }
+
+ if ((*index)<=0 || (*index)>(unsigned int)me->totvert)
+ return 0;
+
+ (*index)--;
+
+ return 1;
+}
+
+/* mouse selection in weight paint */
+/* gets called via generic mouse select operator */
+static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], short extend, Object *obact)
+{
+ Mesh* me= obact->data; /* already checked for NULL */
+ unsigned int index = 0;
+ MVert *mv;
+ if(vertsel_vert_pick(C, me, mval, &index, 1)) {
+ mv = me->mvert+index;
+ if(extend) {
+ mv->flag ^= SELECT;
+ } else {
+ paintvert_deselect_all_visible(obact, SEL_DESELECT, FALSE);
+ mv->flag |= SELECT;
+ }
+ paintvert_flush_flags(obact);
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
+ return 1;
+ }
+ return 0;
+}
+
/* ****** Mouse Select ****** */
@@ -1878,6 +2040,8 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
return PE_mouse_particles(C, event->mval, extend);
else if(obact && paint_facesel_test(obact))
retval = paintface_mouse_select(C, obact, event->mval, extend);
+ else if (paint_vertsel_test(obact))
+ retval = mouse_weight_paint_vertex_select(C, event->mval, extend, obact);
else
retval = mouse_select(C, event->mval, extend, center, enumerate);
@@ -1992,18 +2156,36 @@ static void paint_facesel_circle_select(ViewContext *vc, int select, const int m
{
Object *ob= vc->obact;
Mesh *me = ob?ob->data:NULL;
- int bbsel;
+ /* int bbsel; */ /* UNUSED */
if (me) {
em_vertoffs= me->totface+1; /* max index array */
- bbsel= EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0f));
+ /* bbsel= */ /* UNUSED */ EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0f));
EM_backbuf_checkAndSelectTFaces(me, select==LEFTMOUSE);
EM_free_backbuf();
}
}
+static void paint_vertsel_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
+{
+ Object *ob= vc->obact;
+ Mesh *me = ob?ob->data:NULL;
+ /* int bbsel; */ /* UNUSED */
+ /* struct {ViewContext *vc; short select; int mval[2]; float radius; } data = {NULL}; */ /* UNUSED */
+ if (me) {
+ em_vertoffs= me->totvert+1; /* max index array */
+
+ /* bbsel= */ /* UNUSED */ EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0f));
+ EM_backbuf_checkAndSelectVerts_obmode(me, select==LEFTMOUSE);
+ EM_free_backbuf();
+
+ paintvert_flush_flags(ob);
+ }
+}
+
+
static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
{
struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData;
@@ -2258,7 +2440,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
select= (gesture_mode==GESTURE_MODAL_SELECT);
- if( CTX_data_edit_object(C) || paint_facesel_test(obact) ||
+ if( CTX_data_edit_object(C) || paint_facesel_test(obact) || paint_vertsel_test(obact) ||
(obact && (obact->mode & (OB_MODE_PARTICLE_EDIT|OB_MODE_POSE))) )
{
ViewContext vc;
@@ -2278,6 +2460,10 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
paint_facesel_circle_select(&vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
}
+ else if(paint_vertsel_test(obact)) {
+ paint_vertsel_circle_select(&vc, select, mval, (float)radius);
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
+ }
else if(obact->mode & OB_MODE_POSE)
pose_circle_select(&vc, select, mval, (float)radius);
else
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 45d832d4739..8227ba87021 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1667,7 +1667,7 @@ static void RestoreState(bContext *C, wmWindow *win)
win->queue= queue_back;
GPU_state_init();
- GPU_set_tpage(NULL, 0);
+ GPU_set_tpage(NULL, 0, 0);
glPopAttrib();
}
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index c8b95727304..f6b4f32adef 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4260,7 +4260,6 @@ static int createSlideVerts(TransInfo *t)
LinkNode *edgelist = NULL, *vertlist=NULL, *look;
GHash *vertgh;
TransDataSlideVert *tempsv;
- float vertdist; // XXX, projectMat[4][4];
int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0;
/* UV correction vars */
GHash **uvarray= NULL;
@@ -4525,7 +4524,6 @@ static int createSlideVerts(TransInfo *t)
look = vertlist;
nearest = NULL;
- vertdist = -1;
while(look) {
tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
@@ -5563,7 +5561,7 @@ static void applyTimeTranslate(TransInfo *t, float UNUSED(sval))
const short autosnap= getAnimEdit_SnapMode(t);
- float deltax, val, valprev;
+ float deltax, val /* , valprev */;
/* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
for (i = 0 ; i < t->total; i++, td++, td2d++) {
@@ -5573,7 +5571,7 @@ static void applyTimeTranslate(TransInfo *t, float UNUSED(sval))
*/
AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL;
- valprev = *td->val;
+ /* valprev = *td->val; */ /* UNUSED */
/* check if any need to apply nla-mapping */
if (adt && t->spacetype != SPACE_SEQ) {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index d76e5c8a88a..77d2e6e7ff0 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -1983,7 +1983,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
float *mappedcos = NULL, *quats= NULL;
float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
int count=0, countsel=0, a, totleft;
- int propmode = t->flag & T_PROP_EDIT;
+ int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) : 0;
int mirror = 0;
short selectmode = ts->selectmode;
@@ -2053,7 +2053,9 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
copy_m3_m4(mtx, t->obedit->obmat);
invert_m3_m3(smtx, mtx);
- if(propmode) editmesh_set_connectivity_distance(em, mtx);
+ if(propmode & T_PROP_CONNECTED) {
+ editmesh_set_connectivity_distance(em, mtx);
+ }
/* detect CrazySpace [tm] */
if(modifiers_getCageIndex(t->scene, t->obedit, NULL, 1)>=0) {
@@ -3406,7 +3408,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
const char sel3= use_handle ? bezt->f3 & SELECT : 0;
TransDataCurveHandleFlags *hdata = NULL;
- short h1=1, h2=1;
+ /* short h1=1, h2=1; */ /* UNUSED */
/* only include handles if selected, irrespective of the interpolation modes.
* also, only treat handles specially if the center point isn't selected.
@@ -3416,16 +3418,18 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
hdata = initTransDataCurveHandles(td, bezt);
bezt_to_transdata(td++, td2d++, adt, bezt, 0, 1, 1, intvals, mtx, smtx);
}
- else
- h1= 0;
+ else {
+ /* h1= 0; */ /* UNUSED */
+ }
if (sel3) {
if (hdata==NULL)
hdata = initTransDataCurveHandles(td, bezt);
bezt_to_transdata(td++, td2d++, adt, bezt, 2, 1, 1, intvals, mtx, smtx);
}
- else
- h2= 0;
+ else {
+ /* h2= 0; */ /* UNUSED */
+ }
}
/* only include main vert if selected */
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 3b895f5fbd0..36373562956 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -446,13 +446,13 @@ int calc_manipulator_stats(const bContext *C)
}
else if(obedit->type==OB_MBALL) {
MetaBall *mb = (MetaBall*)obedit->data;
- MetaElem *ml, *ml_sel=NULL;
+ MetaElem *ml /* , *ml_sel=NULL */ /* UNUSED */;
ml= mb->editelems->first;
while(ml) {
if(ml->flag & SELECT) {
calc_tw_center(scene, &ml->x);
- ml_sel = ml;
+ /* ml_sel = ml; */ /* UNUSED */
totsel++;
}
ml= ml->next;
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 3489bf41143..d6e8e4aa695 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -795,7 +795,7 @@ void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_sequencer_active;
- RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "angle", "", -FLT_MAX, FLT_MAX);
+ RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
Transform_Properties(ot, P_SNAP);
}
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 9a21305457c..61b3a9ca1ca 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -125,14 +125,12 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
if(uvedit_face_visible(scene, previma, efa, tf)) {
if(ima) {
tf->tpage= ima;
- tf->mode |= TF_TEX;
if(ima->id.us==0) id_us_plus(&ima->id);
else id_lib_extern(&ima->id);
}
else {
tf->tpage= NULL;
- tf->mode &= ~TF_TEX;
}
update = 1;
@@ -2519,7 +2517,7 @@ static void UV_OT_snap_cursor(wmOperatorType *ot)
ot->poll= ED_operator_image_active; /* requires space image */;
/* properties */
- RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UV's to");
+ RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UVs to");
}
/* ******************** snap selection operator **************** */
@@ -2761,7 +2759,7 @@ static void UV_OT_snap_selected(wmOperatorType *ot)
ot->poll= ED_operator_image_active; /* requires space image */;
/* properties */
- RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UV's to");
+ RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UVs to");
}
/* ******************** pin operator **************** */
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index d75b8db2c4e..55c4ff85a57 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -80,15 +80,15 @@ void GPU_end_object_materials(void);
int GPU_enable_material(int nr, void *attribs);
void GPU_disable_material(void);
-void GPU_set_material_blend_mode(int blendmode);
-int GPU_get_material_blend_mode(void);
+void GPU_set_material_alpha_blend(int alphablend);
+int GPU_get_material_alpha_blend(void);
/* TexFace drawing
* - this is mutually exclusive with material drawing, a mesh should
* be drawn using one or the other
* - passing NULL clears the state again */
-int GPU_set_tpage(struct MTFace *tface, int mipmap);
+int GPU_set_tpage(struct MTFace *tface, int mipmap, int transp);
/* Lights
* - returns how many lights were enabled
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 95a08e6d5b3..29ad9c91374 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -94,7 +94,8 @@ typedef enum GPUBlendMode {
GPU_BLEND_SOLID = 0,
GPU_BLEND_ADD = 1,
GPU_BLEND_ALPHA = 2,
- GPU_BLEND_CLIP = 4
+ GPU_BLEND_CLIP = 4,
+ GPU_BLEND_ALPHA_SORT = 8
} GPUBlendMode;
typedef struct GPUNodeStack {
@@ -121,7 +122,7 @@ int GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNode
void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
void GPU_material_enable_alpha(GPUMaterial *material);
-GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[4]);
+GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
/* High level functions to create and use GPU materials */
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 7af5ef6ea14..4f79d577ae5 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -95,7 +95,7 @@ void GPU_render_text(MTFace *tface, int mode,
const char *textstr, int textlen, unsigned int *col,
float *v1, float *v2, float *v3, float *v4, int glattrib)
{
- if ((mode & TF_BMFONT) && (textlen>0) && tface->tpage) {
+ if ((mode & GEMAT_TEXT) && (textlen>0) && tface->tpage) {
Image* ima = (Image*)tface->tpage;
int index, character;
float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
@@ -245,7 +245,7 @@ static struct GPUTextureState {
int domipmap, linearmipmap;
- int alphamode;
+ int alphablend;
float anisotropic;
MTFace *lasttface;
} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, -1, 1.f, NULL};
@@ -352,7 +352,7 @@ static void gpu_clear_tpage(void)
GTS.curtilemode= 0;
GTS.curtileXRep=0;
GTS.curtileYRep=0;
- GTS.alphamode= -1;
+ GTS.alphablend= -1;
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
@@ -361,19 +361,19 @@ static void gpu_clear_tpage(void)
glDisable(GL_ALPHA_TEST);
}
-static void gpu_set_blend_mode(GPUBlendMode blendmode)
+static void gpu_set_alpha_blend(GPUBlendMode alphablend)
{
- if(blendmode == GPU_BLEND_SOLID) {
+ if(alphablend == GPU_BLEND_SOLID) {
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
- else if(blendmode==GPU_BLEND_ADD) {
+ else if(alphablend==GPU_BLEND_ADD) {
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glDisable(GL_ALPHA_TEST);
}
- else if(blendmode==GPU_BLEND_ALPHA) {
+ else if(ELEM(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ALPHA_SORT)) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -389,21 +389,21 @@ static void gpu_set_blend_mode(GPUBlendMode blendmode)
glAlphaFunc(GL_GREATER, U.glalphaclip);
}
}
- else if(blendmode==GPU_BLEND_CLIP) {
+ else if(alphablend==GPU_BLEND_CLIP) {
glDisable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
}
}
-static void gpu_verify_alpha_mode(MTFace *tface)
+static void gpu_verify_alpha_blend(int alphablend)
{
/* verify alpha blending modes */
- if(GTS.alphamode == tface->transp)
+ if(GTS.alphablend == alphablend)
return;
- gpu_set_blend_mode(tface->transp);
- GTS.alphamode= tface->transp;
+ gpu_set_alpha_blend(alphablend);
+ GTS.alphablend= alphablend;
}
static void gpu_verify_reflection(Image *ima)
@@ -608,7 +608,7 @@ static void gpu_verify_repeat(Image *ima)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
-int GPU_set_tpage(MTFace *tface, int mipmap)
+int GPU_set_tpage(MTFace *tface, int mipmap, int alphablend)
{
Image *ima;
@@ -621,7 +621,7 @@ int GPU_set_tpage(MTFace *tface, int mipmap)
ima= tface->tpage;
GTS.lasttface= tface;
- gpu_verify_alpha_mode(tface);
+ gpu_verify_alpha_blend(alphablend);
gpu_verify_reflection(ima);
if(GPU_verify_image(ima, NULL, tface->tile, 1, mipmap)) {
@@ -945,12 +945,12 @@ static struct GPUMaterialState {
float (*gviewmat)[4];
float (*gviewinv)[4];
- GPUBlendMode *blendmode;
- GPUBlendMode blendmode_fixed[FIXEDMAT];
+ GPUBlendMode *alphablend;
+ GPUBlendMode alphablend_fixed[FIXEDMAT];
int alphapass;
int lastmatnr, lastretval;
- GPUBlendMode lastblendmode;
+ GPUBlendMode lastalphablend;
} GMS = {NULL};
/* fixed function material, alpha handed by caller */
@@ -1000,7 +1000,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
{
Material *ma;
GPUMaterial *gpumat;
- GPUBlendMode blendmode;
+ GPUBlendMode alphablend;
int a;
int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
@@ -1008,7 +1008,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
memset(&GMS, 0, sizeof(GMS));
GMS.lastmatnr = -1;
GMS.lastretval = -1;
- GMS.lastblendmode = GPU_BLEND_SOLID;
+ GMS.lastalphablend = GPU_BLEND_SOLID;
GMS.gob = ob;
GMS.gscene = scene;
@@ -1024,12 +1024,12 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
if(GMS.totmat > FIXEDMAT) {
GMS.matbuf= MEM_callocN(sizeof(GPUMaterialFixed)*GMS.totmat, "GMS.matbuf");
GMS.gmatbuf= MEM_callocN(sizeof(*GMS.gmatbuf)*GMS.totmat, "GMS.matbuf");
- GMS.blendmode= MEM_callocN(sizeof(*GMS.blendmode)*GMS.totmat, "GMS.matbuf");
+ GMS.alphablend= MEM_callocN(sizeof(*GMS.alphablend)*GMS.totmat, "GMS.matbuf");
}
else {
GMS.matbuf= GMS.matbuf_fixed;
GMS.gmatbuf= GMS.gmatbuf_fixed;
- GMS.blendmode= GMS.blendmode_fixed;
+ GMS.alphablend= GMS.alphablend_fixed;
}
/* no materials assigned? */
@@ -1044,7 +1044,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GPU_material_from_blender(GMS.gscene, &defmaterial);
}
- GMS.blendmode[0]= GPU_BLEND_SOLID;
+ GMS.alphablend[0]= GPU_BLEND_SOLID;
}
/* setup materials */
@@ -1060,13 +1060,13 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
if(gpumat) {
/* do glsl only if creating it succeed, else fallback */
GMS.gmatbuf[a]= ma;
- blendmode = GPU_material_blend_mode(gpumat, ob->col);
+ alphablend = GPU_material_alpha_blend(gpumat, ob->col);
}
else {
/* fixed function opengl materials */
gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob);
- blendmode = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
+ alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
if(do_alpha_pass && GMS.alphapass)
GMS.matbuf[a].diff[3]= ma->alpha;
else
@@ -1076,8 +1076,8 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
/* setting do_alpha_pass = 1 indicates this object needs to be
* drawn in a second alpha pass for improved blending */
if(do_alpha_pass) {
- GMS.blendmode[a]= blendmode;
- if(ELEM(blendmode, GPU_BLEND_ALPHA, GPU_BLEND_ADD) && !GMS.alphapass)
+ GMS.alphablend[a]= alphablend;
+ if(ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT) && !GMS.alphapass)
*do_alpha_pass= 1;
}
}
@@ -1090,7 +1090,7 @@ int GPU_enable_material(int nr, void *attribs)
{
GPUVertexAttribs *gattribs = attribs;
GPUMaterial *gpumat;
- GPUBlendMode blendmode;
+ GPUBlendMode alphablend;
/* no GPU_begin_object_materials, use default material */
if(!GMS.matbuf) {
@@ -1131,7 +1131,7 @@ int GPU_enable_material(int nr, void *attribs)
/* draw materials with alpha in alpha pass */
GMS.lastmatnr = nr;
- GMS.lastretval = ELEM(GMS.blendmode[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
+ GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
if(GMS.alphapass)
GMS.lastretval = !GMS.lastretval;
@@ -1145,6 +1145,7 @@ int GPU_enable_material(int nr, void *attribs)
GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT));
GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gviewinv, GMS.gob->col);
GMS.gboundmat= mat;
+ alphablend= mat->game.alpha_blend;
if(GMS.alphapass) glDepthMask(1);
}
@@ -1153,28 +1154,29 @@ int GPU_enable_material(int nr, void *attribs)
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GMS.matbuf[nr].diff);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, GMS.matbuf[nr].spec);
glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, GMS.matbuf[nr].hard);
+ alphablend= GPU_BLEND_SOLID;
}
/* set (alpha) blending mode */
- blendmode = (GMS.alphapass)? GPU_BLEND_ALPHA: GPU_BLEND_SOLID;
- GPU_set_material_blend_mode(blendmode);
+ if(!GMS.alphapass) alphablend= GPU_BLEND_SOLID;
+ GPU_set_material_alpha_blend(alphablend);
}
return GMS.lastretval;
}
-void GPU_set_material_blend_mode(int blendmode)
+void GPU_set_material_alpha_blend(int alphablend)
{
- if(GMS.lastblendmode == blendmode)
+ if(GMS.lastalphablend == alphablend)
return;
- gpu_set_blend_mode(blendmode);
- GMS.lastblendmode = blendmode;
+ gpu_set_alpha_blend(alphablend);
+ GMS.lastalphablend = alphablend;
}
-int GPU_get_material_blend_mode(void)
+int GPU_get_material_alpha_blend(void)
{
- return GMS.lastblendmode;
+ return GMS.lastalphablend;
}
void GPU_disable_material(void)
@@ -1188,7 +1190,7 @@ void GPU_disable_material(void)
GMS.gboundmat= NULL;
}
- GPU_set_material_blend_mode(GPU_BLEND_SOLID);
+ GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
}
void GPU_end_object_materials(void)
@@ -1198,12 +1200,12 @@ void GPU_end_object_materials(void)
if(GMS.matbuf && GMS.matbuf != GMS.matbuf_fixed) {
MEM_freeN(GMS.matbuf);
MEM_freeN(GMS.gmatbuf);
- MEM_freeN(GMS.blendmode);
+ MEM_freeN(GMS.alphablend);
}
GMS.matbuf= NULL;
GMS.gmatbuf= NULL;
- GMS.blendmode= NULL;
+ GMS.alphablend= NULL;
/* resetting the texture matrix after the glScale needed for tiled textures */
if(GTS.tilemode)
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 9aa453af4d6..40186c5a187 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -358,7 +358,7 @@ void GPU_material_enable_alpha(GPUMaterial *material)
material->alpha= 1;
}
-GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[4])
+GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4])
{
if(material->alpha || (material->obcolalpha && obcol[3] < 1.0f))
return GPU_BLEND_ALPHA;
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 060b1bf42d1..6719dc8d9af 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -74,6 +74,14 @@ typedef struct VolumeSettings {
float ms_spread;
} VolumeSettings;
+/* Game Engine Options (old Texface mode, transp and flag) */
+typedef struct GameSettings {
+ int flag;
+ int alpha_blend;
+ int face_orientation;
+ int pad1;
+} GameSettings;
+
typedef struct Material {
ID id;
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
@@ -90,6 +98,7 @@ typedef struct Material {
/* end synced with render_types.h */
struct VolumeSettings vol;
+ struct GameSettings game;
float fresnel_mir, fresnel_mir_i;
float fresnel_tra, fresnel_tra_i;
@@ -166,12 +175,39 @@ typedef struct Material {
ListBase gpumaterial; /* runtime */
} Material;
+
+/* **************** GAME PROPERTIES ********************* */
+// Blend Transparency Options - alpha_blend /* match GPU_material::GPUBlendMode */
+#define GEMAT_SOLID 0 /* GPU_BLEND_SOLID */
+#define GEMAT_ADD 1 /* GPU_BLEND_ADD */
+#define GEMAT_ALPHA 2 /* GPU_BLEND_ALPHA */
+#define GEMAT_CLIP 4 /* GPU_BLEND_CLIP */
+#define GEMAT_ALPHA_SORT 8 /* GPU_BLEND_ALPHA_SORT */
+
+// Game Options - flag
+#define GEMAT_BACKCULL 16 /* KX_BACKCULL */
+#define GEMAT_SHADED 32 /* KX_LIGHT */
+#define GEMAT_TEXT 64 /* RAS_RENDER_3DPOLYGON_TEXT */
+#define GEMAT_NOPHYSICS 128
+#define GEMAT_INVISIBLE 256
+
+// Face Orientation Options - face_orientation
+#define GEMAT_NORMAL 0
+#define GEMAT_HALO 512 /* BILLBOARD_SCREENALIGNED */
+#define GEMAT_BILLBOARD 1024 /* BILLBOARD_AXISALIGNED */
+#define GEMAT_SHADOW 2048 /* SHADOW */
+
+// Use Textures - not defined directly in the UI
+#define GEMAT_TEX 4096 /* KX_TEX */
+
+
/* **************** MATERIAL ********************* */
/* maximum number of materials per material array.
* (on object, mesh, lamp, etc.). limited by
- * short mat_nr in verts, faces. */
-#define MAXMAT 32767
+ * short mat_nr in verts, faces.
+ * -1 becayse for active material we store the index + 1 */
+#define MAXMAT (32767-1)
/* material_type */
#define MA_TYPE_SURFACE 0
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index 6ad60ac2df9..25bb4958c97 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -125,7 +125,7 @@ typedef struct TFace {
#define ME_EDIT_PAINT_MASK (1 << 3)
#define ME_EDIT_MIRROR_TOPO (1 << 4)
-
+#define ME_EDIT_VERT_SEL (1 << 5)
/* me->flag */
/* #define ME_ISDONE 1 */
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 61c4a660992..9d7375b6755 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -247,6 +247,8 @@ typedef struct MRecast{
#define TF_SHAREDVERT 8
#define TF_LIGHT 16
+#define TF_CONVERTED 32 /* tface converted to material */
+
#define TF_SHAREDCOL 64
#define TF_TILES 128 /* deprecated */
#define TF_BILLBOARD 256
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 8750ee9e906..f32f8d626de 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -62,9 +62,14 @@ struct bGPdata;
typedef struct bDeformGroup {
struct bDeformGroup *next, *prev;
char name[32];
+ /* need this flag for locking weights */
+ char flag, pad[7];
} bDeformGroup;
#define MAX_VGROUP_NAME 32
+/* bDeformGroup->flag */
+#define DG_LOCK_WEIGHT 1
+
/**
* The following illustrates the orientation of the
* bounding box in local space
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 5f20432d6f8..9f176a22848 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -759,9 +759,10 @@ typedef struct ToolSettings {
short snap_flag, snap_target;
short proportional, prop_mode;
char proportional_objects; /* proportional edit, object mode */
- char pad[3];
+ char pad[5];
- int auto_normalize; /*auto normalizing mode in wpaint*/
+ char auto_normalize; /*auto normalizing mode in wpaint*/
+ char multipaint; /* paint multiple bones in wpaint */
short sculpt_paint_settings; /* user preferences for sculpt and paint */
short pad1;
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 99473d13daa..5d0c1db572d 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -296,7 +296,8 @@ static EnumPropertyItem *rna_Curve_fill_mode_itemf(bContext *UNUSED(C), PointerR
{
Curve *cu= (Curve*)ptr->id.data;
- return (cu->flag&CU_3D) ? curve3d_fill_mode_items : curve2d_fill_mode_items;
+ /* cast to quiet warning it IS a const still */
+ return (EnumPropertyItem *)((cu->flag & CU_3D) ? curve3d_fill_mode_items : curve2d_fill_mode_items);
}
static int rna_Nurb_length(PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index dcaeb523df5..673e768e71e 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -742,6 +742,61 @@ static void rna_def_material_mtex(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Material_update");
}
+static void rna_def_material_gamesettings(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_alpha_blend_items[] = {
+ {GEMAT_SOLID, "OPAQUE", 0, "Opaque", "Render color of textured face as color"},
+ {GEMAT_ADD, "ADD", 0, "Add", "Render face transparent and add color of face"},
+ {GEMAT_CLIP, "CLIP", 0, "Alpha Clip", "Use the image alpha values clipped with no blending (binary alpha)"},
+ {GEMAT_ALPHA, "ALPHA", 0, "Alpha Blend", "Render polygon transparent, depending on alpha channel of the texture"},
+ {GEMAT_ALPHA_SORT, "ALPHA_SORT", 0, "Alpha Sort", "Sort faces for correct alpha drawing (slow, use Alpha Clip instead when possible)"},
+ {0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem prop_face_orientation_items[] = {
+ {GEMAT_NORMAL,"NORMAL",0,"Normal","No tranformation"},
+ {GEMAT_HALO, "HALO", 0, "Halo", "Screen aligned billboard"},
+ {GEMAT_BILLBOARD, "BILLBOARD", 0, "Billboard", "Billboard with Z-axis constraint"},
+ {GEMAT_SHADOW, "SHADOW", 0, "Shadow", "Faces are used for shadow"},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "MaterialGameSettings", NULL);
+ RNA_def_struct_sdna(srna, "GameSettings");
+ RNA_def_struct_nested(brna, srna, "Material");
+ RNA_def_struct_ui_text(srna, "Material Game Settings", "Game Engine settings for a Material datablock");
+
+ prop= RNA_def_property(srna, "back_culling", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GEMAT_BACKCULL); /* use bitflags */
+ RNA_def_property_ui_text(prop, "Back Culling", "Hide Back of the face in Game Engine ");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
+ prop= RNA_def_property(srna, "text", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GEMAT_TEXT); /* use bitflags */
+ RNA_def_property_ui_text(prop, "Text", "Use material as text in Game Engine ");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
+ prop= RNA_def_property(srna, "invisible", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GEMAT_INVISIBLE); /* use bitflags */
+ RNA_def_property_ui_text(prop, "Invisible", "Make face invisible");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
+ prop= RNA_def_property(srna, "alpha_blend", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "alpha_blend");
+ RNA_def_property_enum_items(prop, prop_alpha_blend_items);
+ RNA_def_property_ui_text(prop, "Blend Mode", "Blend Mode for Transparent Faces");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
+ prop= RNA_def_property(srna, "face_orientation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_face_orientation_items);
+ RNA_def_property_ui_text(prop, "Face Orientations", "Especial face orientation options");
+
+ prop= RNA_def_property(srna, "physics", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GEMAT_NOPHYSICS); /* use bitflags */
+ RNA_def_property_ui_text(prop, "Physics", "Use physics properties of materials ");
+}
+
static void rna_def_material_colors(StructRNA *srna)
{
PropertyRNA *prop;
@@ -1887,6 +1942,13 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_Material_physics_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Physics", "Game physics settings");
+ /* game settings */
+ prop= RNA_def_property(srna, "game_settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "game");
+ RNA_def_property_struct_type(prop, "MaterialGameSettings");
+ RNA_def_property_ui_text(prop, "Game Settings", "Game material settings");
+
/* nodetree */
prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
@@ -1932,6 +1994,7 @@ void RNA_def_material(BlenderRNA *brna)
rna_def_material_mtex(brna);
rna_def_material_strand(brna);
rna_def_material_physics(brna);
+ rna_def_material_gamesettings(brna);
RNA_api_material(srna);
}
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index a560b54a87a..1bbdc7cc853 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -90,6 +90,24 @@ void rna_Mesh_update_draw(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA
}
}
+
+void rna_Mesh_update_vertmask(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ Mesh* me = ptr->data;
+ if ((me->editflag & ME_EDIT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_MASK)) {
+ me->editflag ^= ME_EDIT_PAINT_MASK;
+ }
+ rna_Mesh_update_draw(bmain, scene, ptr);
+}
+
+void rna_Mesh_update_facemask(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ Mesh* me = ptr->data;
+ if ((me->editflag & ME_EDIT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_MASK)) {
+ me->editflag ^= ME_EDIT_VERT_SEL;
+ }
+ rna_Mesh_update_draw(bmain, scene, ptr);
+}
static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value)
{
MVert *mvert= (MVert*)ptr->data;
@@ -1402,6 +1420,9 @@ static void rna_def_mtface(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Image", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ //XXX to be deleted soon -- left for now in case we need it for debug
+ //XXX it should be out before Blender 2.6 (after texface to material patch)
+
prop= RNA_def_property(srna, "use_image", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_TEX);
RNA_def_property_ui_text(prop, "Tex", "Render face with texture");
@@ -1468,6 +1489,9 @@ static void rna_def_mtface(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Transparency", "Transparency blending mode");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ //XXX to be deleted soon -- left for now in case we need it for debug
+ //XXX it should be out before Blender 2.6 (after texface to material patch)
+
prop= RNA_def_property(srna, "select_uv", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TF_SEL1);
RNA_def_property_array(prop, 4);
@@ -2075,8 +2099,14 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_MASK);
RNA_def_property_ui_text(prop, "Paint Mask", "Face selection masking for painting");
RNA_def_property_ui_icon(prop, ICON_FACESEL_HLT, 0);
- RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_facemask");
+
+ prop= RNA_def_property(srna, "use_paint_mask_vertex", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_VERT_SEL);
+ RNA_def_property_ui_text(prop, "Vertex Selection", "Vertex selection masking for painting (weight paint only)");
+ RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0);
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_vertmask");
/* readonly editmesh info - use for extrude menu */
prop= RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 80092b716c2..1b113620663 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -391,6 +391,7 @@ static void rna_NodeGroupSocket_update(Main *bmain, Scene *scene, PointerRNA *pt
node_update(bmain, scene, ntree, node);
}
+#if 0 /* UNUSED */
static void rna_NodeLink_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNodeTree *ntree= (bNodeTree*)ptr->id.data;
@@ -398,6 +399,7 @@ static void rna_NodeLink_update(Main *bmain, Scene *scene, PointerRNA *ptr)
ntree->update |= NTREE_UPDATE_LINKS;
ntreeUpdateTree(ntree);
}
+#endif
static void rna_NodeSocketInt_range(PointerRNA *ptr, int *min, int *max)
{
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 4f5aa2cc8b0..720fea682ce 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1265,6 +1265,11 @@ static void rna_def_vertex_group(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_VertexGroup_name_set");
RNA_def_property_update(prop, NC_GEOM|ND_DATA|NA_RENAME, "rna_Object_internal_update_data"); /* update data because modifiers may use [#24761] */
+
+ prop= RNA_def_property(srna, "lock_weight", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "", "Maintain the relative weights for the group");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", 0);
+ RNA_def_property_update(prop, NC_GEOM|ND_DATA|NA_RENAME, "rna_Object_internal_update_data"); /* update data because modifiers may use [#24761] */
prop= RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 49ca8b2c03c..774e21297da 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1044,6 +1044,22 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons
}
}
+
+
+/* note: without this, when Multi-Paint is activated/deactivated, the colors
+ * will not change right away when multiple bones are selected, this function
+ * is not for general use and only for the few cases where changing scene
+ * settings and NOT for general purpose updates, possibly this should be
+ * given its own notifier. */
+static void rna_Scene_update_active_object_data(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ Object *ob= OBACT;
+ if(ob) {
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_main_add_notifier(NC_OBJECT|ND_DRAW, &ob->id);
+ }
+}
+
#else
static void rna_def_transform_orientation(BlenderRNA *brna)
@@ -1117,9 +1133,17 @@ static void rna_def_tool_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_auto_normalize", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_normalize", 1);
- RNA_def_property_ui_text(prop, "WPaint Auto-Normalize",
- "Ensure all bone-deforming vertex groups add up to 1.0 while "
- "weight painting");
+ RNA_def_property_ui_text(prop, "WPaint Auto-Normalize",
+ "Ensure all bone-deforming vertex groups add up "
+ "to 1.0 while weight painting");
+ RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
+
+ prop = RNA_def_property(srna, "use_multipaint", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "multipaint", 1);
+ RNA_def_property_ui_text(prop, "WPaint Multi-Paint",
+ "Paint across all selected bones while "
+ "weight painting");
+ RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
prop= RNA_def_property(srna, "vertex_paint", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "vpaint");
@@ -1804,7 +1828,7 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem material_items[] ={
- {GAME_MAT_TEXFACE, "TEXTURE_FACE", 0, "Texture Face", "Single texture face materials"},
+ {GAME_MAT_TEXFACE, "SINGLETEXTURE", 0, "Singletexture", "Singletexture face materials"},
{GAME_MAT_MULTITEX, "MULTITEXTURE", 0, "Multitexture", "Multitexture materials"},
{GAME_MAT_GLSL, "GLSL", 0, "GLSL", "OpenGL shading language shaders"},
{0, NULL, 0, NULL, NULL}};
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 912c14adfdd..0c343332736 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -369,7 +369,6 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
}
if(override_image) {
- tface->mode = TF_TEX;
tface->tpage = image;
}
}
diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h
index 57ebe2191dd..f3e0f811f13 100644
--- a/source/blender/nodes/composite/node_composite_util.h
+++ b/source/blender/nodes/composite/node_composite_util.h
@@ -79,6 +79,10 @@
#include "RE_shader_ext.h"
#include "RE_render_ext.h"
+/* only for forward declarations */
+#include "NOD_composite.h"
+
+
/* *************************** operations support *************************** */
/* general signal that's in output sockets, and goes over the wires */
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c
index 418d6802cec..cc55569e566 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c
+++ b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c
@@ -192,7 +192,7 @@ static void node_composit_exec_color_spill(void *UNUSED(data), bNode *node, bNod
/* Originally based on the information from the book "The Art and Science of Digital Composition" and
* discussions from vfxtalk.com .*/
CompBuf *cbuf;
- CompBuf *mask;
+ /* CompBuf *mask; */ /* UNUSED */
CompBuf *rgbbuf;
CompBuf *spillmap;
NodeColorspill *ncs;
@@ -204,7 +204,7 @@ static void node_composit_exec_color_spill(void *UNUSED(data), bNode *node, bNod
if(in[0]->data==NULL) return;
cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
- mask=typecheck_compbuf(in[1]->data, CB_VAL);
+ /* mask= */ /* UNUSED */ typecheck_compbuf(in[1]->data, CB_VAL);
spillmap=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
rgbbuf=dupalloc_compbuf(cbuf);
diff --git a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c
index 9f4af0e0d33..f3cb223079f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c
@@ -91,7 +91,7 @@ static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack **
CompBuf *outbuf= NULL;
CompBuf *imbuf1= NULL;
CompBuf *imbuf2= NULL;
- NodeChroma *c;
+ /* NodeChroma *c; */ /* UNUSED */
/*is anything connected?*/
if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
@@ -107,7 +107,7 @@ static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack **
imbuf2=typecheck_compbuf(in[1]->data, CB_RGBA);
}
- c=node->storage;
+ /* c=node->storage; */ /* UNUSED */
outbuf=dupalloc_compbuf(imbuf1);
/* note, processor gets a keyvals array passed on as buffer constant */
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index d7830b6a260..35f2dbf7b32 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -826,11 +826,11 @@ bNodeTemplate node_forloop_template(bNode *node)
void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp)
{
- bNodeSocket *sock;
+ /* bNodeSocket *sock; */ /* UNUSED */
node->id = (ID*)ntemp->ngroup;
- sock = nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000);
+ /* sock = */ nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000);
/* NB: group socket input/output roles are inverted internally!
* Group "inputs" work as outputs in links and vice versa.
@@ -932,11 +932,11 @@ void node_loop_update_tree(bNodeTree *ngroup)
void node_whileloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp)
{
- bNodeSocket *sock;
+ /* bNodeSocket *sock; */ /* UNUSED */
node->id = (ID*)ntemp->ngroup;
- sock = nodeAddInputFloat(ntree, node, "Condition", PROP_NONE, 1, 0, 1);
+ /* sock = */ nodeAddInputFloat(ntree, node, "Condition", PROP_NONE, 1, 0, 1);
/* max iterations */
node->custom1 = 10000;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index ba7af235acc..a15662f86f4 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -981,7 +981,7 @@ static void flag_render_node_material(Render *re, bNodeTree *ntree)
}
}
-static Material *give_render_material(Render *re, Object *ob, int nr)
+static Material *give_render_material(Render *re, Object *ob, short nr)
{
extern Material defmaterial; /* material.c */
Material *ma;
@@ -2688,7 +2688,8 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
int timeoffset, float *orco, float mat[4][4])
{
Object *ob= obr->ob;
- int a, a1, end, totvert, vertofs;
+ int a, end, totvert, vertofs;
+ short mat_iter;
VertRen *ver;
VlakRen *vlr;
MVert *mvert = NULL;
@@ -2718,16 +2719,16 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
/* faces in order of color blocks */
vertofs= obr->totvert - totvert;
- for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
+ for(mat_iter= 0; (mat_iter < ob->totcol || (mat_iter==0 && ob->totcol==0)); mat_iter++) {
- ma= give_render_material(re, ob, a1+1);
+ ma= give_render_material(re, ob, mat_iter+1);
end= dm->getNumFaces(dm);
mface= dm->getFaceArray(dm);
for(a=0; a<end; a++, mface++) {
int v1, v2, v3, v4, flag;
- if( mface->mat_nr==a1 ) {
+ if(mface->mat_nr == mat_iter) {
float len;
v1= mface->v1;
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index dd5deddece9..5c5162d268b 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -306,7 +306,7 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz,
/* soften the halo if it intersects geometry */
if(har->mat && har->mat->mode & MA_HALO_SOFT) {
- float segment_length, halo_depth, distance_from_z, visible_depth, soften;
+ float segment_length, halo_depth, distance_from_z /* , visible_depth */ /* UNUSED */, soften;
/* calculate halo depth */
segment_length= har->hasize*sasqrt(1.0f - dist/(har->rad*har->rad));
@@ -317,7 +317,7 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz,
/* calculate how much of this depth is visible */
distance_from_z = haloZtoDist(zz) - haloZtoDist(har->zs);
- visible_depth = halo_depth;
+ /* visible_depth = halo_depth; */ /* UNUSED */
if(distance_from_z < segment_length) {
soften= (segment_length + distance_from_z)/halo_depth;
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 980f6b6af1e..36ded5c10d2 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -107,7 +107,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
ParticleSimulationData sim= {NULL};
ParticleData *pa=NULL;
float cfra = BKE_curframe(re->scene);
- int i, childexists;
+ int i /*, childexists*/ /* UNUSED */;
int total_particles, offset=0;
int data_used = point_data_used(pd);
float partco[3];
@@ -143,9 +143,11 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
pd->totpoints = total_particles;
if (data_used & POINT_DATA_VEL) offset = pd->totpoints*3;
+#if 0 /* UNUSED */
if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
childexists = 1;
-
+#endif
+
for (i=0, pa=psys->particles; i < total_particles; i++, pa++) {
state.time = cfra;
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index ad592609ce6..641fec90cf3 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1994,7 +1994,7 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
else {
/* same as above, but doing 5 taps, increasing quality at cost of speed */
float STc[3], STl[3], STr[3], STd[3], STu[3];
- float Hc, Hl, Hr, Hd, Hu;
+ float /* Hc, */ /* UNUSED */ Hl, Hr, Hd, Hu;
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
@@ -2017,7 +2017,7 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
// use texres for the center sample, set rgbnor
rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres);
- Hc = (fromrgb)? RGBTOBW(texres->tr, texres->tg, texres->tb) : texres->tin;
+ /* Hc = (fromrgb)? RGBTOBW(texres->tr, texres->tg, texres->tb) : texres->tin; */ /* UNUSED */
// use ttexr for the other taps
multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr);
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 59a505a3195..bc5e7f23e21 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -992,7 +992,7 @@ static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl)
}
/* adds only alpha values */
-void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz)
+static void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz)
{
/* use zbuffer to define edges, add it to the image */
int y, x, col, *rz, *rz1, *rz2, *rz3;
@@ -1133,7 +1133,7 @@ typedef struct ZbufSolidData {
float *edgerect;
} ZbufSolidData;
-void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
+static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
{
ZbufSolidData *sdata= (ZbufSolidData*)data;
ListBase *lb= sdata->psmlist;
@@ -1515,7 +1515,7 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRe
{
ShadeInput *shi= ssamp->shi;
ShadeResult shr;
- float texfac, orthoarea, nor[3], alpha, sx, sy;
+ float /* texfac,*/ /* UNUSED */ orthoarea, nor[3], alpha, sx, sy;
/* cache for shadow */
shi->samplenr= R.shadowsamplenr[shi->thread]++;
@@ -1578,7 +1578,7 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRe
VECCOPY(color, shr.combined);
/* texture blending */
- texfac= shi->mat->sss_texfac;
+ /* texfac= shi->mat->sss_texfac; */ /* UNUSED */
alpha= shr.combined[3];
*area *= alpha;
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 431b2839c25..41d12c6065e 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -1502,12 +1502,12 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
LampRen *lar;
GroupObject *go;
float inpr, lv[3];
- float *view, shadfac[4];
+ float /* *view, */ shadfac[4];
float ir, accum, visifac, lampdist;
float shaded = 0.0f, lightness = 0.0f;
- view= shi->view;
+ /* view= shi->view; */ /* UNUSED */
accum= ir= 0.0f;
lights= get_lights(shi);
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index ac56304bdcb..f36994e0969 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2864,7 +2864,7 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
float v1[3], v2[3], v3[3], v4[3], fx, fy;
float *rectvz, *dvz, *dimg, *dvec1, *dvec2, *dz, *dz1, *dz2, *rectz;
float *minvecbufrect= NULL, *rectweight, *rw, *rectmax, *rm, *ro;
- float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed, totfac;
+ float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed;
int y, x, step, maxspeed=nbd->maxspeed, samples= nbd->samples;
int tsktsk= 0;
static int firsttime= 1;
@@ -3038,7 +3038,6 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
}
memset(newrect, 0, sizeof(float)*xsize*ysize*4);
- totfac= 0.0f;
/* accumulate */
samples/= 2;
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index de4afa79448..52c0cb902c1 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -232,7 +232,7 @@ static void wm_gesture_draw_circle(wmGesture *gt)
static void draw_filled_lasso(wmGesture *gt)
{
EditVert *v=NULL, *lastv=NULL, *firstv=NULL;
- EditEdge *e;
+ /* EditEdge *e; */ /* UNUSED */
EditFace *efa;
short *lasso= (short *)gt->customdata;
int i;
@@ -246,7 +246,7 @@ static void draw_filled_lasso(wmGesture *gt)
v = BLI_addfillvert(co);
if (lastv)
- e = BLI_addfilledge(lastv, v);
+ /* e = */ /* UNUSED */ BLI_addfilledge(lastv, v);
lastv = v;
if (firstv==NULL) firstv = v;
}
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index d4b43cd7ac1..2c2fd052b5d 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -144,6 +144,8 @@ extern "C" {
#include "BKE_cdderivedmesh.h"
#include "BKE_DerivedMesh.h"
#include "BKE_material.h" /* give_current_material */
+#include "BKE_image.h"
+#include "IMB_imbuf_types.h"
extern Material defmaterial; /* material.c */
}
@@ -195,7 +197,7 @@ extern "C" {
}
#endif
-static int default_face_mode = TF_DYNAMIC;
+static bool default_light_mode = 0;
static unsigned int KX_rgbaint2uint_new(unsigned int icol)
{
@@ -234,9 +236,9 @@ static unsigned int KX_Mcol2uint_new(MCol col)
return out_color.integer;
}
-static void SetDefaultFaceType(Scene* scene)
+static void SetDefaultLightMode(Scene* scene)
{
- default_face_mode = TF_DYNAMIC;
+ default_light_mode = false;
Scene *sce_iter;
Base *base;
@@ -244,7 +246,7 @@ static void SetDefaultFaceType(Scene* scene)
{
if (base->object->type == OB_LAMP)
{
- default_face_mode = TF_DYNAMIC|TF_LIGHT;
+ default_light_mode = true;
return;
}
}
@@ -353,41 +355,41 @@ bool ConvertMaterial(
// use lighting?
material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
+ material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED;
+
// cast shadows?
material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0;
MTex *mttmp = 0;
numchan = getNumTexChannels(mat);
int valid_index = 0;
- // use the face texture if
- // 1) it is set in the buttons
- // 2) we have a face texture and a material but no valid texture in slot 1
+ /* In Multitexture use the face texture if and only if
+ * it is set in the buttons
+ * In GLSL is not working yet :/ 3.2011 */
bool facetex = false;
if(validface && mat->mode &MA_FACETEXTURE)
facetex = true;
- if(validface && !mat->mtex[0])
- facetex = true;
- if(validface && mat->mtex[0]) {
- MTex *tmp = mat->mtex[0];
- if(!tmp->tex || (tmp->tex && !tmp->tex->ima))
- facetex = true;
- }
+
numchan = numchan>MAXTEX?MAXTEX:numchan;
+ if (facetex && numchan == 0) numchan = 1;
// foreach MTex
for(int i=0; i<numchan; i++) {
// use face tex
if(i==0 && facetex ) {
+ facetex = false;
Image*tmp = (Image*)(tface->tpage);
if(tmp) {
material->img[i] = tmp;
material->texname[i] = material->img[i]->id.name;
- material->flag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
- material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
material->flag[i] |= MIPMAP;
+ material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ALPHA_SORT )?USEALPHA:0;
+ material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ALPHA )?USEALPHA:0;
+ material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ADD )?CALCALPHA:0;
+
if(material->img[i]->flag & IMA_REFLECT)
material->mapping[i].mapping |= USEREFL;
else
@@ -405,11 +407,6 @@ bool ConvertMaterial(
material->mapping[i].mapping |= USEUV;
}
- if(material->ras_mode & USE_LIGHT)
- material->ras_mode &= ~USE_LIGHT;
- if(tface->mode & TF_LIGHT)
- material->ras_mode |= USE_LIGHT;
-
valid_index++;
}
else {
@@ -567,25 +564,31 @@ bool ConvertMaterial(
material->ras_mode |= (mat->material_type == MA_TYPE_WIRE)? WIRE: 0;
}
- else {
+ else { // No Material
int valid = 0;
// check for tface tex to fallback on
if( validface ){
-
- // no light bugfix
- if(tface->mode) material->ras_mode |= USE_LIGHT;
-
material->img[0] = (Image*)(tface->tpage);
// ------------------------
if(material->img[0]) {
material->texname[0] = material->img[0]->id.name;
material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
- material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
- material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
+
+ /* see if depth of the image is 32bits */
+ if(BKE_image_has_alpha(material->img[0])) {
+ material->flag[0] |= USEALPHA;
+ material->alphablend = GEMAT_ALPHA;
+ }
+ else
+ material->alphablend = GEMAT_SOLID;
+
valid++;
}
}
+ else
+ material->alphablend = GEMAT_SOLID;
+
material->SetUsers(-1);
material->num_enabled = valid;
material->IdMode = TEXFACE;
@@ -598,6 +601,9 @@ bool ConvertMaterial(
material->matcolor[2] = 0.5f;
material->spec_f = 0.5f;
material->ref = 0.8f;
+
+ // No material - old default TexFace properties
+ material->ras_mode |= USE_LIGHT;
}
MT_Point2 uv[4];
MT_Point2 uv2[4];
@@ -606,13 +612,10 @@ bool ConvertMaterial(
uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f);
+ /* No material, what to do? let's see what is in the UV and set the material accordingly
+ light and visible is always on */
if( validface ) {
-
- material->ras_mode |= (tface->mode & TF_INVISIBLE)?0:POLY_VIS;
-
- material->transp = tface->transp;
material->tile = tface->tile;
- material->mode = tface->mode;
uv[0].setValue(tface->uv[0]);
uv[1].setValue(tface->uv[1]);
@@ -625,31 +628,26 @@ bool ConvertMaterial(
}
else {
// nothing at all
- material->ras_mode |= (POLY_VIS| (validmat?0:USE_LIGHT));
- material->mode = default_face_mode;
- material->transp = TF_SOLID;
+ material->alphablend = GEMAT_SOLID;
material->tile = 0;
uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f);
}
+ if (validmat && validface) {
+ material->alphablend = mat->game.alpha_blend;
+ }
+
// with ztransp enabled, enforce alpha blending mode
- if(validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (material->transp == TF_SOLID))
- material->transp = TF_ALPHA;
+ if(validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (material->alphablend == GEMAT_SOLID))
+ material->alphablend = GEMAT_ALPHA;
// always zsort alpha + add
- if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) && (material->transp != TF_CLIP)) {
+ if((ELEM3(material->alphablend, GEMAT_ALPHA, GEMAT_ALPHA_SORT, GEMAT_ADD) || texalpha) && (material->alphablend != GEMAT_CLIP )) {
material->ras_mode |= ALPHA;
- material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0;
+ material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT))? ZSORT: 0;
}
- // collider or not?
- material->ras_mode |= (material->mode & TF_DYNAMIC)? COLLIDER: 0;
-
- // these flags are irrelevant at this point, remove so they
- // don't hurt material bucketing
- material->mode &= ~(TF_DYNAMIC|TF_ALPHASORT|TF_TEX);
-
// get uv sets
if(validmat)
{
@@ -706,8 +704,8 @@ bool ConvertMaterial(
unsigned int rgb[4];
GetRGB(type,mface,mmcol,mat,rgb[0],rgb[1],rgb[2], rgb[3]);
- // swap the material color, so MCol on TF_BMFONT works
- if (validmat && type==1 && (tface && tface->mode & TF_BMFONT))
+ // swap the material color, so MCol on bitmap font works
+ if (validmat && type==1 && (mat->game.flag & GEMAT_TEXT))
{
rgb[0] = KX_rgbaint2uint_new(rgb[0]);
rgb[1] = KX_rgbaint2uint_new(rgb[1]);
@@ -864,10 +862,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
layers, converter->GetGLSLMaterials());
- visible = ((bl_mat->ras_mode & POLY_VIS)!=0);
- collider = ((bl_mat->ras_mode & COLLIDER)!=0);
- twoside = ((bl_mat->mode & TF_TWOSIDE)!=0);
-
/* vertex colors and uv's were stored in bl_mat temporarily */
bl_mat->GetConversionRGB(rgb);
rgb0 = rgb[0]; rgb1 = rgb[1];
@@ -885,7 +879,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
if (kx_blmat == NULL)
kx_blmat = new KX_BlenderMaterial();
- kx_blmat->Initialize(scene, bl_mat);
+ kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL));
polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
}
else {
@@ -893,37 +887,59 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
Image* bima = (tface)? (Image*)tface->tpage: NULL;
imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
- char transp=0;
- short mode=0, tile=0;
+ char alpha_blend=0;
+ short tile=0;
int tilexrep=4,tileyrep = 4;
-
+
+ /* set material properties - old TexFace */
+ if (ma) {
+ alpha_blend = ma->game.alpha_blend;
+ /* Commented out for now. If we ever get rid of
+ * "Texture Face/Singletexture" we can then think about it */
+
+ /* Texture Face mode ignores texture but requires "Face Textures to be True "*/
+ /**
+ if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) {
+ bima = NULL;
+ imastr = "";
+ alpha_blend = GEMAT_SOLID;
+ }
+ else
+ alpha_blend = ma->game.alpha_blend;
+ */
+ }
+ /* check for tface tex to fallback on */
+ else {
+ if (bima) {
+ /* see if depth of the image is 32 */
+ if (BKE_image_has_alpha(bima))
+ alpha_blend = GEMAT_ALPHA;
+ else
+ alpha_blend = GEMAT_SOLID;
+ }
+ else {
+ alpha_blend = GEMAT_SOLID;
+ }
+ }
+
if (bima) {
tilexrep = bima->xrep;
tileyrep = bima->yrep;
}
- /* get tface properties if available */
+ /* set UV properties */
if(tface) {
- /* TF_DYNAMIC means the polygon is a collision face */
- collider = ((tface->mode & TF_DYNAMIC) != 0);
- transp = tface->transp;
- tile = tface->tile;
- mode = tface->mode;
-
- visible = !(tface->mode & TF_INVISIBLE);
- twoside = ((tface->mode & TF_TWOSIDE)!=0);
-
uv0.setValue(tface->uv[0]);
uv1.setValue(tface->uv[1]);
uv2.setValue(tface->uv[2]);
if (mface->v4)
uv3.setValue(tface->uv[3]);
+
+ tile = tface->tile;
}
else {
- /* no texfaces, set COLLSION true and everything else FALSE */
- mode = default_face_mode;
- transp = TF_SOLID;
+ /* no texfaces */
tile = 0;
}
@@ -964,16 +980,20 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
if (mface->v4)
rgb3 = KX_rgbaint2uint_new(color);
}
-
+
// only zsort alpha + add
- bool alpha = (transp == TF_ALPHA || transp == TF_ADD);
- bool zsort = (mode & TF_ALPHASORT)? alpha: 0;
+ bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT);
+ bool zsort = (alpha_blend == GEMAT_ALPHA_SORT);
+ bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode;
+
+ // don't need zort anymore, deal as if it it's alpha blend
+ if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA;
if (kx_polymat == NULL)
kx_polymat = new KX_PolygonMaterial();
kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
tile, tilexrep, tileyrep,
- mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol);
+ alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol);
polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
if (ma) {
@@ -987,6 +1007,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
}
}
+ // set render flags
+ if (ma)
+ {
+ visible = ((ma->game.flag & GEMAT_INVISIBLE)==0);
+ twoside = ((ma->game.flag & GEMAT_BACKCULL)==0);
+ collider = ((ma->game.flag & GEMAT_NOPHYSICS)==0);
+ }
+ else{
+ visible = true;
+ twoside = false;
+ collider = true;
+ }
+
/* mark face as flat, so vertices are split */
bool flat = (mface->flag & ME_SMOOTH) == 0;
@@ -2035,7 +2068,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
logicmgr->RegisterActionName(curAct->id.name + 2, curAct);
}
- SetDefaultFaceType(blenderscene);
+ SetDefaultLightMode(blenderscene);
// Let's support scene set.
// Beware of name conflict in linked data, it will not crash but will create confusion
// in Python scripting and in certain actuators (replace mesh). Linked scene *should* have
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index 4ae937cdcd6..6680e9556b9 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -27,7 +27,7 @@ BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lig
mGPUMat(NULL)
{
mBlenderScene = scene->GetBlenderScene();
- mBlendMode = GPU_BLEND_SOLID;
+ mAlphaBlend = GPU_BLEND_SOLID;
ReloadMaterial();
}
@@ -148,12 +148,12 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol);
- mBlendMode = GPU_material_blend_mode(gpumat, obcol);
+ mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol);
}
-int BL_BlenderShader::GetBlendMode()
+int BL_BlenderShader::GetAlphaBlend()
{
- return mBlendMode;
+ return mAlphaBlend;
}
bool BL_BlenderShader::Equals(BL_BlenderShader *blshader)
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h
index 2f22e121b8c..f187d93d648 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.h
+++ b/source/gameengine/Ketsji/BL_BlenderShader.h
@@ -63,7 +63,7 @@ private:
struct Scene *mBlenderScene;
struct Material *mMat;
int mLightLayer;
- int mBlendMode;
+ int mAlphaBlend;
GPUMaterial *mGPUMat;
bool VerifyShader()
@@ -86,7 +86,7 @@ public:
void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);
void Update(const class RAS_MeshSlot & ms, class RAS_IRasterizer* rasty);
void ReloadMaterial();
- int GetBlendMode();
+ int GetAlphaBlend();
void SetScene(KX_Scene *scene)
{
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index 25fd5467e93..fd0756d067d 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -52,12 +52,11 @@ void BL_Material::Initialize()
speccolor[0] = 1.f;
speccolor[1] = 1.f;
speccolor[2] = 1.f;
- transp = 0;
+ alphablend = 0;
hard = 50.f;
spec_f = 0.5f;
alpha = 1.f;
emit = 0.f;
- mode = 0;
material = 0;
tface = 0;
materialindex = 0;
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index c0440e66501..2c6316ea32b 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -68,7 +68,7 @@ public:
float matcolor[4];
float speccolor[3];
- short transp, pad;
+ short alphablend, pad;
float hard, spec_f;
float alpha, emit, color_blend[MAXTEX], ref;
@@ -76,7 +76,6 @@ public:
int blend_mode[MAXTEX];
- int mode;
int num_enabled;
BL_Mapping mapping[MAXTEX];
@@ -151,14 +150,16 @@ enum BL_flag
// BL_Material::ras_mode
enum BL_ras_mode
{
- POLY_VIS=1,
+ // POLY_VIS=1,
COLLIDER=2,
ZSORT=4,
ALPHA=8,
// TRIANGLE=16,
USE_LIGHT=32,
WIRE=64,
- CAST_SHADOW=128
+ CAST_SHADOW=128,
+ TEX=256,
+ TWOSIDED=512
};
// -------------------------------------
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 33da17cc505..1a1e046f54c 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -34,6 +34,8 @@
#include "DNA_meshdata_types.h"
#include "BKE_mesh.h"
// ------------------------------------
+#include "BLI_utildefines.h"
+
#define spit(x) std::cout << x << std::endl;
BL_Shader *KX_BlenderMaterial::mLastShader = NULL;
@@ -56,21 +58,24 @@ KX_BlenderMaterial::KX_BlenderMaterial()
}
void KX_BlenderMaterial::Initialize(
- KX_Scene *scene,
- BL_Material *data)
+ KX_Scene *scene,
+ BL_Material *data,
+ GameSettings *game)
{
RAS_IPolyMaterial::Initialize(
- data->texname[0],
- data->matname,
- data->materialindex,
- data->tile,
- data->tilexrep[0],
- data->tileyrep[0],
- data->mode,
- data->transp,
- ((data->ras_mode &ALPHA)!=0),
- ((data->ras_mode &ZSORT)!=0)
- );
+ data->texname[0],
+ data->matname,
+ data->materialindex,
+ data->tile,
+ data->tilexrep[0],
+ data->tileyrep[0],
+ data->alphablend,
+ ((data->ras_mode &ALPHA)!=0),
+ ((data->ras_mode &ZSORT)!=0),
+ ((data->ras_mode &USE_LIGHT)!=0),
+ ((data->ras_mode &TEX)),
+ game
+ );
mMaterial = data;
mShader = 0;
mBlenderShader = 0;
@@ -99,7 +104,7 @@ void KX_BlenderMaterial::Initialize(
for(int i=0; i<mMaterial->num_enabled; i++) {
m_multimode += (mMaterial->flag[i] + mMaterial->blend_mode[i]);
}
- m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(COLLIDER|USE_LIGHT));
+ m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(USE_LIGHT));
}
KX_BlenderMaterial::~KX_BlenderMaterial()
@@ -231,7 +236,7 @@ void KX_BlenderMaterial::OnExit()
}
if( mMaterial->tface )
- GPU_set_tpage(mMaterial->tface, 1);
+ GPU_set_tpage(mMaterial->tface, 1, mMaterial->alphablend);
}
@@ -247,7 +252,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
mLastShader = NULL;
}
- ras->SetBlendingMode(TF_SOLID);
+ ras->SetAlphaBlend(TF_SOLID);
BL_Texture::DisableAllTextures();
return;
}
@@ -268,11 +273,11 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
}
if(!mUserDefBlend) {
- ras->SetBlendingMode(mMaterial->transp);
+ ras->SetAlphaBlend(mMaterial->alphablend);
}
else {
- ras->SetBlendingMode(TF_SOLID);
- ras->SetBlendingMode(-1); // indicates custom mode
+ ras->SetAlphaBlend(TF_SOLID);
+ ras->SetAlphaBlend(-1); // indicates custom mode
// tested to be valid enums
glEnable(GL_BLEND);
@@ -283,7 +288,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras)
{
if( !enable || !mBlenderShader->Ok() ) {
- ras->SetBlendingMode(TF_SOLID);
+ ras->SetAlphaBlend(TF_SOLID);
// frame cleanup.
if(mLastBlenderShader) {
@@ -297,7 +302,7 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras
}
if(!mBlenderShader->Equals(mLastBlenderShader)) {
- ras->SetBlendingMode(mMaterial->transp);
+ ras->SetAlphaBlend(mMaterial->alphablend);
if(mLastBlenderShader)
mLastBlenderShader->SetProg(false);
@@ -314,14 +319,14 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
BL_Texture::DisableAllTextures();
if( !enable ) {
- ras->SetBlendingMode(TF_SOLID);
+ ras->SetAlphaBlend(TF_SOLID);
return;
}
BL_Texture::ActivateFirst();
if( mMaterial->IdMode == DEFAULT_BLENDER ) {
- ras->SetBlendingMode(mMaterial->transp);
+ ras->SetAlphaBlend(mMaterial->alphablend);
return;
}
@@ -331,7 +336,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
mTextures[0].ActivateTexture();
mTextures[0].setTexEnv(0, true);
mTextures[0].SetMapping(mMaterial->mapping[0].mapping);
- ras->SetBlendingMode(mMaterial->transp);
+ ras->SetAlphaBlend(mMaterial->alphablend);
}
return;
}
@@ -354,11 +359,11 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
}
if(!mUserDefBlend) {
- ras->SetBlendingMode(mMaterial->transp);
+ ras->SetAlphaBlend(mMaterial->alphablend);
}
else {
- ras->SetBlendingMode(TF_SOLID);
- ras->SetBlendingMode(-1); // indicates custom mode
+ ras->SetAlphaBlend(TF_SOLID);
+ ras->SetAlphaBlend(-1); // indicates custom mode
glEnable(GL_BLEND);
glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
@@ -393,15 +398,15 @@ KX_BlenderMaterial::ActivatShaders(
else
tmp->setShaderData(false, rasty);
- if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
+ if (mMaterial->ras_mode &TWOSIDED)
rasty->SetCullFace(false);
else
rasty->SetCullFace(true);
- if (((mMaterial->ras_mode &WIRE)!=0) || (mMaterial->mode & RAS_IRasterizer::KX_LINES) ||
+ if ((mMaterial->ras_mode &WIRE) ||
(rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
{
- if((mMaterial->ras_mode &WIRE)!=0)
+ if (mMaterial->ras_mode &WIRE)
rasty->SetCullFace(false);
rasty->SetLines(true);
}
@@ -438,15 +443,15 @@ KX_BlenderMaterial::ActivateBlenderShaders(
else
tmp->setBlenderShaderData(false, rasty);
- if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
+ if (mMaterial->ras_mode &TWOSIDED)
rasty->SetCullFace(false);
else
rasty->SetCullFace(true);
- if (((mMaterial->ras_mode & WIRE)!=0) || (mMaterial->mode & RAS_IRasterizer::KX_LINES) ||
+ if ((mMaterial->ras_mode &WIRE) ||
(rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
{
- if((mMaterial->ras_mode &WIRE)!=0)
+ if (mMaterial->ras_mode &WIRE)
rasty->SetCullFace(false);
rasty->SetLines(true);
}
@@ -487,15 +492,15 @@ KX_BlenderMaterial::ActivateMat(
else
tmp->setTexData( false,rasty);
- if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
+ if (mMaterial->ras_mode &TWOSIDED)
rasty->SetCullFace(false);
else
rasty->SetCullFace(true);
- if (((mMaterial->ras_mode &WIRE)!=0) || (mMaterial->mode & RAS_IRasterizer::KX_LINES) ||
+ if ((mMaterial->ras_mode &WIRE) ||
(rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
{
- if((mMaterial->ras_mode &WIRE)!=0)
+ if (mMaterial->ras_mode &WIRE)
rasty->SetCullFace(false);
rasty->SetLines(true);
}
@@ -570,17 +575,17 @@ void KX_BlenderMaterial::ActivateMeshSlot(const RAS_MeshSlot & ms, RAS_IRasteriz
mShader->Update(ms, rasty);
}
else if(mBlenderShader && GLEW_ARB_shader_objects) {
- int blendmode;
+ int alphablend;
mBlenderShader->Update(ms, rasty);
/* we do blend modes here, because they can change per object
* with the same material due to obcolor/obalpha */
- blendmode = mBlenderShader->GetBlendMode();
- if((blendmode == TF_SOLID || blendmode == TF_ALPHA) && mMaterial->transp != TF_SOLID)
- blendmode = mMaterial->transp;
+ alphablend = mBlenderShader->GetAlphaBlend();
+ if(ELEM3(alphablend, GEMAT_SOLID, GEMAT_ALPHA, GEMAT_ALPHA_SORT) && mMaterial->alphablend != GEMAT_SOLID)
+ alphablend = mMaterial->alphablend;
- rasty->SetBlendingMode(blendmode);
+ rasty->SetAlphaBlend(alphablend);
}
}
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 766e20be825..236bd6afdc8 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -38,7 +38,8 @@ public:
KX_BlenderMaterial();
void Initialize(
class KX_Scene* scene,
- BL_Material* mat
+ BL_Material* mat,
+ GameSettings* game
);
virtual ~KX_BlenderMaterial();
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
index d32f267f0e0..098c136bfa3 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -78,10 +78,10 @@ void KX_PolygonMaterial::Initialize(
int tile,
int tilexrep,
int tileyrep,
- int mode,
- int transp,
+ int alphablend,
bool alpha,
bool zsort,
+ bool light,
int lightlayer,
struct MTFace* tface,
unsigned int* mcol)
@@ -93,10 +93,12 @@ void KX_PolygonMaterial::Initialize(
tile,
tilexrep,
tileyrep,
- mode,
- transp,
+ alphablend,
alpha,
- zsort);
+ zsort,
+ light,
+ (texname && texname != ""?true:false), /* if we have a texture we have image */
+ ma?&ma->game:NULL);
m_tface = tface;
m_mcol = mcol;
m_material = ma;
@@ -168,7 +170,7 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c
if (GetCachingInfo() != cachingInfo)
{
if (!cachingInfo)
- GPU_set_tpage(NULL, 0);
+ GPU_set_tpage(NULL, 0, 0);
cachingInfo = GetCachingInfo();
@@ -176,15 +178,15 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c
{
Image *ima = (Image*)m_tface->tpage;
GPU_update_image_time(ima, rasty->GetTime());
- GPU_set_tpage(m_tface, 1);
+ GPU_set_tpage(m_tface, 1, m_alphablend);
}
else
- GPU_set_tpage(NULL, 0);
+ GPU_set_tpage(NULL, 0, 0);
- if(m_drawingmode & RAS_IRasterizer::KX_TWOSIDE)
- rasty->SetCullFace(false);
- else
+ if(m_drawingmode & RAS_IRasterizer::KX_BACKCULL)
rasty->SetCullFace(true);
+ else
+ rasty->SetCullFace(false);
if ((m_drawingmode & RAS_IRasterizer::KX_LINES) ||
(rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
@@ -318,7 +320,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setTexture, "setTexture(tface)")
if (PyArg_ParseTuple(args, "O!:setTexture", &PyCapsule_Type, &pytface))
{
MTFace *tface = (MTFace*) PyCapsule_GetPointer(pytface, KX_POLYGONMATERIAL_CAPSULE_ID);
- GPU_set_tpage(tface, 1);
+ GPU_set_tpage(tface, 1, m_alphablend);
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index 3520995def3..b09ddd39141 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -78,10 +78,10 @@ public:
int tile,
int tilexrep,
int tileyrep,
- int mode,
- int transp,
+ int alphablend,
bool alpha,
bool zsort,
+ bool light,
int lightlayer,
struct MTFace* tface,
unsigned int* mcol);
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
index 5a1b52489b4..9948f48d7f3 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -36,6 +36,7 @@
#include "DNA_image_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_material_types.h"
void RAS_IPolyMaterial::Initialize(
const STR_String& texname,
@@ -44,10 +45,12 @@ void RAS_IPolyMaterial::Initialize(
int tile,
int tilexrep,
int tileyrep,
- int mode,
- int transp,
+ int alphablend,
bool alpha,
- bool zsort)
+ bool zsort,
+ bool light,
+ bool image,
+ struct GameSettings* game)
{
m_texturename = texname;
m_materialname = matname;
@@ -55,10 +58,10 @@ void RAS_IPolyMaterial::Initialize(
m_tile = tile;
m_tilexrep = tilexrep;
m_tileyrep = tileyrep;
- m_drawingmode = mode;
- m_transp = transp;
+ m_alphablend = alphablend;
m_alpha = alpha;
m_zsort = zsort;
+ m_light = light;
m_polymatid = m_newpolymatid++;
m_flag = 0;
m_multimode = 0;
@@ -66,6 +69,7 @@ void RAS_IPolyMaterial::Initialize(
m_specular.setValue(0.5,0.5,0.5);
m_specularity = 1.0;
m_diffuse.setValue(0.5,0.5,0.5);
+ m_drawingmode = ConvertFaceMode(game, image);
}
RAS_IPolyMaterial::RAS_IPolyMaterial()
@@ -75,9 +79,10 @@ RAS_IPolyMaterial::RAS_IPolyMaterial()
m_tilexrep(0),
m_tileyrep(0),
m_drawingmode (0),
- m_transp(0),
+ m_alphablend(0),
m_alpha(false),
m_zsort(false),
+ m_light(false),
m_materialindex(0),
m_polymatid(0),
m_flag(0),
@@ -95,8 +100,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
int tile,
int tilexrep,
int tileyrep,
- int mode,
- int transp,
+ int alphablend,
bool alpha,
bool zsort)
: m_texturename(texname),
@@ -104,8 +108,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
m_tile(tile),
m_tilexrep(tilexrep),
m_tileyrep(tileyrep),
- m_drawingmode (mode),
- m_transp(transp),
+ m_alphablend(alphablend),
m_alpha(alpha),
m_zsort(zsort),
m_materialindex(materialindex),
@@ -128,9 +131,9 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
this->m_multimode == lhs.m_multimode &&
this->m_flag == lhs.m_flag &&
this->m_drawingmode == lhs.m_drawingmode &&
- this->m_transp == lhs.m_transp &&
- this->m_texturename.hash() == lhs.m_texturename.hash() &&
- this->m_materialname.hash() == lhs.m_materialname.hash()
+ this->m_alphablend == lhs.m_alphablend &&
+ this->m_texturename.hash() == lhs.m_texturename.hash() &&
+ this->m_materialname.hash() == lhs.m_materialname.hash()
);
return test;
@@ -141,9 +144,10 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
this->m_tile == lhs.m_tile &&
this->m_tilexrep == lhs.m_tilexrep &&
this->m_tileyrep == lhs.m_tileyrep &&
- this->m_transp == lhs.m_transp &&
+ this->m_alphablend == lhs.m_alphablend &&
this->m_alpha == lhs.m_alpha &&
this->m_zsort == lhs.m_zsort &&
+ this->m_light == lhs.m_light &&
this->m_drawingmode == lhs.m_drawingmode &&
this->m_texturename.hash() == lhs.m_texturename.hash() &&
this->m_materialname.hash() == lhs.m_materialname.hash()
@@ -151,6 +155,21 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
}
}
+int RAS_IPolyMaterial::ConvertFaceMode(struct GameSettings *game, bool image) const
+{
+ if (!game) return (image?GEMAT_TEX:0);
+
+ int modefinal = 0;
+
+ int orimode = game->face_orientation;
+ int alpha_blend = game->alpha_blend;
+ int flags = game->flag & (GEMAT_TEXT | GEMAT_BACKCULL);
+
+ modefinal = orimode | alpha_blend | flags;
+ modefinal |= (image ? GEMAT_TEX : 0);
+
+ return modefinal;
+}
void RAS_IPolyMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
{
@@ -241,7 +260,7 @@ bool RAS_IPolyMaterial::UsesLighting(RAS_IRasterizer *rasty) const
else if(rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID);
else if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW);
else
- dolights = (m_drawingmode & RAS_IRasterizer::KX_LIGHT)!=0;
+ dolights = m_light;
return dolights;
}
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index 2a5c6a179b6..69d07713c49 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -49,6 +49,7 @@ struct Material;
struct Image;
struct Scene;
class SCA_IScene;
+struct GameSettings;
enum MaterialProps
{
@@ -78,10 +79,11 @@ protected:
STR_HashedString m_materialname; //also needed for touchsensor
int m_tile;
int m_tilexrep,m_tileyrep;
- int m_drawingmode; // tface->mode
- int m_transp;
+ int m_drawingmode;
+ int m_alphablend;
bool m_alpha;
bool m_zsort;
+ bool m_light;
int m_materialindex;
unsigned int m_polymatid;
@@ -102,9 +104,9 @@ public:
// care! these are taken from blender polygonflags, see file DNA_mesh_types.h for #define TF_BILLBOARD etc.
enum MaterialFlags
{
- BILLBOARD_SCREENALIGNED = 256,
- BILLBOARD_AXISALIGNED = 4096,
- SHADOW =8192
+ BILLBOARD_SCREENALIGNED = 512, /* GEMAT_HALO */
+ BILLBOARD_AXISALIGNED = 1024, /* GEMAT_BILLBOARD */
+ SHADOW =2048 /* GEMAT_SHADOW */
};
RAS_IPolyMaterial();
@@ -114,7 +116,6 @@ public:
int tile,
int tilexrep,
int tileyrep,
- int mode,
int transp,
bool alpha,
bool zsort);
@@ -124,10 +125,13 @@ public:
int tile,
int tilexrep,
int tileyrep,
- int mode,
int transp,
bool alpha,
- bool zsort);
+ bool zsort,
+ bool light,
+ bool image,
+ struct GameSettings* game);
+
virtual ~RAS_IPolyMaterial() {};
/**
@@ -174,6 +178,11 @@ public:
virtual void Replace_IScene(SCA_IScene *val) {}; /* overridden by KX_BlenderMaterial */
+ /**
+ * @return the equivalent drawing mode for the material settings (equivalent to old TexFace tface->mode).
+ */
+ int ConvertFaceMode(struct GameSettings *game, bool image) const;
+
/*
* PreCalculate texture gen
*/
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index 877a7219a1c..2988aa4effb 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -68,11 +68,7 @@ class RAS_IRasterizer
public:
RAS_IRasterizer(RAS_ICanvas* canv){};
virtual ~RAS_IRasterizer(){};
- /**
- */
- enum {
- RAS_RENDER_3DPOLYGON_TEXT = 16384 /* TF_BMFONT */
- };
+
/**
* Drawing types
*/
@@ -106,9 +102,9 @@ public:
/**
*/
enum {
- KX_TEX = 4, /* TF_TEX */
- KX_LIGHT = 16, /* TF_LIGHT */
- KX_TWOSIDE = 512, /* TF_TWOSIDE */
+ RAS_RENDER_3DPOLYGON_TEXT = 64, /* GEMAT_TEXT */
+ KX_BACKCULL = 16, /* GEMAT_BACKCULL */
+ KX_TEX = 4096, /* GEMAT_TEX */
KX_LINES = 32768
};
@@ -417,7 +413,7 @@ public:
virtual int GetMotionBlurState()=0;
virtual void SetMotionBlurState(int newstate)=0;
- virtual void SetBlendingMode(int blendmode)=0;
+ virtual void SetAlphaBlend(int alphablend)=0;
virtual void SetFrontFace(bool ccw)=0;
virtual void SetAnisotropicFiltering(short level)=0;
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 6ad9e591474..d9039a2a68d 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -89,7 +89,7 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_motionblurvalue(-1.0),
m_texco_num(0),
m_attrib_num(0),
- //m_last_blendmode(GPU_BLEND_SOLID),
+ //m_last_alphablend(GPU_BLEND_SOLID),
m_last_frontface(true),
m_materialCachingInfo(0)
{
@@ -126,8 +126,8 @@ bool RAS_OpenGLRasterizer::Init()
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
- //m_last_blendmode = GPU_BLEND_SOLID;
- GPU_set_material_blend_mode(GPU_BLEND_SOLID);
+ //m_last_alphablend = GPU_BLEND_SOLID;
+ GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
glFrontFace(GL_CCW);
m_last_frontface = true;
@@ -303,8 +303,8 @@ bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
- //m_last_blendmode = GPU_BLEND_SOLID;
- GPU_set_material_blend_mode(GPU_BLEND_SOLID);
+ //m_last_alphablend = GPU_BLEND_SOLID;
+ GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
glFrontFace(GL_CCW);
m_last_frontface = true;
@@ -873,10 +873,10 @@ void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
// MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
// handle two-side
- if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_TWOSIDE)
- this->SetCullFace(false);
- else
+ if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
this->SetCullFace(true);
+ else
+ this->SetCullFace(false);
if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
// GetMaterialIndex return the original mface material index,
@@ -890,9 +890,9 @@ void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
else
memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
// DM draw can mess up blending mode, restore at the end
- int current_blend_mode = GPU_get_material_blend_mode();
+ int current_blend_mode = GPU_get_material_alpha_blend();
ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
- GPU_set_material_blend_mode(current_blend_mode);
+ GPU_set_material_alpha_blend(current_blend_mode);
} else {
//ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
current_blmat_nr = current_polymat->GetMaterialIndex();
@@ -1204,36 +1204,36 @@ void RAS_OpenGLRasterizer::DisableMotionBlur()
m_motionblurvalue = -1.0;
}
-void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode)
+void RAS_OpenGLRasterizer::SetAlphaBlend(int alphablend)
{
- GPU_set_material_blend_mode(blendmode);
+ GPU_set_material_alpha_blend(alphablend);
/*
- if(blendmode == m_last_blendmode)
+ if(alphablend == m_last_alphablend)
return;
- if(blendmode == GPU_BLEND_SOLID) {
+ if(alphablend == GPU_BLEND_SOLID) {
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
- else if(blendmode == GPU_BLEND_ADD) {
+ else if(alphablend == GPU_BLEND_ADD) {
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
}
- else if(blendmode == GPU_BLEND_ALPHA) {
+ else if(alphablend == GPU_BLEND_ALPHA) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
}
- else if(blendmode == GPU_BLEND_CLIP) {
+ else if(alphablend == GPU_BLEND_CLIP) {
glDisable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
}
- m_last_blendmode = blendmode;
+ m_last_alphablend = alphablend;
*/
}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index c0e02f6df77..cbfa49510a5 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -111,7 +111,7 @@ protected:
TexCoGen m_attrib[RAS_MAX_ATTRIB];
int m_texco_num;
int m_attrib_num;
- //int m_last_blendmode;
+ //int m_last_alphablend;
bool m_last_frontface;
/** Stores the caching information for the last material activated. */
@@ -312,7 +312,7 @@ public:
m_motionblur = newstate;
};
- virtual void SetBlendingMode(int blendmode);
+ virtual void SetAlphaBlend(int alphablend);
virtual void SetFrontFace(bool ccw);
virtual void SetAnisotropicFiltering(short level);