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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c19
-rw-r--r--source/blender/blenkernel/intern/action.c16
-rw-r--r--source/blender/blenkernel/intern/anim.c2
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c71
-rw-r--r--source/blender/blenkernel/intern/boids.c4
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c2
-rw-r--r--source/blender/blenkernel/intern/colortools.c3
-rw-r--r--source/blender/blenkernel/intern/curve.c121
-rw-r--r--source/blender/blenkernel/intern/customdata.c94
-rw-r--r--source/blender/blenkernel/intern/deform.c115
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c2
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c13
-rw-r--r--source/blender/blenkernel/intern/fcurve.c64
-rw-r--r--source/blender/blenkernel/intern/freestyle.c3
-rw-r--r--source/blender/blenkernel/intern/gpencil.c8
-rw-r--r--source/blender/blenkernel/intern/idprop.c118
-rw-r--r--source/blender/blenkernel/intern/image.c6
-rw-r--r--source/blender/blenkernel/intern/library.c5
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c112
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c23
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c20
-rw-r--r--source/blender/blenkernel/intern/modifier.c16
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c3
-rw-r--r--source/blender/blenkernel/intern/movieclip.c1
-rw-r--r--source/blender/blenkernel/intern/multires.c16
-rw-r--r--source/blender/blenkernel/intern/node.c60
-rw-r--r--source/blender/blenkernel/intern/object.c19
-rw-r--r--source/blender/blenkernel/intern/paint.c4
-rw-r--r--source/blender/blenkernel/intern/particle.c8
-rw-r--r--source/blender/blenkernel/intern/particle_system.c11
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c32
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c13
-rw-r--r--source/blender/blenkernel/intern/screen.c2
-rw-r--r--source/blender/blenkernel/intern/sequencer.c5
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c2
-rw-r--r--source/blender/blenkernel/intern/smoke.c3
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c10
-rw-r--r--source/blender/blenkernel/intern/texture.c63
-rw-r--r--source/blender/blenkernel/intern/tracking.c4
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(&ltree->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);
}