diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
42 files changed, 1965 insertions, 924 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index c456840637a..387d4775ad4 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -1798,7 +1798,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, if (seamEdges < 2 || seamEdges != v->numEdges) seam = 0; - if (!v->numEdges) { + if (!v->numEdges || ss->meshIFC.simpleSubdiv) { VertDataCopy(nCo, co, ss); } else if (_vert_isBoundary(v)) { @@ -2246,7 +2246,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) if (seamEdges < 2 || seamEdges != v->numEdges) seam = 0; - if (!v->numEdges) { + if (!v->numEdges || ss->meshIFC.simpleSubdiv) { VertDataCopy(nCo, co, ss); } else if (_vert_isBoundary(v)) { @@ -2827,6 +2827,11 @@ int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level) } } +int ccgSubSurf_getSimpleSubdiv(const CCGSubSurf *ss) +{ + return ss->meshIFC.simpleSubdiv; +} + /* Vert accessors */ CCGVertHDL ccgSubSurf_getVertVertHandle(CCGVert *v) diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h index 33b37ac281c..0f96bcf172d 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.h +++ b/source/blender/blenkernel/intern/CCGSubSurf.h @@ -17,6 +17,7 @@ typedef struct CCGMeshIFC { int vertUserSize, edgeUserSize, faceUserSize; int numLayers; int vertDataSize; + int simpleSubdiv; } CCGMeshIFC; /***/ @@ -91,6 +92,7 @@ int ccgSubSurf_getEdgeSize (const CCGSubSurf *ss); int ccgSubSurf_getEdgeLevelSize (const CCGSubSurf *ss, int level); int ccgSubSurf_getGridSize (const CCGSubSurf *ss); int ccgSubSurf_getGridLevelSize (const CCGSubSurf *ss, int level); +int ccgSubSurf_getSimpleSubdiv (const CCGSubSurf *ss); CCGVert* ccgSubSurf_getVert (CCGSubSurf *ss, CCGVertHDL v); CCGVertHDL ccgSubSurf_getVertVertHandle (CCGVert *v); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 120a0b2ba27..a29484638c0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -498,7 +498,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) } } else { - /*if no object, set to INT_MAX so we don't mess up any shapekey layers*/ + /* if no object, set to INT_MAX so we don't mess up any shapekey layers */ uid = INT_MAX; } @@ -541,7 +541,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) CustomData_free(&me->pdata, me->totpoly); /* ok, this should now use new CD shapekey data, - * which shouuld be fed through the modifier + * which should be fed through the modifier * stack*/ if (tmp.totvert != me->totvert && !did_shapekeys && me->key) { printf("%s: YEEK! this should be recoded! Shape key loss!: ID '%s'\n", __func__, tmp.id.name); @@ -1188,7 +1188,7 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag, wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba); /* Now copy colors in all face verts. */ - /*first add colors to the tessellation faces*/ + /* first add colors to the tessellation faces */ /* XXX Why update that layer? We have to update WEIGHT_MLOOPCOL anyway, * and tessellation recreates mface layers from mloop/mpoly ones, so no * need to fill WEIGHT_MCOL here. */ @@ -1793,7 +1793,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos { finaldm->recalcTessellation(finaldm); } - /* Even if tessellation is not needed, some modifiers migh have modified CD layers + /* Even if tessellation is not needed, some modifiers might have modified CD layers * (like mloopcol or mloopuv), hence we have to update those. */ else if (finaldm->dirty & DM_DIRTY_TESS_CDLAYERS) { /* A tessellation already exists, it should always have a CD_POLYINDEX. */ diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 111ac68b345..9b4f0a31e28 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -282,7 +282,7 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets) /* ........ */ -/* Note on evaluation optimisations: +/* Note on evaluation optimizations: * Optimisations currently used here play tricks with the depsgraph in order to try and * evaluate as few objects as strictly necessary to get nicer performance under standard * production conditions. For those people who really need the accurate version, @@ -323,7 +323,7 @@ static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets) /* update scene for current frame */ static void motionpaths_calc_update_scene(Scene *scene) { -#if 1 // 'production' optimisations always on +#if 1 // 'production' optimizations always on Base *base, *last = NULL; /* only stuff that moves or needs display still */ @@ -431,7 +431,7 @@ void animviz_calc_motionpaths(Scene *scene, ListBase *targets) if (efra <= sfra) return; /* optimize the depsgraph for faster updates */ - /* TODO: whether this is used should depend on some setting for the level of optimisations used */ + /* TODO: whether this is used should depend on some setting for the level of optimizations used */ motionpaths_calc_optimise_depsgraph(scene, targets); /* calculate path over requested range */ @@ -1279,9 +1279,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if (part->dup_group == NULL || part->dup_group->gobject.first == NULL) return; - for (go = part->dup_group->gobject.first; go; go = go->next) - if (go->ob == par) - return; + if (BLI_findptr(&part->dup_group->gobject, par, offsetof(GroupObject, ob))) { + return; + } } /* if we have a hair particle system, use the path cache */ @@ -1469,6 +1469,18 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p quat_to_mat4(obmat, q); obmat[3][3] = 1.0f; + /* add scaling if requested */ + if ((part->draw & PART_DRAW_NO_SCALE_OB) == 0) + mult_m4_m4m4(obmat, obmat, size_mat); + } + else if (part->draw & PART_DRAW_NO_SCALE_OB) { + /* remove scaling */ + float size_mat[4][4], original_size[3]; + + mat4_to_size(original_size, obmat); + size_to_mat4(size_mat, original_size); + invert_m4(size_mat); + mult_m4_m4m4(obmat, obmat, size_mat); } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index c10b1e2d4f4..04585791135 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -210,7 +210,7 @@ bArmature *BKE_armature_copy(bArmature *arm) newArm = BKE_libblock_copy(&arm->id); BLI_duplicatelist(&newArm->bonebase, &arm->bonebase); - /* Duplicate the childrens' lists*/ + /* Duplicate the childrens' lists */ newBone = newArm->bonebase.first; for (oldBone = arm->bonebase.first; oldBone; oldBone = oldBone->next) { newBone->parent = NULL; @@ -1463,7 +1463,7 @@ void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]) * * was 0.0000000000001, caused bug [#31333], smaller values give unstable * roll when toggling editmode again... - * No good value here, trying 0.000000001 as best compromize. :/ + * No good value here, trying 0.000000001 as best compromise. :/ */ if (dot_v3v3(axis, axis) > 1.0e-9f) { /* if nor is *not* a multiple of target ... */ diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index e6259cc9faf..79d5e092a10 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -425,7 +425,7 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va if (flbr->ob) { float vec2[3], t; - /* first check we're not blocking the leader*/ + /* first check we're not blocking the leader */ sub_v3_v3v3(vec, flbr->loc, flbr->oloc); mul_v3_fl(vec, 1.0f/bbd->timestep); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 468861242d0..fde95e0767e 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -421,7 +421,7 @@ void BKE_brush_curve_preset(Brush *b, /*CurveMappingPreset*/ int preset) b->curve->preset = preset; curvemap_reset(cm, &b->curve->clipr, b->curve->preset, CURVEMAP_SLOPE_NEGATIVE); - curvemapping_changed(b->curve, 0); + curvemapping_changed(b->curve, FALSE); } int BKE_brush_texture_set_nr(Brush *brush, int nr) @@ -1253,7 +1253,9 @@ float BKE_brush_curve_strength_clamp(Brush *br, float p, const float len) if (p >= len) return 0; else p = p / len; + curvemapping_initialize(br->curve); p = curvemapping_evaluateF(br->curve, 0, p); + if (p < 0.0f) p = 0.0f; else if (p > 1.0f) p = 1.0f; return p; @@ -1267,6 +1269,7 @@ float BKE_brush_curve_strength(Brush *br, float p, const float len) else p = p / len; + curvemapping_initialize(br->curve); return curvemapping_evaluateF(br->curve, 0, p); } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 88748d5f0b8..881caec8a58 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1869,7 +1869,7 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis dm->deformedOnly = 1; - /*don't add origindex layer if one already exists*/ + /* don't add origindex layer if one already exists */ add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX); mask = use_mdisps ? CD_MASK_DERIVEDMESH | CD_MASK_MDISPS : CD_MASK_DERIVEDMESH; @@ -1886,7 +1886,7 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis CustomData_merge(&bm->pdata, &dm->polyData, mask, CD_CALLOC, dm->numPolyData); - /*add tessellation mface layers*/ + /* add tessellation mface layers */ if (use_tessface) { CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri); } @@ -2260,7 +2260,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap) newe = MEM_callocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts"); newl = MEM_callocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts"); - /*fill newl with destination vertex indices*/ + /* fill newl with destination vertex indices */ mv = cddm->mvert; c = 0; for (i = 0; i < dm->numVertData; i++, mv++) { @@ -2271,14 +2271,14 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap) } } - /*now link target vertices to destination indices*/ + /* now link target vertices to destination indices */ for (i = 0; i < dm->numVertData; i++) { if (vtargetmap[i] != -1) { newv[i] = newv[vtargetmap[i]]; } } - /*find-replace merged vertices with target vertices*/ + /* find-replace merged vertices with target vertices */ ml = cddm->mloop; for (i = 0; i < totloop; i++, ml++) { if (vtargetmap[ml->v] != -1) { @@ -2286,7 +2286,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap) } } - /*now go through and fix edges and faces*/ + /* now go through and fix edges and faces */ med = cddm->medge; c = 0; for (i = 0; i < dm->numEdgeData; i++, med++) { diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 20fae973756..7c03c75bd99 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -56,13 +56,11 @@ /* ***************** operations on full struct ************* */ -CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy) +void curvemapping_set_defaults(CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy) { - CurveMapping *cumap; int a; float clipminx, clipminy, clipmaxx, clipmaxy; - cumap = MEM_callocN(sizeof(CurveMapping), "new curvemap"); cumap->flag = CUMA_DO_CLIP; if (tot == 4) cumap->cur = 3; /* rhms, hack for 'col' curve? */ @@ -89,58 +87,84 @@ CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, floa } cumap->changed_timestamp = 0; +} + +CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy) +{ + CurveMapping *cumap; + + cumap = MEM_callocN(sizeof(CurveMapping), "new curvemap"); + + curvemapping_set_defaults(cumap, tot, minx, miny, maxx, maxy); return cumap; } -void curvemapping_free(CurveMapping *cumap) +void curvemapping_free_data(CurveMapping *cumap) { int a; - + + for (a = 0; a < CM_TOT; a++) { + if (cumap->cm[a].curve) MEM_freeN(cumap->cm[a].curve); + if (cumap->cm[a].table) MEM_freeN(cumap->cm[a].table); + if (cumap->cm[a].premultable) MEM_freeN(cumap->cm[a].premultable); + } +} + +void curvemapping_free(CurveMapping *cumap) +{ if (cumap) { - for (a = 0; a < CM_TOT; a++) { - if (cumap->cm[a].curve) MEM_freeN(cumap->cm[a].curve); - if (cumap->cm[a].table) MEM_freeN(cumap->cm[a].table); - if (cumap->cm[a].premultable) MEM_freeN(cumap->cm[a].premultable); - } + curvemapping_free_data(cumap); MEM_freeN(cumap); } } -CurveMapping *curvemapping_copy(CurveMapping *cumap) +void curvemapping_copy_data(CurveMapping *target, CurveMapping *cumap) { int a; - + + *target = *cumap; + + for (a = 0; a < CM_TOT; a++) { + if (cumap->cm[a].curve) + target->cm[a].curve = MEM_dupallocN(cumap->cm[a].curve); + if (cumap->cm[a].table) + target->cm[a].table = MEM_dupallocN(cumap->cm[a].table); + if (cumap->cm[a].premultable) + target->cm[a].premultable = MEM_dupallocN(cumap->cm[a].premultable); + } +} + +CurveMapping *curvemapping_copy(CurveMapping *cumap) +{ if (cumap) { CurveMapping *cumapn = MEM_dupallocN(cumap); - for (a = 0; a < CM_TOT; a++) { - if (cumap->cm[a].curve) - cumapn->cm[a].curve = MEM_dupallocN(cumap->cm[a].curve); - if (cumap->cm[a].table) - cumapn->cm[a].table = MEM_dupallocN(cumap->cm[a].table); - if (cumap->cm[a].premultable) - cumapn->cm[a].premultable = MEM_dupallocN(cumap->cm[a].premultable); - } + curvemapping_copy_data(cumapn, cumap); return cumapn; } return NULL; } -void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], const float white[3]) +void curvemapping_set_black_white_ex(const float black[3], const float white[3], float r_bwmul[3]) { int a; - - if (white) + + for (a = 0; a < 3; a++) { + const float delta = maxf(white[a] - black[a], 1e-5f); + r_bwmul[a] = 1.0f / delta; + } +} + +void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], const float white[3]) +{ + if (white) { copy_v3_v3(cumap->white, white); - if (black) + } + if (black) { copy_v3_v3(cumap->black, black); - - for (a = 0; a < 3; a++) { - if (cumap->white[a] == cumap->black[a]) - cumap->bwmul[a] = 0.0f; - else - cumap->bwmul[a] = 1.0f / (cumap->white[a] - cumap->black[a]); - } + } + + curvemapping_set_black_white_ex(cumap->black, cumap->white, cumap->bwmul); } /* ***************** operations on single curve ************* */ @@ -173,7 +197,7 @@ void curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point) } /* removes with flag set */ -void curvemap_remove(CurveMap *cuma, int flag) +void curvemap_remove(CurveMap *cuma, const short flag) { CurveMapPoint *cmp = MEM_mallocN((cuma->totpoint) * sizeof(CurveMapPoint), "curve points"); int a, b, removed = 0; @@ -416,7 +440,7 @@ static void calchandle_curvemap(BezTriple *bezt, BezTriple *prev, BezTriple *nex /* in X, out Y. * X is presumed to be outside first or last */ -static float curvemap_calc_extend(CurveMap *cuma, float x, const float first[2], const float last[2]) +static float curvemap_calc_extend(const CurveMap *cuma, float x, const float first[2], const float last[2]) { if (x <= first[0]) { if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { @@ -644,7 +668,7 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles) CurveMap *cuma = cumap->cm + cumap->cur; CurveMapPoint *cmp = cuma->curve; rctf *clipr = &cumap->clipr; - float thresh = 0.01f * (clipr->xmax - clipr->xmin); + float thresh = 0.01f * BLI_RCT_SIZE_X(clipr); float dx = 0.0f, dy = 0.0f; int a; @@ -682,12 +706,12 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles) dy = cmp[a].y - cmp[a + 1].y; if (sqrtf(dx * dx + dy * dy) < thresh) { if (a == 0) { - cmp[a + 1].flag |= 2; + cmp[a + 1].flag |= CUMA_VECTOR; if (cmp[a + 1].flag & CUMA_SELECT) cmp[a].flag |= CUMA_SELECT; } else { - cmp[a].flag |= 2; + cmp[a].flag |= CUMA_VECTOR; if (cmp[a].flag & CUMA_SELECT) cmp[a + 1].flag |= CUMA_SELECT; } @@ -707,7 +731,7 @@ void curvemapping_changed_all(CurveMapping *cumap) for (a = 0; a < CM_TOT; a++) { if (cumap->cm[a].curve) { cumap->cur = a; - curvemapping_changed(cumap, 0); + curvemapping_changed(cumap, FALSE); } } @@ -715,7 +739,7 @@ void curvemapping_changed_all(CurveMapping *cumap) } /* table should be verified */ -float curvemap_evaluateF(CurveMap *cuma, float value) +float curvemap_evaluateF(const CurveMap *cuma, float value) { float fi; int i; @@ -737,49 +761,67 @@ float curvemap_evaluateF(CurveMap *cuma, float value) } /* works with curve 'cur' */ -float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value) +float curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value) { - CurveMap *cuma = cumap->cm + cur; - - /* allocate or bail out */ - if (cuma->table == NULL) { - curvemap_make_table(cuma, &cumap->clipr); - if (cuma->table == NULL) - return 1.0f - value; - } + const CurveMap *cuma = cumap->cm + cur; return curvemap_evaluateF(cuma, value); } /* vector case */ -void curvemapping_evaluate3F(CurveMapping *cumap, float vecout[3], const float vecin[3]) +void curvemapping_evaluate3F(const CurveMapping *cumap, float vecout[3], const float vecin[3]) { - vecout[0] = curvemapping_evaluateF(cumap, 0, vecin[0]); - vecout[1] = curvemapping_evaluateF(cumap, 1, vecin[1]); - vecout[2] = curvemapping_evaluateF(cumap, 2, vecin[2]); + vecout[0] = curvemap_evaluateF(&cumap->cm[0], vecin[0]); + vecout[1] = curvemap_evaluateF(&cumap->cm[1], vecin[1]); + vecout[2] = curvemap_evaluateF(&cumap->cm[2], vecin[2]); } /* RGB case, no black/white points, no premult */ -void curvemapping_evaluateRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3]) +void curvemapping_evaluateRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3]) { - vecout[0] = curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, vecin[0])); - vecout[1] = curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, vecin[1])); - vecout[2] = curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, vecin[2])); + vecout[0] = curvemap_evaluateF(&cumap->cm[0], curvemap_evaluateF(&cumap->cm[3], vecin[0])); + vecout[1] = curvemap_evaluateF(&cumap->cm[1], curvemap_evaluateF(&cumap->cm[3], vecin[1])); + vecout[2] = curvemap_evaluateF(&cumap->cm[2], curvemap_evaluateF(&cumap->cm[3], vecin[2])); } +/** same as #curvemapping_evaluate_premulRGBF + * but black/bwmul are passed as args for the compositor + * where they can change per pixel. + * + * Use in conjunction with #curvemapping_set_black_white_ex + * + * \param black Use instead of cumap->black + * \param bwmul Use instead of cumap->bwmul + */ +void curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap, float vecout[3], const float vecin[3], + const float black[3], const float bwmul[3]) +{ + vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - black[0]) * bwmul[0]); + vecout[1] = curvemap_evaluateF(&cumap->cm[1], (vecin[1] - black[1]) * bwmul[1]); + vecout[2] = curvemap_evaluateF(&cumap->cm[2], (vecin[2] - black[2]) * bwmul[2]); +} /* RGB with black/white points and premult. tables are checked */ -void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3]) +void curvemapping_evaluate_premulRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3]) { - float fac; - - fac = (vecin[0] - cumap->black[0]) * cumap->bwmul[0]; - vecout[0] = curvemap_evaluateF(cumap->cm, fac); - - fac = (vecin[1] - cumap->black[1]) * cumap->bwmul[1]; - vecout[1] = curvemap_evaluateF(cumap->cm + 1, fac); - - fac = (vecin[2] - cumap->black[2]) * cumap->bwmul[2]; - vecout[2] = curvemap_evaluateF(cumap->cm + 2, fac); + vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - cumap->black[0]) * cumap->bwmul[0]); + vecout[1] = curvemap_evaluateF(&cumap->cm[1], (vecin[1] - cumap->black[1]) * cumap->bwmul[1]); + vecout[2] = curvemap_evaluateF(&cumap->cm[2], (vecin[2] - cumap->black[2]) * cumap->bwmul[2]); +} + +/* same as above, byte version */ +void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3]) +{ + float vecin[3], vecout[3]; + + vecin[0] = (float) vecin_byte[0] / 255.0f; + vecin[1] = (float) vecin_byte[1] / 255.0f; + vecin[2] = (float) vecin_byte[2] / 255.0f; + + curvemapping_evaluate_premulRGBF(cumap, vecout, vecin); + + vecout_byte[0] = FTOCHAR(vecout[0]); + vecout_byte[1] = FTOCHAR(vecout[1]); + vecout_byte[2] = FTOCHAR(vecout[2]); } @@ -840,7 +882,7 @@ void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf) curvemapping_premultiply(cumap, 1); } -int curvemapping_RGBA_does_something(CurveMapping *cumap) +int curvemapping_RGBA_does_something(const CurveMapping *cumap) { int a; @@ -876,13 +918,12 @@ void curvemapping_initialize(CurveMapping *cumap) } } -void curvemapping_table_RGBA(CurveMapping *cumap, float **array, int *size) +void curvemapping_table_RGBA(const CurveMapping *cumap, float **array, int *size) { int a; *size = CM_TABLE + 1; *array = MEM_callocN(sizeof(float) * (*size) * 4, "CurveMapping"); - curvemapping_initialize(cumap); for (a = 0; a < *size; a++) { if (cumap->cm[0].table) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 16edbc3f0a9..00130dd3583 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3114,7 +3114,8 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar copy_v3_v3(ownLoc, obmat[3]); INIT_MINMAX(curveMin, curveMax); - BKE_object_minmax(ct->tar, curveMin, curveMax); + /* XXX - don't think this is good calling this here - campbell */ + BKE_object_minmax(ct->tar, curveMin, curveMax, TRUE); /* get targetmatrix */ if (cu->path && cu->path->data) { diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index e2bb1aaa2c7..a2f88781cbb 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1165,7 +1165,7 @@ void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float static void forward_diff_bezier_cotangent(const float p0[3], const float p1[3], const float p2[3], const float p3[3], float p[3], int it, int stride) { - /* note that these are not purpendicular to the curve + /* note that these are not perpendicular to the curve * they need to be rotated for this, * * This could also be optimized like BKE_curve_forward_diff_bezier */ @@ -3047,29 +3047,6 @@ void BKE_nurbList_handles_set(ListBase *editnurb, short code) } } -static void swapdata(void *adr1, void *adr2, int len) -{ - - if (len <= 0) return; - - if (len < 65) { - char adr[64]; - - memcpy(adr, adr1, len); - memcpy(adr1, adr2, len); - memcpy(adr2, adr, len); - } - else { - char *adr; - - adr = (char *)MEM_mallocN(len, "curve swap"); - memcpy(adr, adr1, len); - memcpy(adr1, adr2, len); - memcpy(adr2, adr, len); - MEM_freeN(adr); - } -} - void BKE_nurb_direction_switch(Nurb *nu) { BezTriple *bezt1, *bezt2; @@ -3077,7 +3054,9 @@ void BKE_nurb_direction_switch(Nurb *nu) float *fp1, *fp2, *tempf; int a, b; - if (nu->pntsu == 1 && nu->pntsv == 1) return; + if (nu->pntsu == 1 && nu->pntsv == 1) { + return; + } if (nu->type == CU_BEZIER) { a = nu->pntsu; @@ -3086,19 +3065,22 @@ void BKE_nurb_direction_switch(Nurb *nu) if (a & 1) a += 1; /* if odd, also swap middle content */ a /= 2; while (a > 0) { - if (bezt1 != bezt2) + if (bezt1 != bezt2) { SWAP(BezTriple, *bezt1, *bezt2); + } + + swap_v3_v3(bezt1->vec[0], bezt1->vec[2]); - swapdata(bezt1->vec[0], bezt1->vec[2], 12); - if (bezt1 != bezt2) - swapdata(bezt2->vec[0], bezt2->vec[2], 12); + if (bezt1 != bezt2) { + swap_v3_v3(bezt2->vec[0], bezt2->vec[2]); + } SWAP(char, bezt1->h1, bezt1->h2); - SWAP(short, bezt1->f1, bezt1->f3); + SWAP(char, bezt1->f1, bezt1->f3); if (bezt1 != bezt2) { SWAP(char, bezt2->h1, bezt2->h2); - SWAP(short, bezt2->f1, bezt2->f3); + SWAP(char, bezt2->f1, bezt2->f3); bezt1->alfa = -bezt1->alfa; bezt2->alfa = -bezt2->alfa; } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index d92c4ca8632..a00bea38e51 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -72,25 +72,29 @@ typedef struct LayerTypeInfo { const char *structname; /* name of the struct used, for file writing */ int structnum; /* number of structs per element, for file writing */ - /* default layer name. + /** + * default layer name. * note! when NULL this is a way to ensure there is only ever one item * see: CustomData_layertype_is_singleton() */ const char *defaultname; - /* a function to copy count elements of this layer's data + /** + * a function to copy count elements of this layer's data * (deep copy if appropriate) * if NULL, memcpy is used */ void (*copy)(const void *source, void *dest, int count); - /* a function to free any dynamically allocated components of this + /** + * a function to free any dynamically allocated components of this * layer's data (note the data pointer itself should not be freed) * size should be the size of one element of this layer's data (e.g. * LayerTypeInfo.size) */ void (*free)(void *data, int count, int size); - /* a function to interpolate between count source elements of this + /** + * a function to interpolate between count source elements of this * layer's data and store the result in dest * if weights == NULL or sub_weights == NULL, they should default to 1 * @@ -98,18 +102,24 @@ typedef struct LayerTypeInfo { * sub_weights gives the sub-element weights for each element in sources * (there should be (sub element count)^2 weights per element) * count gives the number of elements in sources + * + * \note in some cases \a dest pointer is in \a sources + * so all functions have to take this into account and delay + * applying changes while reading from sources. + * See bug [#32395] - Campbell. */ - void (*interp)(void **sources, float *weights, float *sub_weights, + void (*interp)(void **sources, const float *weights, const float *sub_weights, int count, void *dest); - /* a function to swap the data in corners of the element */ + /** a function to swap the data in corners of the element */ void (*swap)(void *data, const int *corner_indices); - /* a function to set a layer's data to default values. if NULL, the + /** + * a function to set a layer's data to default values. if NULL, the * default is assumed to be all zeros */ void (*set_default)(void *data, int count); - /* functions necessary for geometry collapse*/ + /** functions necessary for geometry collapse */ int (*equal)(void *data1, void *data2); void (*multiply)(void *data, float fac); void (*initminmax)(void *min, void *max); @@ -117,13 +127,13 @@ typedef struct LayerTypeInfo { void (*dominmax)(void *data1, void *min, void *max); void (*copyvalue)(void *source, void *dest); - /* a function to read data from a cdf file */ + /** a function to read data from a cdf file */ int (*read)(CDataFile *cdf, void *data, int count); - /* a function to write data to a cdf file */ + /** a function to write data to a cdf file */ int (*write)(CDataFile *cdf, void *data, int count); - /* a function to determine file size */ + /** a function to determine file size */ size_t (*filesize)(CDataFile *cdf, void *data, int count); } LayerTypeInfo; @@ -203,8 +213,8 @@ static void linklist_free_simple(void *link) MEM_freeN(link); } -static void layerInterp_mdeformvert(void **sources, float *weights, - float *UNUSED(sub_weights), int count, void *dest) +static void layerInterp_mdeformvert(void **sources, const float *weights, + const float *UNUSED(sub_weights), int count, void *dest) { MDeformVert *dvert = dest; LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */ @@ -243,6 +253,8 @@ static void layerInterp_mdeformvert(void **sources, float *weights, } } + /* delay writing to the destination incase dest is in sources */ + /* now we know how many unique deform weights there are, so realloc */ if (dvert->dw) MEM_freeN(dvert->dw); @@ -261,8 +273,8 @@ static void layerInterp_mdeformvert(void **sources, float *weights, } -static void layerInterp_msticky(void **sources, float *weights, - float *UNUSED(sub_weights), int count, void *dest) +static void layerInterp_msticky(void **sources, const float *weights, + const float *UNUSED(sub_weights), int count, void *dest) { float co[2], w; MSticky *mst; @@ -276,6 +288,7 @@ static void layerInterp_msticky(void **sources, float *weights, madd_v2_v2fl(co, mst->co, w); } + /* delay writing to the destination incase dest is in sources */ mst = (MSticky *)dest; copy_v2_v2(mst->co, co); } @@ -291,13 +304,13 @@ static void layerCopy_tface(const void *source, void *dest, int count) dest_tf[i] = source_tf[i]; } -static void layerInterp_tface(void **sources, float *weights, - float *sub_weights, int count, void *dest) +static void layerInterp_tface(void **sources, const float *weights, + const float *sub_weights, int count, void *dest) { MTFace *tf = dest; int i, j, k; float uv[4][2] = {{0.0f}}; - float *sub_weight; + const float *sub_weight; if (count <= 0) return; @@ -318,6 +331,7 @@ static void layerInterp_tface(void **sources, float *weights, } } + /* delay writing to the destination incase dest is in sources */ *tf = *(MTFace *)(*sources); memcpy(tf->uv, uv, sizeof(tf->uv)); } @@ -392,13 +406,13 @@ static void layerCopy_origspace_face(const void *source, void *dest, int count) dest_tf[i] = source_tf[i]; } -static void layerInterp_origspace_face(void **sources, float *weights, - float *sub_weights, int count, void *dest) +static void layerInterp_origspace_face(void **sources, const float *weights, + const float *sub_weights, int count, void *dest) { OrigSpaceFace *osf = dest; int i, j, k; float uv[4][2] = {{0.0f}}; - float *sub_weight; + const float *sub_weight; if (count <= 0) return; @@ -419,6 +433,8 @@ static void layerInterp_origspace_face(void **sources, float *weights, } } + /* delay writing to the destination incase dest is in sources */ + #if 0 /* no need, this ONLY contains UV's */ *osf = *(OrigSpaceFace *)(*sources); #endif @@ -680,12 +696,12 @@ static void layerDefault_mloopcol(void *data, int count) } -static void layerInterp_mloopcol(void **sources, float *weights, - float *sub_weights, int count, void *dest) +static void layerInterp_mloopcol(void **sources, const float *weights, + const float *sub_weights, int count, void *dest) { MLoopCol *mc = dest; int i; - float *sub_weight; + const float *sub_weight; struct { float a; float r; @@ -719,7 +735,8 @@ static void layerInterp_mloopcol(void **sources, float *weights, CLAMP(col.r, 0.0f, 255.0f); CLAMP(col.g, 0.0f, 255.0f); CLAMP(col.b, 0.0f, 255.0f); - + + /* delay writing to the destination incase dest is in sources */ mc->r = (int)col.r; mc->g = (int)col.g; mc->b = (int)col.b; @@ -768,11 +785,10 @@ static void layerAdd_mloopuv(void *data1, void *data2) add_v2_v2(l1->uv, l2->uv); } -static void layerInterp_mloopuv(void **sources, float *weights, - float *sub_weights, int count, void *dest) +static void layerInterp_mloopuv(void **sources, const float *weights, + const float *sub_weights, int count, void *dest) { - MLoopUV *mluv = dest; - float *uv = mluv->uv; + float uv[2]; int i; zero_v2(uv); @@ -793,6 +809,9 @@ static void layerInterp_mloopuv(void **sources, float *weights, madd_v2_v2fl(uv, src->uv, weight); } } + + /* delay writing to the destination incase dest is in sources */ + copy_v2_v2(((MLoopUV *)dest)->uv, uv); } /* origspace is almost exact copy of mloopuv's, keep in sync */ @@ -838,11 +857,10 @@ static void layerAdd_mloop_origspace(void *data1, void *data2) add_v2_v2(l1->uv, l2->uv); } -static void layerInterp_mloop_origspace(void **sources, float *weights, - float *sub_weights, int count, void *dest) +static void layerInterp_mloop_origspace(void **sources, const float *weights, + const float *sub_weights, int count, void *dest) { - OrigSpaceLoop *mluv = dest; - float *uv = mluv->uv; + float uv[2]; int i; zero_v2(uv); @@ -858,16 +876,19 @@ static void layerInterp_mloop_origspace(void **sources, float *weights, } else { for (i = 0; i < count; i++) { - float weight = weights ? weights[i] : 1; + float weight = weights ? weights[i] : 1.0f; OrigSpaceLoop *src = sources[i]; madd_v2_v2fl(uv, src->uv, weight); } } + + /* delay writing to the destination incase dest is in sources */ + copy_v2_v2(((OrigSpaceLoop *)dest)->uv, uv); } /* --- end copy */ -static void layerInterp_mcol(void **sources, float *weights, - float *sub_weights, int count, void *dest) +static void layerInterp_mcol(void **sources, const float *weights, + const float *sub_weights, int count, void *dest) { MCol *mc = dest; int i, j, k; @@ -878,7 +899,7 @@ static void layerInterp_mcol(void **sources, float *weights, float b; } col[4] = {{0.0f}}; - float *sub_weight; + const float *sub_weight; if (count <= 0) return; @@ -907,6 +928,7 @@ static void layerInterp_mcol(void **sources, float *weights, } } + /* delay writing to the destination incase dest is in sources */ for (j = 0; j < 4; ++j) { /* Subdivide smooth or fractal can cause problems without clamping @@ -946,33 +968,36 @@ static void layerDefault_mcol(void *data, int count) } } -static void layerInterp_bweight(void **sources, float *weights, - float *UNUSED(sub_weights), int count, void *dest) +static void layerInterp_bweight(void **sources, const float *weights, + const float *UNUSED(sub_weights), int count, void *dest) { - float *f = dest; + float f; float **in = (float **)sources; int i; if (count <= 0) return; - *f = 0.0f; + f = 0.0f; if (weights) { for (i = 0; i < count; ++i) { - *f += *in[i] * weights[i]; + f += *in[i] * weights[i]; } } else { for (i = 0; i < count; ++i) { - *f += *in[i]; + f += *in[i]; } } + + /* delay writing to the destination incase dest is in sources */ + *((float *)dest) = f; } -static void layerInterp_shapekey(void **sources, float *weights, - float *UNUSED(sub_weights), int count, void *dest) +static void layerInterp_shapekey(void **sources, const float *weights, + const float *UNUSED(sub_weights), int count, void *dest) { - float *co = dest; + float co[3]; float **in = (float **)sources; int i; @@ -990,6 +1015,9 @@ static void layerInterp_shapekey(void **sources, float *weights, add_v3_v3(co, in[i]); } } + + /* delay writing to the destination incase dest is in sources */ + copy_v3_v3((float *)dest, co); } static void layerDefault_mvert_skin(void *data, int count) @@ -1003,8 +1031,8 @@ static void layerDefault_mvert_skin(void *data, int count) } } -static void layerInterp_mvert_skin(void **sources, float *weights, - float *UNUSED(sub_weights), +static void layerInterp_mvert_skin(void **sources, const float *weights, + const float *UNUSED(sub_weights), int count, void *dest) { float radius[3], w; @@ -1019,6 +1047,7 @@ static void layerInterp_mvert_skin(void **sources, float *weights, madd_v3_v3fl(radius, vs->radius, w); } + /* delay writing to the destination incase dest is in sources */ vs = dest; copy_v3_v3(vs->radius, radius); vs->flag &= ~MVERT_SKIN_ROOT; @@ -1898,7 +1927,7 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest, * (this should work because layers are ordered by type) */ while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) { - ++dest_i; + dest_i++; } /* if there are no more dest layers, we're done */ @@ -1936,7 +1965,7 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest, * we don't want to copy all source layers to the same dest, so * increment dest_i */ - ++dest_i; + dest_i++; } } } @@ -1989,7 +2018,7 @@ void CustomData_interp(const CustomData *source, CustomData *dest, * (this should work because layers are ordered by type) */ while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) { - ++dest_i; + dest_i++; } /* if there are no more dest layers, we're done */ @@ -1999,8 +2028,9 @@ void CustomData_interp(const CustomData *source, CustomData *dest, if (dest->layers[dest_i].type == source->layers[src_i].type) { void *src_data = source->layers[src_i].data; - for (j = 0; j < count; ++j) + for (j = 0; j < count; ++j) { sources[j] = (char *)src_data + typeInfo->size * src_indices[j]; + } dest_offset = dest_index * typeInfo->size; @@ -2011,7 +2041,7 @@ void CustomData_interp(const CustomData *source, CustomData *dest, * we don't want to copy all source layers to the same dest, so * increment dest_i */ - ++dest_i; + dest_i++; } } @@ -2139,8 +2169,8 @@ void CustomData_set(const CustomData *data, int index, int type, void *source) memcpy(dest, source, typeInfo->size); } -/*Bmesh functions*/ -/*needed to convert to/from different face reps*/ +/* BMesh functions */ +/* needed to convert to/from different face reps */ void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int totloop, int totpoly) { @@ -2401,7 +2431,7 @@ void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, * (this should work because layers are ordered by type) */ while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) { - ++dest_i; + dest_i++; } /* if there are no more dest layers, we're done */ @@ -2425,7 +2455,7 @@ void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, * we don't want to copy all source layers to the same dest, so * increment dest_i */ - ++dest_i; + dest_i++; } } } @@ -2590,8 +2620,9 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights CustomDataLayer *layer = &data->layers[i]; const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); if (typeInfo->interp) { - for (j = 0; j < count; ++j) + for (j = 0; j < count; ++j) { sources[j] = (char *)src_blocks[j] + layer->offset; + } typeInfo->interp(sources, weights, sub_weights, count, (char *)dest_block + layer->offset); @@ -2637,7 +2668,7 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, * (this should work because layers are ordered by type) */ while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) { - ++dest_i; + dest_i++; } /* if there are no more dest layers, we're done */ @@ -2661,7 +2692,7 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, * we don't want to copy all source layers to the same dest, so * increment dest_i */ - ++dest_i; + dest_i++; } } } @@ -2680,7 +2711,7 @@ void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest, * (this should work because layers are ordered by type) */ while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) { - ++dest_i; + dest_i++; } /* if there are no more dest layers, we're done */ @@ -2704,7 +2735,7 @@ void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest, * we don't want to copy all source layers to the same dest, so * increment dest_i */ - ++dest_i; + dest_i++; } } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index b22e24e15d4..1b53f8980cb 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -570,12 +570,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O /* softbody collision */ if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) { - if (modifiers_isModifierEnabled(ob, eModifierType_Softbody) - || modifiers_isModifierEnabled(ob, eModifierType_Cloth) - || modifiers_isModifierEnabled(ob, eModifierType_Smoke) - || modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint) - || ob->particlesystem.first) + if (ob->particlesystem.first || + modifiers_isModifierEnabled(ob, eModifierType_Softbody) || + modifiers_isModifierEnabled(ob, eModifierType_Cloth) || + modifiers_isModifierEnabled(ob, eModifierType_Smoke) || + modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)) + { dag_add_collision_field_relation(dag, scene, ob, node); /* TODO: use effectorweight->group */ + } } /* object data drivers */ diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 0daf06c6305..06807dfcbad 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -3996,7 +3996,7 @@ void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, floa float force_intersect; float temp; - /* project force vector on the plane determined by these two neightbour points + /* project force vector on the plane determined by these two neighbor points * and calculate relative force angle from it*/ cross_v3_v3v3(tangent, bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir); normalize_v3(tangent); @@ -4318,7 +4318,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force dir_factor = dir_dot * MIN2(speed_scale, 1.0f) * w_factor; if (dir_factor > 0.5f) dir_factor = 0.5f; - /* mix new wetness*/ + /* mix new wetness */ ePoint->wetness += dir_factor; CLAMP(ePoint->wetness, 0.0f, MAX_WETNESS); diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 32c6caffff7..c6ba6a0d841 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -151,7 +151,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) #endif BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - /*don't consider two-edged faces*/ + /* don't consider two-edged faces */ if (efa->len < 3) { /* do nothing */ } @@ -198,7 +198,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) /* scanfill time */ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) { - /*mark order*/ + /*mark order */ BM_elem_index_set(l, j); /* set_loop */ sf_vert = BLI_scanfill_vert_add(&sf_ctx, l->v->co); @@ -334,7 +334,7 @@ typedef struct EditDerivedBMesh { float (*polyNos)[3]; /* private variables, for number of verts/edges/faces - * within the above hash/table members*/ + * within the above hash/table members */ int tv, te, tf; } EditDerivedBMesh; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 97b245bd067..53c12d32bc1 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -365,7 +365,7 @@ int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, short /* initialize replace-flag first */ *replace = 0; - /* sneaky optimisations (don't go through searching process if...): + /* sneaky optimizations (don't go through searching process if...): * - keyframe to be added is to be added out of current bounds * - keyframe to be added would replace one of the existing ones on bounds */ @@ -433,16 +433,18 @@ int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, short /* ...................................... */ /* helper for calc_fcurve_* functions -> find first and last BezTriple to be used */ -static void get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple **last, - const short do_sel_only) +static short get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple **last, + const short do_sel_only) { + short found = FALSE; + /* init outputs */ *first = NULL; *last = NULL; /* sanity checks */ if (fcu->bezt == NULL) - return; + return found; /* only include selected items? */ if (do_sel_only) { @@ -454,6 +456,7 @@ static void get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple * for (i = 0; i < fcu->totvert; bezt++, i++) { if (BEZSELECTED(bezt)) { *first = bezt; + found = TRUE; break; } } @@ -463,6 +466,7 @@ static void get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple * for (i = 0; i < fcu->totvert; bezt--, i++) { if (BEZSELECTED(bezt)) { *last = bezt; + found = TRUE; break; } } @@ -471,13 +475,16 @@ static void get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple * /* just full array */ *first = fcu->bezt; *last = ARRAY_LAST_ITEM(fcu->bezt, BezTriple, sizeof(BezTriple), fcu->totvert); + found = TRUE; } + + return found; } /* Calculate the extents of F-Curve's data */ -void calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax, - const short do_sel_only, const short include_handles) +short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax, + const short do_sel_only, const short include_handles) { float xminv = 999999999.0f, xmaxv = -999999999.0f; float yminv = 999999999.0f, ymaxv = -999999999.0f; @@ -490,7 +497,7 @@ void calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, floa if (xmin || xmax) { /* get endpoint keyframes */ - get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only); + foundvert = get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only); if (bezt_first) { BLI_assert(bezt_last != NULL); @@ -566,6 +573,8 @@ void calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, floa if (ymin) *ymin = 0.0f; if (ymax) *ymax = 1.0f; } + + return foundvert; } /* Calculate the extents of F-Curve's keyframes */ diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 02e5dc02746..0ffd68c9079 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -60,10 +60,8 @@ #include "BKE_curve.h" #include "BKE_displist.h" -static ListBase ttfdata = {NULL, NULL}; /* The vfont code */ - void BKE_vfont_free_data(struct VFont *vfont) { if (vfont->data) { @@ -83,7 +81,10 @@ void BKE_vfont_free_data(struct VFont *vfont) vfont->data = NULL; } - BKE_vfont_tmpfont_remove(vfont); + if (vfont->temp_pf) { + freePackedFile(vfont->temp_pf); /* NULL when the font file can't be found on disk */ + vfont->temp_pf = NULL; + } } void BKE_vfont_free(struct VFont *vf) @@ -91,7 +92,7 @@ void BKE_vfont_free(struct VFont *vf) if (vf == NULL) return; BKE_vfont_free_data(vf); - + if (vf->packedfile) { freePackedFile(vf->packedfile); vf->packedfile = NULL; @@ -128,63 +129,11 @@ static PackedFile *get_builtin_packedfile(void) } } -static void vfont_tmpfont_free(struct TmpFont *tf) -{ - if (tf->pf) { - freePackedFile(tf->pf); /* NULL when the font file can't be found on disk */ - } - MEM_freeN(tf); -} - -void BKE_vfont_free_global_ttf(void) -{ - struct TmpFont *tf, *tf_next; - - for (tf = ttfdata.first; tf; tf = tf_next) { - tf_next = tf->next; - vfont_tmpfont_free(tf); - } - ttfdata.first = ttfdata.last = NULL; -} - -struct TmpFont *BKE_vfont_tmpfont_find(VFont *vfont) -{ - struct TmpFont *tmpfnt = NULL; - - if (vfont == NULL) return NULL; - - /* Try finding the font from font list */ - for (tmpfnt = ttfdata.first; tmpfnt; tmpfnt = tmpfnt->next) { - if (tmpfnt->vfont == vfont) { - break; - } - } - - return tmpfnt; -} - -/* assumes a VFont's tmpfont can't be in the database more then once */ -void BKE_vfont_tmpfont_remove(VFont *vfont) -{ - struct TmpFont *tmpfnt; - - tmpfnt = BKE_vfont_tmpfont_find(vfont); - - if (tmpfnt) { - vfont_tmpfont_free(tmpfnt); - BLI_remlink(&ttfdata, tmpfnt); - } -} - static VFontData *vfont_get_data(Main *bmain, VFont *vfont) { - struct TmpFont *tmpfnt = NULL; - PackedFile *tpf; - - if (vfont == NULL) return NULL; - - /* Try finding the font from font list */ - tmpfnt = BKE_vfont_tmpfont_find(vfont); + if (vfont == NULL) { + return NULL; + } /* And then set the data */ if (!vfont->data) { @@ -198,30 +147,15 @@ static VFontData *vfont_get_data(Main *bmain, VFont *vfont) pf = vfont->packedfile; /* We need to copy a tmp font to memory unless it is already there */ - if (!tmpfnt) { - tpf = MEM_callocN(sizeof(*tpf), "PackedFile"); - tpf->data = MEM_mallocN(pf->size, "packFile"); - tpf->size = pf->size; - memcpy(tpf->data, pf->data, pf->size); - - /* Add temporary packed file to globals */ - tmpfnt = (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font"); - tmpfnt->pf = tpf; - tmpfnt->vfont = vfont; - BLI_addtail(&ttfdata, tmpfnt); + if (vfont->temp_pf == NULL) { + vfont->temp_pf = dupPackedFile(pf); } } else { pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id)); - if (!tmpfnt) { - tpf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id)); - - /* Add temporary packed file to globals */ - tmpfnt = (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font"); - tmpfnt->pf = tpf; - tmpfnt->vfont = vfont; - BLI_addtail(&ttfdata, tmpfnt); + if (vfont->temp_pf == NULL) { + vfont->temp_pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id)); } } if (!pf) { @@ -252,9 +186,8 @@ VFont *BKE_vfont_load(Main *bmain, const char *name) char filename[FILE_MAXFILE]; VFont *vfont = NULL; PackedFile *pf; - PackedFile *tpf = NULL; + PackedFile *temp_pf = NULL; int is_builtin; - struct TmpFont *tmpfnt; if (strcmp(name, FO_BUILTIN_NAME) == 0) { BLI_strncpy(filename, name, sizeof(filename)); @@ -269,7 +202,7 @@ VFont *BKE_vfont_load(Main *bmain, const char *name) BLI_splitdirstring(dir, filename); pf = newPackedFile(NULL, name, bmain->name); - tpf = newPackedFile(NULL, name, bmain->name); + temp_pf = newPackedFile(NULL, name, bmain->name); is_builtin = FALSE; } @@ -295,10 +228,7 @@ VFont *BKE_vfont_load(Main *bmain, const char *name) /* Do not add FO_BUILTIN_NAME to temporary listbase */ if (strcmp(filename, FO_BUILTIN_NAME)) { - tmpfnt = (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font"); - tmpfnt->pf = tpf; - tmpfnt->vfont = vfont; - BLI_addtail(&ttfdata, tmpfnt); + vfont->temp_pf = temp_pf; } } @@ -306,8 +236,6 @@ VFont *BKE_vfont_load(Main *bmain, const char *name) if (!vfont || vfont->packedfile != pf) { freePackedFile(pf); } - - //XXX waitcursor(0); } return vfont; @@ -317,14 +245,14 @@ static VFont *which_vfont(Curve *cu, CharInfo *info) { switch (info->flag & (CU_CHINFO_BOLD | CU_CHINFO_ITALIC)) { case CU_CHINFO_BOLD: - if (cu->vfontb) return(cu->vfontb); else return(cu->vfont); + return cu->vfontb ? cu->vfontb : cu->vfont; case CU_CHINFO_ITALIC: - if (cu->vfonti) return(cu->vfonti); else return(cu->vfont); + return cu->vfonti ? cu->vfonti : cu->vfont; case (CU_CHINFO_BOLD | CU_CHINFO_ITALIC): - if (cu->vfontbi) return(cu->vfontbi); else return(cu->vfont); + return cu->vfontbi ? cu->vfontbi : cu->vfont; default: - return(cu->vfont); - } + return cu->vfont; + } } VFont *BKE_vfont_builtin_get(void) @@ -344,6 +272,7 @@ static VChar *find_vfont_char(VFontData *vfd, intptr_t character) { VChar *che = NULL; + /* TODO: use ghash */ for (che = vfd->characters.first; che; che = che->next) { if (che->index == character) break; @@ -422,7 +351,7 @@ static void buildchar(Main *bmain, Curve *cu, unsigned long character, CharInfo } #endif - /* make a copy at distance ofsx, ofsy with shear*/ + /* make a copy at distance ofsx, ofsy with shear */ fsize = cu->fsize; shear = cu->shear; si = sinf(rot); diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index c317dc63ef7..2ec5801746c 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -97,7 +97,7 @@ void free_gpencil_layers(ListBase *list) /* error checking */ if (list == NULL) return; - /* delete layers*/ + /* delete layers */ for (gpl = list->first; gpl; gpl = gpln) { gpln = gpl->next; diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 89341845615..500df1b7b75 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -161,11 +161,13 @@ static int add_to_group_internal(Group *group, Object *ob) { GroupObject *go; - if (group == NULL || ob == NULL) return 0; + if (group == NULL || ob == NULL) { + return FALSE; + } /* check if the object has been added already */ - for (go = group->gobject.first; go; go = go->next) { - if (go->ob == ob) return 0; + if (BLI_findptr(&group->gobject, ob, offsetof(GroupObject, ob))) { + return FALSE; } go = MEM_callocN(sizeof(GroupObject), "groupobject"); @@ -173,7 +175,7 @@ static int add_to_group_internal(Group *group, Object *ob) go->ob = ob; - return 1; + return TRUE; } int add_to_group(Group *group, Object *object, Scene *scene, Base *base) @@ -239,15 +241,11 @@ int rem_from_group(Group *group, Object *object, Scene *scene, Base *base) int object_in_group(Object *ob, Group *group) { - GroupObject *go; - - if (group == NULL || ob == NULL) return 0; - - for (go = group->gobject.first; go; go = go->next) { - if (go->ob == ob) - return 1; + if (group == NULL || ob == NULL) { + return FALSE; } - return 0; + + return (BLI_findptr(&group->gobject, ob, offsetof(GroupObject, ob)) != NULL); } Group *find_group(Object *ob, Group *group) diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index a65d03e64cf..7456f9aab8b 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -159,12 +159,12 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen) newarr = MEM_callocN(sizeof(IDProperty) * newsize, "idproperty array resized"); if (newlen >= prop->len) { - /* newlen is bigger*/ + /* newlen is bigger */ memcpy(newarr, prop->data.pointer, prop->len * sizeof(IDProperty)); } else { int i; - /* newlen is smaller*/ + /* newlen is smaller */ for (i = newlen; i < prop->len; i++) { IDP_FreeProperty(GETPROP(prop, i)); } @@ -233,12 +233,12 @@ void IDP_ResizeArray(IDProperty *prop, int newlen) newarr = MEM_callocN(idp_size_table[(int)prop->subtype] * newsize, "idproperty array resized"); if (newlen >= prop->len) { - /* newlen is bigger*/ + /* newlen is bigger */ memcpy(newarr, prop->data.pointer, prop->len * idp_size_table[(int)prop->subtype]); idp_resize_group_array(prop, newlen, newarr); } else { - /* newlen is smaller*/ + /* newlen is smaller */ idp_resize_group_array(prop, newlen, newarr); memcpy(newarr, prop->data.pointer, newlen * idp_size_table[(int)prop->subtype]); } @@ -694,7 +694,7 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n break; case IDP_ARRAY: { - /*for now, we only support float and int and double arrays*/ + /* for now, we only support float and int and double arrays */ if ( (val->array.type == IDP_FLOAT) || (val->array.type == IDP_INT) || (val->array.type == IDP_DOUBLE) || diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 5f6fedc553c..2b2128439c7 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1212,43 +1212,46 @@ void BKE_imformat_defaults(ImageFormatData *im_format) void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *imbuf) { + int ftype = imbuf->ftype & ~IB_CUSTOM_FLAGS_MASK; + int custom_flags = imbuf->ftype & IB_CUSTOM_FLAGS_MASK; + BKE_imformat_defaults(im_format); /* file type */ - if (imbuf->ftype == IMAGIC) + if (ftype == IMAGIC) im_format->imtype = R_IMF_IMTYPE_IRIS; #ifdef WITH_HDR - else if (imbuf->ftype == RADHDR) + else if (ftype == RADHDR) im_format->imtype = R_IMF_IMTYPE_RADHDR; #endif - else if (imbuf->ftype == PNG) + else if (ftype == PNG) im_format->imtype = R_IMF_IMTYPE_PNG; #ifdef WITH_DDS - else if (imbuf->ftype == DDS) + else if (ftype == DDS) im_format->imtype = R_IMF_IMTYPE_DDS; #endif - else if (imbuf->ftype == BMP) + else if (ftype == BMP) im_format->imtype = R_IMF_IMTYPE_BMP; #ifdef WITH_TIFF - else if (imbuf->ftype & TIF) { + else if (ftype == TIF) { im_format->imtype = R_IMF_IMTYPE_TIFF; - if (imbuf->ftype & TIF_16BIT) + if (custom_flags & TIF_16BIT) im_format->depth = R_IMF_CHAN_DEPTH_16; } #endif #ifdef WITH_OPENEXR - else if (imbuf->ftype & OPENEXR) { + else if (ftype == OPENEXR) { im_format->imtype = R_IMF_IMTYPE_OPENEXR; - if (imbuf->ftype & OPENEXR_HALF) + if (custom_flags & OPENEXR_HALF) im_format->depth = R_IMF_CHAN_DEPTH_16; - if (imbuf->ftype & OPENEXR_COMPRESS) + if (custom_flags & OPENEXR_COMPRESS) im_format->exr_codec = R_IMF_EXR_CODEC_ZIP; // Can't determine compression if (imbuf->zbuf_float) im_format->flag |= R_IMF_FLAG_ZBUF; @@ -1256,35 +1259,35 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i #endif #ifdef WITH_CINEON - else if (imbuf->ftype == CINEON) + else if (ftype == CINEON) im_format->imtype = R_IMF_IMTYPE_CINEON; - else if (imbuf->ftype == DPX) + else if (ftype == DPX) im_format->imtype = R_IMF_IMTYPE_DPX; #endif - else if (imbuf->ftype == TGA) { + else if (ftype == TGA) { im_format->imtype = R_IMF_IMTYPE_TARGA; } - else if (imbuf->ftype == RAWTGA) { + else if (ftype == RAWTGA) { im_format->imtype = R_IMF_IMTYPE_RAWTGA; } #ifdef WITH_OPENJPEG - else if (imbuf->ftype & JP2) { + else if (ftype & JP2) { im_format->imtype = R_IMF_IMTYPE_JP2; - im_format->quality = imbuf->ftype & ~JPG_MSK; + im_format->quality = custom_flags & ~JPG_MSK; - if (imbuf->ftype & JP2_16BIT) + if (ftype & JP2_16BIT) im_format->depth = R_IMF_CHAN_DEPTH_16; - else if (imbuf->ftype & JP2_12BIT) + else if (ftype & JP2_12BIT) im_format->depth = R_IMF_CHAN_DEPTH_12; - if (imbuf->ftype & JP2_YCC) + if (ftype & JP2_YCC) im_format->jp2_flag |= R_IMF_JP2_FLAG_YCC; - if (imbuf->ftype & JP2_CINE) { + if (ftype & JP2_CINE) { im_format->jp2_flag |= R_IMF_JP2_FLAG_CINE_PRESET; - if (imbuf->ftype & JP2_CINE_48FPS) + if (ftype & JP2_CINE_48FPS) im_format->jp2_flag |= R_IMF_JP2_FLAG_CINE_48; } } @@ -1292,7 +1295,7 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i else { im_format->imtype = R_IMF_IMTYPE_JPEG90; - im_format->quality = imbuf->ftype & ~JPG_MSK; + im_format->quality = custom_flags & ~JPG_MSK; } /* planes */ @@ -2142,7 +2145,9 @@ RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima) void BKE_image_release_renderresult(Scene *scene, Image *ima) { - if (ima->rr) ; + if (ima->rr) { + /* pass */ + } else if (ima->type == IMA_TYPE_R_RESULT) { if (ima->render_slot == ima->last_render_slot) RE_ReleaseResult(RE_GetRender(scene->id.name)); diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 8de9640eb35..b2a9e229be9 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1764,8 +1764,7 @@ void do_versions_ipos_to_animato(Main *main) for (act = ob->actuators.first; act; act = act->next) { /* Any actuators set to ACT_IPO at this point are actually Action Actuators that need this converted IPO to finish converting the actuator. */ - if (act->type == ACT_IPO) - { + if (act->type == ACT_IPO) { aa = (bActionActuator*)act->data; aa->act = ob->adt->action; act->type = ACT_ACTION; diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 60be0a60dcb..17a3c595ea7 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1449,6 +1449,8 @@ KeyBlock *add_keyblock(Key *key, const char *name) * \note sorting is a problematic side effect in some cases, * better only do this explicitly by having its own function, * + * \param key The key datablock to add to. + * \param name Optional name for the new keyblock. * \param do_force always use ctime even for relative keys. */ KeyBlock *add_keyblock_ctime(Key *key, const char *name, const short do_force) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 3c46e7bcd47..a6ceba588d2 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -158,7 +158,7 @@ MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name) mask->masklay_tot++; - masklay->blend = MASK_BLEND_MERGE; + masklay->blend = MASK_BLEND_MERGE_ADD; masklay->alpha = 1.0f; return masklay; @@ -559,7 +559,7 @@ static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets, int start_b *diagonal_bucket_b_r = &buckets[diagonal_bucket_b_index]; } -static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feather_points)[2], int tot_feather_point) +void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feather_points)[2], const int tot_feather_point) { #define BUCKET_INDEX(co) \ feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side) @@ -721,7 +721,8 @@ static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feat */ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline, int *tot_feather_point, - const unsigned int resol + const unsigned int resol, + const int do_feather_isect ))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); @@ -783,23 +784,24 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl *tot_feather_point = tot; - if (spline->flag & MASK_SPLINE_NOINTERSECT) - spline_feather_collapse_inner_loops(spline, feather, tot); + if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) { + BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot); + } return feather; } float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline, int width, int height, - int *tot_feather_point))[2] + int *tot_feather_point, const int do_feather_isect))[2] { unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height); - return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol); + return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol, do_feather_isect); } float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2] { - return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point); + return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point, TRUE); } float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2] diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 1fde1168999..eb96d6726b9 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -370,8 +370,8 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) { MemArena *arena = BLI_memarena_new(1 << 16, __func__); - const float bucket_dim_x = layer->bounds.xmax - layer->bounds.xmin; - const float bucket_dim_y = layer->bounds.ymax - layer->bounds.ymin; + const float bucket_dim_x = BLI_RCT_SIZE_X(&layer->bounds); + const float bucket_dim_y = BLI_RCT_SIZE_Y(&layer->bounds); layer->buckets_x = (bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL; layer->buckets_y = (bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL; @@ -575,6 +575,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas int tot_diff_point; float (*diff_feather_points)[2]; + float (*diff_feather_points_flip)[2]; int tot_diff_feather_points; const unsigned int resol_a = BKE_mask_spline_resolution(spline, width, height) / 4; @@ -586,7 +587,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas if (do_feather) { diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution_ex( - spline, &tot_diff_feather_points, resol); + spline, &tot_diff_feather_points, resol, FALSE); BLI_assert(diff_feather_points); } else { @@ -649,6 +650,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } if (is_fill) { + /* applt intersections depending on fill settings */ + if (spline->flag & MASK_SPLINE_NOINTERSECT) { + BKE_mask_spline_feather_collapse_inner_loops(spline, diff_feather_points, tot_diff_feather_points); + } + copy_v2_v2(co, diff_points[0]); sf_vert_prev = BLI_scanfill_vert_add(&sf_ctx, co); sf_vert_prev->tmp.u = sf_vert_tot; @@ -710,11 +716,27 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas /* unfilled spline */ if (diff_feather_points) { - float co_diff[3]; + float co_diff[2]; float co_feather[3]; co_feather[2] = 1.0f; + if (spline->flag & MASK_SPLINE_NOINTERSECT) { + diff_feather_points_flip = MEM_mallocN(sizeof(float) * 2 * tot_diff_feather_points, "diff_feather_points_flip"); + + for (j = 0; j < tot_diff_point; j++) { + sub_v2_v2v2(co_diff, diff_points[j], diff_feather_points[j]); + add_v2_v2v2(diff_feather_points_flip[j], diff_points[j], co_diff); + } + + BKE_mask_spline_feather_collapse_inner_loops(spline, diff_feather_points, tot_diff_feather_points); + BKE_mask_spline_feather_collapse_inner_loops(spline, diff_feather_points_flip, tot_diff_feather_points); + } + else { + diff_feather_points_flip = NULL; + } + + open_spline_ranges[open_spline_index].vertex_offset = sf_vert_tot; open_spline_ranges[open_spline_index].vertex_total = tot_diff_point; @@ -738,8 +760,14 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas /* feather vert B */ - sub_v2_v2v2(co_diff, co, co_feather); - add_v2_v2v2(co_feather, co, co_diff); + if (diff_feather_points_flip) { + copy_v2_v2(co_feather, diff_feather_points_flip[j]); + } + else { + sub_v2_v2v2(co_diff, co, co_feather); + add_v2_v2v2(co_feather, co, co_diff); + } + sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather); sf_vert->tmp.u = sf_vert_tot; sf_vert->keyindex = SF_KEYINDEX_TEMP_ID; @@ -752,6 +780,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas tot_feather_quads -= 2; } + if (diff_feather_points_flip) { + MEM_freeN(diff_feather_points_flip); + diff_feather_points_flip = NULL; + } + /* cap ends */ /* dummy init value */ @@ -1163,7 +1196,7 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons BLI_INLINE unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2]) { - BLI_assert(BLI_in_rctf_v(&layer->bounds, xy)); + BLI_assert(BLI_rctf_isect_pt_v(&layer->bounds, xy)); return ( (unsigned int)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0])) + (((unsigned int)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1])) * layer->buckets_x); @@ -1200,7 +1233,7 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2 float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) { /* can't do this because some layers may invert */ - /* if (BLI_in_rctf_v(&mr_handle->bounds, xy)) */ + /* if (BLI_rctf_isect_pt_v(&mr_handle->bounds, xy)) */ const unsigned int layers_tot = mr_handle->layers_tot; unsigned int i; @@ -1213,7 +1246,7 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x float value_layer; /* also used as signal for unused layer (when render is disabled) */ - if (layer->alpha != 0.0f && BLI_in_rctf_v(&layer->bounds, xy)) { + if (layer->alpha != 0.0f && BLI_rctf_isect_pt_v(&layer->bounds, xy)) { value_layer = 1.0f - layer_bucket_depth_from_xy(layer, xy); switch (layer->falloff) { @@ -1249,9 +1282,12 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x } switch (layer->blend) { - case MASK_BLEND_MERGE: + case MASK_BLEND_MERGE_ADD: value += value_layer * (1.0f - value); break; + case MASK_BLEND_MERGE_SUBTRACT: + value -= value_layer * value; + break; case MASK_BLEND_ADD: value += value_layer; break; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 21811c19d24..7523c59a879 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -80,12 +80,18 @@ void init_def_material(void) /* not material itself */ void BKE_material_free(Material *ma) { + BKE_material_free_ex(ma, TRUE); +} + +/* not material itself */ +void BKE_material_free_ex(Material *ma, int do_id_user) +{ MTex *mtex; int a; for (a = 0; a < MAX_MTEX; a++) { mtex = ma->mtex[a]; - if (mtex && mtex->tex) mtex->tex->id.us--; + if (do_id_user && mtex && mtex->tex) mtex->tex->id.us--; if (mtex) MEM_freeN(mtex); } @@ -101,7 +107,7 @@ void BKE_material_free(Material *ma) /* is no lib link block, but material extension */ if (ma->nodetree) { - ntreeFreeTree(ma->nodetree); + ntreeFreeTree_ex(ma->nodetree, do_id_user); MEM_freeN(ma->nodetree); } @@ -235,7 +241,7 @@ Material *BKE_material_copy(Material *ma) if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview); if (ma->nodetree) { - man->nodetree = ntreeCopyTree(ma->nodetree); /* 0 == full new tree */ + man->nodetree = ntreeCopyTree(ma->nodetree); } man->gpumaterial.first = man->gpumaterial.last = NULL; @@ -779,7 +785,7 @@ void assign_material(Object *ob, Material *ma, short act, int assign_type) Material *mao, **matar, ***matarar; char *matbits; short *totcolp; - char bit=0; + char bit = 0; if (act > MAXMAT) return; if (act < 1) act = 1; @@ -807,13 +813,13 @@ void assign_material(Object *ob, Material *ma, short act, int assign_type) *totcolp = act; } - // Determine the object/mesh linking + /* Determine the object/mesh linking */ if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->totcol && ob->actcol) { /* copy from previous material */ bit = ob->matbits[ob->actcol - 1]; } else { - switch(assign_type) { + switch (assign_type) { case BKE_MAT_ASSIGN_OBDATA: bit = 0; break; @@ -1483,7 +1489,11 @@ void ramp_blend(int type, float r_col[3], const float fac, const float col[3]) } } -/* copy/paste buffer, if we had a propper py api that would be better */ +/** + * \brief copy/paste buffer, if we had a propper py api that would be better + * \note matcopybuf.nodetree does _NOT_ use ID's + * \todo matcopybuf.nodetree's node->id's are NOT validated, this will crash! + */ static Material matcopybuf; static short matcopied = 0; @@ -1511,7 +1521,7 @@ void free_matcopybuf(void) matcopybuf.ramp_spec = NULL; if (matcopybuf.nodetree) { - ntreeFreeTree(matcopybuf.nodetree); + ntreeFreeTree_ex(matcopybuf.nodetree, FALSE); MEM_freeN(matcopybuf.nodetree); matcopybuf.nodetree = NULL; } @@ -1537,7 +1547,7 @@ void copy_matcopybuf(Material *ma) matcopybuf.mtex[a] = MEM_dupallocN(mtex); } } - matcopybuf.nodetree = ntreeCopyTree(ma->nodetree); + matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, FALSE); matcopybuf.preview = NULL; matcopybuf.gpumaterial.first = matcopybuf.gpumaterial.last = NULL; matcopied = 1; @@ -1582,7 +1592,7 @@ void paste_matcopybuf(Material *ma) } } - ma->nodetree = ntreeCopyTree(matcopybuf.nodetree); + ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, FALSE); } @@ -1623,7 +1633,7 @@ static void decode_tfaceflag(Material *ma, int flag, int convertall) /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */ flag -= 1; - alphablend = flag >> 15; //encoded in the encode_tfaceflag function + alphablend = flag >> 15; /* encoded in the encode_tfaceflag function */ (*game).flag = 0; /* General Material Options */ @@ -2023,8 +2033,7 @@ int do_version_tface(Main *main, int fileload) nowarning = 0; } else - convert_tfacematerial(main, ma); - continue; + convert_tfacematerial(main, ma); continue; } /* no conflicts in this material - 90% of cases diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index fa5304b081a..039fb2c22f3 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -67,12 +67,9 @@ /* Data types */ -typedef struct point { /* a three-dimensional point */ - float x, y, z; /* its coordinates */ -} MB_POINT; - typedef struct vertex { /* surface vertex */ - MB_POINT position, normal; /* position and surface normal */ + float co[3]; /* position and surface normal */ + float no[3]; } VERTEX; typedef struct vertices { /* list of vertices in polygonization */ @@ -82,7 +79,7 @@ typedef struct vertices { /* list of vertices in polygonization */ typedef struct corner { /* corner of a cube */ int i, j, k; /* (i, j, k) is index within lattice */ - float x, y, z, value; /* location and function value */ + float co[3], value; /* location and function value */ struct corner *next; } CORNER; @@ -159,11 +156,11 @@ struct pgn_elements { }; /* Forward declarations */ -static int vertid(CORNER *c1, CORNER *c2, PROCESS *p, MetaBall *mb); +static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb); static int setcenter(CENTERLIST *table[], int i, int j, int k); static CORNER *setcorner(PROCESS *p, int i, int j, int k); -static void converge(MB_POINT *p1, MB_POINT *p2, float v1, float v2, - float (*function)(float, float, float), MB_POINT *p, MetaBall *mb, int f); +static void converge(const float p1[3], const float p2[3], float v1, float v2, + float (*function)(float, float, float), float p[3], MetaBall *mb, int f); /* Global variables */ @@ -631,65 +628,59 @@ static void calc_mballco(MetaElem *ml, float vec[3]) static float densfunc(MetaElem *ball, float x, float y, float z) { - float dist2 = 0.0, dx, dy, dz; - float vec[3]; + float dist2; + float dvec[3] = {x, y, z}; - vec[0] = x; - vec[1] = y; - vec[2] = z; - mul_m4_v3((float (*)[4])ball->imat, vec); - dx = vec[0]; - dy = vec[1]; - dz = vec[2]; + mul_m4_v3((float (*)[4])ball->imat, dvec); if (ball->type == MB_BALL) { } else if (ball->type == MB_TUBEX) { - if (dx > ball->len) dx -= ball->len; - else if (dx < -ball->len) dx += ball->len; - else dx = 0.0; + if (dvec[0] > ball->len) dvec[0] -= ball->len; + else if (dvec[0] < -ball->len) dvec[0] += ball->len; + else dvec[0] = 0.0; } else if (ball->type == MB_TUBEY) { - if (dy > ball->len) dy -= ball->len; - else if (dy < -ball->len) dy += ball->len; - else dy = 0.0; + if (dvec[1] > ball->len) dvec[1] -= ball->len; + else if (dvec[1] < -ball->len) dvec[1] += ball->len; + else dvec[1] = 0.0; } else if (ball->type == MB_TUBEZ) { - if (dz > ball->len) dz -= ball->len; - else if (dz < -ball->len) dz += ball->len; - else dz = 0.0; + if (dvec[2] > ball->len) dvec[2] -= ball->len; + else if (dvec[2] < -ball->len) dvec[2] += ball->len; + else dvec[2] = 0.0; } else if (ball->type == MB_TUBE) { - if (dx > ball->expx) dx -= ball->expx; - else if (dx < -ball->expx) dx += ball->expx; - else dx = 0.0; + if (dvec[0] > ball->expx) dvec[0] -= ball->expx; + else if (dvec[0] < -ball->expx) dvec[0] += ball->expx; + else dvec[0] = 0.0; } else if (ball->type == MB_PLANE) { - if (dx > ball->expx) dx -= ball->expx; - else if (dx < -ball->expx) dx += ball->expx; - else dx = 0.0; - if (dy > ball->expy) dy -= ball->expy; - else if (dy < -ball->expy) dy += ball->expy; - else dy = 0.0; + if (dvec[0] > ball->expx) dvec[0] -= ball->expx; + else if (dvec[0] < -ball->expx) dvec[0] += ball->expx; + else dvec[0] = 0.0; + if (dvec[1] > ball->expy) dvec[1] -= ball->expy; + else if (dvec[1] < -ball->expy) dvec[1] += ball->expy; + else dvec[1] = 0.0; } else if (ball->type == MB_ELIPSOID) { - dx *= 1 / ball->expx; - dy *= 1 / ball->expy; - dz *= 1 / ball->expz; + dvec[0] *= 1 / ball->expx; + dvec[1] *= 1 / ball->expy; + dvec[2] *= 1 / ball->expz; } else if (ball->type == MB_CUBE) { - if (dx > ball->expx) dx -= ball->expx; - else if (dx < -ball->expx) dx += ball->expx; - else dx = 0.0; - if (dy > ball->expy) dy -= ball->expy; - else if (dy < -ball->expy) dy += ball->expy; - else dy = 0.0; - if (dz > ball->expz) dz -= ball->expz; - else if (dz < -ball->expz) dz += ball->expz; - else dz = 0.0; + if (dvec[0] > ball->expx) dvec[0] -= ball->expx; + else if (dvec[0] < -ball->expx) dvec[0] += ball->expx; + else dvec[0] = 0.0; + if (dvec[1] > ball->expy) dvec[1] -= ball->expy; + else if (dvec[1] < -ball->expy) dvec[1] += ball->expy; + else dvec[1] = 0.0; + if (dvec[2] > ball->expz) dvec[2] -= ball->expz; + else if (dvec[2] < -ball->expz) dvec[2] += ball->expz; + else dvec[2] = 0.0; } - dist2 = (dx * dx + dy * dy + dz * dz); + dist2 = len_v3(dvec); if (ball->flag & MB_NEGATIVE) { dist2 = 1.0f - (dist2 / ball->rad2); @@ -1074,12 +1065,12 @@ static CORNER *setcorner(PROCESS *p, int i, int j, int k) c = (CORNER *) new_pgn_element(sizeof(CORNER)); c->i = i; - c->x = ((float)i - 0.5f) * p->size; + c->co[0] = ((float)i - 0.5f) * p->size; c->j = j; - c->y = ((float)j - 0.5f) * p->size; + c->co[1] = ((float)j - 0.5f) * p->size; c->k = k; - c->z = ((float)k - 0.5f) * p->size; - c->value = p->function(c->x, c->y, c->z); + c->co[2] = ((float)k - 0.5f) * p->size; + c->value = p->function(c->co[0], c->co[1], c->co[2]); c->next = p->corners[index]; p->corners[index] = c; @@ -1204,7 +1195,7 @@ void BKE_mball_cubeTable_free(void) /* setcenter: set (i, j, k) entry of table[] * return 1 if already set; otherwise, set and return 0 */ -static int setcenter(CENTERLIST *table[], int i, int j, int k) +static int setcenter(CENTERLIST *table[], const int i, const int j, const int k) { int index; CENTERLIST *newc, *l, *q; @@ -1324,72 +1315,46 @@ static void addtovertices(VERTICES *vertices, VERTEX v) /* vnormal: compute unit length surface normal at point */ -static void vnormal(MB_POINT *point, PROCESS *p, MB_POINT *v) +static void vnormal(const float point[3], PROCESS *p, float r_no[3]) { float delta = 0.2f * p->delta; - float f = p->function(point->x, point->y, point->z); - - v->x = p->function(point->x + delta, point->y, point->z) - f; - v->y = p->function(point->x, point->y + delta, point->z) - f; - v->z = p->function(point->x, point->y, point->z + delta) - f; - f = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); + float f = p->function(point[0], point[1], point[2]); - if (f != 0.0f) { - v->x /= f; - v->y /= f; - v->z /= f; - } + r_no[0] = p->function(point[0] + delta, point[1], point[2]) - f; + r_no[1] = p->function(point[0], point[1] + delta, point[2]) - f; + r_no[2] = p->function(point[0], point[1], point[2] + delta) - f; + f = normalize_v3(r_no); - if (FALSE) { - MB_POINT temp; + if (0) { + float tvec[3]; delta *= 2.0f; - f = p->function(point->x, point->y, point->z); + f = p->function(point[0], point[1], point[2]); - temp.x = p->function(point->x + delta, point->y, point->z) - f; - temp.y = p->function(point->x, point->y + delta, point->z) - f; - temp.z = p->function(point->x, point->y, point->z + delta) - f; - f = sqrtf(temp.x * temp.x + temp.y * temp.y + temp.z * temp.z); + tvec[0] = p->function(point[0] + delta, point[1], point[2]) - f; + tvec[1] = p->function(point[0], point[1] + delta, point[2]) - f; + tvec[2] = p->function(point[0], point[1], point[2] + delta) - f; - if (f != 0.0f) { - temp.x /= f; - temp.y /= f; - temp.z /= f; - - v->x += temp.x; - v->y += temp.y; - v->z += temp.z; - - f = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); - - if (f != 0.0f) { - v->x /= f; - v->y /= f; - v->z /= f; - } + if (normalize_v3(tvec) != 0.0f) { + add_v3_v3(r_no, tvec); + normalize_v3(r_no); } } - } -static int vertid(CORNER *c1, CORNER *c2, PROCESS *p, MetaBall *mb) +static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb) { VERTEX v; - MB_POINT a, b; int vid = getedge(p->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k); - if (vid != -1) return vid; /* previously computed */ - a.x = c1->x; - a.y = c1->y; - a.z = c1->z; - b.x = c2->x; - b.y = c2->y; - b.z = c2->z; + if (vid != -1) { + return vid; /* previously computed */ + } - converge(&a, &b, c1->value, c2->value, p->function, &v.position, mb, 1); /* position */ - vnormal(&v.position, p, &v.normal); + converge(c1->co, c2->co, c1->value, c2->value, p->function, v.co, mb, 1); /* position */ + vnormal(v.co, p, v.no); addtovertices(&p->vertices, v); /* save vertex */ vid = p->vertices.count - 1; @@ -1403,101 +1368,95 @@ static int vertid(CORNER *c1, CORNER *c2, PROCESS *p, MetaBall *mb) /* converge: from two points of differing sign, converge to zero crossing */ /* watch it: p1 and p2 are used to calculate */ -static void converge(MB_POINT *p1, MB_POINT *p2, float v1, float v2, - float (*function)(float, float, float), MB_POINT *p, MetaBall *mb, int f) +static void converge(const float p1[3], const float p2[3], float v1, float v2, + float (*function)(float, float, float), float p[3], MetaBall *mb, int f) { int i = 0; - MB_POINT pos, neg; + float pos[3], neg[3]; float positive = 0.0f, negative = 0.0f; - float dx = 0.0f, dy = 0.0f, dz = 0.0f; + float dvec[3]; if (v1 < 0) { - pos = *p2; - neg = *p1; + copy_v3_v3(pos, p2); + copy_v3_v3(neg, p1); positive = v2; negative = v1; } else { - pos = *p1; - neg = *p2; + copy_v3_v3(pos, p1); + copy_v3_v3(neg, p2); positive = v1; negative = v2; } - dx = pos.x - neg.x; - dy = pos.y - neg.y; - dz = pos.z - neg.z; + sub_v3_v3v3(dvec, pos, neg); /* Approximation by linear interpolation is faster then binary subdivision, * but it results sometimes (mb->thresh < 0.2) into the strange results */ if ((mb->thresh > 0.2f) && (f == 1)) { - if ((dy == 0.0f) && (dz == 0.0f)) { - p->x = neg.x - negative * dx / (positive - negative); - p->y = neg.y; - p->z = neg.z; + if ((dvec[1] == 0.0f) && (dvec[2] == 0.0f)) { + p[0] = neg[0] - negative * dvec[0] / (positive - negative); + p[1] = neg[1]; + p[2] = neg[2]; return; } - if ((dx == 0.0f) && (dz == 0.0f)) { - p->x = neg.x; - p->y = neg.y - negative * dy / (positive - negative); - p->z = neg.z; + if ((dvec[0] == 0.0f) && (dvec[2] == 0.0f)) { + p[0] = neg[0]; + p[1] = neg[1] - negative * dvec[1] / (positive - negative); + p[2] = neg[2]; return; } - if ((dx == 0.0f) && (dy == 0.0f)) { - p->x = neg.x; - p->y = neg.y; - p->z = neg.z - negative * dz / (positive - negative); + if ((dvec[0] == 0.0f) && (dvec[1] == 0.0f)) { + p[0] = neg[0]; + p[1] = neg[1]; + p[2] = neg[2] - negative * dvec[2] / (positive - negative); return; } } - if ((dy == 0.0f) && (dz == 0.0f)) { - p->y = neg.y; - p->z = neg.z; + if ((dvec[1] == 0.0f) && (dvec[2] == 0.0f)) { + p[1] = neg[1]; + p[2] = neg[2]; while (1) { if (i++ == RES) return; - p->x = 0.5f * (pos.x + neg.x); - if ((function(p->x, p->y, p->z)) > 0.0f) pos.x = p->x; else neg.x = p->x; + p[0] = 0.5f * (pos[0] + neg[0]); + if ((function(p[0], p[1], p[2])) > 0.0f) pos[0] = p[0]; else neg[0] = p[0]; } } - if ((dx == 0.0f) && (dz == 0.0f)) { - p->x = neg.x; - p->z = neg.z; + if ((dvec[0] == 0.0f) && (dvec[2] == 0.0f)) { + p[0] = neg[0]; + p[2] = neg[2]; while (1) { if (i++ == RES) return; - p->y = 0.5f * (pos.y + neg.y); - if ((function(p->x, p->y, p->z)) > 0.0f) pos.y = p->y; else neg.y = p->y; + p[1] = 0.5f * (pos[1] + neg[1]); + if ((function(p[0], p[1], p[2])) > 0.0f) pos[1] = p[1]; else neg[1] = p[1]; } } - - if ((dx == 0.0f) && (dy == 0.0f)) { - p->x = neg.x; - p->y = neg.y; + + if ((dvec[0] == 0.0f) && (dvec[1] == 0.0f)) { + p[0] = neg[0]; + p[1] = neg[1]; while (1) { if (i++ == RES) return; - p->z = 0.5f * (pos.z + neg.z); - if ((function(p->x, p->y, p->z)) > 0.0f) pos.z = p->z; else neg.z = p->z; + p[2] = 0.5f * (pos[2] + neg[2]); + if ((function(p[0], p[1], p[2])) > 0.0f) pos[2] = p[2]; else neg[2] = p[2]; } } /* This is necessary to find start point */ while (1) { - p->x = 0.5f * (pos.x + neg.x); - p->y = 0.5f * (pos.y + neg.y); - p->z = 0.5f * (pos.z + neg.z); - - if (i++ == RES) return; - - if ((function(p->x, p->y, p->z)) > 0.0f) { - pos.x = p->x; - pos.y = p->y; - pos.z = p->z; + mid_v3_v3v3(&p[0], pos, neg); + + if (i++ == RES) { + return; + } + + if ((function(p[0], p[1], p[2])) > 0.0f) { + copy_v3_v3(pos, &p[0]); } else { - neg.x = p->x; - neg.y = p->y; - neg.z = p->z; + copy_v3_v3(neg, &p[0]); } } } @@ -1535,105 +1494,100 @@ static void add_cube(PROCESS *mbproc, int i, int j, int k, int count) static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a) { - MB_POINT IN, in, OUT, out; /*point;*/ MetaElem *ml; - int i, j, k, c_i, c_j, c_k; - int index[3] = {1, 0, -1}; float f = 0.0f; - float in_v /*, out_v*/; - MB_POINT workp; - float tmp_v, workp_v, max_len, len, dx, dy, dz, nx, ny, nz, MAXN; ml = mainb[a]; - - f = 1 - (mb->thresh / ml->s); + f = 1.0 - (mb->thresh / ml->s); /* Skip, when Stiffness of MetaElement is too small ... MetaElement can't be * visible alone ... but still can influence others MetaElements :-) */ if (f > 0.0f) { - OUT.x = IN.x = in.x = 0.0; - OUT.y = IN.y = in.y = 0.0; - OUT.z = IN.z = in.z = 0.0; + float IN[3] = {0.0f}, OUT[3] = {0.0f}, in[3] = {0.0f}, out[3]; + int i, j, k, c_i, c_j, c_k; + int index[3] = {1, 0, -1}; + float in_v /*, out_v*/; + float workp[3]; + float dvec[3]; + float tmp_v, workp_v, max_len, len, nx, ny, nz, MAXN; - calc_mballco(ml, (float *)&in); - in_v = mbproc->function(in.x, in.y, in.z); + calc_mballco(ml, in); + in_v = mbproc->function(in[0], in[1], in[2]); for (i = 0; i < 3; i++) { switch (ml->type) { case MB_BALL: - OUT.x = out.x = IN.x + index[i] * ml->rad; + OUT[0] = out[0] = IN[0] + index[i] * ml->rad; break; case MB_TUBE: case MB_PLANE: case MB_ELIPSOID: case MB_CUBE: - OUT.x = out.x = IN.x + index[i] * (ml->expx + ml->rad); + OUT[0] = out[0] = IN[0] + index[i] * (ml->expx + ml->rad); break; } for (j = 0; j < 3; j++) { switch (ml->type) { case MB_BALL: - OUT.y = out.y = IN.y + index[j] * ml->rad; + OUT[1] = out[1] = IN[1] + index[j] * ml->rad; break; case MB_TUBE: case MB_PLANE: case MB_ELIPSOID: case MB_CUBE: - OUT.y = out.y = IN.y + index[j] * (ml->expy + ml->rad); + OUT[1] = out[1] = IN[1] + index[j] * (ml->expy + ml->rad); break; } for (k = 0; k < 3; k++) { - out.x = OUT.x; - out.y = OUT.y; + out[0] = OUT[0]; + out[1] = OUT[1]; switch (ml->type) { case MB_BALL: case MB_TUBE: case MB_PLANE: - out.z = IN.z + index[k] * ml->rad; + out[2] = IN[2] + index[k] * ml->rad; break; case MB_ELIPSOID: case MB_CUBE: - out.z = IN.z + index[k] * (ml->expz + ml->rad); + out[2] = IN[2] + index[k] * (ml->expz + ml->rad); break; } - calc_mballco(ml, (float *)&out); + calc_mballco(ml, out); - /*out_v = mbproc->function(out.x, out.y, out.z);*/ /*UNUSED*/ + /*out_v = mbproc->function(out[0], out[1], out[2]);*/ /*UNUSED*/ /* find "first points" on Implicit Surface of MetaElemnt ml */ - workp.x = in.x; - workp.y = in.y; - workp.z = in.z; + copy_v3_v3(workp, in); workp_v = in_v; - max_len = sqrtf((out.x - in.x) * (out.x - in.x) + (out.y - in.y) * (out.y - in.y) + (out.z - in.z) * (out.z - in.z)); + max_len = len_v3v3(out, in); - nx = abs((out.x - in.x) / mbproc->size); - ny = abs((out.y - in.y) / mbproc->size); - nz = abs((out.z - in.z) / mbproc->size); + nx = abs((out[0] - in[0]) / mbproc->size); + ny = abs((out[1] - in[1]) / mbproc->size); + nz = abs((out[2] - in[2]) / mbproc->size); MAXN = MAX3(nx, ny, nz); if (MAXN != 0.0f) { - dx = (out.x - in.x) / MAXN; - dy = (out.y - in.y) / MAXN; - dz = (out.z - in.z) / MAXN; + dvec[0] = (out[0] - in[0]) / MAXN; + dvec[1] = (out[1] - in[1]) / MAXN; + dvec[2] = (out[2] - in[2]) / MAXN; len = 0.0; while (len <= max_len) { - workp.x += dx; - workp.y += dy; - workp.z += dz; + workp[0] += dvec[0]; + workp[1] += dvec[1]; + workp[2] += dvec[2]; /* compute value of implicite function */ - tmp_v = mbproc->function(workp.x, workp.y, workp.z); + tmp_v = mbproc->function(workp[0], workp[1], workp[2]); /* add cube to the stack, when value of implicite function crosses zero value */ if ((tmp_v < 0.0f && workp_v >= 0.0f) || (tmp_v > 0.0f && workp_v <= 0.0f)) { /* indexes of CUBE, which includes "first point" */ - c_i = (int)floor(workp.x / mbproc->size); - c_j = (int)floor(workp.y / mbproc->size); - c_k = (int)floor(workp.z / mbproc->size); + c_i = (int)floor(workp[0] / mbproc->size); + c_j = (int)floor(workp[1] / mbproc->size); + c_k = (int)floor(workp[2] / mbproc->size); /* add CUBE (with indexes c_i, c_j, c_k) to the stack, * this cube includes found point of Implicit Surface */ @@ -1642,7 +1596,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a) else add_cube(mbproc, c_i, c_j, c_k, 1); } - len = sqrtf((workp.x - in.x) * (workp.x - in.x) + (workp.y - in.y) * (workp.y - in.y) + (workp.z - in.z) * (workp.z - in.z)); + len = len_v3v3(workp, in); workp_v = tmp_v; } @@ -2283,7 +2237,7 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase) MetaBall *mb; DispList *dl; int a, nr_cubes; - float *ve, *no, totsize, width; + float *co, *no, totsize, width; mb = ob->data; @@ -2362,6 +2316,8 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase) } if (curindex) { + VERTEX *ptr = mbproc.vertices.ptr; + dl = MEM_callocN(sizeof(DispList), "mbaldisp"); BLI_addtail(dispbase, dl); dl->type = DL_INDEX4; @@ -2372,17 +2328,12 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase) indices = NULL; a = mbproc.vertices.count; - dl->verts = ve = MEM_mallocN(sizeof(float) * 3 * a, "mballverts"); + dl->verts = co = MEM_mallocN(sizeof(float) * 3 * a, "mballverts"); dl->nors = no = MEM_mallocN(sizeof(float) * 3 * a, "mballnors"); - for (a = 0; a < mbproc.vertices.count; a++, no += 3, ve += 3) { - ve[0] = mbproc.vertices.ptr[a].position.x; - ve[1] = mbproc.vertices.ptr[a].position.y; - ve[2] = mbproc.vertices.ptr[a].position.z; - - no[0] = mbproc.vertices.ptr[a].normal.x; - no[1] = mbproc.vertices.ptr[a].normal.y; - no[2] = mbproc.vertices.ptr[a].normal.z; + for (a = 0; a < mbproc.vertices.count; ptr++, a++, no += 3, co += 3) { + copy_v3_v3(co, ptr->co); + copy_v3_v3(no, ptr->no); } } @@ -2403,29 +2354,30 @@ int BKE_mball_minmax(MetaBall *mb, float min[3], float max[3]) return (mb->elems.first != NULL); } -int BKE_mball_center_median(MetaBall *mb, float cent[3]) +int BKE_mball_center_median(MetaBall *mb, float r_cent[3]) { MetaElem *ml; int total = 0; - zero_v3(cent); + zero_v3(r_cent); for (ml = mb->elems.first; ml; ml = ml->next) { - add_v3_v3(cent, &ml->x); + add_v3_v3(r_cent, &ml->x); } - if (total) - mul_v3_fl(cent, 1.0f / (float)total); + if (total) { + mul_v3_fl(r_cent, 1.0f / (float)total); + } return (total != 0); } -int BKE_mball_center_bounds(MetaBall *mb, float cent[3]) +int BKE_mball_center_bounds(MetaBall *mb, float r_cent[3]) { float min[3], max[3]; if (BKE_mball_minmax(mb, min, max)) { - mid_v3_v3v3(cent, min, max); + mid_v3_v3v3(r_cent, min, max); return 1; } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 77cd127e6ea..8c3ec7e2e40 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -167,7 +167,7 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2 for (j = 0; j < vtot; j++, v1++, v2++) { if (len_v3v3(v1->co, v2->co) > thresh) return MESHCMP_VERTCOMISMATCH; - /*I don't care about normals, let's just do coodinates*/ + /* I don't care about normals, let's just do coodinates */ } } @@ -990,7 +990,7 @@ static void make_edges_mdata(MVert *UNUSED(allvert), MFace *allface, MLoop *alll MEM_freeN(edsort); - /*set edge members of mloops*/ + /* set edge members of mloops */ medge = *alledge; for (a = 0; a < *_totedge; a++, medge++) { BLI_edgehash_insert(hash, medge->v1, medge->v2, SET_INT_IN_POINTER(a)); @@ -1846,7 +1846,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, int numVerts, return; } - /* if we are not calculating verts and no verts were passes thene we have nothign to do */ + /* if we are not calculating verts and no verts were passes then we have nothing to do */ if ((only_face_normals == TRUE) && (polyNors_r == NULL) && (faceNors_r == NULL)) { printf("%s: called with nothing to do\n", __func__); return; @@ -1910,7 +1910,7 @@ void BKE_mesh_calc_normals(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpo if (!pnors) pnors = MEM_callocN(sizeof(float) * 3 * numPolys, "poly_nors mesh.c"); - /*first go through and calculate normals for all the polys*/ + /* first go through and calculate normals for all the polys */ tnorms = MEM_callocN(sizeof(float) * 3 * numVerts, "tnorms mesh.c"); mp = mpolys; @@ -2702,13 +2702,13 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, #endif { /* sort loop indices to ensure winding is correct */ - if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2); - if (mf->v2 > mf->v3) SWAP(int, mf->v2, mf->v3); - if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2); + if (mf->v1 > mf->v2) SWAP(unsigned int, mf->v1, mf->v2); + if (mf->v2 > mf->v3) SWAP(unsigned int, mf->v2, mf->v3); + if (mf->v1 > mf->v2) SWAP(unsigned int, mf->v1, mf->v2); - if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2); - if (mf->v2 > mf->v3) SWAP(int, mf->v2, mf->v3); - if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2); + if (mf->v1 > mf->v2) SWAP(unsigned int, mf->v1, mf->v2); + if (mf->v2 > mf->v3) SWAP(unsigned int, mf->v2, mf->v3); + if (mf->v1 > mf->v2) SWAP(unsigned int, mf->v1, mf->v2); } /* end abusing the edcode */ @@ -2820,7 +2820,7 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, mf = &mface[k]; if (mf->edcode == 3) { - /*sort loop indices to ensure winding is correct*/ + /* sort loop indices to ensure winding is correct */ /* NO SORT - looks like we can skip this */ lindex[0] = mf->v1; @@ -2828,7 +2828,7 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, lindex[2] = mf->v3; lindex[3] = 0; /* unused */ - /*transform loop indices to vert indices*/ + /* transform loop indices to vert indices */ mf->v1 = mloop[mf->v1].v; mf->v2 = mloop[mf->v2].v; mf->v3 = mloop[mf->v3].v; @@ -2839,7 +2839,7 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, test_index_face(mf, fdata, k, 3); } else { - /*sort loop indices to ensure winding is correct*/ + /* sort loop indices to ensure winding is correct */ /* NO SORT - looks like we can skip this */ lindex[0] = mf->v1; @@ -2847,7 +2847,7 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, lindex[2] = mf->v3; lindex[3] = mf->v4; - /*transform loop indices to vert indices*/ + /* transform loop indices to vert indices */ mf->v1 = mloop[mf->v1].v; mf->v2 = mloop[mf->v2].v; mf->v3 = mloop[mf->v3].v; diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index d62b03b5060..9590160c8f3 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -764,7 +764,7 @@ void BKE_nlastrips_clear_metas(ListBase *strips, short onlySel, short onlyTemp) } /* Add the given NLA-Strip to the given Meta-Strip, assuming that the - * strip isn't attached to anyy list of strips + * strip isn't attached to any list of strips */ short BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip) { diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 7cee9626c3f..c283db94103 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -671,7 +671,7 @@ bNodeTree *ntreeAddTree(const char *name, int type, int nodetype) * copying for internal use (threads for eg), where you wont want it to modify the * scene data. */ -static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_extern) +static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_user, const short do_make_extern) { bNodeTree *newtree; bNode *node /*, *nnode */ /* UNUSED */, *last; @@ -702,6 +702,11 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_e last = ntree->nodes.last; for (node = ntree->nodes.first; node; node = node->next) { + /* ntreeUserDecrefID inline */ + if (do_id_user) { + id_us_plus(node->id); + } + if (do_make_extern) { id_lib_extern(node->id); } @@ -751,22 +756,56 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_e return newtree; } +bNodeTree *ntreeCopyTree_ex(bNodeTree *ntree, const short do_id_user) +{ + return ntreeCopyTree_internal(ntree, do_id_user, TRUE); +} bNodeTree *ntreeCopyTree(bNodeTree *ntree) { - return ntreeCopyTree_internal(ntree, TRUE); + return ntreeCopyTree_ex(ntree, TRUE); } /* use when duplicating scenes */ -void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to) +void ntreeSwitchID_ex(bNodeTree *ntree, ID *id_from, ID *id_to, const short do_id_user) { bNode *node; + + if (id_from == id_to) { + /* should never happen but may as well skip if it does */ + return; + } + /* for scene duplication only */ for (node = ntree->nodes.first; node; node = node->next) { if (node->id == id_from) { + if (do_id_user) { + id_us_min(id_from); + id_us_plus(id_to); + } + node->id = id_to; } } } +void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to) +{ + ntreeSwitchID_ex(ntree, id_from, id_to, TRUE); +} + +void ntreeUserIncrefID(bNodeTree *ntree) +{ + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + id_us_plus(node->id); + } +} +void ntreeUserDecrefID(bNodeTree *ntree) +{ + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + id_us_min(node->id); + } +} /* *************** preview *********** */ /* if node->preview, then we assume the rect to exist */ @@ -913,6 +952,7 @@ static void node_unlink_attached(bNodeTree *ntree, bNode *parent) } } +/** \note caller needs to manage node->id user */ void nodeFreeNode(bNodeTree *ntree, bNode *node) { bNodeSocket *sock, *nextsock; @@ -956,7 +996,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node) } /* do not free ntree itself here, BKE_libblock_free calls this function too */ -void ntreeFreeTree(bNodeTree *ntree) +void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user) { bNode *node, *next; bNodeSocket *sock; @@ -990,6 +1030,12 @@ void ntreeFreeTree(bNodeTree *ntree) for (node = ntree->nodes.first; node; node = next) { next = node->next; + + /* ntreeUserIncrefID inline */ + if (do_id_user) { + id_us_min(node->id); + } + nodeFreeNode(ntree, node); } @@ -1000,6 +1046,11 @@ void ntreeFreeTree(bNodeTree *ntree) node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&ntree->outputs); } +/* same as ntreeFreeTree_ex but always manage users */ +void ntreeFreeTree(bNodeTree *ntree) +{ + ntreeFreeTree_ex(ntree, TRUE); +} void ntreeFreeCache(bNodeTree *ntree) { @@ -1188,7 +1239,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree) } /* node copy func */ - ltree = ntreeCopyTree_internal(ntree, FALSE); + ltree = ntreeCopyTree_internal(ntree, FALSE, FALSE); if (adt) { AnimData *ladt = BKE_animdata_from_id(<ree->id); @@ -1248,7 +1299,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree) if (ntreetype->local_merge) ntreetype->local_merge(localtree, ntree); - ntreeFreeTree(localtree); + ntreeFreeTree_ex(localtree, FALSE); MEM_freeN(localtree); } @@ -1425,13 +1476,37 @@ void nodeSocketSetType(bNodeSocket *sock, int type) /* ************** Node Clipboard *********** */ +#define USE_NODE_CB_VALIDATE + +#ifdef USE_NODE_CB_VALIDATE +/** + * This data structure is to validate the node on creation, + * otherwise we may reference missing data. + * + * Currently its only used for ID's, but nodes may one day + * reference other pointers which need validation. + */ +typedef struct bNodeClipboardExtraInfo { + struct bNodeClipboardExtraInfo *next, *prev; + ID *id; + char id_name[MAX_ID_NAME]; + char library_name[FILE_MAX]; +} bNodeClipboardExtraInfo; +#endif /* USE_NODE_CB_VALIDATE */ + + typedef struct bNodeClipboard { ListBase nodes; + +#ifdef USE_NODE_CB_VALIDATE + ListBase nodes_extra_info; +#endif + ListBase links; int type; } bNodeClipboard; -bNodeClipboard node_clipboard; +bNodeClipboard node_clipboard = {{0}}; void BKE_node_clipboard_init(struct bNodeTree *ntree) { @@ -1454,11 +1529,83 @@ void BKE_node_clipboard_clear(void) nodeFreeNode(NULL, node); } node_clipboard.nodes.first = node_clipboard.nodes.last = NULL; + +#ifdef USE_NODE_CB_VALIDATE + BLI_freelistN(&node_clipboard.nodes_extra_info); +#endif +} + +/* return FALSE when one or more ID's are lost */ +int BKE_node_clipboard_validate(void) +{ + int ok = TRUE; + +#ifdef USE_NODE_CB_VALIDATE + bNodeClipboardExtraInfo *node_info; + bNode *node; + + + /* lists must be aligned */ + BLI_assert(BLI_countlist(&node_clipboard.nodes) == + BLI_countlist(&node_clipboard.nodes_extra_info)); + + for (node = node_clipboard.nodes.first, node_info = node_clipboard.nodes_extra_info.first; + node; + node = node->next, node_info = node_info->next) + { + /* validate the node against the stored node info */ + + /* re-assign each loop since we may clear, + * open a new file where the ID is valid, and paste again */ + node->id = node_info->id; + + /* currently only validate the ID */ + if (node->id) { + ListBase *lb = which_libbase(G.main, GS(node_info->id_name)); + BLI_assert(lb != NULL); + + if (BLI_findindex(lb, node_info->id) == -1) { + /* may assign NULL */ + node->id = BLI_findstring(lb, node_info->id_name + 2, offsetof(ID, name) + 2); + + if (node->id == NULL) { + ok = FALSE; + } + } + } + } +#endif /* USE_NODE_CB_VALIDATE */ + + return ok; } void BKE_node_clipboard_add_node(bNode *node) { +#ifdef USE_NODE_CB_VALIDATE + /* add extra info */ + bNodeClipboardExtraInfo *node_info = MEM_mallocN(sizeof(bNodeClipboardExtraInfo), STRINGIFY(bNodeClipboardExtraInfo)); + + node_info->id = node->id; + if (node->id) { + BLI_strncpy(node_info->id_name, node->id->name, sizeof(node_info->id_name)); + if (node->id->lib) { + BLI_strncpy(node_info->library_name, node->id->lib->filepath, sizeof(node_info->library_name)); + } + else { + node_info->library_name[0] = '\0'; + } + } + else { + node_info->id_name[0] = '\0'; + node_info->library_name[0] = '\0'; + } + BLI_addtail(&node_clipboard.nodes_extra_info, node_info); + /* end extra info */ +#endif /* USE_NODE_CB_VALIDATE */ + + /* add node */ BLI_addtail(&node_clipboard.nodes, node); + } void BKE_node_clipboard_add_link(bNodeLink *link) @@ -1992,6 +2139,7 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_vecblur(ttype); register_node_type_cmp_dilateerode(ttype); register_node_type_cmp_inpaint(ttype); + register_node_type_cmp_despeckle(ttype); register_node_type_cmp_defocus(ttype); register_node_type_cmp_valtorgb(ttype); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 4f4ee3f8433..dfa3582cee8 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1514,7 +1514,7 @@ void BKE_object_mat3_to_rot(Object *ob, float mat[][3], short use_compat) /* end drot correction */ if (use_compat) mat3_to_compatible_eulO(ob->rot, ob->rot, ob->rotmode, tmat); - else mat3_to_eulO(ob->rot, ob->rotmode, tmat); + else mat3_to_eulO(ob->rot, ob->rotmode, tmat); } } } @@ -2234,7 +2234,7 @@ void BKE_object_dimensions_set(Object *ob, const float *value) } } -void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3]) +void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short use_hidden) { BoundBox bb; float vec[3]; @@ -2284,14 +2284,23 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3]) break; case OB_ARMATURE: if (ob->pose) { + bArmature *arm = ob->data; bPoseChannel *pchan; + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); - minmax_v3v3_v3(min_r, max_r, vec); - mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); - minmax_v3v3_v3(min_r, max_r, vec); + + if ((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE)) { + /* pass */ + } + else { + mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); + minmax_v3v3_v3(min_r, max_r, vec); + mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); + minmax_v3v3_v3(min_r, max_r, vec); + + change = TRUE; + } } - change = TRUE; } break; case OB_MESH: @@ -2331,9 +2340,9 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3]) } } -int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_max[3]) +int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_max[3], const short use_hidden) { - int ok = 0; + int ok = FALSE; if ((ob->transflag & OB_DUPLI) == 0) { return ok; } @@ -2343,7 +2352,10 @@ int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_ma lb = object_duplilist(scene, ob); for (dob = lb->first; dob; dob = dob->next) { - if (dob->no_draw == 0) { + if ((use_hidden == FALSE) && (dob->no_draw != 0)) { + /* pass */ + } + else { BoundBox *bb = BKE_object_boundbox_get(dob->ob); if (bb) { @@ -2354,7 +2366,7 @@ int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_ma minmax_v3v3_v3(r_min, r_max, vec); } - ok = 1; + ok = TRUE; } } } diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index f115a41d419..9787a5025f7 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -158,7 +158,17 @@ void freePackedFile(PackedFile *pf) else printf("freePackedFile: Trying to free a NULL pointer\n"); } - + +PackedFile *dupPackedFile(const PackedFile *pf_src) +{ + PackedFile *pf_dst; + + pf_dst = MEM_dupallocN(pf_src); + pf_dst->data = MEM_dupallocN(pf_src->data); + + return pf_dst; +} + PackedFile *newPackedFileMemory(void *mem, int memlen) { PackedFile *pf = MEM_callocN(sizeof(*pf), "PackedFile"); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 889792ad3f8..145bd6a88e5 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -153,7 +153,8 @@ Scene *BKE_scene_copy(Scene *sce, int type) BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets)); if (sce->nodetree) { - scen->nodetree = ntreeCopyTree(sce->nodetree); /* copies actions */ + /* ID's are managed on both copy and switch */ + scen->nodetree = ntreeCopyTree(sce->nodetree); ntreeSwitchID(scen->nodetree, &sce->id, &scen->id); } @@ -550,14 +551,7 @@ Scene *BKE_scene_add(const char *name) Base *BKE_scene_base_find(Scene *scene, Object *ob) { - Base *base; - - base = scene->base.first; - while (base) { - if (base->object == ob) return base; - base = base->next; - } - return NULL; + return BLI_findptr(&scene->base, ob, offsetof(Base, object)); } void BKE_scene_set_background(Main *bmain, Scene *scene) @@ -582,10 +576,10 @@ void BKE_scene_set_background(Main *bmain, Scene *scene) /* group flags again */ for (group = bmain->group.first; group; group = group->id.next) { - go = group->gobject.first; - while (go) { - if (go->ob) go->ob->flag |= OB_FROMGROUP; - go = go->next; + for (go = group->gobject.first; go; go = go->next) { + if (go->ob) { + go->ob->flag |= OB_FROMGROUP; + } } } diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index 387ec67eb1c..e3f0226c863 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -37,8 +37,11 @@ #include "BKE_sequencer.h" #include "IMB_moviecache.h" +#include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "BLI_listbase.h" + typedef struct SeqCacheKey { struct Sequence *seq; SeqRenderData context; @@ -46,7 +49,25 @@ typedef struct SeqCacheKey { seq_stripelem_ibuf_t type; } SeqCacheKey; +typedef struct SeqPreprocessCacheElem { + struct SeqPreprocessCacheElem *next, *prev; + + struct Sequence *seq; + SeqRenderData context; + seq_stripelem_ibuf_t type; + + ImBuf *ibuf; +} SeqPreprocessCacheElem; + +typedef struct SeqPreprocessCache { + int cfra; + ListBase elems; +} SeqPreprocessCache; + static struct MovieCache *moviecache = NULL; +static struct SeqPreprocessCache *preprocess_cache = NULL; + +static void preprocessed_cache_destruct(void); static int seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b) { @@ -160,6 +181,8 @@ void BKE_sequencer_cache_destruct(void) { if (moviecache) IMB_moviecache_free(moviecache); + + preprocessed_cache_destruct(); } void BKE_sequencer_cache_cleanup(void) @@ -168,6 +191,8 @@ void BKE_sequencer_cache_cleanup(void) IMB_moviecache_free(moviecache); moviecache = IMB_moviecache_create("seqcache", sizeof(SeqCacheKey), seqcache_hashhash, seqcache_hashcmp); } + + BKE_sequencer_preprocessed_cache_cleanup(); } static int seqcache_key_check_seq(void *userkey, void *userdata) @@ -219,3 +244,100 @@ void BKE_sequencer_cache_put(SeqRenderData context, Sequence *seq, float cfra, s IMB_moviecache_put(moviecache, &key, i); } + +void BKE_sequencer_preprocessed_cache_cleanup(void) +{ + SeqPreprocessCacheElem *elem; + + if (!preprocess_cache) + return; + + for (elem = preprocess_cache->elems.first; elem; elem = elem->next) { + IMB_freeImBuf(elem->ibuf); + } + BLI_freelistN(&preprocess_cache->elems); + + preprocess_cache->elems.first = preprocess_cache->elems.last = NULL; +} + +static void preprocessed_cache_destruct(void) +{ + if (!preprocess_cache) + return; + + BKE_sequencer_preprocessed_cache_cleanup(); + + MEM_freeN(preprocess_cache); + preprocess_cache = NULL; +} + +ImBuf *BKE_sequencer_preprocessed_cache_get(SeqRenderData context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type) +{ + SeqPreprocessCacheElem *elem; + + if (!preprocess_cache) + return NULL; + + if (preprocess_cache->cfra != cfra) + return NULL; + + for (elem = preprocess_cache->elems.first; elem; elem = elem->next) { + if (elem->seq != seq) + continue; + + if (elem->type != type) + continue; + + if (seq_cmp_render_data(&elem->context, &context) != 0) + continue; + + IMB_refImBuf(elem->ibuf); + return elem->ibuf; + } + + return NULL; +} + +void BKE_sequencer_preprocessed_cache_put(SeqRenderData context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type, ImBuf *ibuf) +{ + SeqPreprocessCacheElem *elem; + + if (!preprocess_cache) { + preprocess_cache = MEM_callocN(sizeof(SeqPreprocessCache), "sequencer preprocessed cache"); + } + else { + if (preprocess_cache->cfra != cfra) + BKE_sequencer_preprocessed_cache_cleanup(); + } + + elem = MEM_callocN(sizeof(SeqPreprocessCacheElem), "sequencer preprocessed cache element"); + + elem->seq = seq; + elem->type = type; + elem->context = context; + elem->ibuf = ibuf; + + preprocess_cache->cfra = cfra; + + IMB_refImBuf(ibuf); + + BLI_addtail(&preprocess_cache->elems, elem); +} + +void BKE_sequencer_preprocessed_cache_cleanup_sequence(Sequence *seq) +{ + SeqPreprocessCacheElem *elem, *elem_next; + + if (!preprocess_cache) + return; + + for (elem = preprocess_cache->elems.first; elem; elem = elem_next) { + elem_next = elem->next; + + if (elem->seq == seq) { + IMB_freeImBuf(elem->ibuf); + + BLI_freelinkN(&preprocess_cache->elems, elem); + } + } +} diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 2380596c6ad..87906337ca2 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -284,14 +284,14 @@ static void do_alphaover_effect(SeqRenderData context, Sequence *UNUSED(seq), fl int start_line, int total_lines, ImBuf *out) { if (out->rect_float) { - float *rect1, *rect2, *rect_out; + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); do_alphaover_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out); } else { - unsigned char *rect1, *rect2, *rect_out; + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -446,14 +446,14 @@ static void do_alphaunder_effect(SeqRenderData context, Sequence *UNUSED(seq), f int start_line, int total_lines, ImBuf *out) { if (out->rect_float) { - float *rect1, *rect2, *rect_out; + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); do_alphaunder_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out); } else { - unsigned char *rect1, *rect2, *rect_out; + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -556,14 +556,14 @@ static void do_cross_effect(SeqRenderData context, Sequence *UNUSED(seq), float int start_line, int total_lines, ImBuf *out) { if (out->rect_float) { - float *rect1, *rect2, *rect_out; + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); do_cross_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out); } else { - unsigned char *rect1, *rect2, *rect_out; + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -805,14 +805,14 @@ static void do_gammacross_effect(SeqRenderData context, Sequence *UNUSED(seq), f int start_line, int total_lines, ImBuf *out) { if (out->rect_float) { - float *rect1, *rect2, *rect_out; + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); do_gammacross_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out); } else { - unsigned char *rect1, *rect2, *rect_out; + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -911,14 +911,14 @@ static void do_add_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out) { if (out->rect_float) { - float *rect1, *rect2, *rect_out; + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); do_add_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out); } else { - unsigned char *rect1, *rect2, *rect_out; + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -1015,14 +1015,14 @@ static void do_sub_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out) { if (out->rect_float) { - float *rect1, *rect2, *rect_out; + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); do_sub_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out); } else { - unsigned char *rect1, *rect2, *rect_out; + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -1212,14 +1212,14 @@ static void do_mul_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out) { if (out->rect_float) { - float *rect1, *rect2, *rect_out; + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); do_mul_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out); } else { - unsigned char *rect1, *rect2, *rect_out; + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -2746,7 +2746,7 @@ static void do_overdrop_effect(SeqRenderData context, Sequence *UNUSED(seq), flo int y = total_lines; if (out->rect_float) { - float *rect1, *rect2, *rect_out; + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -2754,7 +2754,7 @@ static void do_overdrop_effect(SeqRenderData context, Sequence *UNUSED(seq), flo do_alphaover_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out); } else { - unsigned char *rect1, *rect2, *rect_out; + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c new file mode 100644 index 00000000000..70f27db0f74 --- /dev/null +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -0,0 +1,651 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/seqmodifier.c + * \ingroup bke + */ + +#include <stddef.h> +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "DNA_sequence_types.h" + +#include "BKE_colortools.h" +#include "BKE_sequencer.h" +#include "BKE_utildefines.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +static SequenceModifierTypeInfo *modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES]; +static int modifierTypesInit = FALSE; + +/*********************** Modifiers *************************/ + +typedef void (*modifier_apply_threaded_cb) (int width, int height, unsigned char *rect, float *rect_float, + unsigned char *mask_rect, float *mask_rect_float, void *data_v); + +typedef struct ModifierInitData { + ImBuf *ibuf; + ImBuf *mask; + void *user_data; + + modifier_apply_threaded_cb apply_callback; +} ModifierInitData; + +typedef struct ModifierThread { + int width, height; + + unsigned char *rect, *mask_rect; + float *rect_float, *mask_rect_float; + + void *user_data; + + modifier_apply_threaded_cb apply_callback; +} ModifierThread; + + +static ImBuf *modifier_mask_get(SequenceModifierData *smd, SeqRenderData context, int cfra, int make_float) +{ + return BKE_sequencer_render_mask_input(context, smd->mask_input_type, smd->mask_sequence, smd->mask_id, cfra, make_float); +} + +static void modifier_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v) +{ + ModifierThread *handle = (ModifierThread *) handle_v; + ModifierInitData *init_data = (ModifierInitData *) init_data_v; + ImBuf *ibuf = init_data->ibuf; + ImBuf *mask = init_data->mask; + + int offset = 4 * start_line * ibuf->x; + + memset(handle, 0, sizeof(ModifierThread)); + + handle->width = ibuf->x; + handle->height = tot_line; + handle->apply_callback = init_data->apply_callback; + handle->user_data = init_data->user_data; + + if (ibuf->rect) + handle->rect = (unsigned char *) ibuf->rect + offset; + + if (ibuf->rect_float) + handle->rect_float = ibuf->rect_float + offset; + + if (mask) { + if (mask->rect) + handle->mask_rect = (unsigned char *) mask->rect + offset; + + if (mask->rect_float) + handle->mask_rect_float = mask->rect_float + offset; + } + else { + handle->mask_rect = NULL; + handle->mask_rect_float = NULL; + } +} + +static void *modifier_do_thread(void *thread_data_v) +{ + ModifierThread *td = (ModifierThread *) thread_data_v; + + td->apply_callback(td->width, td->height, td->rect, td->rect_float, td->mask_rect, td->mask_rect_float, td->user_data); + + return NULL; +} + +static void modifier_apply_threaded(ImBuf *ibuf, ImBuf *mask, modifier_apply_threaded_cb apply_callback, void *user_data) +{ + ModifierInitData init_data; + + init_data.ibuf = ibuf; + init_data.mask = mask; + init_data.user_data = user_data; + + init_data.apply_callback = apply_callback; + + IMB_processor_apply_threaded(ibuf->y, sizeof(ModifierThread), &init_data, + modifier_init_handle, modifier_do_thread); +} + +/* **** Color Balance Modifier **** */ + +void colorBalance_init_data(SequenceModifierData *smd) +{ + ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd; + int c; + + cbmd->color_multiply = 1.0f; + + for (c = 0; c < 3; c++) { + cbmd->color_balance.lift[c] = 1.0f; + cbmd->color_balance.gamma[c] = 1.0f; + cbmd->color_balance.gain[c] = 1.0f; + } +} + +ImBuf *colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +{ + ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd; + ImBuf *ibuf_new = IMB_dupImBuf(ibuf); + + BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf_new, cbmd->color_multiply, FALSE, mask); + + return ibuf_new; +} + +static SequenceModifierTypeInfo seqModifier_ColorBalance = { + "Color Balance", /* name */ + "ColorBalanceModifierData", /* struct_name */ + sizeof(ColorBalanceModifierData), /* struct_size */ + colorBalance_init_data, /* init_data */ + NULL, /* free_data */ + NULL, /* copy_data */ + colorBalance_apply /* apply */ +}; + +/* **** Curves Modifier **** */ + +void curves_init_data(SequenceModifierData *smd) +{ + CurvesModifierData *cmd = (CurvesModifierData *) smd; + + curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f); +} + +void curves_free_data(SequenceModifierData *smd) +{ + CurvesModifierData *cmd = (CurvesModifierData *) smd; + + curvemapping_free_data(&cmd->curve_mapping); +} + +void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd) +{ + CurvesModifierData *cmd = (CurvesModifierData *) smd; + CurvesModifierData *cmd_target = (CurvesModifierData *) target; + + curvemapping_copy_data(&cmd_target->curve_mapping, &cmd->curve_mapping); +} + +void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, + unsigned char *mask_rect, float *mask_rect_float, void *data_v) +{ + CurveMapping *curve_mapping = (CurveMapping *) data_v; + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int pixel_index = (y * width + x) * 4; + + if (rect_float) { + float *pixel = rect_float + pixel_index; + float result[3]; + + curvemapping_evaluate_premulRGBF(curve_mapping, result, pixel); + + if (mask_rect_float) { + float *m = mask_rect_float + pixel_index; + + pixel[0] = pixel[0] * (1.0f - m[0]) + result[0] * m[0]; + pixel[1] = pixel[1] * (1.0f - m[1]) + result[1] * m[1]; + pixel[2] = pixel[2] * (1.0f - m[2]) + result[2] * m[2]; + } + else { + pixel[0] = result[0]; + pixel[1] = result[1]; + pixel[2] = result[2]; + } + } + if (rect) { + unsigned char *pixel = rect + pixel_index; + unsigned char result[3]; + + curvemapping_evaluate_premulRGB(curve_mapping, result, pixel); + + if (mask_rect) { + float t[3]; + + rgb_uchar_to_float(t, mask_rect + pixel_index); + + pixel[0] = pixel[0] * (1.0f - t[0]) + result[0] * t[0]; + pixel[1] = pixel[1] * (1.0f - t[1]) + result[1] * t[1]; + pixel[2] = pixel[2] * (1.0f - t[2]) + result[2] * t[2]; + } + else { + pixel[0] = result[0]; + pixel[1] = result[1]; + pixel[2] = result[2]; + } + } + } + } +} + +ImBuf *curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +{ + CurvesModifierData *cmd = (CurvesModifierData *) smd; + ImBuf *ibuf_new = IMB_dupImBuf(ibuf); + + float black[3] = {0.0f, 0.0f, 0.0f}; + float white[3] = {1.0f, 1.0f, 1.0f}; + + curvemapping_initialize(&cmd->curve_mapping); + + curvemapping_premultiply(&cmd->curve_mapping, 0); + curvemapping_set_black_white(&cmd->curve_mapping, black, white); + + modifier_apply_threaded(ibuf_new, mask, curves_apply_threaded, &cmd->curve_mapping); + + curvemapping_premultiply(&cmd->curve_mapping, 1); + + return ibuf_new; +} + +static SequenceModifierTypeInfo seqModifier_Curves = { + "Curves", /* name */ + "CurvesModifierData", /* struct_name */ + sizeof(CurvesModifierData), /* struct_size */ + curves_init_data, /* init_data */ + curves_free_data, /* free_data */ + curves_copy_data, /* copy_data */ + curves_apply /* apply */ +}; + +/* **** Hue Correct Modifier **** */ + +void hue_correct_init_data(SequenceModifierData *smd) +{ + HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd; + int c; + + curvemapping_set_defaults(&hcmd->curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f); + hcmd->curve_mapping.preset = CURVE_PRESET_MID9; + + for (c = 0; c < 3; c++) { + CurveMap *cuma = &hcmd->curve_mapping.cm[c]; + + curvemap_reset(cuma, &hcmd->curve_mapping.clipr, hcmd->curve_mapping.preset, CURVEMAP_SLOPE_POSITIVE); + } + + /* default to showing Saturation */ + hcmd->curve_mapping.cur = 1; +} + +void hue_correct_free_data(SequenceModifierData *smd) +{ + HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd; + + curvemapping_free_data(&hcmd->curve_mapping); +} + +void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd) +{ + HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd; + HueCorrectModifierData *hcmd_target = (HueCorrectModifierData *) target; + + curvemapping_copy_data(&hcmd_target->curve_mapping, &hcmd->curve_mapping); +} + +void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, + unsigned char *mask_rect, float *mask_rect_float, void *data_v) +{ + CurveMapping *curve_mapping = (CurveMapping *) data_v; + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int pixel_index = (y * width + x) * 4; + float pixel[3], result[3], mask[3] = {1.0f, 1.0f, 1.0f}; + float hsv[3], f; + + if (rect_float) + copy_v3_v3(pixel, rect_float + pixel_index); + else + rgb_uchar_to_float(pixel, rect + pixel_index); + + rgb_to_hsv(pixel[0], pixel[1], pixel[2], hsv, hsv + 1, hsv + 2); + + /* adjust hue, scaling returned default 0.5 up to 1 */ + f = curvemapping_evaluateF(curve_mapping, 0, hsv[0]); + hsv[0] += f - 0.5f; + + /* adjust saturation, scaling returned default 0.5 up to 1 */ + f = curvemapping_evaluateF(curve_mapping, 1, hsv[0]); + hsv[1] *= (f * 2.0f); + + /* adjust value, scaling returned default 0.5 up to 1 */ + f = curvemapping_evaluateF(curve_mapping, 2, hsv[0]); + hsv[2] *= (f * 2.f); + + hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */ + CLAMP(hsv[1], 0.0f, 1.0f); + + /* convert back to rgb */ + hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2); + + if (mask_rect_float) + copy_v3_v3(mask, mask_rect_float + pixel_index); + else if (mask_rect) + rgb_uchar_to_float(mask, mask_rect + pixel_index); + + result[0] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0]; + result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1]; + result[2] = pixel[2] * (1.0f - mask[2]) + result[2] * mask[2]; + + if (rect_float) + copy_v3_v3(rect_float + pixel_index, result); + else + rgb_float_to_uchar(rect + pixel_index, result); + } + } +} + +ImBuf *hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +{ + HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd; + ImBuf *ibuf_new = IMB_dupImBuf(ibuf); + + curvemapping_initialize(&hcmd->curve_mapping); + + modifier_apply_threaded(ibuf_new, mask, hue_correct_apply_threaded, &hcmd->curve_mapping); + + return ibuf_new; +} + +static SequenceModifierTypeInfo seqModifier_HueCorrect = { + "Hue Correct", /* name */ + "HueCorrectModifierData", /* struct_name */ + sizeof(HueCorrectModifierData), /* struct_size */ + hue_correct_init_data, /* init_data */ + hue_correct_free_data, /* free_data */ + hue_correct_copy_data, /* copy_data */ + hue_correct_apply /* apply */ +}; + +/* **** Bright/Contrast Modifier **** */ + +typedef struct BrightContrastThreadData { + float bright; + float contrast; +} BrightContrastThreadData; + +void brightcontrast_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, + unsigned char *mask_rect, float *mask_rect_float, void *data_v) +{ + BrightContrastThreadData *data = (BrightContrastThreadData *) data_v; + int x, y; + + float i; + int c; + float a, b, v; + float brightness = data->bright / 100.0f; + float contrast = data->contrast; + float delta = contrast / 200.0f; + + a = 1.0f - delta * 2.0f; + /* + * The algorithm is by Werner D. Streidt + * (http://visca.com/ffactory/archives/5-99/msg00021.html) + * Extracted of OpenCV demhist.c + */ + if (contrast > 0) { + a = 1.0f / a; + b = a * (brightness - delta); + } + else { + delta *= -1; + b = a * (brightness + delta); + } + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int pixel_index = (y * width + x) * 4; + + if (rect) { + unsigned char *pixel = rect + pixel_index; + + for (c = 0; c < 3; c++) { + i = pixel[c]; + v = a * i + b; + + if (mask_rect) { + unsigned char *m = mask_rect + pixel_index; + float t = (float) m[c] / 255.0f; + + pixel[c] = pixel[c] * (1.0f - t) + v * t; + } + else + pixel[c] = v; + } + } + else if (rect_float) { + float *pixel = rect_float + pixel_index; + + for (c = 0; c < 3; c++) { + i = pixel[c]; + v = a * i + b; + + if (mask_rect_float) { + float *m = mask_rect_float + pixel_index; + + pixel[c] = pixel[c] * (1.0f - m[c]) + v * m[c]; + } + else + pixel[c] = v; + } + } + } + } +} + +ImBuf *brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +{ + BrightContrastModifierData *bcmd = (BrightContrastModifierData *) smd; + BrightContrastThreadData data; + ImBuf *ibuf_new = IMB_dupImBuf(ibuf); + + data.bright = bcmd->bright; + data.contrast = bcmd->contrast; + + modifier_apply_threaded(ibuf_new, mask, brightcontrast_apply_threaded, &data); + + return ibuf_new; +} + +static SequenceModifierTypeInfo seqModifier_BrightContrast = { + "Bright/Contrast", /* name */ + "BrightContrastModifierData", /* struct_name */ + sizeof(BrightContrastModifierData), /* struct_size */ + NULL, /* init_data */ + NULL, /* free_data */ + NULL, /* copy_data */ + brightcontrast_apply /* apply */ +}; + +/*********************** Modifier functions *************************/ + +static void sequence_modifier_type_info_init(void) +{ +#define INIT_TYPE(typeName) (modifiersTypes[seqModifierType_##typeName] = &seqModifier_##typeName) + + INIT_TYPE(ColorBalance); + INIT_TYPE(Curves); + INIT_TYPE(HueCorrect); + INIT_TYPE(BrightContrast); + +#undef INIT_TYPE +} + +SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type) +{ + if (!modifierTypesInit) { + sequence_modifier_type_info_init(); + modifierTypesInit = TRUE; + } + + return modifiersTypes[type]; +} + +SequenceModifierData *BKE_sequence_modifier_new(Sequence *seq, const char *name, int type) +{ + SequenceModifierData *smd; + SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(type); + + smd = MEM_callocN(smti->struct_size, "sequence modifier"); + + smd->type = type; + smd->flag |= SEQUENCE_MODIFIER_EXPANDED; + + if (!name || !name[0]) + BLI_strncpy(smd->name, smti->name, sizeof(smd->name)); + else + BLI_strncpy(smd->name, name, sizeof(smd->name)); + + BLI_addtail(&seq->modifiers, smd); + + BKE_sequence_modifier_unique_name(seq, smd); + + if (smti->init_data) + smti->init_data(smd); + + return smd; +} + +int BKE_sequence_modifier_remove(Sequence *seq, SequenceModifierData *smd) +{ + if (BLI_findindex(&seq->modifiers, smd) == -1) + return FALSE; + + BLI_remlink(&seq->modifiers, smd); + BKE_sequence_modifier_free(smd); + + return TRUE; +} + +void BKE_sequence_modifier_clear(Sequence *seq) +{ + SequenceModifierData *smd, *smd_next; + + for (smd = seq->modifiers.first; smd; smd = smd_next) { + smd_next = smd->next; + BKE_sequence_modifier_free(smd); + } + + seq->modifiers.first = seq->modifiers.last = NULL; +} + +void BKE_sequence_modifier_free(SequenceModifierData *smd) +{ + SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type); + + if (smti && smti->free_data) { + smti->free_data(smd); + } + + MEM_freeN(smd); +} + +void BKE_sequence_modifier_unique_name(Sequence *seq, SequenceModifierData *smd) +{ + SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type); + + BLI_uniquename(&seq->modifiers, smd, smti->name, '.', offsetof(SequenceModifierData, name), sizeof(smd->name)); +} + +SequenceModifierData *BKE_sequence_modifier_find_by_name(Sequence *seq, char *name) +{ + return BLI_findstring(&(seq->modifiers), name, offsetof(SequenceModifierData, name)); +} + +ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, ImBuf *ibuf, int cfra) +{ + SequenceModifierData *smd; + ImBuf *processed_ibuf = ibuf; + + for (smd = seq->modifiers.first; smd; smd = smd->next) { + SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type); + ImBuf *ibuf_new; + + /* could happen if modifier is being removed or not exists in current version of blender */ + if (!smti) + continue; + + /* modifier is muted, do nothing */ + if (smd->flag & SEQUENCE_MODIFIER_MUTE) + continue; + + if (smti->apply) { + ImBuf *mask = modifier_mask_get(smd, context, cfra, ibuf->rect_float != NULL); + + if (processed_ibuf == ibuf) + processed_ibuf = IMB_dupImBuf(ibuf); + + ibuf_new = smti->apply(smd, processed_ibuf, mask); + + if (ibuf_new != processed_ibuf) { + IMB_freeImBuf(processed_ibuf); + processed_ibuf = ibuf_new; + } + + if (mask) + IMB_freeImBuf(mask); + } + } + + return processed_ibuf; +} + +void BKE_sequence_modifier_list_copy(Sequence *seqn, Sequence *seq) +{ + SequenceModifierData *smd; + + for (smd = seq->modifiers.first; smd; smd = smd->next) { + SequenceModifierData *smdn; + SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type); + + smdn = MEM_dupallocN(smd); + + if (smti && smti->copy_data) + smti->copy_data(smdn, smd); + + smdn->next = smdn->prev = NULL; + BLI_addtail(&seqn->modifiers, smdn); + } +} + +int BKE_sequence_supports_modifiers(Sequence *seq) +{ + return !ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD); +} diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index cec868cfc10..3bcef50a3b4 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -83,6 +83,7 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown); static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra); static void seq_free_animdata(Scene *scene, Sequence *seq); +static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short make_float); /* **** XXX ******** */ #define SELECT 1 @@ -203,7 +204,11 @@ void BKE_sequence_free(Scene *scene, Sequence *seq) seq_free_animdata(scene, seq); } + /* free modifiers */ + BKE_sequence_modifier_clear(seq); + BKE_sequencer_cache_cleanup_sequence(seq); + BKE_sequencer_preprocessed_cache_cleanup_sequence(seq); MEM_freeN(seq); } @@ -1432,7 +1437,7 @@ static void make_cb_table_float(float lift, float gain, float gamma, } } -static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul) +static void color_balance_byte_byte(StripColorBalance *cb_, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul) { unsigned char cb_tab[3][256]; int c; @@ -1440,7 +1445,7 @@ static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned unsigned char *e = p + width * 4 * height; unsigned char *m = mask_rect; - StripColorBalance cb = calc_cb(seq->strip->color_balance); + StripColorBalance cb = calc_cb(cb_); for (c = 0; c < 3; c++) { make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul); @@ -1466,7 +1471,7 @@ static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned } } -static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *rect_float, unsigned char *mask_rect, int width, int height, float mul) +static void color_balance_byte_float(StripColorBalance *cb_, unsigned char *rect, float *rect_float, unsigned char *mask_rect, int width, int height, float mul) { float cb_tab[4][256]; int c, i; @@ -1478,7 +1483,7 @@ static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float * o = rect_float; - cb = calc_cb(seq->strip->color_balance); + cb = calc_cb(cb_); for (c = 0; c < 3; c++) { make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul); @@ -1510,12 +1515,12 @@ static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float * } } -static void color_balance_float_float(Sequence *seq, float *rect_float, float *mask_rect_float, int width, int height, float mul) +static void color_balance_float_float(StripColorBalance *cb_, float *rect_float, float *mask_rect_float, int width, int height, float mul) { float *p = rect_float; float *e = rect_float + width * 4 * height; float *m = mask_rect_float; - StripColorBalance cb = calc_cb(seq->strip->color_balance); + StripColorBalance cb = calc_cb(cb_); while (p < e) { int c; @@ -1535,20 +1540,23 @@ static void color_balance_float_float(Sequence *seq, float *rect_float, float *m } typedef struct ColorBalanceInitData { - Sequence *seq; + StripColorBalance *cb; ImBuf *ibuf; float mul; ImBuf *mask; + short make_float; } ColorBalanceInitData; typedef struct ColorBalanceThread { - Sequence *seq; + StripColorBalance *cb; float mul; int width, height; unsigned char *rect, *mask_rect; float *rect_float, *mask_rect_float; + + short make_float; } ColorBalanceThread; static void color_balance_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v) @@ -1562,10 +1570,11 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li memset(handle, 0, sizeof(ColorBalanceThread)); - handle->seq = init_data->seq; + handle->cb = init_data->cb; handle->mul = init_data->mul; handle->width = ibuf->x; handle->height = tot_line; + handle->make_float = init_data->make_float; if (ibuf->rect) handle->rect = (unsigned char *) ibuf->rect + offset; @@ -1589,7 +1598,7 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li static void *color_balance_do_thread(void *thread_data_v) { ColorBalanceThread *thread_data = (ColorBalanceThread *) thread_data_v; - Sequence *seq = thread_data->seq; + StripColorBalance *cb = thread_data->cb; int width = thread_data->width, height = thread_data->height; unsigned char *rect = thread_data->rect; unsigned char *mask_rect = thread_data->mask_rect; @@ -1598,48 +1607,56 @@ static void *color_balance_do_thread(void *thread_data_v) float mul = thread_data->mul; if (rect_float) { - color_balance_float_float(seq, rect_float, mask_rect_float, width, height, mul); + color_balance_float_float(cb, rect_float, mask_rect_float, width, height, mul); } - else if (seq->flag & SEQ_MAKE_FLOAT) { - color_balance_byte_float(seq, rect, rect_float, mask_rect, width, height, mul); + else if (thread_data->make_float) { + color_balance_byte_float(cb, rect, rect_float, mask_rect, width, height, mul); } else { - color_balance_byte_byte(seq, rect, mask_rect, width, height, mul); + color_balance_byte_byte(cb, rect, mask_rect, width, height, mul); } return NULL; } -static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra) +ImBuf *BKE_sequencer_render_mask_input(SeqRenderData context, int mask_input_type, Sequence *mask_sequence, Mask *mask_id, int cfra, int make_float) +{ + ImBuf *mask_input = NULL; + + if (mask_input_type == SEQUENCE_MASK_INPUT_STRIP) { + if (mask_sequence) { + mask_input = seq_render_strip(context, mask_sequence, cfra); + + if (make_float) { + if (!mask_input->rect_float) + IMB_float_from_rect(mask_input); + } + else { + if (!mask_input->rect) + IMB_rect_from_float(mask_input); + } + } + } + else if (mask_input_type == SEQUENCE_MASK_INPUT_ID) { + mask_input = seq_render_mask(context, mask_id, cfra, make_float); + } + + return mask_input; +} + +void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float mul, short make_float, ImBuf *mask_input) { ColorBalanceInitData init_data; - if (!ibuf->rect_float && seq->flag & SEQ_MAKE_FLOAT) + if (!ibuf->rect_float && make_float) imb_addrectfloatImBuf(ibuf); - init_data.seq = seq; + init_data.cb = cb; init_data.ibuf = ibuf; init_data.mul = mul; init_data.mask = NULL; - - if (seq->mask_sequence) { - if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) { - ImBuf *mask = seq_render_strip(context, seq->mask_sequence, cfra); - - if (mask) { - if (ibuf->rect_float) { - if (!mask->rect_float) - IMB_float_from_rect(mask); - } - else { - if (!mask->rect) - IMB_rect_from_float(mask); - } - - init_data.mask = mask; - } - } - } + init_data.make_float = make_float; + init_data.mask = mask_input; IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data, color_balance_init_handle, color_balance_do_thread); @@ -1650,9 +1667,26 @@ static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, flo */ if (ibuf->rect_float && ibuf->rect) imb_freerectImBuf(ibuf); +} + +static void sequence_color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra) +{ + StripColorBalance *cb = seq->strip->color_balance; + ImBuf *mask_input = NULL; + short make_float = seq->flag & SEQ_MAKE_FLOAT; + + if (seq->mask_sequence) { + if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) { + int make_float = ibuf->rect_float != NULL; + + mask_input = BKE_sequencer_render_mask_input(context, SEQUENCE_MASK_INPUT_STRIP, seq->mask_sequence, NULL, cfra, make_float); + } + } - if (init_data.mask) - IMB_freeImBuf(init_data.mask); + BKE_sequencer_color_balance_apply(cb, ibuf, mul, make_float, mask_input); + + if (mask_input) + IMB_freeImBuf(mask_input); } /* @@ -1696,6 +1730,10 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen if (seq->sat != 1.0f) { return TRUE; } + + if (seq->modifiers.first) { + return TRUE; + } return FALSE; } @@ -1795,7 +1833,7 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, } if (seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) { - color_balance(context, seq, ibuf, mul, cfra); + sequence_color_balance(context, seq, ibuf, mul, cfra); mul = 1.0; } @@ -1818,7 +1856,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, } } - if (ibuf->x != context.rectx || ibuf->y != context.recty) { if (context.scene->r.mode & R_OSA) { IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty); @@ -1827,6 +1864,16 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, IMB_scalefastImBuf(ibuf, (short)context.rectx, (short)context.recty); } } + + if (seq->modifiers.first) { + ImBuf *ibuf_new = BKE_sequence_modifier_apply_stack(context, seq, ibuf, cfra); + + if (ibuf_new != ibuf) { + IMB_freeImBuf(ibuf); + ibuf = ibuf_new; + } + } + return ibuf; } @@ -2098,23 +2145,23 @@ static ImBuf *seq_render_movieclip_strip(SeqRenderData context, Sequence *seq, f } -static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float nr) +static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short make_float) { /* TODO - add option to rasterize to alpha imbuf? */ ImBuf *ibuf = NULL; float *maskbuf; int i; - if (!seq->mask) { + if (!mask) { return NULL; } else { Mask *mask_temp; MaskRasterHandle *mr_handle; - mask_temp = BKE_mask_copy_nolib(seq->mask); + mask_temp = BKE_mask_copy_nolib(mask); - BKE_mask_evaluate(mask_temp, seq->mask->sfra + nr, TRUE); + BKE_mask_evaluate(mask_temp, mask->sfra + nr, TRUE); maskbuf = MEM_mallocN(sizeof(float) * context.rectx * context.recty, __func__); @@ -2131,7 +2178,7 @@ static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float } - if (seq->flag & SEQ_MAKE_FLOAT) { + if (make_float) { /* pixels */ float *fp_src; float *fp_dst; @@ -2173,6 +2220,13 @@ static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float return ibuf; } +static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float nr) +{ + short make_float = seq->flag & SEQ_MAKE_FLOAT; + + return seq_render_mask(context, seq->mask, nr, make_float); +} + static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float nr) { ImBuf *ibuf = NULL; @@ -2328,160 +2382,146 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float return ibuf; } -static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) +static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, float cfra) { ImBuf *ibuf = NULL; - char name[FILE_MAX]; - int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra); - int is_proxy_image = FALSE; float nr = give_stripelem_index(seq, cfra); - /* all effects are handled similarly with the exception of speed effect */ int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type; - int is_preprocessed = !ELEM3(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE); - - ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF); - - /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF, - * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */ - if (ibuf) - use_preprocess = FALSE; - - if (ibuf == NULL) - ibuf = copy_from_ibuf_still(context, seq, nr); - - /* MOVIECLIPs have their own proxy management */ - if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) { - ibuf = seq_proxy_fetch(context, seq, cfra); - is_proxy_image = (ibuf != NULL); - } + int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra); + char name[FILE_MAX]; - if (ibuf == NULL) switch (type) { - case SEQ_TYPE_META: - { - ImBuf *meta_ibuf = NULL; + switch (type) { + case SEQ_TYPE_META: + { + ImBuf *meta_ibuf = NULL; - if (seq->seqbase.first) - meta_ibuf = seq_render_strip_stack( - context, &seq->seqbase, - seq->start + nr, 0); + if (seq->seqbase.first) + meta_ibuf = seq_render_strip_stack(context, &seq->seqbase, seq->start + nr, 0); - if (meta_ibuf) { - ibuf = meta_ibuf; - if (ibuf && use_preprocess) { - ImBuf *i = IMB_dupImBuf(ibuf); + if (meta_ibuf) { + ibuf = meta_ibuf; + if (ibuf && use_preprocess) { + ImBuf *i = IMB_dupImBuf(ibuf); - IMB_freeImBuf(ibuf); + IMB_freeImBuf(ibuf); - ibuf = i; - } + ibuf = i; } - - break; } - case SEQ_TYPE_SPEED: - { - ImBuf *child_ibuf = NULL; - float f_cfra; - SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; + break; + } - BKE_sequence_effect_speed_rebuild_map(context.scene, seq, 0); + case SEQ_TYPE_SPEED: + { + ImBuf *child_ibuf = NULL; - /* weeek! */ - f_cfra = seq->start + s->frameMap[(int)nr]; + float f_cfra; + SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; - child_ibuf = seq_render_strip(context, seq->seq1, f_cfra); + BKE_sequence_effect_speed_rebuild_map(context.scene, seq, 0); - if (child_ibuf) { - ibuf = child_ibuf; - if (ibuf && use_preprocess) { - ImBuf *i = IMB_dupImBuf(ibuf); + /* weeek! */ + f_cfra = seq->start + s->frameMap[(int)nr]; - IMB_freeImBuf(ibuf); + child_ibuf = seq_render_strip(context, seq->seq1, f_cfra); - ibuf = i; - } + if (child_ibuf) { + ibuf = child_ibuf; + if (ibuf && use_preprocess) { + ImBuf *i = IMB_dupImBuf(ibuf); + + IMB_freeImBuf(ibuf); + + ibuf = i; } - break; - } - case SEQ_TYPE_EFFECT: - { - ibuf = seq_render_effect_strip_impl(context, seq, seq->start + nr); - break; } - case SEQ_TYPE_IMAGE: - { - StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra); + break; + } - if (s_elem) { - BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name); - BLI_path_abs(name, G.main->name); - } + case SEQ_TYPE_EFFECT: + { + ibuf = seq_render_effect_strip_impl(context, seq, seq->start + nr); + break; + } - if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) { - /* we don't need both (speed reasons)! */ - if (ibuf->rect_float && ibuf->rect) - imb_freerectImBuf(ibuf); + case SEQ_TYPE_IMAGE: + { + StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra); - /* all sequencer color is done in SRGB space, linear gives odd crossfades */ - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) - IMB_convert_profile(ibuf, IB_PROFILE_NONE); + if (s_elem) { + BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name); + BLI_path_abs(name, G.main->name); + } - copy_to_ibuf_still(context, seq, nr, ibuf); + if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) { + /* we don't need both (speed reasons)! */ + if (ibuf->rect_float && ibuf->rect) + imb_freerectImBuf(ibuf); - s_elem->orig_width = ibuf->x; - s_elem->orig_height = ibuf->y; - } - break; + /* all sequencer color is done in SRGB space, linear gives odd crossfades */ + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) + IMB_convert_profile(ibuf, IB_PROFILE_NONE); + + copy_to_ibuf_still(context, seq, nr, ibuf); + + s_elem->orig_width = ibuf->x; + s_elem->orig_height = ibuf->y; } - case SEQ_TYPE_MOVIE: - { - seq_open_anim_file(seq); + break; + } + + case SEQ_TYPE_MOVIE: + { + seq_open_anim_file(seq); - if (seq->anim) { - IMB_anim_set_preseek(seq->anim, seq->anim_preseek); + if (seq->anim) { + IMB_anim_set_preseek(seq->anim, seq->anim_preseek); - ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs, - seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN, - seq_rendersize_to_proxysize(context.preview_render_size)); + ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs, + seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN, + seq_rendersize_to_proxysize(context.preview_render_size)); - /* we don't need both (speed reasons)! */ - if (ibuf && ibuf->rect_float && ibuf->rect) - imb_freerectImBuf(ibuf); - if (ibuf) { - seq->strip->stripdata->orig_width = ibuf->x; - seq->strip->stripdata->orig_height = ibuf->y; - } + /* we don't need both (speed reasons)! */ + if (ibuf && ibuf->rect_float && ibuf->rect) + imb_freerectImBuf(ibuf); + if (ibuf) { + seq->strip->stripdata->orig_width = ibuf->x; + seq->strip->stripdata->orig_height = ibuf->y; } - copy_to_ibuf_still(context, seq, nr, ibuf); - break; } - case SEQ_TYPE_SCENE: - { - /* scene can be NULL after deletions */ - ibuf = seq_render_scene_strip(context, seq, nr); + copy_to_ibuf_still(context, seq, nr, ibuf); + break; + } - /* Scene strips update all animation, so we need to restore original state.*/ - BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra); + case SEQ_TYPE_SCENE: + { + /* scene can be NULL after deletions */ + ibuf = seq_render_scene_strip(context, seq, nr); - copy_to_ibuf_still(context, seq, nr, ibuf); - break; - } - case SEQ_TYPE_MOVIECLIP: - { - ibuf = seq_render_movieclip_strip(context, seq, nr); + /* Scene strips update all animation, so we need to restore original state.*/ + BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra); - if (ibuf && use_preprocess) { - ImBuf *i = IMB_dupImBuf(ibuf); + copy_to_ibuf_still(context, seq, nr, ibuf); + break; + } - IMB_freeImBuf(ibuf); + case SEQ_TYPE_MOVIECLIP: + { + ibuf = seq_render_movieclip_strip(context, seq, nr); - ibuf = i; - } + if (ibuf && use_preprocess) { + ImBuf *i = IMB_dupImBuf(ibuf); - copy_to_ibuf_still(context, seq, nr, ibuf); - break; + IMB_freeImBuf(ibuf); + + ibuf = i; } + + copy_to_ibuf_still(context, seq, nr, ibuf); + break; + } + case SEQ_TYPE_MASK: { /* ibuf is alwats new */ @@ -2492,6 +2532,47 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) } } + return ibuf; +} + +static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) +{ + ImBuf *ibuf = NULL; + int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra); + int is_proxy_image = FALSE; + float nr = give_stripelem_index(seq, cfra); + /* all effects are handled similarly with the exception of speed effect */ + int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type; + int is_preprocessed = !ELEM3(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE); + + ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF); + + /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF, + * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */ + if (ibuf) + use_preprocess = FALSE; + + if (ibuf == NULL) + ibuf = copy_from_ibuf_still(context, seq, nr); + + if (ibuf == NULL) { + ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF); + + if (ibuf == NULL) { + /* MOVIECLIPs have their own proxy management */ + if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) { + ibuf = seq_proxy_fetch(context, seq, cfra); + is_proxy_image = (ibuf != NULL); + } + + if (ibuf == NULL) + ibuf = do_render_strip_uncached(context, seq, cfra); + + if (ibuf) + BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf); + } + } + if (ibuf == NULL) ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); @@ -2876,7 +2957,7 @@ int BKE_sequence_check_depend(Sequence *seq, Sequence *cur) return TRUE; } -void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) +static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_preprocess) { Editing *ed = scene->ed; Sequence *cur; @@ -2884,18 +2965,33 @@ void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) /* invalidate cache for current sequence */ BKE_sequencer_cache_cleanup_sequence(seq); + if (invalidate_preprocess) + BKE_sequencer_preprocessed_cache_cleanup_sequence(seq); + /* invalidate cache for all dependent sequences */ SEQ_BEGIN (ed, cur) { if (cur == seq) continue; - if (BKE_sequence_check_depend(seq, cur)) + if (BKE_sequence_check_depend(seq, cur)) { BKE_sequencer_cache_cleanup_sequence(cur); + BKE_sequencer_preprocessed_cache_cleanup_sequence(cur); + } } SEQ_END } +void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) +{ + sequence_invalidate_cache(scene, seq, TRUE); +} + +void BKE_sequence_invalidate_cache_for_modifier(Scene *scene, Sequence *seq) +{ + sequence_invalidate_cache(scene, seq, FALSE); +} + void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int check_mem_usage, int keep_file_handles) { Sequence *seq; @@ -3531,8 +3627,8 @@ int BKE_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str) SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity); - SWAP(void *, seq_a->prev, seq_b->prev); - SWAP(void *, seq_a->next, seq_b->next); + SWAP(Sequence *, seq_a->prev, seq_b->prev); + SWAP(Sequence *, seq_a->next, seq_b->next); SWAP(int, seq_a->start, seq_b->start); SWAP(int, seq_a->startofs, seq_b->startofs); SWAP(int, seq_a->endofs, seq_b->endofs); @@ -3626,7 +3722,7 @@ static void seq_free_animdata(Scene *scene, Sequence *seq) } } -Sequence *BKE_sequwnce_get_by_name(ListBase *seqbase, const char *name, int recursive) +Sequence *BKE_sequence_get_by_name(ListBase *seqbase, const char *name, int recursive) { Sequence *iseq = NULL; Sequence *rseq = NULL; @@ -3634,7 +3730,7 @@ Sequence *BKE_sequwnce_get_by_name(ListBase *seqbase, const char *name, int recu for (iseq = seqbase->first; iseq; iseq = iseq->next) { if (strcmp(name, iseq->name + 2) == 0) return iseq; - else if (recursive && (iseq->seqbase.first) && (rseq = BKE_sequwnce_get_by_name(&iseq->seqbase, name, 1))) { + else if (recursive && (iseq->seqbase.first) && (rseq = BKE_sequence_get_by_name(&iseq->seqbase, name, 1))) { return rseq; } } @@ -3941,6 +4037,12 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup seqn->strip->color_balance = MEM_dupallocN(seq->strip->color_balance); } + if (seqn->modifiers.first) { + seqn->modifiers.first = seqn->modifiers.last = NULL; + + BKE_sequence_modifier_list_copy(seqn, seq); + } + if (seq->type == SEQ_TYPE_META) { seqn->strip->stripdata = NULL; @@ -4060,3 +4162,4 @@ int BKE_seqence_is_valid_check(Sequence *seq) return TRUE; } + diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 14360297ec0..2462de07a18 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -774,37 +774,37 @@ void sound_force_device(int UNUSED(device)) {} void sound_init_once(void) {} void sound_init(struct Main *UNUSED(bmain)) {} void sound_exit(void) {} -void sound_cache(struct bSound* UNUSED(sound)) { } -void sound_delete_cache(struct bSound* UNUSED(sound)) {} -void sound_load(struct Main *UNUSED(bmain), struct bSound* UNUSED(sound)) {} +void sound_cache(struct bSound *UNUSED(sound)) { } +void sound_delete_cache(struct bSound *UNUSED(sound)) {} +void sound_load(struct Main *UNUSED(bmain), struct bSound *UNUSED(sound)) {} void sound_create_scene(struct Scene *UNUSED(scene)) {} void sound_destroy_scene(struct Scene *UNUSED(scene)) {} void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {} -void* sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } -void* sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; } -void* sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } -void* sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; } -void sound_remove_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle)) {} -void sound_mute_scene_sound(void* UNUSED(handle), char UNUSED(mute)) {} -void sound_move_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {} +void *sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } +void *sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) { return NULL; } +void *sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } +void *sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) { return NULL; } +void sound_remove_scene_sound(struct Scene *UNUSED(scene), void *UNUSED(handle)) {} +void sound_mute_scene_sound(void *UNUSED(handle), char UNUSED(mute)) {} +void sound_move_scene_sound(struct Scene *UNUSED(scene), void *UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {} void sound_move_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) {} void sound_play_scene(struct Scene *UNUSED(scene)) {} void sound_stop_scene(struct Scene *UNUSED(scene)) {} void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {} float sound_sync_scene(struct Scene *UNUSED(scene)) { return NAN_FLT; } int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; } -int sound_read_sound_buffer(struct bSound* UNUSED(sound), float* UNUSED(buffer), int UNUSED(length), float UNUSED(start), float UNUSED(end)) { return 0; } -void sound_read_waveform(struct bSound* sound) { (void)sound; } +int sound_read_sound_buffer(struct bSound *UNUSED(sound), float *UNUSED(buffer), int UNUSED(length), float UNUSED(start), float UNUSED(end)) { return 0; } +void sound_read_waveform(struct bSound *sound) { (void)sound; } void sound_init_main(struct Main *bmain) { (void)bmain; } void sound_set_cfra(int cfra) { (void)cfra; } -void sound_update_sequencer(struct Main* main, struct bSound* sound) { (void)main; (void)sound; } -void sound_update_scene(struct Scene* scene) { (void)scene; } -void sound_update_scene_sound(void* handle, struct bSound* sound) { (void)handle; (void)sound; } +void sound_update_sequencer(struct Main *main, struct bSound *sound) { (void)main; (void)sound; } +void sound_update_scene(struct Scene *scene) { (void)scene; } +void sound_update_scene_sound(void *handle, struct bSound *sound) { (void)handle; (void)sound; } void sound_update_scene_listener(struct Scene *scene) { (void)scene; } void sound_update_fps(struct Scene *scene) { (void)scene; } -void sound_set_scene_sound_volume(void* handle, float volume, char animated) { (void)handle; (void)volume; (void)animated; } -void sound_set_scene_sound_pan(void* handle, float pan, char animated) { (void)handle; (void)pan; (void)animated; } +void sound_set_scene_sound_volume(void *handle, float volume, char animated) { (void)handle; (void)volume; (void)animated; } +void sound_set_scene_sound_pan(void *handle, float pan, char animated) { (void)handle; (void)pan; (void)animated; } void sound_set_scene_volume(struct Scene *scene, float volume) { (void)scene; (void)volume; } -void sound_set_scene_sound_pitch(void* handle, float pitch, char animated) { (void)handle; (void)pitch; (void)animated; } -float sound_get_length(struct bSound* sound) { (void)sound; return 0; } +void sound_set_scene_sound_pitch(void *handle, float pitch, char animated) { (void)handle; (void)pitch; (void)animated; } +float sound_get_length(struct bSound *sound) { (void)sound; return 0; } #endif // WITH_AUDASPACE diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 5c387e8cee0..555ed5890c8 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -113,7 +113,8 @@ typedef enum { CCG_USE_ARENA = 2, CCG_CALC_NORMALS = 4, /* add an extra four bytes for a mask layer */ - CCG_ALLOC_MASK = 8 + CCG_ALLOC_MASK = 8, + CCG_SIMPLE_SUBDIV = 16 } CCGFlags; static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, @@ -133,7 +134,10 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL); - if (oldUseAging != useAging) { + if ((oldUseAging != useAging) || + (ccgSubSurf_getSimpleSubdiv(prevSS) != + !!(flags & CCG_SIMPLE_SUBDIV))) + { ccgSubSurf_free(prevSS); } else { @@ -156,6 +160,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, ifc.vertDataSize += sizeof(float) * 3; if (flags & CCG_ALLOC_MASK) ifc.vertDataSize += sizeof(float); + ifc.simpleSubdiv = !!(flags & CCG_SIMPLE_SUBDIV); if (useArena) { CCGAllocatorIFC allocatorIFC; @@ -1463,9 +1468,9 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) } static void ccgDM_foreachMappedVert( - DerivedMesh *dm, - void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), - void *userData) + DerivedMesh *dm, + void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), + void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGVertIterator *vi; @@ -1485,9 +1490,9 @@ static void ccgDM_foreachMappedVert( } static void ccgDM_foreachMappedEdge( - DerivedMesh *dm, - void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]), - void *userData) + DerivedMesh *dm, + void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]), + void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; @@ -2487,9 +2492,9 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, } static void ccgDM_foreachMappedFaceCenter( - DerivedMesh *dm, - void (*func)(void *userData, int index, const float co[3], const float no[3]), - void *userData) + DerivedMesh *dm, + void (*func)(void *userData, int index, const float co[3], const float no[3]), + void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; @@ -3474,7 +3479,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( float (*vertCos)[3], SubsurfFlags flags) { - int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF; + int useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : 0; CCGFlags useAging = smd->flags & eSubsurfModifierFlag_DebugIncr ? CCG_USE_AGING : 0; int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv; int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges); @@ -3483,7 +3488,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( if (flags & SUBSURF_FOR_EDIT_MODE) { int levels = (smd->modifier.scene) ? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels) : smd->levels; - smd->emCache = _getSubSurf(smd->emCache, levels, 3, useAging | CCG_CALC_NORMALS); + smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS); ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple); result = getCCGDerivedMesh(smd->emCache, @@ -3498,7 +3503,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( if (levels == 0) return dm; - ss = _getSubSurf(NULL, levels, 3, CCG_USE_ARENA | CCG_CALC_NORMALS); + ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); @@ -3529,7 +3534,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( } if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) { - smd->mCache = ss = _getSubSurf(smd->mCache, levels, 3, useAging | CCG_CALC_NORMALS); + smd->mCache = ss = _getSubSurf(smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); @@ -3538,7 +3543,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( useSubsurfUv, dm); } else { - CCGFlags ccg_flags = CCG_USE_ARENA | CCG_CALC_NORMALS; + CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS; if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) { ccgSubSurf_free(smd->mCache); diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 5bad69c2e8d..2f54fe6cebd 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -1292,7 +1292,7 @@ PointDensity *BKE_add_pointdensity(void) pd->falloff_curve->preset = CURVE_PRESET_LINE; pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; curvemap_reset(pd->falloff_curve->cm, &pd->falloff_curve->clipr, pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE); - curvemapping_changed(pd->falloff_curve, 0); + curvemapping_changed(pd->falloff_curve, FALSE); return pd; } diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 303098ea0bd..dd71e43182e 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -128,8 +128,9 @@ World *BKE_world_copy(World *wrld) } } - if (wrld->nodetree) + if (wrld->nodetree) { wrldn->nodetree = ntreeCopyTree(wrld->nodetree); + } if (wrld->preview) wrldn->preview = BKE_previewimg_copy(wrld->preview); diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index f22fd74baf4..3526058e12b 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -69,8 +69,6 @@ #include "ffmpeg_compat.h" -extern void do_init_ffmpeg(void); - static int ffmpeg_type = 0; static int ffmpeg_codec = CODEC_ID_MPEG4; static int ffmpeg_audio_codec = CODEC_ID_NONE; @@ -101,6 +99,8 @@ static AUD_Device *audio_mixdown_device = 0; #define FFMPEG_AUTOSPLIT_SIZE 2000000000 +#define PRINT if (G.debug & G_DEBUG_FFMPEG) printf + /* Delete a picture buffer */ static void delete_picture(AVFrame *f) @@ -125,9 +125,7 @@ static int write_audio_frame(void) AUD_readDevice(audio_mixdown_device, audio_input_buffer, audio_input_samples); audio_time += (double) audio_input_samples / (double) c->sample_rate; - pkt.size = avcodec_encode_audio(c, audio_output_buffer, - audio_outbuf_size, - (short *)audio_input_buffer); + pkt.size = avcodec_encode_audio(c, audio_output_buffer, audio_outbuf_size, (short *) audio_input_buffer); if (pkt.size < 0) { // XXX error("Error writing audio packet"); @@ -137,9 +135,8 @@ static int write_audio_frame(void) pkt.data = audio_output_buffer; if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE) { - pkt.pts = av_rescale_q(c->coded_frame->pts, - c->time_base, audio_stream->time_base); - fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts); + pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, audio_stream->time_base); + PRINT("Audio Frame PTS: %d\n", (int) pkt.pts); } pkt.stream_index = audio_stream->index; @@ -189,8 +186,7 @@ static const char **get_file_extensions(int format) return rv; } case FFMPEG_MPEG2: { - static const char *rv[] = { ".dvd", ".vob", ".mpg", ".mpeg", - NULL }; + static const char *rv[] = { ".dvd", ".vob", ".mpg", ".mpeg", NULL }; return rv; } case FFMPEG_MPEG4: { @@ -254,21 +250,18 @@ static int write_video_frame(RenderData *rd, int cfra, AVFrame *frame, ReportLis frame->top_field_first = ((rd->mode & R_ODDFIELD) != 0); } - outsize = avcodec_encode_video(c, video_buffer, video_buffersize, - frame); + outsize = avcodec_encode_video(c, video_buffer, video_buffersize, frame); if (outsize > 0) { AVPacket packet; av_init_packet(&packet); if (c->coded_frame->pts != AV_NOPTS_VALUE) { - packet.pts = av_rescale_q(c->coded_frame->pts, - c->time_base, - video_stream->time_base); - fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts); + packet.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_stream->time_base); + PRINT("Video Frame PTS: %d\n", (int)packet.pts); } else { - fprintf(stderr, "Video Frame PTS: not set\n"); + PRINT("Video Frame PTS: not set\n"); } if (c->coded_frame->key_frame) packet.flags |= AV_PKT_FLAG_KEY; @@ -364,7 +357,7 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop) char *param; const AVOption *rv = NULL; - fprintf(stderr, "FFMPEG expert option: %s: ", prop->name); + PRINT("FFMPEG expert option: %s: ", prop->name); BLI_strncpy(name, prop->name, sizeof(name)); @@ -376,15 +369,15 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop) switch (prop->type) { case IDP_STRING: - fprintf(stderr, "%s.\n", IDP_String(prop)); + PRINT("%s.\n", IDP_String(prop)); av_set_string3(c, prop->name, IDP_String(prop), 1, &rv); break; case IDP_FLOAT: - fprintf(stderr, "%g.\n", IDP_Float(prop)); + PRINT("%g.\n", IDP_Float(prop)); rv = av_set_double(c, prop->name, IDP_Float(prop)); break; case IDP_INT: - fprintf(stderr, "%d.\n", IDP_Int(prop)); + PRINT("%d.\n", IDP_Int(prop)); if (param) { if (IDP_Int(prop)) { @@ -401,8 +394,7 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop) } if (!rv) { - fprintf(stderr, "ffmpeg-option not supported: %s! Skipping.\n", - prop->name); + PRINT("ffmpeg-option not supported: %s! Skipping.\n", prop->name); } } @@ -446,11 +438,14 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char /* prepare a video stream for the output file */ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContext *of, - int rectx, int recty) + int rectx, int recty, char *error, int error_size) { AVStream *st; AVCodecContext *c; AVCodec *codec; + + error[0] = '\0'; + st = av_new_stream(of, 0); if (!st) return NULL; @@ -460,7 +455,6 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex c->codec_id = codec_id; c->codec_type = AVMEDIA_TYPE_VIDEO; - /* Get some values from the current render settings */ c->width = rectx; @@ -492,7 +486,8 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex c->me_method = ME_EPZS; codec = avcodec_find_encoder(c->codec_id); - if (!codec) return NULL; + if (!codec) + return NULL; /* Be sure to use the correct pixel format(e.g. RGB, YUV) */ @@ -547,27 +542,25 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex // || !strcmp(of->oformat->name, "3gp") ) { - fprintf(stderr, "Using global header\n"); + PRINT("Using global header\n"); c->flags |= CODEC_FLAG_GLOBAL_HEADER; } /* Determine whether we are encoding interlaced material or not */ if (rd->mode & R_FIELDS) { - fprintf(stderr, "Encoding interlaced video\n"); + PRINT("Encoding interlaced video\n"); c->flags |= CODEC_FLAG_INTERLACED_DCT; c->flags |= CODEC_FLAG_INTERLACED_ME; } /* xasp & yasp got float lately... */ - st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q( - ((double) rd->xasp / (double) rd->yasp), 255); + st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q(((double) rd->xasp / (double) rd->yasp), 255); set_ffmpeg_properties(rd, c, "video"); if (avcodec_open(c, codec) < 0) { - // - //XXX error("Couldn't initialize codec"); + BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size); return NULL; } @@ -584,16 +577,11 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex else video_buffersize = avpicture_get_size(c->pix_fmt, c->width, c->height); - video_buffer = (uint8_t *)MEM_mallocN(video_buffersize * sizeof(uint8_t), - "FFMPEG video buffer"); + video_buffer = (uint8_t *)MEM_mallocN(video_buffersize * sizeof(uint8_t), "FFMPEG video buffer"); current_frame = alloc_picture(c->pix_fmt, c->width, c->height); - img_convert_ctx = sws_getContext(c->width, c->height, - PIX_FMT_BGR32, - c->width, c->height, - c->pix_fmt, - SWS_BICUBIC, + img_convert_ctx = sws_getContext(c->width, c->height, PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL); return st; } @@ -645,11 +633,9 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex audio_outbuf_size = c->frame_size * c->channels * sizeof(int16_t) * 4; } - audio_output_buffer = (uint8_t *)av_malloc( - audio_outbuf_size); + audio_output_buffer = (uint8_t *) av_malloc(audio_outbuf_size); - audio_input_buffer = (uint8_t *)av_malloc( - audio_input_samples * c->channels * sizeof(int16_t)); + audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(int16_t)); audio_time = 0.0f; @@ -672,7 +658,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report AVFormatContext *of; AVOutputFormat *fmt; AVDictionary *opts = NULL; - char name[256]; + char name[256], error[1024]; const char **exts; ffmpeg_type = rd->ffcodecdata.type; @@ -681,14 +667,11 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report ffmpeg_video_bitrate = rd->ffcodecdata.video_bitrate; ffmpeg_audio_bitrate = rd->ffcodecdata.audio_bitrate; ffmpeg_gop_size = rd->ffcodecdata.gop_size; - ffmpeg_autosplit = rd->ffcodecdata.flags - & FFMPEG_AUTOSPLIT_OUTPUT; + ffmpeg_autosplit = rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT; - do_init_ffmpeg(); - /* Determine the correct filename */ BKE_ffmpeg_filepath_get(name, rd); - fprintf(stderr, "Starting output to %s(ffmpeg)...\n" + PRINT("Starting output to %s(ffmpeg)...\n" " Using type=%d, codec=%d, audio_codec=%d,\n" " video_bitrate=%d, audio_bitrate=%d,\n" " gop_size=%d, autosplit=%d\n" @@ -793,10 +776,14 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report } if (fmt->video_codec != CODEC_ID_NONE) { - video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty); - printf("alloc video stream %p\n", video_stream); + video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty, error, sizeof(error)); + PRINT("alloc video stream %p\n", video_stream); if (!video_stream) { - BKE_report(reports, RPT_ERROR, "Error initializing video stream."); + if (error[0]) + BKE_report(reports, RPT_ERROR, error); + else + BKE_report(reports, RPT_ERROR, "Error initializing video stream."); + av_dict_free(&opts); return 0; } @@ -867,13 +854,11 @@ void flush_ffmpeg(void) break; } if (c->coded_frame->pts != AV_NOPTS_VALUE) { - packet.pts = av_rescale_q(c->coded_frame->pts, - c->time_base, - video_stream->time_base); - fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts); + packet.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_stream->time_base); + PRINT("Video Frame PTS: %d\n", (int) packet.pts); } else { - fprintf(stderr, "Video Frame PTS: not set\n"); + PRINT("Video Frame PTS: not set\n"); } if (c->coded_frame->key_frame) { packet.flags |= AV_PKT_FLAG_KEY; @@ -916,8 +901,7 @@ void BKE_ffmpeg_filepath_get(char *string, RenderData *rd) } while (*fe) { - if (BLI_strcasecmp(string + strlen(string) - strlen(*fe), - *fe) == 0) + if (BLI_strcasecmp(string + strlen(string) - strlen(*fe), *fe) == 0) { break; } @@ -983,9 +967,7 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i AVFrame *avframe; int success = 1; - fprintf(stderr, "Writing frame %i, " - "render width=%d, render height=%d\n", frame, - rectx, recty); + PRINT("Writing frame %i, render width=%d, render height=%d\n", frame, rectx, recty); // why is this done before writing the video frame and again at end_ffmpeg? // write_audio_frames(frame / (((double)rd->frs_sec) / rd->frs_sec_base)); @@ -1013,7 +995,7 @@ void BKE_ffmpeg_end(void) { unsigned int i; - fprintf(stderr, "Closing ffmpeg...\n"); + PRINT("Closing ffmpeg...\n"); #if 0 if (audio_stream) { /* SEE UPPER */ @@ -1029,7 +1011,7 @@ void BKE_ffmpeg_end(void) #endif if (video_stream && video_stream->codec) { - fprintf(stderr, "Flushing delayed frames...\n"); + PRINT("Flushing delayed frames...\n"); flush_ffmpeg(); } @@ -1041,7 +1023,7 @@ void BKE_ffmpeg_end(void) if (video_stream && video_stream->codec) { avcodec_close(video_stream->codec); - printf("zero video stream %p\n", video_stream); + PRINT("zero video stream %p\n", video_stream); video_stream = 0; } @@ -1142,8 +1124,7 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in BLI_strncpy(name, o->name, sizeof(name)); } - fprintf(stderr, "ffmpeg_property_add: %s %d %d %s\n", - type, parent_index, opt_index, name); + PRINT("ffmpeg_property_add: %s %d %d %s\n", type, parent_index, opt_index, name); prop = IDP_GetPropertyFromGroup(group, name); if (prop) { @@ -1181,8 +1162,7 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in /* not all versions of ffmpeg include that, so here we go ... */ -static const AVOption *my_av_find_opt(void *v, const char *name, - const char *unit, int mask, int flags) +static const AVOption *my_av_find_opt(void *v, const char *name, const char *unit, int mask, int flags) { AVClass *c = *(AVClass **)v; const AVOption *o = c->option; @@ -1235,14 +1215,11 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char if (param && o->type != FF_OPT_TYPE_CONST && o->unit) { p = my_av_find_opt(&c, param, o->unit, 0, 0); if (p) { - prop = BKE_ffmpeg_property_add(rd, - (char *) type, p - c.av_class->option, - o - c.av_class->option); + prop = BKE_ffmpeg_property_add(rd, (char *) type, p - c.av_class->option, o - c.av_class->option); } } else { - prop = BKE_ffmpeg_property_add(rd, - (char *) type, o - c.av_class->option, 0); + prop = BKE_ffmpeg_property_add(rd, (char *) type, o - c.av_class->option, 0); } @@ -1316,12 +1293,10 @@ static void ffmpeg_set_expert_options(RenderData *rd) if (rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT) BKE_ffmpeg_property_add_string(rd, "video", "cqp:0"); } -#if 0 /* disabled for after release */ else if (codec_id == CODEC_ID_DNXHD) { if (rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT) - ffmpeg_property_add_string(rd, "video", "mbd:rd"); + BKE_ffmpeg_property_add_string(rd, "video", "mbd:rd"); } -#endif } void BKE_ffmpeg_preset_set(RenderData *rd, int preset) |