forked from bartvdbraak/blender
svn merge ^/trunk/blender -r42521:42550
This commit is contained in:
commit
65f3b93f14
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user