diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
41 files changed, 766 insertions, 331 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index d4454a95a2d..ffb92788d4d 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -248,7 +248,7 @@ static CCGAllocatorIFC *_getStandardAllocatorIFC(void) /***/ -int ccg_gridsize(int level) +BLI_INLINE int ccg_gridsize(int level) { BLI_assert(level > 0); BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1); @@ -256,7 +256,12 @@ int ccg_gridsize(int level) return (1 << (level - 1)) + 1; } -int ccg_factor(int low_level, int high_level) +int BKE_ccg_gridsize(int level) +{ + return ccg_gridsize(level); +} + +int BKE_ccg_factor(int low_level, int high_level) { BLI_assert(low_level > 0 && high_level > 0); BLI_assert(low_level <= high_level); @@ -264,7 +269,7 @@ int ccg_factor(int low_level, int high_level) return 1 << (high_level - low_level); } -static int ccg_edgesize(int level) +BLI_INLINE int ccg_edgesize(int level) { BLI_assert(level > 0); BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1); @@ -272,7 +277,7 @@ static int ccg_edgesize(int level) return 1 + (1 << level); } -static int ccg_spacing(int high_level, int low_level) +BLI_INLINE int ccg_spacing(int high_level, int low_level) { BLI_assert(high_level > 0 && low_level > 0); BLI_assert(high_level >= low_level); @@ -281,7 +286,7 @@ static int ccg_spacing(int high_level, int low_level) return 1 << (high_level - low_level); } -static int ccg_edgebase(int level) +BLI_INLINE int ccg_edgebase(int level) { BLI_assert(level > 0); BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1); @@ -742,7 +747,7 @@ BLI_INLINE float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int le byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize)); return (float *) &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing) + normalDataOffset]; } -static int _face_getVertIndex(CCGFace *f, CCGVert *v) +BLI_INLINE int _face_getVertIndex(CCGFace *f, CCGVert *v) { int i; for (i = 0; i < f->numVerts; i++) @@ -750,7 +755,7 @@ static int _face_getVertIndex(CCGFace *f, CCGVert *v) return i; return -1; } -static int _face_getEdgeIndex(CCGFace *f, CCGEdge *e) +BLI_INLINE int _face_getEdgeIndex(CCGFace *f, CCGEdge *e) { int i; for (i = 0; i < f->numVerts; i++) diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 644fefad3b0..b0644da4598 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -489,6 +489,22 @@ bPoseChannel *BKE_pose_channel_verify(bPose *pose, const char *name) return chan; } +#ifndef NDEBUG +bool BKE_pose_channels_is_valid(const bPose *pose) +{ + if (pose->chanhash) { + bPoseChannel *pchan; + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + if (BLI_ghash_lookup(pose->chanhash, pchan->name) != pchan) { + return false; + } + } + } + + return true; +} + +#endif /* Find the active posechannel for an object (we can't just use pose, as layer info is in armature) */ bPoseChannel *BKE_pose_channel_active(Object *ob) { diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 5c3f67d8959..225be335c6d 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -530,7 +530,7 @@ void calc_curvepath(Object *ob, ListBase *nurbs) path->len = nu->resolu * SEGMENTSU(nu); } - dist = (float *)MEM_mallocN((tot + 1) * 4, "calcpathdist"); + dist = (float *)MEM_mallocN(sizeof(float) * (tot + 1), "calcpathdist"); /* all lengths in *dist */ bevp = bevpfirst = (BevPoint *)(bl + 1); diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 8e697ad4ef3..74578266c63 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -42,6 +42,7 @@ #include "BLI_blenlib.h" #include "BLI_alloca.h" #include "BLI_dynstr.h" +#include "BLI_listbase.h" #include "BLF_translation.h" @@ -759,6 +760,76 @@ void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, cons MEM_freeN(newN); } +/* *************************** */ +/* remove of individual paths */ + +/* Check RNA-Paths for a list of F-Curves */ +static void fcurves_path_remove_fix(const char *prefix, ListBase *curves) +{ + FCurve *fcu, *fcn; + if (!prefix) return; + + /* we need to check every curve... */ + for (fcu = curves->first; fcu; fcu = fcn) { + fcn = fcu->next; + + if (fcu->rna_path) { + if (STRPREFIX(fcu->rna_path, prefix)) { + BLI_remlink(curves, fcu); + free_fcurve(fcu); + } + } + } +} + +/* Check RNA-Paths for a list of F-Curves */ +static void nlastrips_path_remove_fix(const char *prefix, ListBase *strips) +{ + NlaStrip *strip; + + /* recursively check strips, fixing only actions... */ + for (strip = strips->first; strip; strip = strip->next) { + + /* fix strip's action */ + if (strip->act) + fcurves_path_remove_fix(prefix, &strip->act->curves); + + /* check sub-strips (if metas) */ + nlastrips_path_remove_fix(prefix, &strip->strips); + } +} + +void BKE_animdata_fix_paths_remove(ID *id, const char *prefix) +{ + /* Only some ID-blocks have this info for now, so we cast the + * types that do to be of type IdAdtTemplate + */ + NlaTrack *nlt; + + if (id_type_can_have_animdata(id)) { + IdAdtTemplate *iat = (IdAdtTemplate *)id; + AnimData *adt = iat->adt; + + /* check if there's any AnimData to start with */ + if (adt) { + + /* free fcurves */ + if (adt->action) + fcurves_path_remove_fix(prefix, &adt->action->curves); + + if (adt->tmpact) + fcurves_path_remove_fix(prefix, &adt->tmpact->curves); + + /* free drivers - stored as a list of F-Curves */ + fcurves_path_remove_fix(prefix, &adt->drivers); + + /* NLA Data - Animation Data for Strips */ + for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) + nlastrips_path_remove_fix(prefix, &nlt->strips); + } + } +} + /* Whole Database Ops -------------------------------------------- */ /* apply the given callback function on all data in main database */ diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 8ce84609c15..a8d64ea9fb6 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -206,6 +206,8 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * BVHTreeRayHit hit; float radius = val->personal_space * pa->size, ray_dir[3]; + memset(&col, 0, sizeof(ParticleCollision)); + copy_v3_v3(col.co1, pa->prev_state.co); add_v3_v3v3(col.co2, pa->prev_state.co, pa->prev_state.vel); sub_v3_v3v3(ray_dir, col.co2, col.co1); @@ -777,6 +779,8 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float grou if (!bbd->sim->colliders) return NULL; + memset(&col, 0, sizeof(ParticleCollision)); + /* first try to find below boid */ copy_v3_v3(col.co1, pa->state.co); sub_v3_v3v3(col.co2, pa->state.co, zvec); diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index 5b66b8b4cd4..370dbc62ef8 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -355,7 +355,7 @@ float nearest_point_in_tri_surface(const float v0[3], const float v1[3], const f /* - * BVH from meshs callbacks + * BVH from meshes callbacks */ /* Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces. diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 7f94f365925..578fa5d348d 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -972,9 +972,6 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const ColorM if (ibuf->rect_float) cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings); - /* persistent draw */ - hist->flag |= HISTO_FLAG_SAMPLELINE; /* keep drawing the flag after */ - for (i = 0; i < 256; i++) { x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f); y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 02b35794d28..e255732d3fb 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -3102,46 +3102,67 @@ void BKE_nurb_handle_calc_simple(Nurb *nu, BezTriple *bezt) } } -void BKE_nurb_handles_test(Nurb *nu) -{ - /* use when something has changed with handles. - * it treats all BezTriples with the following rules: - * PHASE 1: do types have to be altered? - * Auto handles: become aligned when selection status is NOT(000 || 111) - * Vector handles: become 'nothing' when (one half selected AND other not) - * PHASE 2: recalculate handles - */ - BezTriple *bezt; - short flag, a; +/** + * Use when something has changed handle positions. + * + * The caller needs to recalculate handles. + */ +void BKE_nurb_bezt_handle_test(BezTriple *bezt, const bool use_handle) +{ + short flag = 0; - if (nu->type != CU_BEZIER) return; +#define SEL_F1 (1 << 0) +#define SEL_F2 (1 << 1) +#define SEL_F3 (1 << 2) - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - flag = 0; - if (bezt->f1 & SELECT) - flag++; - if (bezt->f2 & SELECT) - flag += 2; - if (bezt->f3 & SELECT) - flag += 4; + if (use_handle) { + if (bezt->f1 & SELECT) flag |= SEL_F1; + if (bezt->f2 & SELECT) flag |= SEL_F2; + if (bezt->f3 & SELECT) flag |= SEL_F3; + } + else { + flag = (bezt->f2 & SELECT) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0; + } - if (!(flag == 0 || flag == 7) ) { - if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) { /* auto */ - bezt->h1 = HD_ALIGN; - } - if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { /* auto */ - bezt->h2 = HD_ALIGN; - } + /* check for partial selection */ + if (!ELEM(flag, 0, SEL_F1 | SEL_F2 | SEL_F3)) { + if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) { + bezt->h1 = HD_ALIGN; + } + if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { + bezt->h2 = HD_ALIGN; + } - if (bezt->h1 == HD_VECT) { /* vector */ - if (flag < 4) bezt->h1 = 0; + if (bezt->h1 == HD_VECT) { + if ((!(flag & SEL_F1)) != (!(flag & SEL_F2))) { + bezt->h1 = HD_FREE; } - if (bezt->h2 == HD_VECT) { /* vector */ - if (flag > 3) bezt->h2 = 0; + } + if (bezt->h2 == HD_VECT) { + if ((!(flag & SEL_F3)) != (!(flag & SEL_F2))) { + bezt->h2 = HD_FREE; } } + } + +#undef SEL_F1 +#undef SEL_F2 +#undef SEL_F3 + +} + +void BKE_nurb_handles_test(Nurb *nu, const bool use_handle) +{ + BezTriple *bezt; + short a; + + if (nu->type != CU_BEZIER) + return; + + bezt = nu->bezt; + a = nu->pntsu; + while (a--) { + BKE_nurb_bezt_handle_test(bezt, use_handle); bezt++; } @@ -3151,9 +3172,11 @@ void BKE_nurb_handles_test(Nurb *nu) void BKE_nurb_handles_autocalc(Nurb *nu, int flag) { /* checks handle coordinates and calculates type */ + const float eps = 0.0001f; + const float eps_sq = eps * eps; BezTriple *bezt2, *bezt1, *bezt0; - int i, align, leftsmall, rightsmall; + int i; if (nu == NULL || nu->bezt == NULL) return; @@ -3164,54 +3187,54 @@ void BKE_nurb_handles_autocalc(Nurb *nu, int flag) i = nu->pntsu; while (i--) { - align = leftsmall = rightsmall = 0; + bool align = false, leftsmall = false, rightsmall = false; /* left handle: */ if (flag == 0 || (bezt1->f1 & flag) ) { - bezt1->h1 = 0; + bezt1->h1 = HD_FREE; /* distance too short: vectorhandle */ - if (len_v3v3(bezt1->vec[1], bezt0->vec[1]) < 0.0001f) { + if (len_squared_v3v3(bezt1->vec[1], bezt0->vec[1]) < eps_sq) { bezt1->h1 = HD_VECT; - leftsmall = 1; + leftsmall = true; } else { /* aligned handle? */ - if (dist_to_line_v2(bezt1->vec[1], bezt1->vec[0], bezt1->vec[2]) < 0.0001f) { - align = 1; + if (dist_to_line_v2(bezt1->vec[1], bezt1->vec[0], bezt1->vec[2]) < eps) { + align = true; bezt1->h1 = HD_ALIGN; } /* or vector handle? */ - if (dist_to_line_v2(bezt1->vec[0], bezt1->vec[1], bezt0->vec[1]) < 0.0001f) + if (dist_to_line_v2(bezt1->vec[0], bezt1->vec[1], bezt0->vec[1]) < eps) bezt1->h1 = HD_VECT; } } /* right handle: */ if (flag == 0 || (bezt1->f3 & flag) ) { - bezt1->h2 = 0; + bezt1->h2 = HD_FREE; /* distance too short: vectorhandle */ - if (len_v3v3(bezt1->vec[1], bezt2->vec[1]) < 0.0001f) { + if (len_squared_v3v3(bezt1->vec[1], bezt2->vec[1]) < eps_sq) { bezt1->h2 = HD_VECT; - rightsmall = 1; + rightsmall = true; } else { /* aligned handle? */ if (align) bezt1->h2 = HD_ALIGN; /* or vector handle? */ - if (dist_to_line_v2(bezt1->vec[2], bezt1->vec[1], bezt2->vec[1]) < 0.0001f) + if (dist_to_line_v2(bezt1->vec[2], bezt1->vec[1], bezt2->vec[1]) < eps) bezt1->h2 = HD_VECT; } } if (leftsmall && bezt1->h2 == HD_ALIGN) - bezt1->h2 = 0; + bezt1->h2 = HD_FREE; if (rightsmall && bezt1->h1 == HD_ALIGN) - bezt1->h1 = 0; + bezt1->h1 = HD_FREE; /* undesired combination: */ if (bezt1->h1 == HD_ALIGN && bezt1->h2 == HD_VECT) - bezt1->h1 = 0; + bezt1->h1 = HD_FREE; if (bezt1->h2 == HD_ALIGN && bezt1->h1 == HD_VECT) - bezt1->h2 = 0; + bezt1->h2 = HD_FREE; bezt0 = bezt1; bezt1 = bezt2; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 03dfee4b57c..8a74f4719d5 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -971,6 +971,11 @@ static void layerDefault_mcol(void *data, int count) } } +static void layerDefault_origindex(void *data, int count) +{ + fill_vn_i((int *)data, count, ORIGINDEX_NONE); +} + static void layerInterp_bweight(void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest) { @@ -1077,7 +1082,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(MCol) * 4, "MCol", 4, N_("Col"), NULL, NULL, layerInterp_mcol, layerSwap_mcol, layerDefault_mcol}, /* 7: CD_ORIGINDEX */ - {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, + {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_origindex}, /* 8: CD_NORMAL */ /* 3 floats per normal vector */ {sizeof(float) * 3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL}, @@ -1313,7 +1318,7 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest, if (lastflag & CD_FLAG_NOCOPY) continue; else if (!(mask & CD_TYPE_AS_MASK(type))) continue; - else if (number < CustomData_number_of_layers(dest, type)) continue; + else if (CustomData_get_layer_named(dest, type, layer->name)) continue; switch (alloctype) { case CD_ASSIGN: @@ -1457,8 +1462,9 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha int i; for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type && strcmp(data->layers[i].name, name) == 0) - return i; + if (data->layers[i].type == type) + if (strcmp(data->layers[i].name, name) == 0) + return i; return -1; } @@ -1947,13 +1953,61 @@ void CustomData_copy_elements(int type, void *source, void *dest, int count) memcpy(dest, source, typeInfo->size * count); } +static void CustomData_copy_data_layer(const CustomData *source, CustomData *dest, + int src_i, int dest_i, + int source_index, int dest_index, int count) { + const LayerTypeInfo *typeInfo; + int src_offset; + int dest_offset; + + char *src_data = source->layers[src_i].data; + char *dest_data = dest->layers[dest_i].data; + + typeInfo = layerType_getInfo(source->layers[src_i].type); + + src_offset = source_index * typeInfo->size; + dest_offset = dest_index * typeInfo->size; + + if (!src_data || !dest_data) { + if (!(src_data == NULL && dest_data == NULL)) { + printf("%s: warning null data for %s type (%p --> %p), skipping\n", + __func__, layerType_getName(source->layers[src_i].type), + (void *)src_data, (void *)dest_data); + } + return; + } + + if (typeInfo->copy) + typeInfo->copy(src_data + src_offset, + dest_data + dest_offset, + count); + else + memcpy(dest_data + dest_offset, + src_data + src_offset, + count * typeInfo->size); +} + +void CustomData_copy_data_named(const CustomData *source, CustomData *dest, + int source_index, int dest_index, int count) +{ + int src_i, dest_i; + + /* copies a layer at a time */ + for (src_i = 0; src_i < source->totlayer; ++src_i) { + + dest_i = CustomData_get_named_layer_index(dest, source->layers[src_i].type, source->layers[src_i].name); + + /* if we found a matching layer, copy the data */ + if (dest_i > -1) { + CustomData_copy_data_layer(source, dest, src_i, dest_i, source_index, dest_index, count); + } + } +} + void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count) { - const LayerTypeInfo *typeInfo; int src_i, dest_i; - int src_offset; - int dest_offset; /* copies a layer at a time */ dest_i = 0; @@ -1971,32 +2025,8 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest, /* if we found a matching layer, copy the data */ if (dest->layers[dest_i].type == source->layers[src_i].type) { - char *src_data = source->layers[src_i].data; - char *dest_data = dest->layers[dest_i].data; - - typeInfo = layerType_getInfo(source->layers[src_i].type); - - src_offset = source_index * typeInfo->size; - dest_offset = dest_index * typeInfo->size; - - if (!src_data || !dest_data) { - if (src_data != NULL && dest_data != NULL) { - printf("%s: warning null data for %s type (%p --> %p), skipping\n", - __func__, layerType_getName(source->layers[src_i].type), - (void *)src_data, (void *)dest_data); - } - continue; - } + CustomData_copy_data_layer(source, dest, src_i, dest_i, source_index, dest_index, count); - if (typeInfo->copy) - typeInfo->copy(src_data + src_offset, - dest_data + dest_offset, - count); - else - memcpy(dest_data + dest_offset, - src_data + src_offset, - count * typeInfo->size); - /* if there are multiple source & dest layers of the same type, * we don't want to copy all source layers to the same dest, so * increment dest_i diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 882085aa5db..a183872552d 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -217,24 +217,35 @@ void defvert_remap(MDeformVert *dvert, int *map, const int map_len) void defvert_normalize_subset(MDeformVert *dvert, const bool *vgroup_subset, const int vgroup_tot) { - MDeformWeight *dw; - unsigned int i; - float tot_weight = 0.0f; - - for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if (dvert->totweight == 0) { + /* nothing */ + } + else if (dvert->totweight == 1) { + MDeformWeight *dw = dvert->dw; if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { - tot_weight += dw->weight; + dw->weight = 1.0f; } } + else { + MDeformWeight *dw; + unsigned int i; + float tot_weight = 0.0f; - if (tot_weight > 0.0f) { - float scalar = 1.0f / tot_weight; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { - dw->weight *= scalar; - - /* in case of division errors with very low weights */ - CLAMP(dw->weight, 0.0f, 1.0f); + tot_weight += dw->weight; + } + } + + if (tot_weight > 0.0f) { + float scalar = 1.0f / tot_weight; + for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + dw->weight *= scalar; + + /* in case of division errors with very low weights */ + CLAMP(dw->weight, 0.0f, 1.0f); + } } } } @@ -242,7 +253,7 @@ void defvert_normalize_subset(MDeformVert *dvert, void defvert_normalize(MDeformVert *dvert) { - if (dvert->totweight <= 0) { + if (dvert->totweight == 0) { /* nothing */ } else if (dvert->totweight == 1) { @@ -269,14 +280,20 @@ void defvert_normalize(MDeformVert *dvert) } } -void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock) +/* Same as defvert_normalize() if the locked vgroup is not a member of the subset */ +void defvert_normalize_lock_single(MDeformVert *dvert, + const bool *vgroup_subset, const int vgroup_tot, + const int def_nr_lock) { - if (dvert->totweight <= 0) { + if (dvert->totweight == 0) { /* nothing */ } else if (dvert->totweight == 1) { - if (def_nr_lock != 0) { - dvert->dw[0].weight = 1.0f; + MDeformWeight *dw = dvert->dw; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if (def_nr_lock != 0) { + dw->weight = 1.0f; + } } } else { @@ -287,13 +304,15 @@ void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock) float lock_iweight = 1.0f; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { - if (dw->def_nr != def_nr_lock) { - tot_weight += dw->weight; - } - else { - dw_lock = dw; - lock_iweight = (1.0f - dw_lock->weight); - CLAMP(lock_iweight, 0.0f, 1.0f); + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if (dw->def_nr != def_nr_lock) { + tot_weight += dw->weight; + } + else { + dw_lock = dw; + lock_iweight = (1.0f - dw_lock->weight); + CLAMP(lock_iweight, 0.0f, 1.0f); + } } } @@ -302,25 +321,33 @@ void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock) float scalar = (1.0f / tot_weight) * lock_iweight; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { - if (dw != dw_lock) { - dw->weight *= scalar; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if (dw != dw_lock) { + dw->weight *= scalar; - /* in case of division errors with very low weights */ - CLAMP(dw->weight, 0.0f, 1.0f); + /* in case of division errors with very low weights */ + CLAMP(dw->weight, 0.0f, 1.0f); + } } } } } } -void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, const int defbase_tot) +/* Same as defvert_normalize() if no locked vgroup is a member of the subset */ +void defvert_normalize_lock_map(MDeformVert *dvert, + const bool *vgroup_subset, const int vgroup_tot, + const bool *lock_flags, const int defbase_tot) { - if (dvert->totweight <= 0) { + if (dvert->totweight == 0) { /* nothing */ } else if (dvert->totweight == 1) { - if (LIKELY(defbase_tot >= 1) && lock_flags[0]) { - dvert->dw[0].weight = 1.0f; + MDeformWeight *dw = dvert->dw; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if (LIKELY(defbase_tot >= 1) && lock_flags[0]) { + dw->weight = 1.0f; + } } } else { @@ -330,12 +357,14 @@ void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, cons float lock_iweight = 0.0f; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { - if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { - tot_weight += dw->weight; - } - else { - /* invert after */ - lock_iweight += dw->weight; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { + tot_weight += dw->weight; + } + else { + /* invert after */ + lock_iweight += dw->weight; + } } } @@ -346,11 +375,13 @@ void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, cons float scalar = (1.0f / tot_weight) * lock_iweight; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { - if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { - dw->weight *= scalar; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { + dw->weight *= scalar; - /* in case of division errors with very low weights */ - CLAMP(dw->weight, 0.0f, 1.0f); + /* in case of division errors with very low weights */ + CLAMP(dw->weight, 0.0f, 1.0f); + } } } } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 13181662bd8..cb7b4a32feb 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2115,6 +2115,8 @@ void DAG_on_visible_update(Main *bmain, const short do_time) if ((oblay & lay) & ~scene->lay_updated) { if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) ob->recalc |= OB_RECALC_DATA; + if (ob->proxy && (ob->proxy_group == NULL)) + ob->proxy->recalc |= OB_RECALC_DATA; if (ob->dup_group) dag_group_on_visible_update(ob->dup_group); } diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 580172bcccd..fe9a96d60cf 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -98,12 +98,13 @@ #endif /* precalculated gaussian factors for 5x super sampling */ -static float gaussianFactors[5] = {0.996849f, - 0.596145f, - 0.596145f, - 0.596145f, - 0.524141f}; -static float gaussianTotal = 3.309425f; +static const float gaussianFactors[5] = { + 0.996849f, + 0.596145f, + 0.596145f, + 0.596145f, + 0.524141f}; +static const float gaussianTotal = 3.309425f; /* UV Image neighboring pixel table x and y list */ static int neighX[8] = {1, 1, 0, -1, -1, -1, 0, 1}; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 791c47cc551..dbdf30ea63d 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -688,21 +688,27 @@ short fcurve_are_keyframes_usable(FCurve *fcu) return 1; } +bool BKE_fcurve_is_protected(FCurve *fcu) +{ + return ((fcu->flag & FCURVE_PROTECTED) || + ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED))); +} + /* Can keyframes be added to F-Curve? * Keyframes can only be added if they are already visible */ -short fcurve_is_keyframable(FCurve *fcu) +bool fcurve_is_keyframable(FCurve *fcu) { /* F-Curve's keyframes must be "usable" (i.e. visible + have an effect on final result) */ if (fcurve_are_keyframes_usable(fcu) == 0) - return 0; + return false; /* F-Curve must currently be editable too */ - if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) - return 0; + if (BKE_fcurve_is_protected(fcu)) + return false; /* F-Curve is keyframable */ - return 1; + return true; } /* ***************************** Keyframe Column Tools ********************************* */ @@ -841,14 +847,7 @@ void calchandles_fcurve(FCurve *fcu) } } -/* Use when F-Curve with handles has changed - * It treats all BezTriples with the following rules: - * - PHASE 1: do types have to be altered? - * -> Auto handles: become aligned when selection status is NOT(000 || 111) - * -> Vector handles: become 'nothing' when (one half selected AND other not) - * - PHASE 2: recalculate handles - */ -void testhandles_fcurve(FCurve *fcu, const short use_handle) +void testhandles_fcurve(FCurve *fcu, const bool use_handle) { BezTriple *bezt; unsigned int a; @@ -856,45 +855,10 @@ void testhandles_fcurve(FCurve *fcu, const short use_handle) /* only beztriples have handles (bpoints don't though) */ if (ELEM(NULL, fcu, fcu->bezt)) return; - + /* loop over beztriples */ for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) { - short flag = 0; - - /* flag is initialized as selection status - * of beztriple control-points (labelled 0, 1, 2) - */ - if (bezt->f2 & SELECT) flag |= (1 << 1); // == 2 - if (use_handle == FALSE) { - if (flag & 2) { - flag |= (1 << 0) | (1 << 2); - } - } - else { - if (bezt->f1 & SELECT) flag |= (1 << 0); // == 1 - if (bezt->f3 & SELECT) flag |= (1 << 2); // == 4 - } - - /* one or two handles selected only */ - if (ELEM(flag, 0, 7) == 0) { - /* auto handles become aligned */ - if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) - bezt->h1 = HD_ALIGN; - if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) - bezt->h2 = HD_ALIGN; - - /* vector handles become 'free' when only one half selected */ - if (bezt->h1 == HD_VECT) { - /* only left half (1 or 2 or 1+2) */ - if (flag < 4) - bezt->h1 = 0; - } - if (bezt->h2 == HD_VECT) { - /* only right half (4 or 2+4) */ - if (flag > 3) - bezt->h2 = 0; - } - } + BKE_nurb_bezt_handle_test(bezt, use_handle); } /* recalculate handles */ diff --git a/source/blender/blenkernel/intern/freestyle.c b/source/blender/blenkernel/intern/freestyle.c index 1f106ff90a7..d87c93310c8 100644 --- a/source/blender/blenkernel/intern/freestyle.c +++ b/source/blender/blenkernel/intern/freestyle.c @@ -107,7 +107,8 @@ void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *con static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset) { new_lineset->linestyle = lineset->linestyle; - new_lineset->linestyle->id.us++; + if (new_lineset->linestyle) + new_lineset->linestyle->id.us++; new_lineset->flags = lineset->flags; new_lineset->selection = lineset->selection; new_lineset->qi = lineset->qi; diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 31dd79e7623..4d17bd286b4 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -42,6 +42,7 @@ #include "BLF_translation.h" #include "DNA_gpencil_types.h" +#include "DNA_userdef_types.h" #include "BKE_global.h" #include "BKE_gpencil.h" @@ -125,8 +126,8 @@ bGPDframe *gpencil_frame_addnew(bGPDlayer *gpl, int cframe) bGPDframe *gpf, *gf; short state = 0; - /* error checking */ - if ((gpl == NULL) || (cframe <= 0)) + /* error checking (neg frame only if they are not allowed in Blender!) */ + if ((gpl == NULL) || ((U.flag & USER_NONEGFRAMES) && (cframe <= 0))) return NULL; /* allocate memory for this frame */ @@ -349,7 +350,8 @@ bGPDframe *gpencil_layer_getframe(bGPDlayer *gpl, int cframe, short addnew) /* error checking */ if (gpl == NULL) return NULL; - if (cframe <= 0) cframe = 1; + /* No reason to forbid negative frames when they are allowed in Blender! */ + if ((U.flag & USER_NONEGFRAMES) && cframe <= 0) cframe = 1; /* check if there is already an active frame */ if (gpl->actframe) { diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 2e32c18b264..6f275e4ec75 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -56,7 +56,13 @@ static char idp_size_table[] = { sizeof(double) }; -/* ------------Property Array Type ----------- */ + +/* -------------------------------------------------------------------- */ +/* Array Functions */ + +/** \name IDP Array API + * \{ */ + #define GETPROP(prop, i) (((IDProperty *)(prop)->data.pointer) + (i)) /* --------- property array type -------------*/ @@ -78,9 +84,12 @@ IDProperty *IDP_NewIDPArray(const char *name) IDProperty *IDP_CopyIDPArray(IDProperty *array) { /* don't use MEM_dupallocN because this may be part of an array */ - IDProperty *narray = MEM_mallocN(sizeof(IDProperty), "IDP_CopyIDPArray"), *tmp; + IDProperty *narray, *tmp; int i; + BLI_assert(array->type == IDP_IDPARRAY); + + narray = MEM_mallocN(sizeof(IDProperty), __func__); *narray = *array; narray->data.pointer = MEM_dupallocN(array->data.pointer); @@ -103,6 +112,8 @@ void IDP_FreeIDPArray(IDProperty *prop) { int i; + BLI_assert(prop->type == IDP_IDPARRAY); + for (i = 0; i < prop->len; i++) IDP_FreeProperty(GETPROP(prop, i)); @@ -113,7 +124,11 @@ void IDP_FreeIDPArray(IDProperty *prop) /*shallow copies item*/ void IDP_SetIndexArray(IDProperty *prop, int index, IDProperty *item) { - IDProperty *old = GETPROP(prop, index); + IDProperty *old; + + BLI_assert(prop->type == IDP_IDPARRAY); + + old = GETPROP(prop, index); if (index >= prop->len || index < 0) return; if (item != old) IDP_FreeProperty(old); @@ -122,11 +137,15 @@ void IDP_SetIndexArray(IDProperty *prop, int index, IDProperty *item) IDProperty *IDP_GetIndexArray(IDProperty *prop, int index) { + BLI_assert(prop->type == IDP_IDPARRAY); + return GETPROP(prop, index); } void IDP_AppendArray(IDProperty *prop, IDProperty *item) { + BLI_assert(prop->type == IDP_IDPARRAY); + IDP_ResizeIDPArray(prop, prop->len + 1); IDP_SetIndexArray(prop, prop->len - 1, item); } @@ -135,6 +154,8 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen) { int newsize; + BLI_assert(prop->type == IDP_IDPARRAY); + /* first check if the array buffer size has room */ /* if newlen is 200 items less then totallen, reallocate anyway */ if (newlen <= prop->totallen) { @@ -286,8 +307,14 @@ static IDProperty *IDP_CopyArray(IDProperty *prop) return newp; } +/** \} */ + -/* ---------- String Type ------------ */ +/* -------------------------------------------------------------------- */ +/* String Functions */ + +/** \name IDProperty String API + * \{ */ /** * @@ -327,9 +354,13 @@ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen) static IDProperty *IDP_CopyString(IDProperty *prop) { - IDProperty *newp = idp_generic_copy(prop); + IDProperty *newp; + + BLI_assert(prop->type == IDP_STRING); + newp = idp_generic_copy(prop); - if (prop->data.pointer) newp->data.pointer = MEM_dupallocN(prop->data.pointer); + if (prop->data.pointer) + newp->data.pointer = MEM_dupallocN(prop->data.pointer); newp->len = prop->len; newp->subtype = prop->subtype; newp->totallen = prop->totallen; @@ -340,8 +371,10 @@ static IDProperty *IDP_CopyString(IDProperty *prop) void IDP_AssignString(IDProperty *prop, const char *st, int maxlen) { - int stlen = strlen(st); + int stlen; + BLI_assert(prop->type == IDP_STRING); + stlen = strlen(st); if (maxlen > 0 && maxlen < stlen) stlen = maxlen; @@ -360,6 +393,8 @@ void IDP_ConcatStringC(IDProperty *prop, const char *st) { int newlen; + BLI_assert(prop->type == IDP_STRING); + newlen = prop->len + strlen(st); /* we have to remember that prop->len includes the null byte for strings. * so there's no need to add +1 to the resize function.*/ @@ -371,6 +406,8 @@ void IDP_ConcatString(IDProperty *str1, IDProperty *append) { int newlen; + BLI_assert(append->type == IDP_STRING); + /* since ->len for strings includes the NULL byte, we have to subtract one or * we'll get an extra null byte after each concatenation operation.*/ newlen = str1->len + append->len - 1; @@ -380,13 +417,19 @@ void IDP_ConcatString(IDProperty *str1, IDProperty *append) void IDP_FreeString(IDProperty *prop) { + BLI_assert(prop->type == IDP_STRING); + if (prop->data.pointer) MEM_freeN(prop->data.pointer); } +/** \} */ -/*-------- ID Type, not in use yet -------*/ +/* -------------------------------------------------------------------- */ +/* ID Type (not in use yet) */ +/** \name IDProperty ID API (unused) + * \{ */ void IDP_LinkID(IDProperty *prop, ID *id) { if (prop->data.pointer) ((ID *)prop->data.pointer)->us--; @@ -398,15 +441,26 @@ void IDP_UnlinkID(IDProperty *prop) { ((ID *)prop->data.pointer)->us--; } +/** \} */ + -/*-------- Group Functions -------*/ +/* -------------------------------------------------------------------- */ +/* Group Functions */ -/*checks if a property with the same name as prop exists, and if so replaces it.*/ +/** \name IDProperty Group API + * \{ */ + +/** + * Checks if a property with the same name as prop exists, and if so replaces it. + */ static IDProperty *IDP_CopyGroup(IDProperty *prop) { - IDProperty *newp = idp_generic_copy(prop), *link; - newp->len = prop->len; + IDProperty *newp, *link; + BLI_assert(prop->type == IDP_GROUP); + newp = idp_generic_copy(prop); + newp->len = prop->len; + for (link = prop->data.group.first; link; link = link->next) { BLI_addtail(&newp->data.group, IDP_CopyProperty(link)); } @@ -419,6 +473,10 @@ static IDProperty *IDP_CopyGroup(IDProperty *prop) void IDP_SyncGroupValues(IDProperty *dest, IDProperty *src) { IDProperty *other, *prop; + + BLI_assert(dest->type == IDP_GROUP); + BLI_assert(src->type == IDP_GROUP); + for (prop = src->data.group.first; prop; prop = prop->next) { other = BLI_findstring(&dest->data.group, prop->name, offsetof(IDProperty, name)); if (other && prop->type == other->type) { @@ -454,6 +512,10 @@ void IDP_SyncGroupValues(IDProperty *dest, IDProperty *src) void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src) { IDProperty *loop, *prop; + + BLI_assert(dest->type == IDP_GROUP); + BLI_assert(src->type == IDP_GROUP); + for (prop = src->data.group.first; prop; prop = prop->next) { for (loop = dest->data.group.first; loop; loop = loop->next) { if (STREQ(loop->name, prop->name)) { @@ -484,6 +546,9 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src) void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) { IDProperty *loop; + + BLI_assert(group->type == IDP_GROUP); + if ((loop = IDP_GetPropertyFromGroup(group, prop->name))) { BLI_insertlinkafter(&group->data.group, loop, prop); @@ -497,13 +562,16 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) } } -/* +/** * If a property is missing in \a dest, add it. */ void IDP_MergeGroup(IDProperty *dest, IDProperty *src, const int do_overwrite) { IDProperty *prop; + BLI_assert(dest->type == IDP_GROUP); + BLI_assert(src->type == IDP_GROUP); + if (do_overwrite) { for (prop = src->data.group.first; prop; prop = prop->next) { IDProperty *copy = IDP_CopyProperty(prop); @@ -538,6 +606,8 @@ void IDP_MergeGroup(IDProperty *dest, IDProperty *src, const int do_overwrite) */ int IDP_AddToGroup(IDProperty *group, IDProperty *prop) { + BLI_assert(group->type == IDP_GROUP); + if (IDP_GetPropertyFromGroup(group, prop->name) == NULL) { group->len++; BLI_addtail(&group->data.group, prop); @@ -553,6 +623,8 @@ int IDP_AddToGroup(IDProperty *group, IDProperty *prop) */ int IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew) { + BLI_assert(group->type == IDP_GROUP); + if (IDP_GetPropertyFromGroup(group, pnew->name) == NULL) { group->len++; BLI_insertlinkafter(&group->data.group, previous, pnew); @@ -571,12 +643,16 @@ int IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew) */ void IDP_RemFromGroup(IDProperty *group, IDProperty *prop) { + BLI_assert(group->type == IDP_GROUP); + group->len--; BLI_remlink(&group->data.group, prop); } IDProperty *IDP_GetPropertyFromGroup(IDProperty *prop, const char *name) { + BLI_assert(prop->type == IDP_GROUP); + return (IDProperty *)BLI_findstring(&prop->data.group, name, offsetof(IDProperty, name)); } /** same as above but ensure type match */ @@ -599,7 +675,10 @@ typedef struct IDPIter { */ void *IDP_GetGroupIterator(IDProperty *prop) { - IDPIter *iter = MEM_callocN(sizeof(IDPIter), "IDPIter"); + IDPIter *iter; + + BLI_assert(prop->type == IDP_GROUP); + iter = MEM_mallocN(sizeof(IDPIter), "IDPIter"); iter->next = prop->data.group.first; iter->parent = prop; return (void *) iter; @@ -640,14 +719,21 @@ void IDP_FreeIterBeforeEnd(void *vself) static void IDP_FreeGroup(IDProperty *prop) { IDProperty *loop; + + BLI_assert(prop->type == IDP_GROUP); for (loop = prop->data.group.first; loop; loop = loop->next) { IDP_FreeProperty(loop); } BLI_freelistN(&prop->data.group); } +/** \} */ -/*-------- Main Functions --------*/ +/* -------------------------------------------------------------------- */ +/* Main Functions */ + +/** \name IDProperty Main API + * \{ */ IDProperty *IDP_CopyProperty(IDProperty *prop) { switch (prop->type) { @@ -909,3 +995,5 @@ void IDP_UnlinkProperty(IDProperty *prop) break; } } + +/** \} */ diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 2bf6304b04b..01b41eb22cd 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1250,6 +1250,12 @@ static int do_add_image_extension(char *string, const char imtype, const ImageFo } } #endif +#ifdef WITH_OPENIMAGEIO + else if (imtype == R_IMF_IMTYPE_PSD) { + if (!BLI_testextensie(string, ".psd")) + extension = ".psd"; + } +#endif #ifdef WITH_OPENEXR else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) { if (!BLI_testextensie(string, ".exr")) diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index c23fa097d3e..9b8d34e651d 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -269,7 +269,8 @@ bool id_make_local(ID *id, bool test) if (!test) BKE_action_make_local((bAction *)id); return true; case ID_NT: - return false; /* not implemented */ + if (!test) ntreeMakeLocal((bNodeTree *)id); + return true; case ID_BR: if (!test) BKE_brush_make_local((Brush *)id); return true; @@ -1410,7 +1411,7 @@ bool new_id(ListBase *lb, ID *id, const char *tname) /* This was in 2.43 and previous releases * however all data in blender should be sorted, not just duplicate names - * sorting should not hurt, but noting just incause it alters the way other + * sorting should not hurt, but noting just incase it alters the way other * functions work, so sort every time */ #if 0 if (result) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 874e60936d1..a43bf41058c 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -409,7 +409,7 @@ static void layer_bucket_init_dummy(MaskRasterLayer *layer) static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) { - MemArena *arena = BLI_memarena_new(1 << 16, __func__); + MemArena *arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), __func__); const float bucket_dim_x = BLI_rctf_size_x(&layer->bounds); const float bucket_dim_y = BLI_rctf_size_y(&layer->bounds); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 63a7b8cd982..a77f768835a 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -40,6 +40,8 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_edgehash.h" +#include "BLI_string_utf8.h" +#include "BLI_string.h" #include "BKE_animsys.h" #include "BKE_main.h" @@ -528,8 +530,9 @@ Mesh *BKE_mesh_copy(Mesh *me) BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob) { BMesh *bm; + const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me); - bm = BM_mesh_create(&bm_mesh_allocsize_default); + bm = BM_mesh_create(&allocsize); BM_mesh_bm_from_me(bm, me, false, true, ob->shapenr); @@ -622,6 +625,113 @@ void BKE_mesh_make_local(Mesh *me) } } +bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int loop_index, const int face_index, + const char *new_name, const bool do_tessface) +{ + CustomData *pdata, *ldata, *fdata; + CustomDataLayer *cdlp, *cdlu, *cdlf; + const int step = do_tessface ? 3 : 2; + int i; + + if (me->edit_btmesh) { + pdata = &me->edit_btmesh->bm->pdata; + ldata = &me->edit_btmesh->bm->ldata; + fdata = NULL; /* No tessellated data in BMesh! */ + } + else { + pdata = &me->pdata; + ldata = &me->ldata; + fdata = &me->fdata; + } + cdlp = &pdata->layers[poly_index]; + cdlu = &ldata->layers[loop_index]; + cdlf = fdata && do_tessface ? &fdata->layers[face_index] : NULL; + + BLI_strncpy(cdlp->name, new_name, sizeof(cdlp->name)); + CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers); + + /* Loop until we do have exactly the same name for all layers! */ + for (i = 1; (strcmp(cdlp->name, cdlu->name) != 0 || (cdlf && strcmp(cdlp->name, cdlf->name) != 0)); i++) { + switch (i % step) { + case 0: + BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name)); + CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers); + break; + case 1: + BLI_strncpy(cdlu->name, cdlp->name, sizeof(cdlu->name)); + CustomData_set_layer_unique_name(ldata, cdlu - ldata->layers); + break; + case 2: + if (cdlf) { + BLI_strncpy(cdlf->name, cdlp->name, sizeof(cdlf->name)); + CustomData_set_layer_unique_name(fdata, cdlf - fdata->layers); + } + break; + } + } + + return true; +} + +bool BKE_mesh_uv_cdlayer_rename(Mesh *me, const char *old_name, const char *new_name, bool do_tessface) +{ + CustomData *pdata, *ldata, *fdata; + if (me->edit_btmesh) { + pdata = &me->edit_btmesh->bm->pdata; + ldata = &me->edit_btmesh->bm->ldata; + /* No tessellated data in BMesh! */ + fdata = NULL; + do_tessface = false; + } + else { + pdata = &me->pdata; + ldata = &me->ldata; + fdata = &me->fdata; + do_tessface = (do_tessface && fdata->totlayer); + } + + { + const int pidx_start = CustomData_get_layer_index(pdata, CD_MTEXPOLY); + const int lidx_start = CustomData_get_layer_index(ldata, CD_MLOOPUV); + const int fidx_start = do_tessface ? CustomData_get_layer_index(fdata, CD_MTFACE) : -1; + int pidx = CustomData_get_named_layer(pdata, CD_MTEXPOLY, old_name); + int lidx = CustomData_get_named_layer(ldata, CD_MLOOPUV, old_name); + int fidx = do_tessface ? CustomData_get_named_layer(fdata, CD_MTFACE, old_name) : -1; + + /* None of those cases should happen, in theory! + * Note this assume we have the same number of mtexpoly, mloopuv and mtface layers! + */ + if (pidx == -1) { + if (lidx == -1) { + if (fidx == -1) { + /* No layer found with this name! */ + return false; + } + else { + lidx = lidx_start + (fidx - fidx_start); + } + } + pidx = pidx_start + (lidx - lidx_start); + } + else { + if (lidx == -1) { + lidx = lidx_start + (pidx - pidx_start); + } + if (fidx == -1 && do_tessface) { + fidx = fidx_start + (pidx - pidx_start); + } + } +#if 0 + /* For now, we do not consider mismatch in indices (i.e. same name leading to (relative) different indices). */ + else if ((pidx - pidx_start) != (lidx - lidx_start)) { + lidx = lidx_start + (pidx - pidx_start); + } +#endif + + return BKE_mesh_uv_cdlayer_rename_index(me, pidx, lidx, fidx, new_name, do_tessface); + } +} + void BKE_mesh_boundbox_calc(Mesh *me, float r_loc[3], float r_size[3]) { BoundBox *bb; diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 07dfae2f28a..47b8e053bf7 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -318,9 +318,9 @@ void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces, * Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals'). * Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry (splitting edges). */ -void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *medges, int numEdges, - MLoop *mloops, float (*r_loopnors)[3], int numLoops, - MPoly *mpolys, float (*polynors)[3], int numPolys, float split_angle) +void BKE_mesh_normals_loop_split(MVert *mverts, const int UNUSED(numVerts), MEdge *medges, const int numEdges, + MLoop *mloops, float (*r_loopnors)[3], const int numLoops, + MPoly *mpolys, float (*polynors)[3], const int numPolys, float split_angle) { #define INDEX_UNSET INT_MIN #define INDEX_INVALID -1 @@ -333,7 +333,7 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med * sharp edge: < 0 (INDEX_INVALID || INDEX_UNSET), * unset: INDEX_UNSET * Note that currently we only have two values for second loop of sharp edges. However, if needed, we can - * store the negated value of loop index instead of INDEX_INVALID to retrieve th real value later in code). + * store the negated value of loop index instead of INDEX_INVALID to retrieve the real value later in code). * Note also that lose edges always have both values set to 0! */ int (*edge_to_loops)[2] = MEM_callocN(sizeof(int[2]) * (size_t)numEdges, __func__); @@ -377,7 +377,7 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med /* Check whether current edge might be smooth or sharp */ if ((e2l[0] | e2l[1]) == 0) { - /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INT_MIN to tag it as unset). */ + /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */ e2l[0] = ml_curr_index; e2l[1] = INDEX_UNSET; } @@ -397,7 +397,7 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med } } else if (!IS_EDGE_SHARP(e2l)) { - /* More that two loops using this edge, tag as sharp if not yet done. */ + /* More than two loops using this edge, tag as sharp if not yet done. */ e2l[1] = INDEX_INVALID; } /* Else, edge is already 'disqualified' (i.e. sharp)! */ @@ -448,6 +448,7 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med * it should not be a common case in real-life meshes anyway). */ const unsigned int mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */ + const MVert *mv_pivot = &mverts[mv_pivot_index]; const int *e2lfan_curr; float vec_curr[3], vec_prev[3]; MLoop *mlfan_curr, *mlfan_next; @@ -464,11 +465,10 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med /* Only need to compute previous edge's vector once, then we can just reuse old current one! */ { - const MEdge *me_prev = &medges[ml_prev->e]; - const MVert *mv_1 = &mverts[mv_pivot_index]; + const MEdge *me_prev = &medges[ml_curr->e]; /* ml_curr would be mlfan_prev if we needed that one */ const MVert *mv_2 = (me_prev->v1 == mv_pivot_index) ? &mverts[me_prev->v2] : &mverts[me_prev->v1]; - sub_v3_v3v3(vec_prev, mv_2->co, mv_1->co); + sub_v3_v3v3(vec_prev, mv_2->co, mv_pivot->co); normalize_v3(vec_prev); } @@ -479,12 +479,11 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med * given the fact that this code should not be called that much in real-life meshes... */ { - const MEdge *me_curr = &medges[ml_curr->e]; - const MVert *mv_1 = &mverts[mv_pivot_index]; + const MEdge *me_curr = &medges[mlfan_curr->e]; const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &mverts[me_curr->v2] : &mverts[me_curr->v1]; - sub_v3_v3v3(vec_curr, mv_2->co, mv_1->co); + sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co); normalize_v3(vec_curr); } diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 557d201e7fd..1c9576d74d0 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -989,28 +989,40 @@ void BKE_mesh_cd_validate(Mesh *me) { int totlayer_mtex = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); int totlayer_uv = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + int mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY); + int uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV); + int i; if (LIKELY(totlayer_mtex == totlayer_uv)) { /* pass */ } else if (totlayer_mtex < totlayer_uv) { - const int uv_index_first = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV); do { - const char *from_name = me->ldata.layers[uv_index_first + totlayer_mtex].name; + const char *from_name = me->ldata.layers[uv_index + totlayer_mtex].name; CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, from_name); CustomData_set_layer_unique_name(&me->pdata, totlayer_mtex); } while (totlayer_uv != ++totlayer_mtex); + mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY); } else if (totlayer_uv < totlayer_mtex) { - const int mtex_index_first = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY); do { - const char *from_name = me->pdata.layers[mtex_index_first + totlayer_uv].name; + const char *from_name = me->pdata.layers[mtex_index + totlayer_uv].name; CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, from_name); CustomData_set_layer_unique_name(&me->ldata, totlayer_uv); } while (totlayer_mtex != ++totlayer_uv); + uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV); } BLI_assert(totlayer_mtex == totlayer_uv); + + /* Check uv/tex names match as well!!! */ + for (i = 0; i < totlayer_mtex; i++, mtex_index++, uv_index++) { + const char *name_src = me->pdata.layers[mtex_index].name; + const char *name_dst = me->ldata.layers[uv_index].name; + if (!STREQ(name_src, name_dst)) { + BKE_mesh_uv_cdlayer_rename_index(me, mtex_index, uv_index, -1, name_src, false); + } + } } /** \} */ diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 780bd9733f5..4871b9bf3bf 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -593,21 +593,21 @@ bool modifiers_usesArmature(Object *ob, bArmature *arm) bool modifier_isCorrectableDeformed(ModifierData *md) { - if (md->type == eModifierType_Armature) - return true; - if (md->type == eModifierType_ShapeKey) - return true; - - return false; + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + return (mti->deformMatricesEM != NULL); } -bool modifiers_isCorrectableDeformed(Object *ob) +bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); + int required_mode = eModifierMode_Realtime; + + if (ob->mode == OB_MODE_EDIT) + required_mode |= eModifierMode_Editmode; for (; md; md = md->next) { - if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) { + if (!modifier_isEnabled(scene, md, required_mode)) { /* pass */ } else if (modifier_isCorrectableDeformed(md)) { diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index d1797810c86..a9ff569e70a 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -232,8 +232,9 @@ BMEditMesh *DM_to_editbmesh(DerivedMesh *dm, BMEditMesh *existing, const bool do BMesh *DM_to_bmesh(DerivedMesh *dm, const bool calc_face_normal) { BMesh *bm; + const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_DM(dm); - bm = BM_mesh_create(&bm_mesh_allocsize_default); + bm = BM_mesh_create(&allocsize); DM_to_bmesh_ex(dm, bm, calc_face_normal); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index bf4a63c52a8..d9630a7343d 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -62,7 +62,6 @@ #include "BLI_blenlib.h" #include "BLI_ghash.h" #include "BLI_math.h" -#include "BLI_mempool.h" #include "BLI_threads.h" #include "BKE_animsys.h" diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 4519a116946..0cdcf4e7298 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -114,8 +114,8 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden, BLI_bitmap *prev_hidden) { BLI_bitmap *subd; - int hi_gridsize = ccg_gridsize(hi_level); - int lo_gridsize = ccg_gridsize(lo_level); + int hi_gridsize = BKE_ccg_gridsize(hi_level); + int lo_gridsize = BKE_ccg_gridsize(lo_level); int yh, xh, xl, yl, xo, yo, hi_ndx; int offset, factor; @@ -127,7 +127,7 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden, subd = BLI_BITMAP_NEW(hi_gridsize * hi_gridsize, "MDisps.hidden upsample"); - factor = ccg_factor(lo_level, hi_level); + factor = BKE_ccg_factor(lo_level, hi_level); offset = 1 << (hi_level - lo_level - 1); /* low-res blocks */ @@ -173,12 +173,12 @@ static BLI_bitmap *multires_mdisps_downsample_hidden(BLI_bitmap *old_hidden, int new_level) { BLI_bitmap *new_hidden; - int new_gridsize = ccg_gridsize(new_level); - int old_gridsize = ccg_gridsize(old_level); + int new_gridsize = BKE_ccg_gridsize(new_level); + int old_gridsize = BKE_ccg_gridsize(old_level); int x, y, factor, old_value; BLI_assert(new_level <= old_level); - factor = ccg_factor(new_level, old_level); + factor = BKE_ccg_factor(new_level, old_level); new_hidden = BLI_BITMAP_NEW(new_gridsize * new_gridsize, "downsample hidden"); @@ -246,7 +246,7 @@ static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level) { MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop); - int gridsize = ccg_gridsize(level); + int gridsize = BKE_ccg_gridsize(level); int gridarea = gridsize * gridsize; int i, j, k; @@ -594,7 +594,7 @@ static void multires_copy_dm_grid(CCGElem *gridA, CCGElem *gridB, CCGKey *keyA, static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level) { if (level < gpm->level) { - int gridsize = ccg_gridsize(level); + int gridsize = BKE_ccg_gridsize(level); float *data = MEM_callocN(sizeof(float) * gridsize * gridsize, "multires_grid_paint_mask_downsample"); int x, y; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 2305c0696af..c0df306a3fa 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1107,7 +1107,7 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname) * 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_id_user, const short do_make_extern, const short copy_previews) +static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_id_user, bool do_make_extern, bool copy_previews) { bNodeTree *newtree; bNode *node /*, *nnode */ /* UNUSED */, *last; @@ -1116,13 +1116,17 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_use if (ntree == NULL) return NULL; - /* is ntree part of library? */ - for (newtree = G.main->nodetree.first; newtree; newtree = newtree->id.next) - if (newtree == ntree) break; - if (newtree) { - newtree = BKE_libblock_copy(&ntree->id); + if (bmain) { + /* is ntree part of library? */ + if (BLI_findindex(&bmain->nodetree, ntree) != -1) + newtree = BKE_libblock_copy(&ntree->id); + else + newtree = NULL; } - else { + else + newtree = NULL; + + if (newtree == NULL) { newtree = MEM_dupallocN(ntree); newtree->id.lib = NULL; /* same as owning datablock id.lib */ BKE_libblock_copy_data(&newtree->id, &ntree->id, true); /* copy animdata and ID props */ @@ -1208,7 +1212,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_use bNodeTree *ntreeCopyTree_ex(bNodeTree *ntree, const short do_id_user) { - return ntreeCopyTree_internal(ntree, do_id_user, TRUE, TRUE); + return ntreeCopyTree_internal(ntree, G.main, do_id_user, TRUE, TRUE); } bNodeTree *ntreeCopyTree(bNodeTree *ntree) { @@ -1590,6 +1594,8 @@ static void node_unlink_attached(bNodeTree *ntree, bNode *parent) void nodeFreeNode(bNodeTree *ntree, bNode *node) { bNodeSocket *sock, *nextsock; + char propname_esc[MAX_IDPROP_NAME * 2]; + char prefix[MAX_IDPROP_NAME * 2]; /* extra free callback */ if (node->typeinfo && node->typeinfo->freefunc_api) { @@ -1609,6 +1615,11 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node) BLI_remlink(&ntree->nodes, node); + BLI_strescape(propname_esc, node->name, sizeof(propname_esc)); + BLI_snprintf(prefix, sizeof(prefix), "nodes[\"%s\"]", propname_esc); + + BKE_animdata_fix_paths_remove((ID *)ntree, prefix); + if (ntree->typeinfo && ntree->typeinfo->free_node_cache) ntree->typeinfo->free_node_cache(ntree, node); @@ -1657,6 +1668,22 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *so MEM_freeN(sock->default_value); } +static void free_localized_node_groups(bNodeTree *ntree) +{ + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == NODE_GROUP && node->id) { + bNodeTree *ngroup = (bNodeTree *)node->id; + if (BLI_findindex(&G.main->nodetree, ngroup) == -1) { + /* ntree is not in library, i.e. localized node group: free it */ + ntreeFreeTree_ex(ngroup, false); + MEM_freeN(ngroup); + } + } + } +} + /* do not free ntree itself here, BKE_libblock_free calls this function too */ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user) { @@ -1683,6 +1710,9 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user) } } + /* XXX not nice, but needed to free localized node groups properly */ + free_localized_node_groups(ntree); + /* unregister associated RNA types */ ntreeInterfaceTypeFree(ntree); @@ -1932,8 +1962,14 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree) /* Make full copy. * Note: previews are not copied here. */ - ltree = ntreeCopyTree_internal(ntree, FALSE, FALSE, FALSE); - + ltree = ntreeCopyTree_internal(ntree, NULL, FALSE, FALSE, FALSE); + + for (node = ltree->nodes.first; node; node = node->next) { + if (node->type == NODE_GROUP && node->id) { + node->id = (ID *)ntreeLocalize((bNodeTree *)node->id); + } + } + if (adt) { AnimData *ladt = BKE_animdata_from_id(<ree->id); @@ -1978,7 +2014,7 @@ void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree) /* we have to assume the editor already changed completely */ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree) { - if (localtree && ntree) { + if (ntree && localtree) { if (ntree->typeinfo->local_merge) ntree->typeinfo->local_merge(localtree, ntree); @@ -2285,7 +2321,7 @@ bNode *nodeGetActive(bNodeTree *ntree) static bNode *node_get_active_id_recursive(bNodeInstanceKey active_key, bNodeInstanceKey parent_key, bNodeTree *ntree, short idtype) { - if (parent_key.value == active_key.value) { + if (parent_key.value == active_key.value || active_key.value == 0) { bNode *node; for (node = ntree->nodes.first; node; node = node->next) if (node->id && GS(node->id->name) == idtype) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 26890380f53..2b95b2346f6 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -652,7 +652,9 @@ void BKE_object_unlink(Object *ob) for (lineset = (FreestyleLineSet *)srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { - BKE_unlink_linestyle_target_object(lineset->linestyle, ob); + if (lineset->linestyle) { + BKE_unlink_linestyle_target_object(lineset->linestyle, ob); + } } } } @@ -2990,21 +2992,20 @@ void BKE_object_handle_update_ex(Scene *scene, Object *ob, /* quick cache removed */ } - /* the no-group proxy case, we call update */ - if (ob->proxy && ob->proxy_group == NULL) { - /* set pointer in library proxy target, for copying, but restore it */ - ob->proxy->proxy_from = ob; - // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name); - BKE_object_handle_update(scene, ob->proxy); - } - ob->recalc &= ~OB_RECALC_ALL; } /* the case when this is a group proxy, object_update is called in group.c */ if (ob->proxy) { + /* set pointer in library proxy target, for copying, but restore it */ ob->proxy->proxy_from = ob; // printf("set proxy pointer for later group stuff %s\n", ob->id.name); + + /* the no-group proxy case, we call update */ + if (ob->proxy_group == NULL) { + // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name); + BKE_object_handle_update(scene, ob->proxy); + } } } /* WARNING: "scene" here may not be the scene object actually resides in. diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index b47a493581e..6bdfb22dc1a 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -359,8 +359,8 @@ int paint_is_bmesh_face_hidden(BMFace *f) float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level, unsigned x, unsigned y) { - int factor = ccg_factor(level, gpm->level); - int gridsize = ccg_gridsize(gpm->level); + int factor = BKE_ccg_factor(level, gpm->level); + int gridsize = BKE_ccg_gridsize(gpm->level); return gpm->data[(y * factor) * gridsize + (x * factor)]; } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 216bc94a058..24cf98d957d 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1729,7 +1729,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ return 0; if (dm->deformedOnly || index_dmcache == DMCACHE_ISCHILD) { - /* for meshes that are either only defined or for child particles, the + /* for meshes that are either only deformed or for child particles, the * index and fw do not require any mapping, so we can directly use it */ if (from == PART_FROM_VERT) { if (index >= dm->getNumVerts(dm)) @@ -1817,8 +1817,8 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache copy_v3_v3(orco, orcodata[mapindex]); if (ornor) { - dm->getVertNo(dm, mapindex, nor); - normalize_v3(nor); + dm->getVertNo(dm, mapindex, ornor); + normalize_v3(ornor); } if (utan && vtan) { @@ -1843,7 +1843,7 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache if (nor) copy_v3_v3(nor, tmpnor); - normalize_v3(tmpnor); + normalize_v3(tmpnor); /* XXX Why not normalize tmpnor before copying it into nor??? -- mont29 */ mul_v3_fl(tmpnor, -foffset); add_v3_v3(vec, tmpnor); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index db22e030821..526d54a97fa 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3313,9 +3313,14 @@ static float collision_newton_rhapson(ParticleCollision *col, float radius, Part pce->inv_nor = -1; - /* Initial step size should be small, but not too small or floating point - * precision errors will appear. - z0r */ - dt_init = COLLISION_INIT_STEP * col->inv_total_time; + if (col->inv_total_time > 0.0f) { + /* Initial step size should be small, but not too small or floating point + * precision errors will appear. - z0r */ + dt_init = COLLISION_INIT_STEP * col->inv_total_time; + } + else { + dt_init = 0.001f; + } /* start from the beginning */ t0 = 0.f; diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index c83d760797b..deb77d14988 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -438,10 +438,6 @@ static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f) if (new_node) { pbvh_bmesh_vert_ownership_transfer(bvh, new_node, v); } - else { - BLI_gset_remove(f_node->bm_unique_verts, v, NULL); - BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL); - } } else { /* Remove from other verts */ @@ -516,10 +512,10 @@ static int edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f) return ((len_squared_v3v3(q->center, c) <= q->radius_squared)); } -/* Return true if the vertex mask is less than 0.5, false otherwise */ -static bool check_mask_half(EdgeQueueContext *eq_ctx, BMVert *v) +/* Return true if the vertex mask is less than 1.0, false otherwise */ +static bool check_mask(EdgeQueueContext *eq_ctx, BMVert *v) { - return (BM_ELEM_CD_GET_FLOAT(v, eq_ctx->cd_vert_mask_offset) < 0.5f); + return (BM_ELEM_CD_GET_FLOAT(v, eq_ctx->cd_vert_mask_offset) < 1.0f); } static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e, @@ -527,11 +523,13 @@ static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e, { BMVert **pair; - /* Don't let topology update affect masked vertices. Unlike with - * displacements, can't do 50% topology update, so instead set - * (arbitrary) cutoff: if both vertices' masks are less than 50%, - * topology update can happen. */ - if (check_mask_half(eq_ctx, e->v1) && check_mask_half(eq_ctx, e->v2)) { + /* Don't let topology update affect fully masked vertices. This used to + * have a 50% mask cutoff, with the reasoning that you can't do a 50% + * topology update. But this gives an ugly border in the mesh. The mask + * should already make the brush move the vertices only 50%, which means + * that topology updates will also happen less frequent, that should be + * enough. */ + if (check_mask(eq_ctx, e->v1) || check_mask(eq_ctx, e->v2)) { pair = BLI_mempool_alloc(eq_ctx->pool); pair[0] = e->v1; pair[1] = e->v2; @@ -678,6 +676,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh, BMVert *v_new; float mid[3]; int i, node_index; + const int cd_vert_mask_offset = CustomData_get_offset(&bvh->bm->vdata, CD_PAINT_MASK); /* Get all faces adjacent to the edge */ pbvh_bmesh_edge_loops(edge_loops, e); @@ -689,6 +688,15 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh, e->v1)); v_new = pbvh_bmesh_vert_create(bvh, node_index, mid, e->v1); + /* update paint mask */ + if (cd_vert_mask_offset != -1) { + float mask_v1 = BM_ELEM_CD_GET_FLOAT(e->v1, cd_vert_mask_offset); + float mask_v2 = BM_ELEM_CD_GET_FLOAT(e->v2, cd_vert_mask_offset); + float mask_v_new = 0.5f * (mask_v1 + mask_v2); + + BM_ELEM_CD_SET_FLOAT(v_new, cd_vert_mask_offset, mask_v_new); + } + /* For each face, add two new triangles and delete the original */ for (i = 0; i < edge_loops->count; i++) { BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i); diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index f3276992381..42147be33e4 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1166,7 +1166,7 @@ static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw) if (ob) { RigidBodyOb *rbo = ob->rigidbody_object; /* reset kinematic state for transformed objects */ - if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) { + if (rbo && (ob->flag & SELECT) && (G.moving & G_TRANSFORM_OBJ)) { RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED); RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo)); /* deactivate passive objects so they don't interfere with deactivation of active objects */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b89cb6b7b82..41e43c00457 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -493,23 +493,10 @@ Scene *BKE_scene_add(Main *bmain, const char *name) sce->r.border.ymax = 1.0f; sce->toolsettings = MEM_callocN(sizeof(struct ToolSettings), "Tool Settings Struct"); - sce->toolsettings->cornertype = 1; - sce->toolsettings->degr = 90; - sce->toolsettings->step = 9; - sce->toolsettings->turn = 1; - sce->toolsettings->extr_offs = 1; sce->toolsettings->doublimit = 0.001; - sce->toolsettings->segments = 32; - sce->toolsettings->rings = 32; - sce->toolsettings->vertices = 32; - sce->toolsettings->uvcalc_radius = 1.0f; - sce->toolsettings->uvcalc_cubesize = 1.0f; - sce->toolsettings->uvcalc_mapdir = 1; - sce->toolsettings->uvcalc_mapalign = 1; sce->toolsettings->uvcalc_margin = 0.001f; sce->toolsettings->unwrapper = 1; sce->toolsettings->select_thresh = 0.01f; - sce->toolsettings->jointrilimit = 0.8f; sce->toolsettings->selectmode = SCE_SELECT_VERTEX; sce->toolsettings->uv_selectmode = UV_SELECT_VERTEX; diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index efcbcacf974..c41c66ef561 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -112,7 +112,7 @@ ARegionType *BKE_regiontype_from_id(SpaceType *st, int regionid) if (art->regionid == regionid) return art; - printf("Error, region type missing in - name:\"%s\", id:%d\n", st->name, st->spaceid); + printf("Error, region type %d missing in - name:\"%s\", id:%d\n", regionid, st->name, st->spaceid); return st->regiontypes.first; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 43845638754..dd7e847feaf 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -632,7 +632,7 @@ static void seq_update_sound_bounds_recursive_rec(Scene *scene, Sequence *metase endofs = seq->start + seq->len - end; sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, - seq->start + seq->len - endofs, startofs); + seq->start + seq->len - endofs, startofs + seq->anim_startofs); } } } @@ -664,8 +664,9 @@ void BKE_sequence_calc_disp(Scene *scene, Sequence *seq) if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) { BKE_sequencer_update_sound_bounds(scene, seq); } - else if (seq->type == SEQ_TYPE_META) + else if (seq->type == SEQ_TYPE_META) { seq_update_sound_bounds_recursive(scene, seq); + } } void BKE_sequence_calc(Scene *scene, Sequence *seq) diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 9bc7f4b9e2b..5c9c564998e 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -506,7 +506,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM DerivedMesh *ss_mesh = NULL; ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData; - /* remove loop dependencies on derived meshs (TODO should this be done elsewhere?) */ + /* remove loop dependencies on derived meshes (TODO should this be done elsewhere?) */ if (smd->target == ob) smd->target = NULL; if (smd->auxTarget == ob) smd->auxTarget = NULL; diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 189c1e967dd..fb0e22abf2a 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -2386,6 +2386,7 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, if (effectors) { float *density = smoke_get_density(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); float *force_x = smoke_get_force_x(sds->fluid); float *force_y = smoke_get_force_y(sds->fluid); float *force_z = smoke_get_force_z(sds->fluid); @@ -2408,7 +2409,7 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float voxelCenter[3] = {0, 0, 0}, vel[3] = {0, 0, 0}, retvel[3] = {0, 0, 0}; unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); - if ((density[index] < FLT_EPSILON) || obstacle[index]) + if (((fuel ? MAX2(density[index], fuel[index]) : density[index]) < FLT_EPSILON) || obstacle[index]) continue; vel[0] = velocity_x[index]; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 2461ec85bb4..9a38a5f87b8 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -170,7 +170,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, if (useArena) { CCGAllocatorIFC allocatorIFC; - CCGAllocatorHDL allocator = BLI_memarena_new((1 << 16), "subsurf arena"); + CCGAllocatorHDL allocator = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "subsurf arena"); allocatorIFC.alloc = arena_alloc; allocatorIFC.realloc = arena_realloc; @@ -1064,8 +1064,8 @@ void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly, for (j = 0; j < mpoly[i].totloop; j++) { const MDisps *md = &mdisps[mpoly[i].loopstart + j]; - int hidden_gridsize = ccg_gridsize(md->level); - int factor = ccg_factor(level, md->level); + int hidden_gridsize = BKE_ccg_gridsize(md->level); + int factor = BKE_ccg_factor(level, md->level); if (!md->hidden) continue; @@ -1107,8 +1107,8 @@ void subsurf_copy_grid_paint_mask(DerivedMesh *dm, const MPoly *mpoly, if (!gpm->data) continue; - factor = ccg_factor(level, gpm->level); - gpm_gridsize = ccg_gridsize(gpm->level); + factor = BKE_ccg_factor(level, gpm->level); + gpm_gridsize = BKE_ccg_gridsize(gpm->level); for (y = 0; y < gridSize; y++) { for (x = 0; x < gridSize; x++) { diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index e2b7358525a..22b0fe7bc24 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -71,16 +71,16 @@ /* ****************** Mapping ******************* */ -TexMapping *add_tex_mapping(void) +TexMapping *add_tex_mapping(int type) { TexMapping *texmap = MEM_callocN(sizeof(TexMapping), "TexMapping"); - default_tex_mapping(texmap); + default_tex_mapping(texmap, type); return texmap; } -void default_tex_mapping(TexMapping *texmap) +void default_tex_mapping(TexMapping *texmap, int type) { memset(texmap, 0, sizeof(TexMapping)); @@ -92,11 +92,12 @@ void default_tex_mapping(TexMapping *texmap) texmap->projy = PROJ_Y; texmap->projz = PROJ_Z; texmap->mapping = MTEX_FLAT; + texmap->type = type; } void init_tex_mapping(TexMapping *texmap) { - float smat[3][3], rmat[3][3], mat[3][3], proj[3][3]; + float smat[4][4], rmat[4][4], tmat[4][4], proj[4][4], size[3]; if (texmap->projx == PROJ_X && texmap->projy == PROJ_Y && texmap->projz == PROJ_Z && is_zero_v3(texmap->loc) && is_zero_v3(texmap->rot) && is_one_v3(texmap->size)) @@ -107,7 +108,8 @@ void init_tex_mapping(TexMapping *texmap) } else { /* axis projection */ - zero_m3(proj); + zero_m4(proj); + proj[3][3] = 1.0f; if (texmap->projx != PROJ_N) proj[texmap->projx - 1][0] = 1.0f; @@ -117,19 +119,50 @@ void init_tex_mapping(TexMapping *texmap) proj[texmap->projz - 1][2] = 1.0f; /* scale */ - size_to_mat3(smat, texmap->size); + copy_v3_v3(size, texmap->size); + + if (ELEM(texmap->type, TEXMAP_TYPE_TEXTURE, TEXMAP_TYPE_NORMAL)) { + /* keep matrix invertible */ + if (fabsf(size[0]) < 1e-5f) + size[0] = signf(size[0]) * 1e-5f; + if (fabsf(size[1]) < 1e-5f) + size[1] = signf(size[1]) * 1e-5f; + if (fabsf(size[2]) < 1e-5f) + size[2] = signf(size[2]) * 1e-5f; + } + size_to_mat4(smat, texmap->size); + /* rotation */ - /* TexMapping rotation are now in radians. */ - eul_to_mat3(rmat, texmap->rot); - - /* compose it all */ - mul_m3_m3m3(mat, rmat, smat); - mul_m3_m3m3(mat, proj, mat); - + eul_to_mat4(rmat, texmap->rot); + /* translation */ - copy_m4_m3(texmap->mat, mat); - copy_v3_v3(texmap->mat[3], texmap->loc); + unit_m4(tmat); + copy_v3_v3(tmat[3], texmap->loc); + + if (texmap->type == TEXMAP_TYPE_TEXTURE) { + /* to transform a texture, the inverse transform needs + * to be applied to the texture coordinate */ + mul_serie_m4(texmap->mat, tmat, rmat, smat, 0, 0, 0, 0, 0); + invert_m4(texmap->mat); + } + else if (texmap->type == TEXMAP_TYPE_POINT) { + /* forward transform */ + mul_serie_m4(texmap->mat, tmat, rmat, smat, 0, 0, 0, 0, 0); + } + else if (texmap->type == TEXMAP_TYPE_VECTOR) { + /* no translation for vectors */ + mul_m4_m4m4(texmap->mat, rmat, smat); + } + else if (texmap->type == TEXMAP_TYPE_NORMAL) { + /* no translation for normals, and inverse transpose */ + mul_m4_m4m4(texmap->mat, rmat, smat); + invert_m4(texmap->mat); + transpose_m4(texmap->mat); + } + + /* projection last */ + mul_m4_m4m4(texmap->mat, texmap->mat, proj); texmap->flag &= ~TEXMAP_UNIT_MATRIX; } diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index fd92ec9f462..b8711f6e5f6 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -3340,7 +3340,7 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac break; } - libmv_homography2DFromCorrespondencesLinear(x1, x2, num_correspondences, H_double, 1e-8); + libmv_homography2DFromCorrespondencesEuc(x1, x2, num_correspondences, H_double); mat3f_from_mat3d(H, H_double); @@ -3444,7 +3444,7 @@ void BKE_tracking_homography_between_two_quads(/*const*/ float reference_corners float_corners_to_double(reference_corners, x1); float_corners_to_double(corners, x2); - libmv_homography2DFromCorrespondencesLinear(x1, x2, 4, H_double, 1e-8); + libmv_homography2DFromCorrespondencesEuc(x1, x2, 4, H_double); mat3f_from_mat3d(H, H_double); } |