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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-12-10 09:38:00 +0400
committerCampbell Barton <ideasman42@gmail.com>2011-12-10 09:38:00 +0400
commit65f3b93f144699fa4aafa46c7e226aa1390b7239 (patch)
tree1a9599589c98d9e17631844fd011463031fe59cd /source/blender/blenkernel
parent99d893bb89a96dd0d6cb9410b12928e7ade4b565 (diff)
parenta88b29c062f32514e4414bfd4006f7b348077a42 (diff)
svn merge ^/trunk/blender -r42521:42550
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-rw-r--r--source/blender/blenkernel/BKE_deform.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c193
-rw-r--r--source/blender/blenkernel/intern/armature.c16
-rw-r--r--source/blender/blenkernel/intern/deform.c38
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c25
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c37
-rw-r--r--source/blender/blenkernel/intern/particle.c19
8 files changed, 261 insertions, 71 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 98a5154c256..139119ee873 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -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);
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index b08afd9c475..9902b26e15b 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -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);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 64a802f225f..8405a3922e6 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -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)
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 68d2cf940af..e10c4b24458 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -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;
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 088241791a7..8967dcdbd0e 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -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
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 3297417eb8c..89bf06be07e 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -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 */
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index fd19d8461d5..d3cfa42b179 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -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)
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 56d29467ac7..b84d06d78e9 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -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);
}
}
}