From 1d46bbef7e07d70cf44d304f261bc5a1e8056f24 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 19 Jan 2012 16:22:22 +0000 Subject: Fix issue in recent color commits, was still doing a multiplication by 255 too many, also don't check uchar range after casting to int, this can still cause overflow with large float values. --- source/blender/blenlib/BLI_math_color.h | 3 +++ source/blender/blenlib/intern/math_color.c | 22 ++----------------- source/blender/blenlib/intern/math_color_inline.c | 26 ++++++----------------- 3 files changed, 12 insertions(+), 39 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index 453f1258272..f4d6882b5d8 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -91,6 +91,9 @@ MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4]); MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4]); MINLINE void linearrgb_to_srgb_predivide_v4(float srgb[4], const float linear[4]); +MINLINE void linearrgb_to_srgb_uchar3(unsigned char srgb[3], const float linear[3]); +MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[4]); + void BLI_init_srgb_conversion(void); /************************** Other *************************/ diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 94dbdf9fe58..ca2aeca8f36 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -354,30 +354,12 @@ void rgba_uchar_to_float(float col_r[4], const unsigned char col_ub[4]) void rgb_float_to_uchar(unsigned char col_r[3], const float col_f[3]) { - int r, g, b; - - r= (int)(col_f[0] * 255.0f); - g= (int)(col_f[1] * 255.0f); - b= (int)(col_f[2] * 255.0f); - - col_r[0]= (char)((r <= 0)? 0 : (r >= 255)? 255 : r); - col_r[1]= (char)((g <= 0)? 0 : (g >= 255)? 255 : g); - col_r[2]= (char)((b <= 0)? 0 : (b >= 255)? 255 : b); + F3TOCHAR3(col_f, col_r); } void rgba_float_to_uchar(unsigned char col_r[4], const float col_f[4]) { - int r, g, b, a; - - r= (int)(col_f[0] * 255.0f); - g= (int)(col_f[1] * 255.0f); - b= (int)(col_f[2] * 255.0f); - a= (int)(col_f[3] * 255.0f); - - col_r[0]= (char)((r <= 0)? 0 : (r >= 255)? 255 : r); - col_r[1]= (char)((g <= 0)? 0 : (g >= 255)? 255 : g); - col_r[2]= (char)((b <= 0)? 0 : (b >= 255)? 255 : b); - col_r[3]= (char)((a <= 0)? 0 : (a >= 255)? 255 : a); + F4TOCHAR4(col_f, col_r); } /* ********************************* color transforms ********************************* */ diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c index 2c7b13b86a2..386452ed592 100644 --- a/source/blender/blenlib/intern/math_color_inline.c +++ b/source/blender/blenlib/intern/math_color_inline.c @@ -62,32 +62,20 @@ MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4]) srgb[3] = linear[3]; } -MINLINE void linearrgb_to_srgb_uchar3(unsigned char srgb[4], const float linear[4]) +MINLINE void linearrgb_to_srgb_uchar3(unsigned char srgb[3], const float linear[3]) { - int r, g, b; + float srgb_f[3]; - r = 255 * linearrgb_to_srgb(linear[0]); - g = 255 * linearrgb_to_srgb(linear[1]); - b = 255 * linearrgb_to_srgb(linear[2]); - - srgb[0] = FTOCHAR(r); - srgb[1] = FTOCHAR(g); - srgb[2] = FTOCHAR(b); + linearrgb_to_srgb_v3_v3(srgb_f, linear); + F3TOCHAR3(srgb_f, srgb); } MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[4]) { - int r, g, b, a; - - r = 255 * linearrgb_to_srgb(linear[0]); - g = 255 * linearrgb_to_srgb(linear[1]); - b = 255 * linearrgb_to_srgb(linear[2]); - a = 255 * linear[3]; + float srgb_f[4]; - srgb[0] = FTOCHAR(r); - srgb[1] = FTOCHAR(g); - srgb[2] = FTOCHAR(b); - srgb[3] = FTOCHAR(a); + linearrgb_to_srgb_v4(srgb_f, linear); + F4TOCHAR4(srgb_f, srgb); } /* predivide versions to work on associated/premultipled alpha. if this should -- cgit v1.2.3 From a31d1132e8e0f63cdcfb4af8772d832f5f490d34 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 19 Jan 2012 19:09:59 +0000 Subject: Minor code enhancement (replace for loops with while's, and avoid multiple checks to get good face vertex index). No functional changes. --- source/blender/blenkernel/intern/dynamicpaint.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index fc0fe37d106..8dc568cd004 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1613,11 +1613,11 @@ static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData if (col) { #pragma omp parallel for schedule(static) for (i=0; ipreview_id == MOD_DPAINT_SURFACE_PREV_PAINT) { float c[3]; @@ -1666,9 +1666,9 @@ static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData if (col) { #pragma omp parallel for schedule(static) for (i=0; i Date: Fri, 20 Jan 2012 00:02:48 +0000 Subject: smart stitch ============= * refactoring, separate common functionality to functions. * enable each uv to check independently for other stitchable uvs. This allows to limit stitch uvs belonging to the same vertex, while previously this was impossible. * made changes to island rotation when calculated from sole uvs when using midpoint stitch. It should now be evenly distributed across islands. There are still some glitches with vertices that have multiple uvs per island for the snap island + midpoint stitch combination. The solution is to precalculate the static island rotation/translation in this case. If I haven't managed to make this work correctly I may turn this combination off before release. It's more like an extra feature than really necessary. --- .../blender/editors/uvedit/uvedit_smart_stitch.c | 284 +++++++++++---------- 1 file changed, 154 insertions(+), 130 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 38c8f5bc69c..04748ae3413 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -80,10 +80,12 @@ typedef struct IslandStitchData{ float medianPoint[2]; int numOfElements; int num_rot_elements; - /* Flag to remember if island has been added for preview */ + /* flag to remember if island has been added for preview */ char addedForPreview; - /* Flag an island to be considered for determining static island */ + /* flag an island to be considered for determining static island */ char stitchableCandidate; + /* if edge rotation is used, flag so that vertex rotation is not used */ + char use_edge_rotation; }IslandStitchData; /* just for averaging UVs */ @@ -262,6 +264,38 @@ static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2]){ uv[1] = uv_rotation_result[1] + medianPoint[1]; } +static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state){ + float limit; + int do_limit; + + if(element_iter == element){ + return 0; + } + + limit = state->limit_dist; + do_limit = state->use_limit; + + if(do_limit){ + MTFace *mtface_orig = CustomData_em_get(&state->em->fdata, element->face->data, CD_MTFACE); + MTFace *mtface_iter = CustomData_em_get(&state->em->fdata, element_iter->face->data, CD_MTFACE); + + if(fabs(mtface_orig->uv[element->tfindex][0] - mtface_iter->uv[element_iter->tfindex][0]) < limit + && fabs(mtface_orig->uv[element->tfindex][1] - mtface_iter->uv[element_iter->tfindex][1]) < limit){ + return 1; + }else + return 0; + }else + return 1; +} + + +static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state){ + if(state->snap_islands && element->island == element_iter->island) + return 0; + + return stitch_check_uvs_stitchable(element, element_iter, state); +} + /* calculate snapping for islands */ static void stitch_calculate_island_snapping(StitchState *state, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final){ @@ -324,26 +358,31 @@ static void stitch_calculate_island_snapping(StitchState *state, StitchPreviewer static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map, IslandStitchData *island_stitch_data) { - UvElement *element; - EditFace *efa; - MTFace *mt; - int nverts; + UvElement *element1, *element2; + EditFace *efa1; + EditFace *efa2; + MTFace *mt1; + MTFace *mt2; float uv1[2], uv2[2]; float edgecos, edgesin; int index1, index2; + float rotation; + + element1 = state->uvs[edge->uv1]; + element2 = state->uvs[edge->uv2]; - element = edge->element; - efa = element->face; - nverts = (efa->v4)? 4 : 3; - mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + efa1 = element1->face; + mt1 = CustomData_em_get(&state->em->fdata, efa1->data, CD_MTFACE); + efa2 = element2->face; + mt2 = CustomData_em_get(&state->em->fdata, efa2->data, CD_MTFACE); - index1 = uvfinal_map[(*(&element->face->v1 + element->tfindex))->tmp.l]; - index2 = uvfinal_map[(*(&element->face->v1 + (element->tfindex + 1)%nverts))->tmp.l]; + index1 = uvfinal_map[element1 - state->element_map->buf]; + index2 = uvfinal_map[element2 - state->element_map->buf]; /* the idea here is to take the directions of the edges and find the rotation between final and initial * direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */ - uv1[0] = mt->uv[(element->tfindex + 1)%nverts][0] - mt->uv[element->tfindex][0]; - uv1[1] = mt->uv[(element->tfindex + 1)%nverts][1] - mt->uv[element->tfindex][1]; + uv1[0] = mt2->uv[element2->tfindex][0] - mt1->uv[element1->tfindex][0]; + uv1[1] = mt2->uv[element2->tfindex][1] - mt1->uv[element1->tfindex][1]; uv2[0] = uv_average[index2].uv[0] - uv_average[index1].uv[0]; uv2[1] = uv_average[index2].uv[1] - uv_average[index1].uv[1]; @@ -353,47 +392,50 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *sta edgecos = uv1[0]*uv2[0] + uv1[1]*uv2[1]; edgesin = uv1[0]*uv2[1] - uv2[0]*uv1[1]; - island_stitch_data[element->island].num_rot_elements++; - island_stitch_data[element->island].rotation += (edgesin > 0)? acos(MAX2(-1.0, MIN2(1.0, edgecos))): -acos(MAX2(-1.0, MIN2(1.0, edgecos))); + + rotation = (edgesin > 0)? acos(MAX2(-1.0, MIN2(1.0, edgecos))): -acos(MAX2(-1.0, MIN2(1.0, edgecos))); + + island_stitch_data[element1->island].num_rot_elements++; + island_stitch_data[element1->island].rotation += rotation; } -static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, char do_static) + +static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data) { float edgecos = 1, edgesin = 0; int index; UvElement *element_iter; + float rotation = 0; - if((element->island == state->static_island) && !do_static) + if(element->island == state->static_island && !state->midpoints) return; index = (*(&element->face->v1 + element->tfindex))->tmp.l; element_iter = state->element_map->vert[index]; - if(!do_static){ - for(; element_iter; element_iter = element_iter->next){ - if((element_iter->separate) && (element_iter->flag & STITCH_STITCHABLE) && - (element_iter != element) && (element_iter->island == state->static_island) - ){ - int index_tmp1, index_tmp2; - float normal[2]; - /* easily possible*/ - - index_tmp1 = element_iter - state->element_map->buf; - index_tmp1 = state->map[index_tmp1]; - index_tmp2 = element - state->element_map->buf; - index_tmp2 = state->map[index_tmp2]; - - negate_v2_v2(normal, state->normals + index_tmp2*2); - edgecos = dot_v2v2(normal, state->normals + index_tmp1*2); - edgesin = cross_v2v2(normal, state->normals + index_tmp1*2); - break; - } + for(; element_iter; element_iter = element_iter->next){ + if(element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)){ + int index_tmp1, index_tmp2; + float normal[2]; + /* easily possible*/ + + index_tmp1 = element_iter - state->element_map->buf; + index_tmp1 = state->map[index_tmp1]; + index_tmp2 = element - state->element_map->buf; + index_tmp2 = state->map[index_tmp2]; + + negate_v2_v2(normal, state->normals + index_tmp2*2); + edgecos = dot_v2v2(normal, state->normals + index_tmp1*2); + edgesin = cross_v2v2(normal, state->normals + index_tmp1*2); + rotation += (edgesin > 0)? acos(edgecos): -acos(edgecos); } } + if(state->midpoints) + rotation /= 2.0; island_stitch_data[element->island].num_rot_elements++; - island_stitch_data[element->island].rotation += (edgesin > 0)? acos(edgecos): -acos(edgecos); + island_stitch_data[element->island].rotation += rotation; } @@ -434,8 +476,6 @@ static void stitch_state_delete(StitchState *stitch_state) static void determine_uv_stitchability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){ int vert_index; UvElement *element_iter; - float limit= state->limit_dist; - int do_limit = state->use_limit; vert_index = (*(&element->face->v1 + element->tfindex))->tmp.l; element_iter = state->element_map->vert[vert_index]; @@ -445,18 +485,7 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I if(element_iter == element){ continue; } - if(do_limit){ - MTFace *mtface_orig = CustomData_em_get(&state->em->fdata, element->face->data, CD_MTFACE); - MTFace *mtface_iter = CustomData_em_get(&state->em->fdata, element_iter->face->data, CD_MTFACE); - - if(fabs(mtface_orig->uv[element->tfindex][0] - mtface_iter->uv[element_iter->tfindex][0]) < limit - && fabs(mtface_orig->uv[element->tfindex][1] - mtface_iter->uv[element_iter->tfindex][1]) < limit){ - island_stitch_data[element_iter->island].stitchableCandidate = 1; - island_stitch_data[element->island].stitchableCandidate = 1; - element->flag |= STITCH_STITCHABLE_CANDIDATE; - } - }else{ - /* if no limit exists, then the mere existence of a separate uv means that the uv is stitchable */ + if(stitch_check_uvs_stitchable(element, element_iter, state)){ island_stitch_data[element_iter->island].stitchableCandidate = 1; island_stitch_data[element->island].stitchableCandidate = 1; element->flag |= STITCH_STITCHABLE_CANDIDATE; @@ -466,7 +495,6 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I } - /* set preview buffer position of UV face in editface->tmp.l */ static void stitch_set_face_preview_buffer_position(EditFace *efa, StitchPreviewer *preview) { @@ -489,8 +517,8 @@ static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchSta StitchPreviewer *preview = uv_get_stitch_previewer(); /* static island does not change so returning immediately */ - //if(state->snap_islands && !state->midpoints && state->static_island == element->island) - // return; + if(state->snap_islands && !state->midpoints && state->static_island == element->island) + return; if(state->snap_islands){ island_stitch_data[element->island].addedForPreview = 1; @@ -515,21 +543,7 @@ static void stitch_validate_stichability(UvElement *element, StitchState *state, if(element_iter->separate){ if(element_iter == element) continue; - if(state->use_limit){ - MTFace *mtface_orig = CustomData_em_get(&state->em->fdata, element->face->data, CD_MTFACE); - MTFace *mtface_iter = CustomData_em_get(&state->em->fdata, element_iter->face->data, CD_MTFACE); - - if(fabs(mtface_orig->uv[element->tfindex][0] - mtface_iter->uv[element_iter->tfindex][0]) < state->limit_dist - && fabs(mtface_orig->uv[element->tfindex][1] - mtface_iter->uv[element_iter->tfindex][1]) < state->limit_dist){ - if(((element_iter->island == state->static_island) || (element->island == state->static_island)) && - !((element_iter->island == element->island) && state->snap_islands)){ - element->flag |= STITCH_STITCHABLE; - preview->num_stitchable++; - stitch_setup_face_preview_for_uv_group(element, state, island_stitch_data); - return; - } - } - }else{ + if(stitch_check_uvs_stitchable(element, element_iter, state)){ if(((element_iter->island == state->static_island) || (element->island == state->static_island)) && !((element_iter->island == element->island) && state->snap_islands)){ element->flag |= STITCH_STITCHABLE; @@ -558,8 +572,6 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) EditVert *ev; UVVertAverage *final_position; char stitch_midpoints = state->midpoints; - /* use vertex normals for snapping rotation */ - char use_vert_normals = 1; /* used to map uv indices to uvaverage indices for selection */ unsigned int *uvfinal_map; @@ -578,7 +590,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) return 0; } - /* store Indices to editVerts. */ + /* store indices to editVerts. */ for(ev = state->em->verts.first, i = 0; ev; ev = ev->next, i++){ ev->tmp.l = i; } @@ -708,26 +720,46 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) ******************************************************/ final_position = MEM_callocN(state->selection_size*sizeof(*final_position), "stitch_uv_average"); - uvfinal_map = MEM_mallocN(state->em->totvert*sizeof(*uvfinal_map), "stitch_uv_final_map"); + uvfinal_map = MEM_mallocN(state->element_map->totalUVs*sizeof(*uvfinal_map), "stitch_uv_final_map"); /* first pass, calculate final position for stitchable uvs of the static island */ for(i = 0; i < state->selection_size; i++){ UvElement *element = state->selection_stack[i]; if(element->flag & STITCH_STITCHABLE){ - UvElement *element_iter = state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l]; - uvfinal_map[(*(&element->face->v1 + element->tfindex))->tmp.l] = i; + MTFace *mt; + + UvElement *element_iter; + + uvfinal_map[element - state->element_map->buf] = i; + + efa = element->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + + final_position[i].uv[0] = mt->uv[element->tfindex][0]; + final_position[i].uv[1] = mt->uv[element->tfindex][1]; + final_position[i].count = 1; + + if(state->snap_islands && element->island == state->static_island && !stitch_midpoints) + continue; + + element_iter = state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l]; + for(;element_iter; element_iter = element_iter->next){ - if(element_iter->flag & STITCH_STITCHABLE){ - MTFace *mt; - efa = element_iter->face; - mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); - if(stitch_midpoints){ - final_position[i].uv[0] += mt->uv[element_iter->tfindex][0]; - final_position[i].uv[1] += mt->uv[element_iter->tfindex][1]; - final_position[i].count++; - }else if(element_iter->island == state->static_island){ - final_position[i].uv[0] = mt->uv[element_iter->tfindex][0]; - final_position[i].uv[1] = mt->uv[element_iter->tfindex][1]; + if(element_iter->separate){ + if(stitch_check_uvs_state_stitchable(element, element_iter, state)){ + efa = element_iter->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + if(stitch_midpoints){ + final_position[i].uv[0] += mt->uv[element_iter->tfindex][0]; + final_position[i].uv[1] += mt->uv[element_iter->tfindex][1]; + final_position[i].count++; + }else if(element_iter->island == state->static_island){ + /* if multiple uvs on the static island exist, + * last checked remains. to disambiguate we need to limit or use + * edge stitch */ + final_position[i].uv[0] = mt->uv[element_iter->tfindex][0]; + final_position[i].uv[1] = mt->uv[element_iter->tfindex][1]; + } } } } @@ -762,65 +794,57 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) UvEdge *edge = state->edges+i; if((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)){ stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data); - use_vert_normals = 0; + island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = 1; } } - if(use_vert_normals){ - for(i = 0; i < state->selection_size; i++){ - UvElement *element = state->selection_stack[i]; + + for(i = 0; i < state->selection_size; i++){ + UvElement *element = state->selection_stack[i]; + if(!island_stitch_data[element->island].use_edge_rotation){ if(element->flag & STITCH_STITCHABLE){ - stitch_island_calculate_vert_rotation(element, state, island_stitch_data, 0); + stitch_island_calculate_vert_rotation(element, state, island_stitch_data); } } } + } - /* third pass, propagate changes to stitchable uvs */ + /* third pass, propagate changes to coincident uvs */ for(i = 0; i < state->selection_size; i++){ UvElement *element = state->selection_stack[i]; if(element->flag & STITCH_STITCHABLE){ - UvElement *element_iter = state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l]; - for(;element_iter;){ - /* determine if uv stitchable */ - if(element_iter->separate && element_iter->flag & STITCH_STITCHABLE){ - MTFace *mt; - efa = element_iter->face; - mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); - - /* propagate to coincident uvs */ - do{ - efa = element_iter->face; - mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); - - element_iter->flag |= STITCH_PROCESSED; - /* either flush to preview or to the MTFace, if final */ - if(final){ - mt->uv[element_iter->tfindex][0] = final_position[i].uv[0]; - mt->uv[element_iter->tfindex][1] = final_position[i].uv[1]; - - uvedit_uv_select(scene, efa, mt, element_iter->tfindex); - }else if(efa->tmp.l != STITCH_NO_PREVIEW){ - if(efa->v4){ - *(preview->preview_quads+efa->tmp.l + element_iter->tfindex*2) = final_position[i].uv[0]; - *(preview->preview_quads+efa->tmp.l + element_iter->tfindex*2 + 1) = final_position[i].uv[1]; - }else{ - *(preview->preview_tris+efa->tmp.l + element_iter->tfindex*2) = final_position[i].uv[0]; - *(preview->preview_tris+efa->tmp.l + element_iter->tfindex*2 + 1) = final_position[i].uv[1]; - } - } + UvElement *element_iter = element; + /* propagate to coincident uvs */ + do{ + MTFace *mt; - /* end of calculations, keep only the selection flag */ - if( (!state->snap_islands) || ((!stitch_midpoints) && (element_iter->island == state->static_island))) { - element_iter->flag &= STITCH_SELECTED; - } + efa = element_iter->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); - element_iter = element_iter->next; - }while(element_iter && !element_iter->separate); + element_iter->flag |= STITCH_PROCESSED; + /* either flush to preview or to the MTFace, if final */ + if(final){ + mt->uv[element_iter->tfindex][0] = final_position[i].uv[0]; + mt->uv[element_iter->tfindex][1] = final_position[i].uv[1]; + + uvedit_uv_select(scene, efa, mt, element_iter->tfindex); + }else if(efa->tmp.l != STITCH_NO_PREVIEW){ + if(efa->v4){ + *(preview->preview_quads+efa->tmp.l + element_iter->tfindex*2) = final_position[i].uv[0]; + *(preview->preview_quads+efa->tmp.l + element_iter->tfindex*2 + 1) = final_position[i].uv[1]; + }else{ + *(preview->preview_tris+efa->tmp.l + element_iter->tfindex*2) = final_position[i].uv[0]; + *(preview->preview_tris+efa->tmp.l + element_iter->tfindex*2 + 1) = final_position[i].uv[1]; + } + } - continue; + /* end of calculations, keep only the selection flag */ + if( (!state->snap_islands) || ((!stitch_midpoints) && (element_iter->island == state->static_island))) { + element_iter->flag &= STITCH_SELECTED; } + element_iter = element_iter->next; - } + }while(element_iter && !element_iter->separate); } } -- cgit v1.2.3 From 181a4b74c17e1f007b5a9b5aa7a01eb051c1e48c Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Fri, 20 Jan 2012 01:43:49 +0000 Subject: Small cleanup to parameters of _getSubSurf(). Removed the unused third argument and changed useAging and useArena to named flags. --- source/blender/blenkernel/intern/subsurf_ccg.c | 27 ++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index e773eb6dd35..806cb158ea4 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -92,9 +92,16 @@ static void arena_release(CCGAllocatorHDL a) { BLI_memarena_free(a); } -static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int UNUSED(useFlatSubdiv)) { +typedef enum { + CCG_USE_AGING = 1, + CCG_USE_ARENA = 2, +} CCGFlags; + +static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, CCGFlags flags) { CCGMeshIFC ifc; CCGSubSurf *ccgSS; + int useAging = !!(flags & CCG_USE_AGING); + int useArena = flags & CCG_USE_ARENA; /* subdivLevels==0 is not allowed */ subdivLevels = MAX2(subdivLevels, 1); @@ -102,7 +109,6 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAgin if (prevSS) { int oldUseAging; - useAging = !!useAging; ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL); if (oldUseAging!=useAging) { @@ -322,7 +328,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, return; /* create a CCGSubSurf from uv's */ - uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0); + uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), CCG_USE_ARENA); if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) { ccgSubSurf_free(uvss); @@ -2773,7 +2779,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( int isFinalCalc, int forEditMode, int inEditMode) { int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF; - int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr; + CCGFlags useAging = smd->flags & eSubsurfModifierFlag_DebugIncr ? CCG_USE_AGING : 0; int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv; int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges); CCGDerivedMesh *result; @@ -2781,8 +2787,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( if(forEditMode) { int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels; - smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0, - useSimple); + smd->emCache = _getSubSurf(smd->emCache, levels, useAging); ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple); result = getCCGDerivedMesh(smd->emCache, @@ -2796,7 +2801,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( if(levels == 0) return dm; - ss = _getSubSurf(NULL, levels, 0, 1, useSimple); + ss = _getSubSurf(NULL, levels, CCG_USE_ARENA); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); @@ -2806,7 +2811,6 @@ struct DerivedMesh *subsurf_make_derived_from_derived( result->freeSS = 1; } else { int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental); - int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr; int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels; CCGSubSurf *ss; @@ -2827,8 +2831,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( } if(useIncremental && isFinalCalc) { - smd->mCache = ss = _getSubSurf(smd->mCache, levels, - useAging, 0, useSimple); + smd->mCache = ss = _getSubSurf(smd->mCache, levels, useAging); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); @@ -2841,7 +2844,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( smd->mCache = NULL; } - ss = _getSubSurf(NULL, levels, 0, 1, useSimple); + ss = _getSubSurf(NULL, levels, CCG_USE_ARENA); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm); @@ -2863,7 +2866,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) * calculated vert positions is incorrect for the verts * on the boundary of the mesh. */ - CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0); + CCGSubSurf *ss = _getSubSurf(NULL, 1, CCG_USE_ARENA); float edge_sum[3], face_sum[3]; CCGVertIterator *vi; DerivedMesh *dm = CDDM_from_mesh(me, NULL); -- cgit v1.2.3 From 62ac943e3108ad5f70cd5349cd5f1cef98138313 Mon Sep 17 00:00:00 2001 From: Andrew Hale Date: Fri, 20 Jan 2012 02:10:09 +0000 Subject: - Added functions to remove mesh vertices, edges and faces. These functions remove a specified number of elements from the end of their respective arrays. For example, removing two vertices removes the last two vertices of the mesh. - Minor fixes to descriptions of add edge and add face functions. --- source/blender/editors/include/ED_mesh.h | 4 ++ source/blender/editors/mesh/mesh_data.c | 85 +++++++++++++++++++++++++++++++ source/blender/makesrna/intern/rna_mesh.c | 16 +++++- 3 files changed, 103 insertions(+), 2 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 790fb88300d..160e3eea6cc 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -235,6 +235,10 @@ void ED_mesh_faces_add(struct Mesh *mesh, struct ReportList *reports, int count) void ED_mesh_edges_add(struct Mesh *mesh, struct ReportList *reports, int count); void ED_mesh_vertices_add(struct Mesh *mesh, struct ReportList *reports, int count); +void ED_mesh_faces_remove(struct Mesh *mesh, struct ReportList *reports, int count); +void ED_mesh_edges_remove(struct Mesh *mesh, struct ReportList *reports, int count); +void ED_mesh_vertices_remove(struct Mesh *mesh, struct ReportList *reports, int count); + void ED_mesh_transform(struct Mesh *me, float *mat); void ED_mesh_calc_normals(struct Mesh *me); void ED_mesh_material_link(struct Mesh *me, struct Material *ma); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index e40c806fd17..7f599fb3458 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -695,6 +695,49 @@ static void mesh_add_faces(Mesh *mesh, int len) mesh->totface= totface; } +static void mesh_remove_verts(Mesh *mesh, int len) +{ + CustomData vdata; + int totvert; + + if(len == 0) + return; + + totvert= mesh->totvert - len; + CustomData_free_elem(&mesh->vdata, totvert, len); + + /* set final vertex list size */ + mesh->totvert= totvert; +} + +static void mesh_remove_edges(Mesh *mesh, int len) +{ + CustomData edata; + int totedge; + + if(len == 0) + return; + + totedge= mesh->totedge - len; + CustomData_free_elem(&mesh->edata, totedge, len); + + mesh->totedge= totedge; +} + +static void mesh_remove_faces(Mesh *mesh, int len) +{ + CustomData fdata; + int totface; + + if(len == 0) + return; + + totface= mesh->totface - len; /* new face count */ + CustomData_free_elem(&mesh->fdata, totface, len); + + mesh->totface= totface; +} + /* void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces) { @@ -742,6 +785,48 @@ void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count) mesh_add_verts(mesh, count); } +void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count) +{ + if(mesh->edit_mesh) { + BKE_report(reports, RPT_ERROR, "Can't remove faces in edit mode"); + return; + } + else if(count > mesh->totface) { + BKE_report(reports, RPT_ERROR, "Can't remove more faces than the mesh contains"); + return; + } + + mesh_remove_faces(mesh, count); +} + +void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count) +{ + if(mesh->edit_mesh) { + BKE_report(reports, RPT_ERROR, "Can't remove edges in edit mode"); + return; + } + else if(count > mesh->totedge) { + BKE_report(reports, RPT_ERROR, "Can't remove more edges than the mesh contains"); + return; + } + + mesh_remove_edges(mesh, count); +} + +void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count) +{ + if(mesh->edit_mesh) { + BKE_report(reports, RPT_ERROR, "Can't remove vertices in edit mode"); + return; + } + else if(count > mesh->totvert) { + BKE_report(reports, RPT_ERROR, "Can't remove more vertices than the mesh contains"); + return; + } + + mesh_remove_verts(mesh, count); +} + void ED_mesh_calc_normals(Mesh *me) { mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index f6e958ab1f5..689b19b9371 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1699,6 +1699,10 @@ static void rna_def_mesh_vertices(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "add", "ED_mesh_vertices_add"); RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to add", 0, INT_MAX); + + func= RNA_def_function(srna, "remove", "ED_mesh_vertices_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to remove", 0, INT_MAX); } /* mesh.edges */ @@ -1717,7 +1721,11 @@ static void rna_def_mesh_edges(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "add", "ED_mesh_edges_add"); RNA_def_function_flag(func, FUNC_USE_REPORTS); - RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to add", 0, INT_MAX); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of edges to add", 0, INT_MAX); + + func= RNA_def_function(srna, "remove", "ED_mesh_edges_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of edges to remove", 0, INT_MAX); } /* mesh.faces */ @@ -1746,7 +1754,11 @@ static void rna_def_mesh_faces(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "add", "ED_mesh_faces_add"); RNA_def_function_flag(func, FUNC_USE_REPORTS); - RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to add", 0, INT_MAX); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of faces to add", 0, INT_MAX); + + func= RNA_def_function(srna, "remove", "ED_mesh_faces_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of faces to remove", 0, INT_MAX); } /* mesh.vertex_colors */ -- cgit v1.2.3 From fe71f40f889921ea3ab9282b5cbbc42ba19317e2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2012 02:24:01 +0000 Subject: misc changes from bmesh, syncing across to trunk, no functional changes --- source/blender/blenkernel/intern/mesh.c | 4 +- source/blender/blenlib/BLI_math_geom.h | 5 + source/blender/blenlib/BLI_math_vector.h | 1 + source/blender/blenlib/intern/BLI_ghash.c | 2 +- source/blender/blenlib/intern/math_geom.c | 55 ++++++++ source/blender/blenlib/intern/math_vector.c | 14 ++ source/blender/blenlib/intern/math_vector_inline.c | 23 ++++ source/blender/blenloader/intern/readfile.c | 2 +- source/blender/editors/mesh/mesh_ops.c | 1 + source/blender/modifiers/intern/MOD_build.c | 151 +++++++++++---------- 10 files changed, 186 insertions(+), 72 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 189ce890c2f..f6bd321466c 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -42,12 +42,12 @@ #include "DNA_meshdata_types.h" #include "DNA_ipo_types.h" +#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_bpath.h" #include "BLI_editVert.h" #include "BLI_math.h" #include "BLI_edgehash.h" -#include "BLI_utildefines.h" #include "BKE_animsys.h" #include "BKE_main.h" @@ -1295,7 +1295,7 @@ float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3] if (numVerts_r) *numVerts_r = numVerts; for (i=0; imvert[i].co); + copy_v3_v3(cos[i], me->mvert[i].co); return cos; } diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 27da6c1025d..8d18f5253c4 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -54,6 +54,8 @@ float area_tri_v3(const float a[3], const float b[3], const float c[3]); float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]); float area_poly_v3(int nr, float verts[][3], const float normal[3]); +int is_quad_convex_v3(const float *v1, const float *v2, const float *v3, const float *v4); + /********************************* Distance **********************************/ float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]); @@ -221,6 +223,9 @@ void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3], float n4[3], const float f_no[3], const float co1[3], const float co2[3], const float co3[3], const float co4[3]); +void accumulate_vertex_normals_poly(float **vertnos, float polyno[3], + float **vertcos, float vdiffs[][3], int nverts); + /********************************* Tangents **********************************/ typedef struct VertexTangent { diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index b75d8e0daa6..12a0b1892a1 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -171,6 +171,7 @@ float angle_v3v3v3(const float a[3], const float b[3], const float c[3]); float angle_normalized_v3v3(const float v1[3], const float v2[3]); void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3]); void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3]); +void angle_poly_v3(float* angles, const float* verts[3], int len); /********************************* Geometry **********************************/ diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 9f388b68c38..e10082348be 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -40,8 +40,8 @@ // #include "BLI_blenlib.h" -#include "BLI_mempool.h" #include "BLI_utildefines.h" +#include "BLI_mempool.h" #include "BLI_ghash.h" #include "BLO_sys_types.h" // for intptr_t support diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index ef04e5e9bce..d7880e40626 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2382,6 +2382,38 @@ void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3], } } +/* Add weighted face normal component into normals of the face vertices. + Caller must pass pre-allocated vdiffs of nverts length. */ +void accumulate_vertex_normals_poly(float **vertnos, float polyno[3], + float **vertcos, float vdiffs[][3], int nverts) +{ + int i; + + /* calculate normalized edge directions for each edge in the poly */ + for (i = 0; i < nverts; i++) { + sub_v3_v3v3(vdiffs[i], vertcos[(i+1) % nverts], vertcos[i]); + normalize_v3(vdiffs[i]); + } + + /* accumulate angle weighted face normal */ + { + const float *prev_edge = vdiffs[nverts-1]; + int i; + + for(i=0; i 0) ? 1 : 0; +} diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 590a48e8085..47deb705def 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -239,6 +239,20 @@ void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const angles[3]= (float)M_PI - angle_normalized_v3v3(ed4, ed1); } +void angle_poly_v3(float *angles, const float *verts[3], int len) +{ + int i; + float vec[3][3]; + + sub_v3_v3v3(vec[2], verts[len-1], verts[0]); + normalize_v3(vec[2]); + for (i = 0; i < len; i++) { + sub_v3_v3v3(vec[i%3], verts[i%len], verts[(i+1)%len]); + normalize_v3(vec[i%3]); + angles[i] = (float)M_PI - angle_normalized_v3v3(vec[(i+2)%3], vec[i%3]); + } +} + /********************************* Geometry **********************************/ /* Project v1 on v2 */ diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index dc9a32222f7..9c5d8f3261f 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -515,6 +515,29 @@ MINLINE float normalize_v3_v3(float r[3], const float a[3]) return d; } +MINLINE double normalize_v3_d(double n[3]) +{ + double d= n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; + + /* a larger value causes normalize errors in a + scaled down models with camera xtreme close */ + if(d > 1.0e-35) { + double mul; + + d= sqrt(d); + mul = 1.0 / d; + + n[0] *= mul; + n[1] *= mul; + n[2] *= mul; + } else { + n[0] = n[1] = n[2] = 0; + d= 0.0; + } + + return d; +} + MINLINE float normalize_v3(float n[3]) { return normalize_v3_v3(n, n); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fa15590e4e3..fb49f3974b4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -97,9 +97,9 @@ #include "MEM_guardedalloc.h" +#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_utildefines.h" #include "BKE_anim.h" #include "BKE_action.h" diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 90b3d45deb7..2ff90525498 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -300,6 +300,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_fill", FKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_beautify_fill", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); + WM_keymap_add_item(keymap, "MESH_OT_quads_convert_to_tris", TKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_edge_flip", FKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 119934ea2f0..ebb5bd9ab9b 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -76,135 +76,150 @@ static int dependsOnTime(ModifierData *UNUSED(md)) } static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), - DerivedMesh *derivedData, - int UNUSED(useRenderParams), - int UNUSED(isFinalCalc)) + DerivedMesh *derivedData, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) { DerivedMesh *dm = derivedData; DerivedMesh *result; BuildModifierData *bmd = (BuildModifierData*) md; int i; - int numFaces, numEdges; + int numFaces_dst, numEdges_dst; int *vertMap, *edgeMap, *faceMap; float frac; GHashIterator *hashIter; /* maps vert indices in old mesh to indices in new mesh */ GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash, - BLI_ghashutil_intcmp, "build ve apply gh"); + BLI_ghashutil_intcmp, "build ve apply gh"); /* maps edge indices in new mesh to indices in old mesh */ GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash, - BLI_ghashutil_intcmp, "build ed apply gh"); + BLI_ghashutil_intcmp, "build ed apply gh"); - const int maxVerts= dm->getNumVerts(dm); - const int maxEdges= dm->getNumEdges(dm); - const int maxFaces= dm->getNumFaces(dm); + const int numVert_src= dm->getNumVerts(dm); + const int numEdge_src= dm->getNumEdges(dm); + const int numFace_src= dm->getNumFaces(dm); - vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts, "build modifier vertMap"); - for(i = 0; i < maxVerts; ++i) vertMap[i] = i; - edgeMap = MEM_callocN(sizeof(*edgeMap) * maxEdges, "build modifier edgeMap"); - for(i = 0; i < maxEdges; ++i) edgeMap[i] = i; - faceMap = MEM_callocN(sizeof(*faceMap) * maxFaces, "build modifier faceMap"); - for(i = 0; i < maxFaces; ++i) faceMap[i] = i; + vertMap = MEM_callocN(sizeof(*vertMap) * numVert_src, "build modifier vertMap"); + for (i = 0; i < numVert_src; i++) vertMap[i] = i; + edgeMap = MEM_callocN(sizeof(*edgeMap) * numEdge_src, "build modifier edgeMap"); + for (i = 0; i < numEdge_src; i++) edgeMap[i] = i; + faceMap = MEM_callocN(sizeof(*faceMap) * numFace_src, "build modifier faceMap"); + for (i = 0; i < numFace_src; i++) faceMap[i] = i; frac = (BKE_curframe(md->scene) - bmd->start) / bmd->length; CLAMP(frac, 0.0f, 1.0f); - numFaces = dm->getNumFaces(dm) * frac; - numEdges = dm->getNumEdges(dm) * frac; + numFaces_dst = dm->getNumFaces(dm) * frac; + numEdges_dst = dm->getNumEdges(dm) * frac; /* if there's at least one face, build based on faces */ - if(numFaces) { - if(bmd->randomize) + if (numFaces_dst) { + if (bmd->randomize) { BLI_array_randomize(faceMap, sizeof(*faceMap), - maxFaces, bmd->seed); + numFace_src, bmd->seed); + } /* get the set of all vert indices that will be in the final mesh, - * mapped to the new indices - */ - for(i = 0; i < numFaces; ++i) { + * mapped to the new indices + */ + for (i = 0; i < numFaces_dst; i++) { MFace mf; dm->getFace(dm, faceMap[i], &mf); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1))) + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2))) + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3))) + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } + if (mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } } /* get the set of edges that will be in the new mesh (i.e. all edges - * that have both verts in the new mesh) - */ - for(i = 0; i < maxEdges; ++i) { + * that have both verts in the new mesh) + */ + for (i = 0; i < numEdge_src; i++) { MEdge me; dm->getEdge(dm, i, &me); - if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) - && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) - BLI_ghash_insert(edgeHash, - SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i)); + if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) && + BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) + { + BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), + SET_INT_IN_POINTER(i)); + } } - } else if(numEdges) { - if(bmd->randomize) + } + else if (numEdges_dst) { + if (bmd->randomize) { BLI_array_randomize(edgeMap, sizeof(*edgeMap), - maxEdges, bmd->seed); + numEdge_src, bmd->seed); + } /* get the set of all vert indices that will be in the final mesh, - * mapped to the new indices - */ - for(i = 0; i < numEdges; ++i) { + * mapped to the new indices + */ + for (i = 0; i < numEdges_dst; i++) { MEdge me; dm->getEdge(dm, edgeMap[i], &me); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))) + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } } /* get the set of edges that will be in the new mesh - */ - for(i = 0; i < numEdges; ++i) { + */ + for (i = 0; i < numEdges_dst; i++) { MEdge me; dm->getEdge(dm, edgeMap[i], &me); BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), - SET_INT_IN_POINTER(edgeMap[i])); + SET_INT_IN_POINTER(edgeMap[i])); } - } else { + } + else { int numVerts = dm->getNumVerts(dm) * frac; - if(bmd->randomize) + if (bmd->randomize) { BLI_array_randomize(vertMap, sizeof(*vertMap), - maxVerts, bmd->seed); + numVert_src, bmd->seed); + } /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ - for(i = 0; i < numVerts; ++i) - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i)); + for (i = 0; i < numVerts; i++) { + BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), + SET_INT_IN_POINTER(i)); + } } /* now we know the number of verts, edges and faces, we can create - * the mesh - */ + * the mesh + */ result = CDDM_from_template(dm, BLI_ghash_size(vertHash), - BLI_ghash_size(edgeHash), numFaces); + BLI_ghash_size(edgeHash), numFaces_dst); /* copy the vertices across */ - for( hashIter = BLI_ghashIterator_new(vertHash); - !BLI_ghashIterator_isDone(hashIter); - BLI_ghashIterator_step(hashIter) - ) { + for ( hashIter = BLI_ghashIterator_new(vertHash); + !BLI_ghashIterator_isDone(hashIter); + BLI_ghashIterator_step(hashIter)) + { MVert source; MVert *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); @@ -219,7 +234,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), BLI_ghashIterator_free(hashIter); /* copy the edges across, remapping indices */ - for(i = 0; i < BLI_ghash_size(edgeHash); ++i) { + for (i = 0; i < BLI_ghash_size(edgeHash); i++) { MEdge source; MEdge *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i))); @@ -235,7 +250,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), } /* copy the faces across, remapping indices */ - for(i = 0; i < numFaces; ++i) { + for (i = 0; i < numFaces_dst; i++) { MFace source; MFace *dest; int orig_v4; @@ -248,7 +263,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3))); - if(source.v4) + if (source.v4) source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4))); DM_copy_face_data(dm, result, faceMap[i], i, 1); @@ -258,14 +273,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), } CDDM_calc_normals(result); - + BLI_ghash_free(vertHash, NULL, NULL); BLI_ghash_free(edgeHash, NULL, NULL); MEM_freeN(vertMap); MEM_freeN(edgeMap); MEM_freeN(faceMap); - + return result; } -- cgit v1.2.3 From 8817aaef3ed730760416d5f5801175d54e1149fa Mon Sep 17 00:00:00 2001 From: Andrew Hale Date: Fri, 20 Jan 2012 05:11:42 +0000 Subject: - Fix for commit 43551 which caused a linking error in blenderplayer. - Minor clean up for commit 43551. --- source/blender/editors/mesh/mesh_data.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 7f599fb3458..d752d90ffdd 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -697,7 +697,6 @@ static void mesh_add_faces(Mesh *mesh, int len) static void mesh_remove_verts(Mesh *mesh, int len) { - CustomData vdata; int totvert; if(len == 0) @@ -712,7 +711,6 @@ static void mesh_remove_verts(Mesh *mesh, int len) static void mesh_remove_edges(Mesh *mesh, int len) { - CustomData edata; int totedge; if(len == 0) @@ -726,7 +724,6 @@ static void mesh_remove_edges(Mesh *mesh, int len) static void mesh_remove_faces(Mesh *mesh, int len) { - CustomData fdata; int totface; if(len == 0) -- cgit v1.2.3 From f0fc8c22bb9f8fa4cab232fd88b9aed27ca6637f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 20 Jan 2012 07:43:46 +0000 Subject: Fix #27120: Bake to image used for rendering glitch (bake feedback loop) Detect feedback loop and do not bake to images detected in this loop and show nice warning message in such cases. It's a way which wouldn't overcomplicate code trying to duplicate images and so without real benefit. --- source/blender/editors/object/object_bake.c | 19 +++++++++++++------ source/blender/makesdna/DNA_image_types.h | 1 + source/blender/render/extern/include/RE_shader_ext.h | 4 ++++ source/blender/render/intern/source/imagetexture.c | 6 ++++++ source/blender/render/intern/source/rendercore.c | 16 ++++++++++++++-- 5 files changed, 38 insertions(+), 8 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 6ec778d7ee9..2fe2e71f2d9 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -1255,7 +1255,7 @@ typedef struct BakeRender { Main *main; Scene *scene; struct Object *actob; - int tot, ready; + int result, ready; ReportList *reports; @@ -1328,7 +1328,7 @@ static void finish_bake_internal(BakeRender *bkr) if(bkr->prev_r_raytrace == 0) bkr->scene->r.mode &= ~R_RAYTRACE; - if(bkr->tot) { + if(bkr->result==BAKE_RESULT_OK) { Image *ima; /* force OpenGL reload and mipmap recalc */ for(ima= G.main->image.first; ima; ima= ima->id.next) { @@ -1355,7 +1355,7 @@ static void *do_bake_render(void *bake_v) { BakeRender *bkr= bake_v; - bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress); + bkr->result= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress); bkr->ready= 1; return NULL; @@ -1377,7 +1377,7 @@ static void bake_startjob(void *bkv, short *stop, short *do_update, float *progr RE_Database_Baking(bkr->re, bmain, scene, scene->lay, scene->r.bake_mode, bkr->actob); /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */ - bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress); + bkr->result= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress); } static void bake_update(void *bkv) @@ -1396,7 +1396,11 @@ static void bake_freejob(void *bkv) BakeRender *bkr= bkv; finish_bake_internal(bkr); - if(bkr->tot==0) BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to"); + if(bkr->result==BAKE_RESULT_NO_OBJECTS) + BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to"); + else if(bkr->result==BAKE_RESULT_FEEDBACK_LOOP) + BKE_report(bkr->reports, RPT_WARNING, "Feedback loop detected"); + MEM_freeN(bkr); G.rendering = 0; } @@ -1513,7 +1517,10 @@ static int bake_image_exec(bContext *C, wmOperator *op) } BLI_end_threads(&threads); - if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to"); + if(bkr.result==BAKE_RESULT_NO_OBJECTS) + BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to"); + else if(bkr.result==BAKE_RESULT_FEEDBACK_LOOP) + BKE_report(op->reports, RPT_ERROR, "Feedback loop detected"); finish_bake_internal(&bkr); diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index 110ac59edc9..efe6c4d2586 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -120,6 +120,7 @@ typedef struct Image { #define IMA_DEPRECATED 64 #define IMA_OLD_PREMUL 128 #define IMA_CM_PREDIVIDE 256 +#define IMA_USED_FOR_RENDER 512 /* Image.tpageflag */ #define IMA_TILES 1 diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index dd0a0f308ce..2f585f91d44 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -210,4 +210,8 @@ int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob struct Image *RE_bake_shade_get_image(void); void RE_bake_ibuf_filter(struct ImBuf *ibuf, char *mask, const int filter); +#define BAKE_RESULT_OK 0 +#define BAKE_RESULT_NO_OBJECTS 1 +#define BAKE_RESULT_FEEDBACK_LOOP 2 + #endif /* RE_SHADER_EXT_H */ diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 0b6e1b8ee01..2d64828b6b3 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -131,6 +131,8 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul return retval; ibuf= BKE_image_get_ibuf(ima, &tex->iuser); + + ima->flag|= IMA_USED_FOR_RENDER; } if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) return retval; @@ -1441,6 +1443,8 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const return retval; ibuf= BKE_image_get_ibuf(ima, &tex->iuser); + + ima->flag|= IMA_USED_FOR_RENDER; } if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) return retval; @@ -1812,6 +1816,8 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *res if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) ibuf->rect-= (ibuf->x*ibuf->y); + + ima->flag|= IMA_USED_FOR_RENDER; } void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 773af96671a..2d3837acbfa 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2440,6 +2440,11 @@ static int get_next_bake_face(BakeShade *bs) if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) continue; + if(ima->flag & IMA_USED_FOR_RENDER) { + ima->id.flag &= ~LIB_DOIT; + continue; + } + /* find the image for the first time? */ if(ima->id.flag & LIB_DOIT) { ima->id.flag &= ~LIB_DOIT; @@ -2584,7 +2589,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up BakeShade *handles; ListBase threads; Image *ima; - int a, vdone=0, usemask=0; + int a, vdone=0, usemask=0, result=BAKE_RESULT_OK; /* initialize render global */ R= *re; @@ -2601,6 +2606,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up for(ima= G.main->image.first; ima; ima= ima->id.next) { ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); ima->id.flag |= LIB_DOIT; + ima->flag&= ~IMA_USED_FOR_RENDER; if(ibuf) { ibuf->userdata = NULL; /* use for masking if needed */ if(ibuf->rect_float) @@ -2659,6 +2665,9 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up if((ima->id.flag & LIB_DOIT)==0) { ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + if(ima->flag & IMA_USED_FOR_RENDER) + result= BAKE_RESULT_FEEDBACK_LOOP; + if(!ibuf) continue; @@ -2679,7 +2688,10 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up BLI_end_threads(&threads); - return vdone; + if(vdone==0) + result= BAKE_RESULT_NO_OBJECTS; + + return result; } struct Image *RE_bake_shade_get_image(void) -- cgit v1.2.3