svn merge ^/trunk/blender -r42521:42550

This commit is contained in:
Campbell Barton 2011-12-10 05:38:00 +00:00
commit 65f3b93f14
39 changed files with 574 additions and 290 deletions

@ -1,4 +1,4 @@
.TH "BLENDER" "1" "October 17, 2011" "Blender Blender 2\&.60 (sub 0)"
.TH "BLENDER" "1" "December 10, 2011" "Blender Blender 2\&.60 (sub 7)"
.SH NAME
blender \- a 3D modelling and rendering package
@ -15,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business
http://www.blender.org
.SH OPTIONS
Blender 2.59 (sub 4)
Blender 2.60 (sub 7)
Usage: blender [args ...] [file] [args ...]
.br
.SS "Render Options:"
@ -378,11 +378,10 @@ Arguments are executed in the order they are given. eg
\fIBLENDER_USER_CONFIG\fR Directory for user configuration files.
\fIBLENDER_USER_SCRIPTS\fR Directory for user scripts.
\fIBLENDER_SYSTEM_SCRIPTS\fR Directory for system wide scripts.
\fIBLENDER_USER_DATAFILES\fR Directory for user data files (icons, translations, ..).
\fIBLENDER_USER_DAT`AFILES\fR Directory for user data files (icons, translations, ..).
\fIBLENDER_SYSTEM_DATAFILES\fR Directory for system wide data files.
\fIBLENDER_SYSTEM_PYTHON\fR Directory for system python libraries.
\fITMP\fR or \fITMPDIR\fR Store temporary files here.
\fISDL_AUDIODRIVER\fR LibSDL audio driver \- alsa, esd, dma.
\fIPYTHONHOME\fR Path to the python directory, eg. /usr/lib/python.
.br
.br

@ -233,9 +233,9 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
BL::Object::material_slots_iterator slot;
for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
if(render_layer.material_override)
find_shader(render_layer.material_override, used_shaders);
find_shader(render_layer.material_override, used_shaders, scene->default_surface);
else
find_shader(slot->material(), used_shaders);
find_shader(slot->material(), used_shaders, scene->default_surface);
}
if(used_shaders.size() == 0)

@ -137,7 +137,7 @@ void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob,
/* shader */
vector<uint> used_shaders;
find_shader(b_lamp, used_shaders);
find_shader(b_lamp, used_shaders, scene->default_light);
if(used_shaders.size() == 0)
used_shaders.push_back(scene->default_light);

@ -36,9 +36,9 @@ typedef map<void*, SocketPair> PtrSockMap;
/* Find */
void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders)
void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader)
{
Shader *shader = shader_map.find(id);
Shader *shader = (id)? shader_map.find(id): scene->shaders[default_shader];
for(size_t i = 0; i < scene->shaders.size(); i++) {
if(scene->shaders[i] == shader) {

@ -81,7 +81,7 @@ private:
void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm);
/* util */
void find_shader(BL::ID id, vector<uint>& used_shaders);
void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader);
bool object_is_modified(BL::Object b_ob);
bool object_is_mesh(BL::Object b_ob);
bool object_is_light(BL::Object b_ob);

@ -65,19 +65,45 @@ def load_image(imagepath,
# TODO: recursive
# -------------------------------------------------------------------------
# Utility Functions
def _image_load_placeholder(path):
name = bpy.path.basename(path)
if type(name) == bytes:
name = name.decode('utf-8', "replace")
image = bpy.data.images.new(name, 128, 128)
# allow the path to be resolved later
image.filepath = path
image.source = 'FILE'
return image
def _image_load(path):
import bpy
if convert_callback:
path = convert_callback(path)
image = bpy.data.images.load(path)
try:
image = bpy.data.images.load(path)
except RuntimeError:
image = None
if verbose:
print(" image loaded '%s'" % path)
if image:
print(" image loaded '%s'" % path)
else:
print(" image load failed '%s'" % path)
# image path has been checked so the path could not be read for some
# reason, so be sure to return a placeholder
if place_holder:
image = _image_load_placeholder(path)
return image
# -------------------------------------------------------------------------
if verbose:
print("load_image('%s', '%s', ...)" % (imagepath, dirname))
@ -103,11 +129,9 @@ def load_image(imagepath,
if os.path.exists(nfilepath):
return _image_load(nfilepath)
# None of the paths exist so return placeholder
if place_holder:
image = bpy.data.images.new(bpy.path.basename(imagepath), 128, 128)
# allow the path to be resolved later
image.filepath = imagepath
return image
return _image_load_placeholder(imagepath)
# TODO comprehensiveImageLoad also searched in bpy.config.textureDir
return None

@ -22,6 +22,7 @@ import bpy
from bpy.types import Operator
from mathutils import Vector
def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min):
import random
@ -42,8 +43,13 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min):
else: # otherwise the values change under us
uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0)
if rot: # TODO, non euler's
if rot:
vec = rand_vec(rot)
rotation_mode = obj.rotation_mode
if rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}:
obj.rotation_mode = 'XYZ'
if delta:
obj.delta_rotation_euler[0] += vec[0]
obj.delta_rotation_euler[1] += vec[1]
@ -52,6 +58,7 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min):
obj.rotation_euler[0] += vec[0]
obj.rotation_euler[1] += vec[1]
obj.rotation_euler[2] += vec[2]
obj.rotation_mode = rotation_mode
else:
uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0)

@ -457,8 +457,8 @@ class WM_OT_context_cycle_enum(Operator):
class WM_OT_context_cycle_array(Operator):
'''Set a context array value.
Useful for cycling the active mesh edit mode'''
'''Set a context array value. '''
'''Useful for cycling the active mesh edit mode'''
bl_idname = "wm.context_cycle_array"
bl_label = "Context Array Cycle"
bl_options = {'UNDO', 'INTERNAL'}

@ -128,6 +128,7 @@ struct DerivedMesh {
BVHCache bvhCache;
struct GPUDrawObject *drawObject;
DerivedMeshType type;
float auto_bump_scale;
/* calculate vert and face normals */
void (*calcNormals)(DerivedMesh *dm);
@ -655,6 +656,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm,
struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs);
void DM_add_tangent_layer(DerivedMesh *dm);
void DM_calc_auto_bump_scale(DerivedMesh *dm);
/* Set object's bounding box based on DerivedMesh min/max data */
void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm);

@ -63,7 +63,7 @@ void defvert_copy_index(struct MDeformVert *dvert_dst, const struct MDeformVert
void defvert_sync(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, int use_verify);
void defvert_sync_mapped(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src,
const int *flip_map, const int flip_map_len, const int use_verify);
void defvert_remap (struct MDeformVert *dvert, int *map);
void defvert_remap (struct MDeformVert *dvert, int *map, const int map_len);
void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
void defvert_normalize(struct MDeformVert *dvert);

@ -276,6 +276,7 @@ void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges,
DM_init_funcs(dm);
dm->needsFree = 1;
dm->auto_bump_scale = -1.0f;
}
void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type,
@ -883,7 +884,7 @@ enum {
};
static void calc_weightpaint_vert_color(
Object *ob, ColorBand *coba, int vert, unsigned char *col,
Object *ob, const int defbase_tot, ColorBand *coba, int vert, unsigned char *col,
const char *dg_flags, int selected, int UNUSED(unselected), const int draw_flag)
{
Mesh *me = ob->data;
@ -902,10 +903,12 @@ static void calc_weightpaint_vert_color(
for (i = dvert->totweight; i > 0; i--, dw++) {
/* in multipaint, get the average if auto normalize is inactive
* get the sum if it is active */
if (dg_flags[dw->def_nr]) {
if (dw->weight) {
input += dw->weight;
was_a_nonzero= TRUE;
if (dw->def_nr < defbase_tot) {
if (dg_flags[dw->def_nr]) {
if (dw->weight) {
input += dw->weight;
was_a_nonzero= TRUE;
}
}
}
}
@ -964,10 +967,10 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
int i, j, totface=dm->getNumTessFaces(dm), totloop;
int *origIndex = dm->getVertDataArray(dm, CD_ORIGINDEX);
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;
int defbase_tot = BLI_countlist(&ob->defbase);
char *defbase_sel = MEM_mallocN(defbase_tot * sizeof(char), __func__);
int selected = get_selected_defgroups(ob, defbase_sel, defbase_tot);
int unselected = defbase_tot - selected;
wtcol = MEM_callocN (sizeof (unsigned char) * totface*4*4, "weightmap");
@ -975,11 +978,11 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
memset(wtcol, 0x55, sizeof (unsigned char) * totface*4*4);
for (i=0; i<totface; i++, mf++) {
/*origindex being NULL means we're operating on original mesh data*/
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);
calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag);
calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag);
calc_weightpaint_vert_color(ob, defbase_tot, 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], defbase_sel, selected, unselected, draw_flag);
calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag);
}
CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, totface);
@ -992,7 +995,7 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
for (j=0; j<mp->totloop; j++, ml++, totloop++) {
BLI_array_growone(wlcol);
calc_weightpaint_vert_color(ob, coba, origIndex ? origIndex[ml->v] : ml->v,
calc_weightpaint_vert_color(ob, defbase_tot, coba, origIndex ? origIndex[ml->v] : ml->v,
(unsigned char *)&wlcol[totloop], defbase_sel, selected, unselected, draw_flag);
}
}
@ -2222,6 +2225,159 @@ void DM_add_tangent_layer(DerivedMesh *dm)
MEM_freeN(vtangents);
}
void DM_calc_auto_bump_scale(DerivedMesh *dm)
{
/* int totvert= dm->getNumVerts(dm); */ /* UNUSED */
int totface= dm->getNumTessFaces(dm);
MVert * mvert = dm->getVertArray(dm);
MFace * mface = dm->getTessFaceArray(dm);
MTFace * mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
if(mtface)
{
double dsum = 0.0;
int nr_accumulated = 0;
int f;
for ( f=0; f<totface; f++ )
{
{
float * verts[4], * tex_coords[4];
const int nr_verts = mface[f].v4!=0 ? 4 : 3;
int i, is_degenerate;
verts[0]=mvert[mface[f].v1].co; verts[1]=mvert[mface[f].v2].co; verts[2]=mvert[mface[f].v3].co;
tex_coords[0]=mtface[f].uv[0]; tex_coords[1]=mtface[f].uv[1]; tex_coords[2]=mtface[f].uv[2];
if(nr_verts==4)
{
verts[3]=mvert[mface[f].v4].co;
tex_coords[3]=mtface[f].uv[3];
}
// discard degenerate faces
is_degenerate = 0;
if( equals_v3v3(verts[0], verts[1]) || equals_v3v3(verts[0], verts[2]) || equals_v3v3(verts[1], verts[2]) ||
equals_v2v2(tex_coords[0], tex_coords[1]) || equals_v2v2(tex_coords[0], tex_coords[2]) || equals_v2v2(tex_coords[1], tex_coords[2]) )
{
is_degenerate = 1;
}
// verify last vertex as well if this is a quad
if ( is_degenerate==0 && nr_verts==4 )
{
if( equals_v3v3(verts[3], verts[0]) || equals_v3v3(verts[3], verts[1]) || equals_v3v3(verts[3], verts[2]) ||
equals_v2v2(tex_coords[3], tex_coords[0]) || equals_v2v2(tex_coords[3], tex_coords[1]) || equals_v2v2(tex_coords[3], tex_coords[2]) )
{
is_degenerate = 1;
}
// verify the winding is consistent
if ( is_degenerate==0 )
{
float prev_edge[2];
int is_signed = 0;
sub_v2_v2v2(prev_edge, tex_coords[0], tex_coords[3]);
i = 0;
while ( is_degenerate==0 && i<4 )
{
float cur_edge[2], signed_area;
sub_v2_v2v2(cur_edge, tex_coords[(i+1)&0x3], tex_coords[i]);
signed_area = prev_edge[0]*cur_edge[1] - prev_edge[1]*cur_edge[0];
if ( i==0 ) is_signed = signed_area<0.0f ? 1 : 0;
else if((is_signed!=0)!=(signed_area<0.0f)) is_degenerate=1;
if ( is_degenerate==0 )
{
copy_v2_v2(prev_edge, cur_edge);
++i;
}
}
}
}
// proceed if not a degenerate face
if ( is_degenerate==0 )
{
int nr_tris_to_pile=0;
// quads split at shortest diagonal
int offs = 0; // initial triangulation is 0,1,2 and 0, 2, 3
if ( nr_verts==4 )
{
float pos_len_diag0, pos_len_diag1;
float vtmp[3];
sub_v3_v3v3(vtmp, verts[2], verts[0]);
pos_len_diag0 = dot_v3v3(vtmp, vtmp);
sub_v3_v3v3(vtmp, verts[3], verts[1]);
pos_len_diag1 = dot_v3v3(vtmp, vtmp);
if(pos_len_diag1<pos_len_diag0)
offs=1; // alter split
else if(pos_len_diag0==pos_len_diag1) // do UV check instead
{
float tex_len_diag0, tex_len_diag1;
sub_v2_v2v2(vtmp, tex_coords[2], tex_coords[0]);
tex_len_diag0 = dot_v2v2(vtmp, vtmp);
sub_v2_v2v2(vtmp, tex_coords[3], tex_coords[1]);
tex_len_diag1 = dot_v2v2(vtmp, vtmp);
if(tex_len_diag1<tex_len_diag0)
{
offs=1; // alter split
}
}
}
nr_tris_to_pile = nr_verts-2 ;
if ( nr_tris_to_pile==1 || nr_tris_to_pile==2 )
{
const int indices[] = {offs+0, offs+1, offs+2, offs+0, offs+2, (offs+3)&0x3 };
int t;
for ( t=0; t<nr_tris_to_pile; t++ )
{
float f2x_area_uv;
float * p0 = verts[indices[t*3+0]];
float * p1 = verts[indices[t*3+1]];
float * p2 = verts[indices[t*3+2]];
float edge_t0[2], edge_t1[2];
sub_v2_v2v2(edge_t0, tex_coords[indices[t*3+1]], tex_coords[indices[t*3+0]]);
sub_v2_v2v2(edge_t1, tex_coords[indices[t*3+2]], tex_coords[indices[t*3+0]]);
f2x_area_uv = fabsf(edge_t0[0]*edge_t1[1] - edge_t0[1]*edge_t1[0]);
if ( f2x_area_uv>FLT_EPSILON )
{
float norm[3], v0[3], v1[3], f2x_surf_area, fsurf_ratio;
sub_v3_v3v3(v0, p1, p0);
sub_v3_v3v3(v1, p2, p0);
cross_v3_v3v3(norm, v0, v1);
f2x_surf_area = len_v3(norm);
fsurf_ratio = f2x_surf_area/f2x_area_uv; // tri area divided by texture area
++nr_accumulated;
dsum += (double)(fsurf_ratio);
}
}
}
}
}
}
// finalize
{
const float avg_area_ratio = (nr_accumulated>0) ? ((float)(dsum / nr_accumulated)) : 1.0f;
const float use_as_render_bump_scale = sqrtf(avg_area_ratio); // use width of average surface ratio as your bump scale
dm->auto_bump_scale = use_as_render_bump_scale;
}
}
else
{
dm->auto_bump_scale = 1.0f;
}
}
void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs)
{
CustomData *vdata, *fdata, *tfdata = NULL;
@ -2235,6 +2391,15 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
vdata = &dm->vertData;
fdata = tfdata = dm->getTessFaceDataLayout(dm);
/* calc auto bump scale if necessary */
#if 0
if(dm->auto_bump_scale<=0.0f)
DM_calc_auto_bump_scale(dm);
#else
dm->auto_bump_scale = 1.0f; // will revert this after release
#endif
/* add a tangent layer if necessary */
for(b = 0; b < gattribs->totlayer; b++)
if(gattribs->layer[b].type == CD_TANGENT)

@ -827,7 +827,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
const short use_envelope = deformflag & ARM_DEF_ENVELOPE;
const short use_quaternion = deformflag & ARM_DEF_QUATERNION;
const short invert_vgroup= deformflag & ARM_DEF_INVERT_VGROUP;
int numGroups = 0; /* safety for vertexgroup index overflow */
int defbase_tot = 0; /* safety for vertexgroup index overflow */
int i, target_totvert = 0; /* safety for vertexgroup overflow */
int use_dverts = 0;
int armature_def_nr;
@ -869,7 +869,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
armature_def_nr= defgroup_name_index(target, defgrp_name);
if(ELEM(target->type, OB_MESH, OB_LATTICE)) {
numGroups = BLI_countlist(&target->defbase);
defbase_tot = BLI_countlist(&target->defbase);
if(target->type==OB_MESH) {
Mesh *me= target->data;
@ -896,8 +896,8 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
else if(dverts) use_dverts = 1;
if(use_dverts) {
defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups, "defnrToBone");
defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * numGroups, "defnrToIndex");
defnrToPC = MEM_callocN(sizeof(*defnrToPC) * defbase_tot, "defnrToBone");
defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * defbase_tot, "defnrToIndex");
for(i = 0, dg = target->defbase.first; dg;
i++, dg = dg->next) {
defnrToPC[i] = get_pose_channel(armOb->pose, dg->name);
@ -975,7 +975,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
for(j = 0; j < dvert->totweight; j++){
int index = dvert->dw[j].def_nr;
if(index < numGroups && (pchan= defnrToPC[index])) {
if(index < defbase_tot && (pchan= defnrToPC[index])) {
float weight = dvert->dw[j].weight;
Bone *bone= pchan->bone;
pdef_info= pdef_info_array + defnrToPCIndex[index];
@ -2473,7 +2473,7 @@ 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)
int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_tot)
{
bDeformGroup *defgroup;
unsigned int i;
@ -2482,7 +2482,7 @@ int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_len)
if(armob) {
bPose *pose= armob->pose;
for (i= 0, defgroup= ob->defbase.first; i < defbase_len && defgroup; defgroup = defgroup->next, i++) {
for (i= 0, defgroup= ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
bPoseChannel *pchan= get_pose_channel(pose, defgroup->name);
if(pchan && (pchan->bone->flag & BONE_SELECTED)) {
dg_selection[i]= TRUE;
@ -2494,7 +2494,7 @@ int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_len)
}
}
else {
memset(dg_selection, FALSE, sizeof(char) * defbase_len);
memset(dg_selection, FALSE, sizeof(char) * defbase_tot);
}
return dg_flags_sel_tot;

@ -164,12 +164,14 @@ void defvert_sync_mapped(MDeformVert *dvert_dst, const MDeformVert *dvert_src,
}
/* be sure all flip_map values are valid */
void defvert_remap(MDeformVert *dvert, int *map)
void defvert_remap(MDeformVert *dvert, int *map, const int map_len)
{
MDeformWeight *dw;
int i;
for (i=0, dw=dvert->dw; i<dvert->totweight; i++, dw++) {
dw->def_nr= map[dw->def_nr];
if (dw->def_nr < map_len) {
dw->def_nr= map[dw->def_nr];
}
}
}
@ -201,8 +203,10 @@ void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_le
int i;
for (dw= dvert->dw, i=0; i<dvert->totweight; dw++, i++) {
if ((dw->def_nr < flip_map_len) && (flip_map[dw->def_nr] >= 0)) {
dw->def_nr= flip_map[dw->def_nr];
if (dw->def_nr < flip_map_len) {
if (flip_map[dw->def_nr] >= 0) {
dw->def_nr= flip_map[dw->def_nr];
}
}
}
}
@ -286,17 +290,17 @@ int defgroup_find_index(Object *ob, bDeformGroup *dg)
/* note, must be freed */
int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default)
{
int totdg= *flip_map_len= BLI_countlist(&ob->defbase);
int defbase_tot= *flip_map_len= BLI_countlist(&ob->defbase);
if (totdg==0) {
if (defbase_tot==0) {
return NULL;
}
else {
bDeformGroup *dg;
char name[sizeof(dg->name)];
int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__);
int i, flip_num, *map= MEM_mallocN(defbase_tot * sizeof(int), __func__);
for (i=0; i < totdg; i++) {
for (i=0; i < defbase_tot; i++) {
map[i]= -1;
}
@ -324,17 +328,17 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default)
/* note, must be freed */
int *defgroup_flip_map_single(Object *ob, int *flip_map_len, int use_default, int defgroup)
{
int totdg= *flip_map_len= BLI_countlist(&ob->defbase);
int defbase_tot= *flip_map_len= BLI_countlist(&ob->defbase);
if (totdg==0) {
if (defbase_tot==0) {
return NULL;
}
else {
bDeformGroup *dg;
char name[sizeof(dg->name)];
int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__);
int i, flip_num, *map= MEM_mallocN(defbase_tot * sizeof(int), __func__);
for (i=0; i < totdg; i++) {
for (i=0; i < defbase_tot; i++) {
if (use_default) map[i]= i;
else map[i]= -1;
}
@ -413,11 +417,15 @@ void flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_
char number[MAX_VGROUP_NAME]= ""; /* The number extension string */
char *index=NULL;
len= BLI_strnlen(from_name, MAX_VGROUP_NAME);
if (len < 3) return; // we don't do names like .R or .L
/* always copy the name, since this can be called with an uninitialized string */
BLI_strncpy(name, from_name, MAX_VGROUP_NAME);
len= BLI_strnlen(from_name, MAX_VGROUP_NAME);
if (len < 3) {
/* we don't do names like .R or .L */
return;
}
/* We first check the case with a .### extension, let's find the last period */
if (isdigit(name[len-1])) {
index= strrchr(name, '.'); // last occurrence

@ -619,7 +619,10 @@ static void emDM_drawMappedFaces(
{
EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
BMFace *efa;
int i, draw;
struct BMLoop *(*looptris)[3]= bmdm->tc->looptris;
const int tottri= bmdm->tc->tottri;
const int lasttri= tottri - 1; /* compare agasint this a lot */
int i, draw, flush;
const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
/* GL_ZERO is used to detect if drawing has started or not */
@ -639,8 +642,8 @@ static void emDM_drawMappedFaces(
BM_ElemIndex_Ensure(bmdm->tc->bm, BM_VERT | BM_FACE);
for (i=0; i<bmdm->tc->tottri; i++) {
BMLoop **l = bmdm->tc->looptris[i];
for (i=0; i < tottri; i++) {
BMLoop **l = looptris[i];
int drawSmooth;
efa = l[0]->f;
@ -695,7 +698,11 @@ static void emDM_drawMappedFaces(
}
}
if (draw==2) {
flush= (draw==2);
if (!skip_normals && !flush && (i != lasttri))
flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
if (flush) {
glEnd();
poly_prev= GL_ZERO; /* force glBegin */
@ -707,8 +714,8 @@ static void emDM_drawMappedFaces(
else {
BM_ElemIndex_Ensure(bmdm->tc->bm, BM_FACE);
for (i=0; i<bmdm->tc->tottri; i++) {
BMLoop **l = bmdm->tc->looptris[i];
for (i=0; i < tottri; i++) {
BMLoop **l = looptris[i];
int drawSmooth;
efa = l[0]->f;
@ -763,8 +770,12 @@ static void emDM_drawMappedFaces(
}
}
flush= (draw==2);
if (!skip_normals && !flush && (i != lasttri)) {
flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
}
if (draw==2) {
if (flush) {
glEnd();
poly_prev= GL_ZERO; /* force glBegin */

@ -136,9 +136,11 @@ int BKE_mesh_validate_arrays( Mesh *me,
MVert *mvert= mverts;
unsigned int i;
int do_face_free= FALSE;
int do_edge_free= FALSE;
int verts_fixed= FALSE;
short do_face_free= FALSE;
short do_edge_free= FALSE;
short verts_fixed= FALSE;
short vert_weights_fixed= FALSE;
int do_edge_recalc= FALSE;
@ -165,9 +167,12 @@ int BKE_mesh_validate_arrays( Mesh *me,
for(j=0; j<3; j++) {
if(!finite(mvert->co[j])) {
PRINT(" vertex %u: has invalid coordinate\n", i);
zero_v3(mvert->co);
verts_fixed= TRUE;
if (do_fixes) {
zero_v3(mvert->co);
verts_fixed= TRUE;
}
}
if(mvert->no[j]!=0)
@ -176,8 +181,10 @@ int BKE_mesh_validate_arrays( Mesh *me,
if(fix_normal) {
PRINT(" vertex %u: has zero normal, assuming Z-up normal\n", i);
mvert->no[2]= SHRT_MAX;
verts_fixed= TRUE;
if (do_fixes) {
mvert->no[2]= SHRT_MAX;
verts_fixed= TRUE;
}
}
}
@ -318,8 +325,8 @@ int BKE_mesh_validate_arrays( Mesh *me,
if (dverts) {
MDeformVert *dv;
for(i=0, dv= dverts; i<totvert; i++, dv++) {
MDeformWeight *dw= dv->dw;
unsigned int j= 0;
MDeformWeight *dw;
unsigned int j;
for(j=0, dw= dv->dw; j < dv->totweight; j++, dw++) {
/* note, greater then max defgroups is accounted for in our code, but not < 0 */
@ -327,6 +334,14 @@ int BKE_mesh_validate_arrays( Mesh *me,
PRINT(" vertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
if (do_fixes) {
dw->weight= 0.0f;
vert_weights_fixed= TRUE;
}
}
else if (dw->weight < 0.0f || dw->weight > 1.0f) {
PRINT(" vertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
if (do_fixes) {
CLAMP(dw->weight, 0.0f, 1.0f);
vert_weights_fixed= TRUE;
}
}
@ -339,6 +354,8 @@ int BKE_mesh_validate_arrays( Mesh *me,
* within the for loop and may not be valid */
j--;
dw= dv->dw + j;
vert_weights_fixed= TRUE;
}
else { /* all freed */
break;
@ -369,7 +386,7 @@ int BKE_mesh_validate_arrays( Mesh *me,
}
}
return (verts_fixed || do_face_free || do_edge_free || do_edge_recalc);
return (verts_fixed || vert_weights_fixed || do_face_free || do_edge_free || do_edge_recalc);
}
static int mesh_validate_customdata(CustomData *data, short do_verbose, const short do_fixes)

@ -81,6 +81,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "BKE_deform.h"
#include "RE_render_ext.h"
@ -1849,20 +1850,6 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in
/************************************************/
/* Path Cache */
/************************************************/
static float vert_weight(MDeformVert *dvert, int group)
{
MDeformWeight *dw;
int i;
if(dvert) {
dw= dvert->dw;
for(i= dvert->totweight; i>0; i--, dw++) {
if(dw->def_nr == group) return dw->weight;
if(i==1) break; /*otherwise dw will point to somewhere it shouldn't*/
}
}
return 0.0;
}
static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat, short type, short axis, float obmat[][4], int smooth_start)
{
@ -2310,11 +2297,11 @@ float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup)
vg=MEM_callocN(sizeof(float)*totvert, "vg_cache");
if(psys->vg_neg&(1<<vgroup)){
for(i=0; i<totvert; i++)
vg[i]=1.0f-vert_weight(dvert+i,psys->vgroup[vgroup]-1);
vg[i]= 1.0f - defvert_find_weight(&dvert[i], psys->vgroup[vgroup] - 1);
}
else{
for(i=0; i<totvert; i++)
vg[i]=vert_weight(dvert+i,psys->vgroup[vgroup]-1);
vg[i]= defvert_find_weight(&dvert[i], psys->vgroup[vgroup] - 1);
}
}
}

@ -78,7 +78,8 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
/* try to resolve the path */
if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
char *structname=NULL, *propname=NULL, arrayindbuf[16];
const char *structname=NULL, *propname=NULL;
char arrayindbuf[16];
const char *arrayname=NULL;
short free_structname = 0;
@ -122,11 +123,11 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
free_structname= 1;
}
else
structname= (char *)RNA_struct_ui_name(ptr.type);
structname= RNA_struct_ui_name(ptr.type);
}
/* Property Name is straightforward */
propname= (char *)RNA_property_ui_name(prop);
propname= RNA_property_ui_name(prop);
/* Array Index - only if applicable */
if (RNA_property_array_length(&ptr, prop)) {
@ -153,7 +154,7 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
/* free temp name if nameprop is set */
if (free_structname)
MEM_freeN(structname);
MEM_freeN((void *)structname);
/* Icon for this property's owner:

@ -524,7 +524,8 @@ static float setting_get_rna_value (PointerRNA *ptr, PropertyRNA *prop, int inde
enum {
VISUALKEY_NONE = 0,
VISUALKEY_LOC,
VISUALKEY_ROT,
VISUALKEY_ROT
/* VISUALKEY_SCA */ /* TODO - looks like support can be added now */
};
/* This helper function determines if visual-keyframing should be used when
@ -655,7 +656,7 @@ static short visualkey_can_use (PointerRNA *ptr, PropertyRNA *prop)
*/
static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_index)
{
char *identifier= (char *)RNA_property_identifier(prop);
const char *identifier= RNA_property_identifier(prop);
/* handle for Objects or PoseChannels only
* - constraints can be on either Objects or PoseChannels, so we only check if the

@ -161,7 +161,7 @@ void ED_armature_edit_bone_remove(bArmature *arm, EditBone *exBone)
EditBone *ED_armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo)
{
EditBone *eboflip= NULL;
char name[32];
char name[MAXBONENAME];
if (ebo == NULL)
return NULL;
@ -4663,7 +4663,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob,
/* find flipped group */
if (dgroup && mirror) {
char name[32];
char name[MAXBONENAME];
// 0 = don't strip off number extensions
flip_side_name(name, dgroup->name, FALSE);
@ -5456,7 +5456,7 @@ static int armature_flip_names_exec (bContext *C, wmOperator *UNUSED(op))
{
Object *ob= CTX_data_edit_object(C);
bArmature *arm;
char newname[32];
char newname[MAXBONENAME];
/* paranoia checks */
if (ELEM(NULL, ob, ob->pose))

@ -989,7 +989,7 @@ static void set_pose_keys (Object *ob)
static bPoseChannel *pose_bone_do_paste (Object *ob, bPoseChannel *chan, short selOnly, short flip)
{
bPoseChannel *pchan;
char name[32];
char name[MAXBONENAME];
short paste_ok;
/* get the name - if flipping, we must flip this first */
@ -1740,7 +1740,7 @@ static int pose_flip_names_exec (bContext *C, wmOperator *UNUSED(op))
/* loop through selected bones, auto-naming them */
CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
{
char newname[32];
char newname[MAXBONENAME];
flip_side_name(newname, pchan->name, TRUE);
ED_armature_bone_rename(arm, pchan->name, newname);
}

@ -895,7 +895,7 @@ static int object_delete_exec(bContext *C, wmOperator *op)
{
Main *bmain= CTX_data_main(C);
Scene *scene= CTX_data_scene(C);
const short use_global= RNA_boolean_get(op->ptr, "global");
const short use_global= RNA_boolean_get(op->ptr, "use_global");
/* int islamp= 0; */ /* UNUSED */
if(CTX_data_edit_object(C))
@ -953,7 +953,7 @@ void OBJECT_OT_delete(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "global", 0, "Delete Globally", "Remove object from all scenes");
RNA_def_boolean(ot->srna, "use_global", 0, "Delete Globally", "Remove object from all scenes");
}
/**************************** Copy Utilities ******************************/

@ -339,9 +339,9 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "global", TRUE);
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "use_global", TRUE);
WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "global", TRUE);
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "use_global", TRUE);
WM_keymap_add_menu(keymap, "INFO_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0);

@ -41,6 +41,7 @@
#include "DNA_modifier_types.h"
#include "DNA_property_types.h"
#include "DNA_scene_types.h"
#include "DNA_armature_types.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
@ -893,7 +894,7 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op)
extend= RNA_boolean_get(op->ptr, "extend");
CTX_DATA_BEGIN(C, Base*, primbase, selected_bases) {
char tmpname[32];
char tmpname[MAXBONENAME];
flip_side_name(tmpname, primbase->object->id.name+2, TRUE);

@ -290,8 +290,8 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from)
int dvert_tot_from;
int dvert_tot;
int i;
int totdef_from= BLI_countlist(&ob_from->defbase);
int totdef= BLI_countlist(&ob->defbase);
int defbase_tot_from= BLI_countlist(&ob_from->defbase);
int defbase_tot= BLI_countlist(&ob->defbase);
short new_vgroup= FALSE;
ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from);
@ -318,11 +318,11 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from)
BLI_duplicatelist(&ob->defbase, &ob_from->defbase);
ob->actdef= ob_from->actdef;
if(totdef_from < totdef) {
if(defbase_tot_from < defbase_tot) {
/* correct vgroup indices because the number of vgroups is being reduced. */
int *remap= MEM_mallocN(sizeof(int) * (totdef + 1), "ED_vgroup_copy_array");
for(i=0; i<=totdef_from; i++) remap[i]= i;
for(; i<=totdef; i++) remap[i]= 0; /* can't use these, so disable */
int *remap= MEM_mallocN(sizeof(int) * (defbase_tot + 1), "ED_vgroup_copy_array");
for(i=0; i<=defbase_tot_from; i++) remap[i]= i;
for(; i<=defbase_tot; i++) remap[i]= 0; /* can't use these, so disable */
vgroup_remap_update_users(ob, remap);
MEM_freeN(remap);
@ -1814,12 +1814,12 @@ static void vgroup_remap_update_users(Object *ob, int *map)
static void vgroup_delete_update_users(Object *ob, int id)
{
int i, tot= BLI_countlist(&ob->defbase) + 1;
int *map= MEM_mallocN(sizeof(int) * tot, "vgroup del");
int i, defbase_tot= BLI_countlist(&ob->defbase) + 1;
int *map= MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del");
map[id]= map[0]= 0;
for(i=1; i<id; i++) map[i]=i;
for(i=id+1; i<tot; i++) map[i]=i-1;
for(i=id+1; i<defbase_tot; i++) map[i]=i-1;
vgroup_remap_update_users(ob, map);
MEM_freeN(map);
@ -2822,8 +2822,8 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
static char *vgroup_init_remap(Object *ob)
{
bDeformGroup *def;
int def_tot = BLI_countlist(&ob->defbase);
char *name_array= MEM_mallocN(MAX_VGROUP_NAME * sizeof(char) * def_tot, "sort vgroups");
int defbase_tot = BLI_countlist(&ob->defbase);
char *name_array= MEM_mallocN(MAX_VGROUP_NAME * sizeof(char) * defbase_tot, "sort vgroups");
char *name;
name= name_array;
@ -2839,8 +2839,8 @@ static int vgroup_do_remap(Object *ob, char *name_array, wmOperator *op)
{
MDeformVert *dvert= NULL;
bDeformGroup *def;
int def_tot = BLI_countlist(&ob->defbase);
int *sort_map_update= MEM_mallocN(sizeof(int) * (def_tot + 1), "sort vgroups"); /* needs a dummy index at the start*/
int defbase_tot = BLI_countlist(&ob->defbase);
int *sort_map_update= MEM_mallocN(sizeof(int) * (defbase_tot + 1), "sort vgroups"); /* needs a dummy index at the start*/
int *sort_map= sort_map_update + 1;
char *name;
int i;
@ -2862,7 +2862,7 @@ static int vgroup_do_remap(Object *ob, char *name_array, wmOperator *op)
BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
if(dvert && dvert->totweight){
defvert_remap(dvert, sort_map);
defvert_remap(dvert, sort_map, defbase_tot);
}
}
}
@ -2880,13 +2880,13 @@ static int vgroup_do_remap(Object *ob, char *name_array, wmOperator *op)
/*create as necassary*/
while(dvert && dvert_tot--) {
if(dvert->totweight)
defvert_remap(dvert, sort_map);
defvert_remap(dvert, sort_map, defbase_tot);
dvert++;
}
}
/* update users */
for(i=0; i<def_tot; i++)
for(i=0; i<defbase_tot; i++)
sort_map[i]++;
sort_map_update[0]= 0;

@ -1047,11 +1047,11 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
index= view3d_sample_backbuf(&vc, win->eventstate->x - vc.ar->winrct.xmin, win->eventstate->y - vc.ar->winrct.ymin);
if(index && index<=me->totface) {
const int totgroup= BLI_countlist(&vc.obact->defbase);
if(totgroup) {
const int defbase_tot= BLI_countlist(&vc.obact->defbase);
if(defbase_tot) {
MPoly *mf= ((MPoly *)me->mpoly) + index-1;
unsigned int fidx= mf->totloop - 1;
int *groups= MEM_callocN(totgroup*sizeof(int), "groups");
int *groups= MEM_callocN(defbase_tot*sizeof(int), "groups");
int found= FALSE;
do {
@ -1059,8 +1059,10 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
int i= dvert->totweight;
MDeformWeight *dw;
for(dw= dvert->dw; i > 0; dw++, i--) {
groups[dw->def_nr]= TRUE;
found= TRUE;
if (dw->def_nr < defbase_tot) {
groups[dw->def_nr]= TRUE;
found= TRUE;
}
}
} while (fidx--);
@ -1072,7 +1074,7 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
int totitem= 0;
int i= 0;
bDeformGroup *dg;
for(dg= vc.obact->defbase.first; dg && i<totgroup; i++, dg= dg->next) {
for(dg= vc.obact->defbase.first; dg && i<defbase_tot; i++, dg= dg->next) {
if(groups[i]) {
item_tmp.identifier= item_tmp.name= dg->name;
item_tmp.value= i;
@ -1171,7 +1173,8 @@ 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, const char *vgroup_validmap, char do_auto_normalize)
static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const int defbase_tot,
const char *vgroup_validmap, char do_auto_normalize)
{
if (do_auto_normalize == FALSE) {
return;
@ -1182,9 +1185,11 @@ static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const
MDeformWeight *dw;
for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
if (vgroup_validmap[dw->def_nr]) {
tot++;
sum += dw->weight;
if (dw->def_nr < defbase_tot) {
if (vgroup_validmap[dw->def_nr]) {
tot++;
sum += dw->weight;
}
}
}
@ -1195,8 +1200,10 @@ static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const
fac= 1.0f / sum;
for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
if (vgroup_validmap[dw->def_nr]) {
dw->weight *= fac;
if (dw->def_nr < defbase_tot) {
if (vgroup_validmap[dw->def_nr]) {
dw->weight *= fac;
}
}
}
}
@ -1205,12 +1212,17 @@ static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const
/*
See if the current deform vertex has a locked group
*/
static char has_locked_group(MDeformVert *dvert, const char *lock_flags)
static char has_locked_group(MDeformVert *dvert, const int defbase_tot,
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;
MDeformWeight *dw;
for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
if (dw->def_nr < defbase_tot) {
if (lock_flags[dw->def_nr] && dw->weight > 0.0f) {
return TRUE;
}
}
}
return FALSE;
@ -1239,7 +1251,7 @@ static char *gen_lock_flags(Object* ob, int defbase_tot)
return NULL;
}
static int has_locked_group_selected(int defbase_tot, char *defbase_sel, char *lock_flags)
static int has_locked_group_selected(int defbase_tot, const char *defbase_sel, const char *lock_flags)
{
int i;
for(i = 0; i < defbase_tot; i++) {
@ -1268,7 +1280,7 @@ static int has_unselected_unlocked_bone_group(int defbase_tot, char *defbase_sel
#endif
static void multipaint_selection(MDeformVert *dvert, float change, char *defbase_sel, int defbase_tot)
static void multipaint_selection(MDeformVert *dvert, const int defbase_tot, float change, const char *defbase_sel)
{
int i;
MDeformWeight *dw;
@ -1307,7 +1319,10 @@ static void multipaint_selection(MDeformVert *dvert, float change, char *defbase
/* 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)
static float redistribute_change(MDeformVert *ndv, const int defbase_tot,
char *change_status, const char change_me, int changeto,
float totchange, float total_valid,
char do_auto_normalize)
{
float was_change;
float change;
@ -1321,30 +1336,35 @@ static float redistribute_change(MDeformVert *ndv, char *change_status, int chan
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;
/* ignore anything outside the value range */
if (ndw->def_nr < defbase_tot) {
/* change only the groups with a valid status */
if(change_status[ndw->def_nr] == change_me) {
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;
}
}
}
}
@ -1354,12 +1374,14 @@ static float redistribute_change(MDeformVert *ndv, char *change_status, int chan
/* left overs */
return totchange;
}
static float get_mp_change(MDeformVert *odv, char *defbase_sel, float brush_change);
static float get_mp_change(MDeformVert *odv, const int defbase_tot, const char *defbase_sel, float brush_change);
/* 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, char *defbase_sel,
const char *lock_flags, const char *vgroup_validmap, char do_auto_normalize, char do_multipaint)
static void enforce_locks(MDeformVert *odv, MDeformVert *ndv,
const int defbase_tot, const char *defbase_sel,
const char *lock_flags, const char *vgroup_validmap,
char do_auto_normalize, char do_multipaint)
{
float totchange = 0.0f;
float totchange_allowed = 0.0f;
@ -1375,7 +1397,7 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defbase_tot, c
char *change_status;
if(!lock_flags || !has_locked_group(ndv, lock_flags)) {
if(!lock_flags || !has_locked_group(ndv, defbase_tot, lock_flags)) {
return;
}
/* record if a group was changed, unlocked and not changed, or locked */
@ -1439,17 +1461,17 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defbase_tot, c
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);
totchange_allowed = redistribute_change(ndv, defbase_tot, 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 with multipaint, so keep them changed that way! */
if(total_changed > 1 && do_multipaint) {
float undo_change = get_mp_change(ndv, defbase_sel, left_over);
multipaint_selection(ndv, undo_change, defbase_sel, defbase_tot);
float undo_change = get_mp_change(ndv, defbase_tot, defbase_sel, left_over);
multipaint_selection(ndv, defbase_tot, undo_change, defbase_sel);
}
/* 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);
redistribute_change(ndv, defbase_tot, change_status, 2, -2, left_over, total_changed, do_auto_normalize);
}
}
}
@ -1469,15 +1491,17 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defbase_tot, c
}
/* 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)
static float get_mp_change(MDeformVert *odv, const int defbase_tot, const 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 (dw->def_nr < defbase_tot) {
if(defbase_sel[dw->def_nr]) {
selwsum += dw->weight;
}
}
}
if(selwsum && selwsum+brush_change > 0) {
@ -1523,13 +1547,13 @@ typedef struct WeightPaintInfo {
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 */
const char *lock_flags; /* boolean array for locked bones,
* length of defbase_tot */
const char *defbase_sel; /* boolean array for selected bones,
* length of defbase_tot, cant be const because of how its passed */
char *vgroup_validmap; /* same as WeightPaintData.vgroup_validmap,
* only added here for convenience */
const char *vgroup_validmap; /* same as WeightPaintData.vgroup_validmap,
* only added here for convenience */
char do_flip;
char do_multipaint;
@ -1538,7 +1562,10 @@ typedef struct 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 */
* normalizing while multi-painting
*
* note: this assumes dw->def_nr range has been checked by the caller
*/
static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi,
const unsigned int index,
MDeformWeight *dw, MDeformWeight *tdw,
@ -1553,13 +1580,13 @@ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi,
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->lock_flags == NULL) ||
((wpi->lock_flags[dw->def_nr] == FALSE) && /* def_nr range has to be checked for by caller */
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);
multipaint_selection(dv, wpi->defbase_tot, change, wpi->defbase_sel);
}
}
else { /* this lets users paint normally, but don't let them paint locked groups */
@ -1570,7 +1597,7 @@ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi,
enforce_locks(&dv_test, dv, wpi->defbase_tot, wpi->defbase_sel, wpi->lock_flags, wpi->vgroup_validmap, wpi->do_auto_normalize, wpi->do_multipaint);
do_weight_paint_auto_normalize_all_groups(dv, wpi->vgroup_validmap, wpi->do_auto_normalize);
do_weight_paint_auto_normalize_all_groups(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->do_auto_normalize);
if(oldChange && wpi->do_multipaint && wpi->defbase_tot_sel > 1) {
if(tdw->weight != oldw) {
@ -1594,13 +1621,15 @@ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi,
/* 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)
static int get_first_selected_nonzero_weight(MDeformVert *dvert, const int defbase_tot, const 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;
if (dw->def_nr < defbase_tot) {
if (defbase_sel[dw->def_nr] && dw->weight > 0.0f) {
return i;
}
}
}
return -1;
@ -1640,8 +1669,8 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert
/* 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(dv, wpi->lock_flags) == FALSE))
if ( (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) &&
(wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->lock_flags) == FALSE))
{
wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, FALSE);
@ -1659,7 +1688,7 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert
* which has already been scaled down in relation to other weights,
* then scales a second time [#26193]. Tricky multi-paint code doesn't
* suffer from this problem - campbell */
do_weight_paint_auto_normalize_all_groups(dv, wpi->vgroup_validmap, wpi->do_auto_normalize);
do_weight_paint_auto_normalize_all_groups(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->do_auto_normalize);
}
else {
/* use locks and/or multipaint */
@ -1684,13 +1713,13 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert
dv_copy.totweight = dv->totweight;
tdw = dw;
tuw = uw;
change = get_mp_change(wp->wpaint_prev+index, wpi->defbase_sel, neww - oldw);
change = get_mp_change(&wp->wpaint_prev[index], wpi->defbase_tot, wpi->defbase_sel, neww - oldw);
if(change) {
if(!tdw->weight) {
i = get_first_selected_nonzero_weight(dv, wpi->defbase_sel);
i = get_first_selected_nonzero_weight(dv, wpi->defbase_tot, wpi->defbase_sel);
if(i>=0) {
tdw = &(dv->dw[i]);
tuw = defvert_verify_index(wp->wpaint_prev+index, tdw->def_nr);
tuw = defvert_verify_index(&wp->wpaint_prev[index], tdw->def_nr);
}
else {
change = 0;
@ -1847,8 +1876,8 @@ struct WPaintData {
float wpimat[3][3];
/*variables for auto normalize*/
char *vgroup_validmap; /*stores if vgroups tie to deforming bones or not*/
char *lock_flags;
const char *vgroup_validmap; /*stores if vgroups tie to deforming bones or not*/
const char *lock_flags;
int defbase_tot;
};
@ -1903,6 +1932,8 @@ static char *wpaint_make_validmap(Object *ob)
vgroup_validmap[i]= (BLI_ghash_lookup(gh, dg->name) != NULL);
}
BLI_assert(i == BLI_ghash_size(gh));
BLI_ghash_free(gh, NULL, NULL);
return vgroup_validmap;
@ -2005,6 +2036,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
float alpha;
float mval[2], pressure;
int use_vert_sel;
char *defbase_sel;
/* intentionally dont initialize as NULL, make sure we initialize all members below */
WeightPaintInfo wpi;
@ -2036,9 +2068,11 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* *** 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);
defbase_sel= MEM_mallocN(wpi.defbase_tot*sizeof(char), "wpi.defbase_sel");
wpi.defbase_tot_sel= get_selected_defgroups(ob, defbase_sel, wpi.defbase_tot);
wpi.defbase_sel= defbase_sel; /* so we can stay const */
if(wpi.defbase_tot_sel == 0 && ob->actdef > 0) 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;
@ -2160,7 +2194,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* *** free wpi members */
MEM_freeN(wpi.defbase_sel);
MEM_freeN((void *)wpi.defbase_sel);
/* *** dont freeing wpi members */
@ -2182,9 +2216,9 @@ static void wpaint_stroke_done(bContext *C, struct PaintStroke *stroke)
MEM_freeN(wpd->indexar);
if (wpd->vgroup_validmap)
MEM_freeN(wpd->vgroup_validmap);
MEM_freeN((void *)wpd->vgroup_validmap);
if(wpd->lock_flags)
MEM_freeN(wpd->lock_flags);
MEM_freeN((void *)wpd->lock_flags);
MEM_freeN(wpd);
}
@ -2215,8 +2249,8 @@ static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
op->customdata = paint_stroke_new(C, NULL, wpaint_stroke_test_start,
wpaint_stroke_update_step,
wpaint_stroke_done, event->type);
wpaint_stroke_update_step,
wpaint_stroke_done, event->type);
/* add modal handler */
WM_event_add_modal_handler(C, op);

@ -977,7 +977,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if(te->name)
te->flag |= TE_FREE_NAME;
else
te->name= (char*)RNA_struct_ui_name(ptr->type);
te->name= RNA_struct_ui_name(ptr->type);
/* If searching don't expand RNA entries */
if(SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA",te->name)==0) tselem->flag &= ~TSE_CHILDSEARCH;
@ -1007,7 +1007,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
prop= propptr.data;
proptype= RNA_property_type(prop);
te->name= (char*)RNA_property_ui_name(prop);
te->name= RNA_property_ui_name(prop);
te->directdata= prop;
te->rnaptr= *ptr;

@ -531,7 +531,7 @@ static int draw_tface_mapped__set_draw(void *userData, int index)
static int draw_em_tf_mapped__set_draw(void *userData, int index)
{
struct {DerivedMesh *dm; BMEditMesh *em; short has_mcol; short has_mtface;} *data = userData;
struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data = userData;
BMEditMesh *em = data->em;
BMFace *efa= EDBM_get_face_for_index(em, index);
@ -660,14 +660,12 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
static int compareDrawOptions(void *userData, int cur_index, int next_index)
{
DerivedMesh *dm= (DerivedMesh*) userData;
MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
struct { MFace *mf; MTFace *tf; } *data = userData;
if(mf && mf[cur_index].mat_nr != mf[next_index].mat_nr)
if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
return 0;
if(tf && tf[cur_index].tpage != tf[next_index].tpage)
if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
return 0;
return 1;
@ -675,14 +673,12 @@ static int compareDrawOptions(void *userData, int cur_index, int next_index)
static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
{
struct {DerivedMesh *dm; EditMesh *em; short has_mcol; short has_mtface;} *data= userData;
MFace *mf = DM_get_tessface_data_layer(data->dm, CD_MFACE);
MTFace *tf = DM_get_tessface_data_layer(data->dm, CD_MTFACE);
struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData;
if(mf && mf[cur_index].mat_nr != mf[next_index].mat_nr)
if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
return 0;
if(tf && tf[cur_index].tpage != tf[next_index].tpage)
if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
return 0;
return 1;
@ -702,12 +698,13 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
glColor4f(1.0f,1.0f,1.0f,1.0f);
if(ob->mode & OB_MODE_EDIT) {
struct {DerivedMesh *dm; BMEditMesh *em; short has_mcol; short has_mtface;} data;
struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data;
data.dm = dm;
data.em= me->edit_btmesh;
data.has_mcol= CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
data.has_mtface= CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
data.mf= DM_get_tessface_data_layer(dm, CD_MFACE);
data.tf= DM_get_tessface_data_layer(dm, CD_MTFACE);
dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
}
@ -725,10 +722,15 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
}
else {
struct { MFace *mf; MTFace *tf; } userData;
if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
add_tface_color_layer(dm);
dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, dm);
userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
}
}

@ -2375,7 +2375,7 @@ static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
* return 2 for the active face so it renders with stipple enabled */
static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r))
{
struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} *data = userData;
struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; int *orig_index;} *data = userData;
BMFace *efa = EDBM_get_face_for_index(data->em, index);
unsigned char *col;
@ -2398,18 +2398,18 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNU
static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
{
struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} * data = userData;
int *orig_index= DM_get_tessface_data_layer(data->dm, CD_ORIGINDEX);
struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; int *orig_index; } * data = userData;
BMFace *efa;
BMFace *next_efa;
unsigned char *col, *next_col;
if(!orig_index)
if(!data->orig_index)
return 0;
efa= EDBM_get_face_for_index(data->em, orig_index[index]);
next_efa= EDBM_get_face_for_index(data->em, orig_index[next_index]);
efa= EDBM_get_face_for_index(data->em, data->orig_index[index]);
next_efa= EDBM_get_face_for_index(data->em, data->orig_index[next_index]);
if(efa == next_efa)
return 1;
@ -2428,16 +2428,16 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
/* also draws the active face */
static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
unsigned char *selCol, unsigned char *actCol, BMFace *efa_act, Mesh *me)
unsigned char *selCol, unsigned char *actCol, BMFace *efa_act)
{
struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} data;
struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; int *orig_index; } data;
data.dm= dm;
data.cols[0] = baseCol;
data.em = em;
data.cols[1] = selCol;
data.cols[2] = actCol;
data.efa_act = efa_act;
data.me = me;
data.orig_index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0);
}
@ -2928,7 +2928,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
if CHECK_OB_DRAWTEXTURE(v3d, dt)
col1[3] = 0;
draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me);
draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
glDisable(GL_BLEND);
glDepthMask(1); // restore write in zbuffer
@ -2943,7 +2943,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
glEnable(GL_BLEND);
glDepthMask(0); // disable write in zbuffer, needed for nice transp
draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me);
draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
glDisable(GL_BLEND);
glDepthMask(1); // restore write in zbuffer

@ -83,7 +83,8 @@ typedef enum GPUBuiltin {
GPU_INVERSE_OBJECT_MATRIX = 8,
GPU_VIEW_POSITION = 16,
GPU_VIEW_NORMAL = 32,
GPU_OBCOLOR = 64
GPU_OBCOLOR = 64,
GPU_AUTO_BUMPSCALE = 128
} GPUBuiltin;
typedef enum GPUBlendMode {
@ -129,7 +130,7 @@ void GPU_material_free(struct Material *ma);
void GPU_materials_free(void);
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap);
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4]);
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale);
void GPU_material_unbind(GPUMaterial *material);
int GPU_material_bound(GPUMaterial *material);
@ -162,6 +163,7 @@ typedef enum GPUDynamicType {
GPU_DYNAMIC_OBJECT_VIEWIMAT = 3,
GPU_DYNAMIC_OBJECT_IMAT = 4,
GPU_DYNAMIC_OBJECT_COLOR = 5,
GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE = 15,
GPU_DYNAMIC_LAMP_FIRST = 6,
GPU_DYNAMIC_LAMP_DYNVEC = 6,
GPU_DYNAMIC_LAMP_DYNCO = 7,

@ -344,6 +344,8 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
return "varnormal";
else if(builtin == GPU_OBCOLOR)
return "unfobcolor";
else if(builtin == GPU_AUTO_BUMPSCALE)
return "unfobautobumpscale";
else
return "";
}

@ -60,6 +60,7 @@
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_DerivedMesh.h"
#include "BLI_threads.h"
#include "BLI_blenlib.h"
@ -1155,11 +1156,14 @@ int GPU_enable_material(int nr, void *attribs)
if(gattribs && GMS.gmatbuf[nr]) {
/* bind glsl material and get attributes */
Material *mat = GMS.gmatbuf[nr];
float auto_bump_scale;
gpumat = GPU_material_from_blender(GMS.gscene, mat);
GPU_material_vertex_attributes(gpumat, gattribs);
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);
auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gviewinv, GMS.gob->col, auto_bump_scale);
GMS.gboundmat= mat;
/* for glsl use alpha blend mode, unless it's set to solid and

@ -94,7 +94,7 @@ struct GPUMaterial {
/* for passing uniforms */
int viewmatloc, invviewmatloc;
int obmatloc, invobmatloc;
int obcolloc;
int obcolloc, obautobumpscaleloc;
ListBase lamps;
};
@ -212,7 +212,8 @@ static int GPU_material_construct_end(GPUMaterial *material)
material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX));
if(material->builtins & GPU_OBCOLOR)
material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
if(material->builtins & GPU_AUTO_BUMPSCALE)
material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE));
return 1;
}
@ -273,7 +274,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
}
}
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4])
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale)
{
if(material->pass) {
GPUShader *shader = GPU_pass_shader(material->pass);
@ -300,7 +301,9 @@ void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float v
CLAMP(col[3], 0.0f, 1.0f);
GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col);
}
if(material->builtins & GPU_AUTO_BUMPSCALE) {
GPU_shader_uniform_vector(shader, material->obautobumpscaleloc, 1, 1, &autobumpscale);
}
/* update lamps */
for(nlink=material->lamps.first; nlink; nlink=nlink->next) {
lamp= nlink->data;
@ -1087,8 +1090,7 @@ static void do_material_tex(GPUShadeInput *shi)
/* ntap bumpmap image */
int iBumpSpace;
float ima_x, ima_y;
float hScale = 0.1f; // compatibility adjustment factor for all bumpspace types
float hScaleTex = 13.0f; // factor for scaling texspace bumps
float hScale;
float imag_tspace_dimension_x = 1024.0f; // only used for texture space variant
float aspect = 1.0f;
@ -1096,16 +1098,35 @@ static void do_material_tex(GPUShadeInput *shi)
GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
GPUNodeLink *vR1, *vR2;
GPUNodeLink *dBs, *dBt, *fDet;
hScale = 0.1; // compatibility adjustment factor for all bumpspace types
if( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
hScale = hScaleTex;
hScale = 13.0f; // factor for scaling texspace bumps
else if(found_deriv_map!=0)
hScale = 1.0f;
// resolve texture resolution
if( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) {
ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser);
ima_x= 512.0f; ima_y= 512.f; // prevent calling textureSize, glsl 1.3 only
if(ibuf) {
ima_x= ibuf->x;
ima_y= ibuf->y;
aspect = ((float) ima_y) / ima_x;
}
}
// The negate on norfac is done because the
// normal in the renderer points inward which corresponds
// to inverting the bump map. Should this ever change
// this negate must be removed.
norfac = -hScale * mtex->norfac;
if(found_deriv_map) norfac /= sqrtf(ima_x*ima_y);
tnorfac = GPU_uniform(&norfac);
if(found_deriv_map)
GPU_link(mat, "math_multiply", tnorfac, GPU_builtin(GPU_AUTO_BUMPSCALE), &tnorfac);
if(GPU_link_changed(stencil))
GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
@ -1152,17 +1173,6 @@ static void do_material_tex(GPUShadeInput *shi)
iBumpSpacePrev = iBumpSpace;
}
// resolve texture resolution
if( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) {
ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser);
ima_x= 512.0f; ima_y= 512.f; // prevent calling textureSize, glsl 1.3 only
if(ibuf) {
ima_x= ibuf->x;
ima_y= ibuf->y;
aspect = ((float) ima_y) / ima_x;
}
}
if(found_deriv_map) {
@ -1703,6 +1713,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
{ GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F },
{ GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F },
{ GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F },
{ GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F },
{ 0 }
};

@ -3751,7 +3751,7 @@ char *RNA_path_append(const char *path, PointerRNA *UNUSED(ptr), PropertyRNA *pr
BLI_dynstr_append(dynstr, ".");
}
BLI_dynstr_append(dynstr, (char*)RNA_property_identifier(prop));
BLI_dynstr_append(dynstr, RNA_property_identifier(prop));
if(RNA_property_type(prop) == PROP_COLLECTION) {
/* add ["strkey"] or [intkey] */

@ -185,22 +185,20 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
const float fac_orig= hmd->force;
float fac;
const int *origindex_ar;
/* if DerivedMesh is present and has original index data,
* use it
*/
/* if DerivedMesh is present and has original index data, use it */
if(dm && (origindex_ar= dm->getVertDataArray(dm, CD_ORIGINDEX))) {
for(i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) {
if(*index_pt < numVerts) {
int j;
for(j = 0; j < numVerts; j++) {
if(origindex_ar[j] == *index_pt) {
float *co = vertexCos[j];
if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
if(dvert)
fac *= defvert_find_weight(dvert+j, defgrp_index);
if(fac) {
mul_v3_m4v3(vec, mat, co);
interp_v3_v3v3(co, co, vec, fac);
@ -218,7 +216,7 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
if(dvert)
fac *= defvert_find_weight(dvert+(*index_pt), defgrp_index);
if(fac) {
mul_v3_m4v3(vec, mat, co);
interp_v3_v3v3(co, co, vec, fac);
@ -230,11 +228,11 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
}
else if(dvert) { /* vertex group hook */
const float fac_orig= hmd->force;
for(i = 0; i < max_dvert; i++, dvert++) {
float fac;
float *co = vertexCos[i];
if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
fac *= defvert_find_weight(dvert, defgrp_index);
if(fac) {
@ -251,12 +249,8 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData,
int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
{
HookModifierData *hmd = (HookModifierData*) md;
DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, 0);
deformVerts_do(hmd, ob, dm, vertexCos, numVerts);
if(derivedData != dm)
dm->release(dm);
deformVerts_do(hmd, ob, derivedData, vertexCos, numVerts);
}
static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editData,

@ -137,12 +137,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
bDeformGroup *def;
char *bone_select_array;
int bone_select_tot= 0;
const int defbase_tot= BLI_countlist(&ob->defbase);
/* check that there is armature object with bones to use, otherwise return original mesh */
if (ELEM3(NULL, mmd->ob_arm, mmd->ob_arm->pose, ob->defbase.first))
return derivedData;
bone_select_array= MEM_mallocN(BLI_countlist(&ob->defbase) * sizeof(char), "mask array");
bone_select_array= MEM_mallocN(defbase_tot * sizeof(char), "mask array");
for (i = 0, def = ob->defbase.first; def; def = def->next, i++)
{
@ -194,12 +195,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
MDeformWeight *dw= dv->dw;
int j;
for (j= dv->totweight; j > 0; j--, dw++)
{
if (bone_select_array[dw->def_nr])
{
if(dw->weight != 0.0f) {
break;
for (j= dv->totweight; j > 0; j--, dw++) {
if (dw->def_nr < defbase_tot) {
if (bone_select_array[dw->def_nr]) {
if(dw->weight != 0.0f) {
break;
}
}
}
}

@ -87,6 +87,7 @@ PyInit_gpu(void)
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT);
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_IMAT);
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_COLOR);
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE);
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNVEC);
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCO);
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNIMAT);

@ -1932,11 +1932,13 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
float *nvec = texres->nor;
texres->nor = NULL;
if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
if(tex->ima)
Hscale *= 13.0f; // appears to be a sensible default value
} else
Hscale *= 0.1f; // factor 0.1 proved to look like the previous bump code
if(found_deriv_map==0) {
if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
if(tex->ima)
Hscale *= 13.0f; // appears to be a sensible default value
} else
Hscale *= 0.1f; // factor 0.1 proved to look like the previous bump code
}
if( !ntap_bump->init_done ) {
copy_v3_v3(ntap_bump->vNacc, shi->vn);
@ -1958,15 +1960,21 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
}
if(found_deriv_map) {
float dBdu, dBdv;
float dBdu, dBdv, auto_bump = 1.0f;
float s = 1; // negate this if flipped texture coordinate
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres);
if(shi->obr->ob->derivedFinal)
{
auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale;
auto_bump /= sqrtf((float) (dimx*dimy));
}
// this variant using a derivative map is described here
// http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
dBdu = Hscale*dimx*(2*texres->tr-1);
dBdv = Hscale*dimy*(2*texres->tg-1);
dBdu = auto_bump*Hscale*dimx*(2*texres->tr-1);
dBdv = auto_bump*Hscale*dimy*(2*texres->tg-1);
dHdx = dBdu*dxt[0] + s * dBdv*dxt[1];
dHdy = dBdu*dyt[0] + s * dBdv*dyt[1];

@ -217,14 +217,14 @@ void BL_SkinDeformer::BGEDeformVerts()
Object *par_arma = m_armobj->GetArmatureObject();
MDeformVert *dverts = m_bmesh->dvert;
bDeformGroup *dg;
int numGroups = BLI_countlist(&m_objMesh->defbase);
int defbase_tot = BLI_countlist(&m_objMesh->defbase);
if (!dverts)
return;
if (m_dfnrToPC == NULL)
{
m_dfnrToPC = new bPoseChannel*[numGroups];
m_dfnrToPC = new bPoseChannel*[defbase_tot];
int i;
for (i=0, dg=(bDeformGroup*)m_objMesh->defbase.first;
dg;
@ -260,7 +260,7 @@ void BL_SkinDeformer::BGEDeformVerts()
{
int index = dvert->dw[j].def_nr;
if (index < numGroups && (pchan=m_dfnrToPC[index]))
if (index < defbase_tot && (pchan=m_dfnrToPC[index]))
{
weight = dvert->dw[j].weight;

@ -8,6 +8,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_DerivedMesh.h"
#include "BL_BlenderShader.h"
#include "BL_Material.h"
@ -146,7 +147,8 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
else
obcol[0]= obcol[1]= obcol[2]= obcol[3]= 1.0f;
GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol);
float auto_bump_scale = ms.m_pDerivedMesh!=0 ? ms.m_pDerivedMesh->auto_bump_scale : 1.0f;
GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol, auto_bump_scale);
mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol);
}