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:
authorSybren A. Stüvel <sybren@stuvel.eu>2017-02-08 15:10:16 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2017-02-08 15:10:16 +0300
commitd4913af84660318047e3404f9766014cd78864ab (patch)
tree216516057dc8df5177e4f179392de5a79811ba3f /source/blender
parentc973e8d2da5cf3f615256269128a07390f8c06a9 (diff)
parent8cda364d6f2e6e8da454034f19fb959739045813 (diff)
Merge branch 'master' into blender2.8
# Conflicts: # source/blender/blenloader/intern/writefile.c
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/alembic/intern/abc_curves.cc10
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc19
-rw-r--r--source/blender/alembic/intern/abc_hair.cc5
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc18
-rw-r--r--source/blender/alembic/intern/abc_nurbs.cc4
-rw-r--r--source/blender/alembic/intern/abc_util.cc4
-rw-r--r--source/blender/alembic/intern/abc_util.h8
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h6
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h1
-rw-r--r--source/blender/blenkernel/BKE_texture.h7
-rw-r--r--source/blender/blenkernel/intern/armature.c14
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c237
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c38
-rw-r--r--source/blender/blenkernel/intern/customdata.c2
-rw-r--r--source/blender/blenkernel/intern/lamp.c8
-rw-r--r--source/blender/blenkernel/intern/particle.c5
-rw-r--r--source/blender/blenkernel/intern/sequencer.c89
-rw-r--r--source/blender/blenkernel/intern/sound.c4
-rw-r--r--source/blender/blenkernel/intern/text.c16
-rw-r--r--source/blender/blenkernel/intern/texture.c15
-rw-r--r--source/blender/blenlib/BLI_dynlib.h2
-rw-r--r--source/blender/blenlib/BLI_sys_types.h5
-rw-r--r--source/blender/blenlib/PIL_time_utildefines.h5
-rw-r--r--source/blender/blenlib/intern/dynlib.c4
-rw-r--r--source/blender/blenloader/intern/writefile.c365
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc6
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c5
-rw-r--r--source/blender/editors/include/ED_transform_snap_object_context.h4
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c2
-rw-r--r--source/blender/editors/object/object_vgroup.c61
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c2
-rw-r--r--source/blender/editors/transform/transform.c27
-rw-r--r--source/blender/editors/transform/transform.h4
-rw-r--r--source/blender/editors/transform/transform_conversions.c7
-rw-r--r--source/blender/editors/transform/transform_snap.c2
-rw-r--r--source/blender/editors/transform/transform_snap_object.c1009
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h12
-rw-r--r--source/blender/imbuf/intern/colormanagement.c173
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c209
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c4
42 files changed, 1286 insertions, 1136 deletions
diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc
index 4ecb9d944f2..282777f3af0 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -102,7 +102,7 @@ void AbcCurveWriter::do_write()
const BPoint *point = nurbs->bp;
for (int i = 0; i < totpoint; ++i, ++point) {
- copy_zup_yup(temp_vert.getValue(), point->vec);
+ copy_yup_from_zup(temp_vert.getValue(), point->vec);
verts.push_back(temp_vert);
weights.push_back(point->vec[3]);
widths.push_back(point->radius);
@@ -118,7 +118,7 @@ void AbcCurveWriter::do_write()
/* TODO(kevin): store info about handles, Alembic doesn't have this. */
for (int i = 0; i < totpoint; ++i, ++bezier) {
- copy_zup_yup(temp_vert.getValue(), bezier->vec[1]);
+ copy_yup_from_zup(temp_vert.getValue(), bezier->vec[1]);
verts.push_back(temp_vert);
widths.push_back(bezier->radius);
}
@@ -322,7 +322,7 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
weight = (*weights)[idx];
}
- copy_yup_zup(bp->vec, pos.getValue());
+ copy_zup_from_yup(bp->vec, pos.getValue());
bp->vec[3] = weight;
bp->f1 = SELECT;
bp->radius = radius;
@@ -389,7 +389,7 @@ DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float t
for (int i = 0; i < totpoint; ++i, ++point, ++vertex_idx) {
const Imath::V3f &pos = (*positions)[vertex_idx];
- copy_yup_zup(point->vec, pos.getValue());
+ copy_zup_from_yup(point->vec, pos.getValue());
}
}
else if (nurbs->bezt) {
@@ -397,7 +397,7 @@ DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float t
for (int i = 0; i < totpoint; ++i, ++bezier, ++vertex_idx) {
const Imath::V3f &pos = (*positions)[vertex_idx];
- copy_yup_zup(bezier->vec[1], pos.getValue());
+ copy_zup_from_yup(bezier->vec[1], pos.getValue());
}
}
}
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index cc61d5ad49f..844079faa78 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -382,7 +382,10 @@ void AbcExporter::createTransformWritersFlat()
void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent)
{
- createTransformWriter(ob, parent, dupliObParent);
+
+ if (export_object(&m_settings, ob) && object_is_shape(ob)) {
+ createTransformWriter(ob, parent, dupliObParent);
+ }
ListBase *lb = object_duplilist(eval_ctx, m_scene, ob);
@@ -410,8 +413,12 @@ void AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupl
{
const std::string name = get_object_dag_path_name(ob, dupliObParent);
+ /* An object should not be its own parent, or we'll get infinite loops. */
+ BLI_assert(ob != parent);
+ BLI_assert(ob != dupliObParent);
+
/* check if we have already created a transform writer for this object */
- if (m_xforms.find(name) != m_xforms.end()){
+ if (getXForm(name) != NULL){
std::cerr << "xform " << name << " already exists\n";
return;
}
@@ -426,6 +433,14 @@ void AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupl
if (parent->parent) {
createTransformWriter(parent, parent->parent, dupliObParent);
}
+ else if (parent == dupliObParent) {
+ if (dupliObParent->parent == NULL) {
+ createTransformWriter(parent, NULL, NULL);
+ }
+ else {
+ createTransformWriter(parent, dupliObParent->parent, dupliObParent->parent);
+ }
+ }
else {
createTransformWriter(parent, dupliObParent, dupliObParent);
}
diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc
index 14bcf6731ea..e328df24e53 100644
--- a/source/blender/alembic/intern/abc_hair.cc
+++ b/source/blender/alembic/intern/abc_hair.cc
@@ -77,7 +77,6 @@ void AbcHairWriter::do_write()
DerivedMesh *dm = mesh_create_derived_view(m_scene, m_object, CD_MASK_MESH);
DM_ensure_tessface(dm);
- DM_update_tessface_data(dm);
std::vector<Imath::V3f> verts;
std::vector<int32_t> hvertices;
@@ -164,7 +163,7 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, normal, NULL, NULL, NULL, NULL);
- copy_zup_yup(tmp_nor.getValue(), normal);
+ copy_yup_from_zup(tmp_nor.getValue(), normal);
norm_values.push_back(tmp_nor);
}
}
@@ -198,7 +197,7 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
MVert *mv = mverts + vtx[o];
normal_short_to_float_v3(normal, mv->no);
- copy_zup_yup(tmp_nor.getValue(), normal);
+ copy_yup_from_zup(tmp_nor.getValue(), normal);
norm_values.push_back(tmp_nor);
found = true;
break;
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index bdd75f93189..8bc9c335054 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -112,7 +112,7 @@ static void get_vertices(DerivedMesh *dm, std::vector<Imath::V3f> &points)
MVert *verts = dm->getVertArray(dm);
for (int i = 0, e = dm->getNumVerts(dm); i < e; ++i) {
- copy_zup_yup(points[i].getValue(), verts[i].co);
+ copy_yup_from_zup(points[i].getValue(), verts[i].co);
}
}
@@ -182,7 +182,7 @@ static void get_vertex_normals(DerivedMesh *dm, std::vector<Imath::V3f> &normals
for (int i = 0, e = dm->getNumVerts(dm); i < e; ++i) {
normal_short_to_float_v3(no, verts[i].no);
- copy_zup_yup(normals[i].getValue(), no);
+ copy_yup_from_zup(normals[i].getValue(), no);
}
}
@@ -211,7 +211,7 @@ static void get_loop_normals(DerivedMesh *dm, std::vector<Imath::V3f> &normals)
for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
const int index = ml->v;
- copy_zup_yup(normals[loop_index].getValue(), lnors[index]);
+ copy_yup_from_zup(normals[loop_index].getValue(), lnors[index]);
}
}
}
@@ -226,14 +226,14 @@ static void get_loop_normals(DerivedMesh *dm, std::vector<Imath::V3f> &normals)
BKE_mesh_calc_poly_normal(mp, ml - (mp->totloop - 1), verts, no);
for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
- copy_zup_yup(normals[loop_index].getValue(), no);
+ copy_yup_from_zup(normals[loop_index].getValue(), no);
}
}
else {
/* Smooth shaded, use individual vert normals. */
for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
normal_short_to_float_v3(no, verts[ml->v].no);
- copy_zup_yup(normals[loop_index].getValue(), no);
+ copy_yup_from_zup(normals[loop_index].getValue(), no);
}
}
}
@@ -590,7 +590,7 @@ void AbcMeshWriter::getVelocities(DerivedMesh *dm, std::vector<Imath::V3f> &vels
float *mesh_vels = reinterpret_cast<float *>(fss->meshVelocities);
for (int i = 0; i < totverts; ++i) {
- copy_zup_yup(vels[i].getValue(), mesh_vels);
+ copy_yup_from_zup(vels[i].getValue(), mesh_vels);
mesh_vels += 3;
}
}
@@ -726,7 +726,7 @@ static void read_mverts_interp(MVert *mverts, const P3fArraySamplePtr &positions
const Imath::V3f &ceil_pos = (*ceil_positions)[i];
interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), weight);
- copy_yup_zup(mvert.co, tmp);
+ copy_zup_from_yup(mvert.co, tmp);
mvert.bweight = 0;
}
@@ -755,7 +755,7 @@ void read_mverts(MVert *mverts, const P3fArraySamplePtr &positions, const N3fArr
MVert &mvert = mverts[i];
Imath::V3f pos_in = (*positions)[i];
- copy_yup_zup(mvert.co, pos_in.getValue());
+ copy_zup_from_yup(mvert.co, pos_in.getValue());
mvert.bweight = 0;
@@ -765,7 +765,7 @@ void read_mverts(MVert *mverts, const P3fArraySamplePtr &positions, const N3fArr
short no[3];
normal_float_to_short_v3(no, nor_in.getValue());
- copy_yup_zup(mvert.no, no);
+ copy_zup_from_yup(mvert.no, no);
}
}
}
diff --git a/source/blender/alembic/intern/abc_nurbs.cc b/source/blender/alembic/intern/abc_nurbs.cc
index 4f57dfdae9e..d0b9561f679 100644
--- a/source/blender/alembic/intern/abc_nurbs.cc
+++ b/source/blender/alembic/intern/abc_nurbs.cc
@@ -153,7 +153,7 @@ void AbcNurbsWriter::do_write()
const BPoint *bp = nu->bp;
for (int i = 0; i < size; ++i, ++bp) {
- copy_zup_yup(positions[i].getValue(), bp->vec);
+ copy_yup_from_zup(positions[i].getValue(), bp->vec);
weights[i] = bp->vec[3];
}
@@ -281,7 +281,7 @@ void AbcNurbsReader::readObjectData(Main *bmain, float time)
posw_in = (*weights)[i];
}
- copy_yup_zup(bp->vec, pos_in.getValue());
+ copy_zup_from_yup(bp->vec, pos_in.getValue());
bp->vec[3] = posw_in;
bp->f1 = SELECT;
bp->radius = 1.0f;
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
index f8ce72d845d..08c94f437e6 100644
--- a/source/blender/alembic/intern/abc_util.cc
+++ b/source/blender/alembic/intern/abc_util.cc
@@ -197,7 +197,7 @@ void create_transform_matrix(float r_mat[4][4])
copy_m4_m3(transform_mat, rot_mat);
/* Add translation to transformation matrix. */
- copy_yup_zup(transform_mat[3], loc);
+ copy_zup_from_yup(transform_mat[3], loc);
/* Create scale matrix. */
scale_mat[0][0] = scale[0];
@@ -417,7 +417,7 @@ void create_transform_matrix(Object *obj, float transform_mat[4][4])
copy_m4_m3(transform_mat, rot_mat);
/* Add translation to transformation matrix. */
- copy_zup_yup(transform_mat[3], loc);
+ copy_yup_from_zup(transform_mat[3], loc);
/* Create scale matrix. */
scale_mat[0][0] = scale[0];
diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h
index 60a96855d14..a7ac9df91c7 100644
--- a/source/blender/alembic/intern/abc_util.h
+++ b/source/blender/alembic/intern/abc_util.h
@@ -116,14 +116,14 @@ AbcObjectReader *create_reader(const Alembic::AbcGeom::IObject &object, ImportSe
/* Copy from Y-up to Z-up. */
-ABC_INLINE void copy_yup_zup(float zup[3], const float yup[3])
+ABC_INLINE void copy_zup_from_yup(float zup[3], const float yup[3])
{
zup[0] = yup[0];
zup[1] = -yup[2];
zup[2] = yup[1];
}
-ABC_INLINE void copy_yup_zup(short zup[3], const short yup[3])
+ABC_INLINE void copy_zup_from_yup(short zup[3], const short yup[3])
{
zup[0] = yup[0];
zup[1] = -yup[2];
@@ -132,14 +132,14 @@ ABC_INLINE void copy_yup_zup(short zup[3], const short yup[3])
/* Copy from Z-up to Y-up. */
-ABC_INLINE void copy_zup_yup(float yup[3], const float zup[3])
+ABC_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
{
yup[0] = zup[0];
yup[1] = zup[2];
yup[2] = -zup[1];
}
-ABC_INLINE void copy_zup_yup(short yup[3], const short zup[3])
+ABC_INLINE void copy_yup_from_zup(short yup[3], const short zup[3])
{
yup[0] = zup[0];
yup[1] = zup[2];
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index 07db2217bac..bf45a27e51c 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -133,6 +133,12 @@ BVHTree *bvhtree_from_editmesh_edges_ex(
BVHTree *bvhtree_from_mesh_edges(
struct BVHTreeFromMesh *data, struct DerivedMesh *mesh,
float epsilon, int tree_type, int axis);
+BVHTree *bvhtree_from_mesh_edges_ex(
+ struct BVHTreeFromMesh *data,
+ struct MVert *vert, const bool vert_allocated,
+ struct MEdge *edge, const int edges_num, const bool edge_allocated,
+ const BLI_bitmap *edges_mask, int edges_num_active,
+ float epsilon, int tree_type, int axis);
BVHTree *bvhtree_from_mesh_faces(
struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon,
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index 9948f21ba90..4876461bfe0 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -79,6 +79,7 @@ DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispba
*/
struct DerivedMesh *CDDM_copy(struct DerivedMesh *dm);
struct DerivedMesh *CDDM_copy_from_tessface(struct DerivedMesh *dm);
+struct DerivedMesh *CDDM_copy_with_tessface(struct DerivedMesh *dm);
/* creates a CDDerivedMesh with the same layer stack configuration as the
* given DerivedMesh and containing the requested numbers of elements.
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 1c5ea946f59..9a60eb29957 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -42,6 +42,7 @@ struct Brush;
struct ColorBand;
struct EnvMap;
struct FreestyleLineStyle;
+struct ImagePool;
struct Lamp;
struct Main;
struct Material;
@@ -133,6 +134,12 @@ struct OceanTex *BKE_texture_ocean_copy(struct OceanTex *ot);
bool BKE_texture_dependsOnTime(const struct Tex *texture);
bool BKE_texture_is_image_user(const struct Tex *tex);
+void BKE_texture_get_value_ex(
+ const struct Scene *scene, struct Tex *texture,
+ float *tex_co, struct TexResult *texres,
+ struct ImagePool *pool,
+ bool use_color_management);
+
void BKE_texture_get_value(
const struct Scene *scene, struct Tex *texture,
float *tex_co, struct TexResult *texres, bool use_color_management);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 89e93a6384d..2565eb1900c 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1037,6 +1037,17 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
if (use_dverts) {
defnrToPC = MEM_callocN(sizeof(*defnrToPC) * defbase_tot, "defnrToBone");
defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * defbase_tot, "defnrToIndex");
+ /* TODO(sergey): Some considerations here:
+ *
+ * - Make it more generic function, maybe even keep together with chanhash.
+ * - Check whether keeping this consistent across frames gives speedup.
+ * - Don't use hash for small armatures.
+ */
+ GHash *idx_hash = BLI_ghash_ptr_new("pose channel index by name");
+ int pchan_index = 0;
+ for (pchan = armOb->pose->chanbase.first; pchan != NULL; pchan = pchan->next, ++pchan_index) {
+ BLI_ghash_insert(idx_hash, pchan, SET_INT_IN_POINTER(pchan_index));
+ }
for (i = 0, dg = target->defbase.first; dg; i++, dg = dg->next) {
defnrToPC[i] = BKE_pose_channel_find_name(armOb->pose, dg->name);
/* exclude non-deforming bones */
@@ -1045,10 +1056,11 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
defnrToPC[i] = NULL;
}
else {
- defnrToPCIndex[i] = BLI_findindex(&armOb->pose->chanbase, defnrToPC[i]);
+ defnrToPCIndex[i] = GET_INT_FROM_POINTER(BLI_ghash_lookup(idx_hash, defnrToPC[i]));
}
}
}
+ BLI_ghash_free(idx_hash, NULL, NULL);
}
}
}
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index a8670395fc4..afd60102453 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -234,7 +234,7 @@ int BKE_blender_test_break(void)
* \note Don't use MEM_mallocN so functions can be registered at any time.
* \{ */
-struct AtExitData {
+static struct AtExitData {
struct AtExitData *next;
void (*func)(void *user_data);
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 264d87b86f3..d0e0c82e3be 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -376,6 +376,45 @@ static void mesh_edges_spherecast(void *userdata, int index, const BVHTreeRay *r
}
}
+#define V3_MUL_ELEM(a, b) \
+ (a)[0] * (b)[0], \
+ (a)[1] * (b)[1], \
+ (a)[2] * (b)[2]
+
+/* Callback to bvh tree nearest edge to ray.
+ * The tree must have been built using bvhtree_from_mesh_edges.
+ * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */
+static void mesh_edges_nearest_to_ray(
+ void *userdata, const float ray_co[3], const float ray_dir[3],
+ const float scale[3], int index, BVHTreeNearest *nearest)
+{
+ struct BVHTreeFromMesh *data = userdata;
+ const MVert *vert = data->vert;
+ const MEdge *e = &data->edge[index];
+
+ const float t0[3] = {V3_MUL_ELEM(vert[e->v1].co, scale)};
+ const float t1[3] = {V3_MUL_ELEM(vert[e->v2].co, scale)};
+ const float origin_sc[3] = {V3_MUL_ELEM(ray_co, scale)};
+ const float dir_sc[3] = {V3_MUL_ELEM(ray_dir, scale)};
+
+ float depth, point[3];
+ const float dist_sq = dist_squared_ray_to_seg_v3(origin_sc, dir_sc, t0, t1, point, &depth);
+
+ if (dist_sq < nearest->dist_sq) {
+ nearest->dist_sq = dist_sq;
+ nearest->index = index;
+
+ point[0] /= scale[0];
+ point[1] /= scale[1];
+ point[2] /= scale[2];
+
+ copy_v3_v3(nearest->co, point);
+ sub_v3_v3v3(nearest->no, t0, t1);
+ }
+}
+
+#undef V3_MUL_ELEM
+
/** \} */
/*
@@ -393,8 +432,6 @@ static BVHTree *bvhtree_from_editmesh_verts_create_tree(
BMEditMesh *em, const int verts_num,
const BLI_bitmap *verts_mask, int verts_num_active)
{
- BVHTree *tree = NULL;
- int i;
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
if (verts_mask) {
BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num));
@@ -403,15 +440,14 @@ static BVHTree *bvhtree_from_editmesh_verts_create_tree(
verts_num_active = verts_num;
}
- tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis);
+ BVHTree *tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis);
if (tree) {
- BMIter iter;
- BMVert *eve;
- BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ for (int i = 0; i < verts_num; i++) {
if (verts_mask && !BLI_BITMAP_TEST_BOOL(verts_mask, i)) {
continue;
}
+ BMVert *eve = BM_vert_at_index(em->bm, i);
BLI_bvhtree_insert(tree, i, eve->co, 1);
}
BLI_assert(BLI_bvhtree_get_size(tree) == verts_num_active);
@@ -426,28 +462,25 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree(
MVert *vert, const int verts_num,
const BLI_bitmap *verts_mask, int verts_num_active)
{
- BVHTree *tree = NULL;
- int i;
- if (vert) {
- if (verts_mask) {
- BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num));
- }
- else {
- verts_num_active = verts_num;
- }
+ BLI_assert(vert != NULL);
+ if (verts_mask) {
+ BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num));
+ }
+ else {
+ verts_num_active = verts_num;
+ }
- tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis);
+ BVHTree *tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis);
- if (tree) {
- for (i = 0; i < verts_num; i++) {
- if (verts_mask && !BLI_BITMAP_TEST_BOOL(verts_mask, i)) {
- continue;
- }
- BLI_bvhtree_insert(tree, i, vert[i].co, 1);
+ if (tree) {
+ for (int i = 0; i < verts_num; i++) {
+ if (verts_mask && !BLI_BITMAP_TEST_BOOL(verts_mask, i)) {
+ continue;
}
- BLI_assert(BLI_bvhtree_get_size(tree) == verts_num_active);
- BLI_bvhtree_balance(tree);
+ BLI_bvhtree_insert(tree, i, vert[i].co, 1);
}
+ BLI_assert(BLI_bvhtree_get_size(tree) == verts_num_active);
+ BLI_bvhtree_balance(tree);
}
return tree;
@@ -488,11 +521,9 @@ BVHTree *bvhtree_from_editmesh_verts_ex(
const BLI_bitmap *verts_mask, int verts_num_active,
float epsilon, int tree_type, int axis)
{
- int vert_num = em->bm->totvert;
-
BVHTree *tree = bvhtree_from_editmesh_verts_create_tree(
epsilon, tree_type, axis,
- em, vert_num, verts_mask, verts_num_active);
+ em, em->bm->totvert, verts_mask, verts_num_active);
if (tree) {
memset(data, 0, sizeof(*data));
@@ -505,6 +536,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(
return tree;
}
+
BVHTree *bvhtree_from_editmesh_verts(
BVHTreeFromEditMesh *data, BMEditMesh *em,
float epsilon, int tree_type, int axis)
@@ -515,8 +547,8 @@ BVHTree *bvhtree_from_editmesh_verts(
epsilon, tree_type, axis);
}
-
-/* Builds a bvh tree where nodes are the vertices of the given dm */
+/* Builds a bvh tree where nodes are the vertices of the given dm
+ * and stores the BVHTree in dm->bvhCache */
BVHTree *bvhtree_from_mesh_verts(
BVHTreeFromMesh *data, DerivedMesh *dm,
float epsilon, int tree_type, int axis)
@@ -557,7 +589,8 @@ BVHTree *bvhtree_from_mesh_verts(
}
/* Setup BVHTreeFromMesh */
- bvhtree_from_mesh_verts_setup_data(data, tree, true, epsilon, vert, vert_allocated);
+ bvhtree_from_mesh_verts_setup_data(
+ data, tree, true, epsilon, vert, vert_allocated);
return data->tree;
}
@@ -577,7 +610,8 @@ BVHTree *bvhtree_from_mesh_verts_ex(
epsilon, tree_type, axis, vert, verts_num, verts_mask, verts_num_active);
/* Setup BVHTreeFromMesh */
- bvhtree_from_mesh_verts_setup_data(data, tree, false, epsilon, vert, vert_allocated);
+ bvhtree_from_mesh_verts_setup_data(
+ data, tree, false, epsilon, vert, vert_allocated);
return data->tree;
}
@@ -595,8 +629,6 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(
BMEditMesh *em, const int edges_num,
const BLI_bitmap *edges_mask, int edges_num_active)
{
- BVHTree *tree = NULL;
- int i;
BM_mesh_elem_table_ensure(em->bm, BM_EDGE);
if (edges_mask) {
BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edges_num));
@@ -605,9 +637,10 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(
edges_num_active = edges_num;
}
- tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis);
+ BVHTree *tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis);
if (tree) {
+ int i;
BMIter iter;
BMEdge *eed;
BM_ITER_MESH_INDEX (eed, &iter, em->bm, BM_EDGES_OF_MESH, i) {
@@ -627,6 +660,70 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(
return tree;
}
+static BVHTree *bvhtree_from_mesh_edges_create_tree(
+ MVert *vert, MEdge *edge, const int edge_num,
+ const BLI_bitmap *edges_mask, int edges_num_active,
+ float epsilon, int tree_type, int axis)
+{
+ if (edges_mask) {
+ BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edge_num));
+ }
+ else {
+ edges_num_active = edge_num;
+ }
+ BLI_assert(vert != NULL);
+ BLI_assert(edge != NULL);
+
+ /* Create a bvh-tree of the given target */
+ BVHTree *tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis);
+ if (tree) {
+ for (int i = 0; i < edge_num; i++) {
+ if (edges_mask && !BLI_BITMAP_TEST_BOOL(edges_mask, i)) {
+ continue;
+ }
+ float co[2][3];
+ copy_v3_v3(co[0], vert[edge[i].v1].co);
+ copy_v3_v3(co[1], vert[edge[i].v2].co);
+
+ BLI_bvhtree_insert(tree, i, co[0], 2);
+ }
+ BLI_bvhtree_balance(tree);
+ }
+
+ return tree;
+}
+
+static void bvhtree_from_mesh_edges_setup_data(
+ BVHTreeFromMesh *data, BVHTree *tree, const bool is_cached, float epsilon,
+ MVert *vert, const bool vert_allocated, MEdge *edge, const bool edge_allocated)
+{
+ memset(data, 0, sizeof(*data));
+ data->tree = tree;
+
+ if (data->tree) {
+ data->cached = is_cached;
+
+ data->nearest_callback = mesh_edges_nearest_point;
+ data->raycast_callback = mesh_edges_spherecast;
+ data->nearest_to_ray_callback = mesh_edges_nearest_to_ray;
+
+ data->vert = vert;
+ data->vert_allocated = vert_allocated;
+ data->edge = edge;
+ data->edge_allocated = edge_allocated;
+
+ data->sphere_radius = epsilon;
+ }
+ else {
+ if (vert_allocated) {
+ MEM_freeN(vert);
+ }
+ if (edge_allocated) {
+ MEM_freeN(edge);
+ }
+ }
+}
+
/* Builds a bvh tree where nodes are the edges of the given em */
BVHTree *bvhtree_from_editmesh_edges_ex(
BVHTreeFromEditMesh *data, BMEditMesh *em,
@@ -651,6 +748,7 @@ BVHTree *bvhtree_from_editmesh_edges_ex(
return tree;
}
+
BVHTree *bvhtree_from_editmesh_edges(
BVHTreeFromEditMesh *data, BMEditMesh *em,
float epsilon, int tree_type, int axis)
@@ -683,27 +781,13 @@ BVHTree *bvhtree_from_mesh_edges(
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_EDGES);
if (tree == NULL) {
- int i;
- int numEdges = dm->getNumEdges(dm);
-
- if (vert != NULL && edge != NULL) {
- /* Create a bvh-tree of the given target */
- tree = BLI_bvhtree_new(numEdges, epsilon, tree_type, axis);
- if (tree != NULL) {
- for (i = 0; i < numEdges; i++) {
- float co[2][3];
- copy_v3_v3(co[0], vert[edge[i].v1].co);
- copy_v3_v3(co[1], vert[edge[i].v2].co);
-
- BLI_bvhtree_insert(tree, i, co[0], 2);
- }
- BLI_bvhtree_balance(tree);
+ tree = bvhtree_from_mesh_edges_create_tree(
+ vert, edge, dm->getNumEdges(dm),
+ NULL, -1, epsilon, tree_type, axis);
- /* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
- bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_EDGES);
- }
- }
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_EDGES);
}
BLI_rw_mutex_unlock(&cache_rwlock);
}
@@ -711,33 +795,34 @@ BVHTree *bvhtree_from_mesh_edges(
/* printf("BVHTree is already build, using cached tree\n"); */
}
-
/* Setup BVHTreeFromMesh */
- memset(data, 0, sizeof(*data));
- data->tree = tree;
+ bvhtree_from_mesh_edges_setup_data(
+ data, tree, true, epsilon, vert, vert_allocated, edge, edge_allocated);
- if (data->tree) {
- data->cached = true;
+ return data->tree;
+}
- data->nearest_callback = mesh_edges_nearest_point;
- data->raycast_callback = mesh_edges_spherecast;
- data->nearest_to_ray_callback = NULL;
+/**
+ * Builds a bvh tree where nodes are the given edges .
+ * \param vert/edge_allocated if true, elem freeing will be done when freeing data.
+ * \param edges_mask if not null, true elements give which vert to add to BVH tree.
+ * \param edges_num_active if >= 0, number of active edges to add to BVH tree (else will be computed from mask).
+ */
+BVHTree *bvhtree_from_mesh_edges_ex(
+ BVHTreeFromMesh *data,
+ MVert *vert, const bool vert_allocated,
+ MEdge *edge, const int edges_num, const bool edge_allocated,
+ const BLI_bitmap *edges_mask, int edges_num_active,
+ float epsilon, int tree_type, int axis)
+{
+ BVHTree *tree = bvhtree_from_mesh_edges_create_tree(
+ vert, edge, edges_num, edges_mask, edges_num_active,
+ epsilon, tree_type, axis);
- data->vert = vert;
- data->vert_allocated = vert_allocated;
- data->edge = edge;
- data->edge_allocated = edge_allocated;
+ /* Setup BVHTreeFromMesh */
+ bvhtree_from_mesh_edges_setup_data(
+ data, tree, false, epsilon, vert, vert_allocated, edge, edge_allocated);
- data->sphere_radius = epsilon;
- }
- else {
- if (vert_allocated) {
- MEM_freeN(vert);
- }
- if (edge_allocated) {
- MEM_freeN(edge);
- }
- }
return data->tree;
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index fc3e358cb25..483fa977aff 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -2398,13 +2398,16 @@ DerivedMesh *CDDM_from_editbmesh(BMEditMesh *em, const bool use_mdisps, const bo
use_tessface, em->tottri, (const BMLoop *(*)[3])em->looptris);
}
-static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
+static DerivedMesh *cddm_copy_ex(DerivedMesh *source,
+ const bool need_tessface_data,
+ const bool faces_from_tessfaces)
{
+ const bool copy_tessface_data = (faces_from_tessfaces || need_tessface_data);
CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
DerivedMesh *dm = &cddm->dm;
int numVerts = source->numVertData;
int numEdges = source->numEdgeData;
- int numTessFaces = source->numTessFaceData;
+ int numTessFaces = copy_tessface_data ? source->numTessFaceData : 0;
int numLoops = source->numLoopData;
int numPolys = source->numPolyData;
@@ -2414,10 +2417,12 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
source->getVertDataArray(source, CD_ORIGINDEX);
source->getEdgeDataArray(source, CD_ORIGINDEX);
source->getPolyDataArray(source, CD_ORIGINDEX);
+ if (copy_tessface_data) {
+ source->getTessFaceDataArray(source, CD_ORIGINDEX);
+ }
/* this initializes dm, and copies all non mvert/medge/mface layers */
- DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges,
- faces_from_tessfaces ? numTessFaces : 0,
+ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
numLoops, numPolys);
dm->deformedOnly = source->deformedOnly;
dm->cd_flag = source->cd_flag;
@@ -2428,6 +2433,9 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
+ if (copy_tessface_data) {
+ CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
+ }
/* now add mvert/medge/mface layers */
cddm->mvert = source->dupVertArray(source);
@@ -2435,17 +2443,16 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
-
- if (!faces_from_tessfaces) {
- DM_DupPolys(source, dm);
- }
- else {
- source->getTessFaceDataArray(source, CD_ORIGINDEX);
- CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
+ if (faces_from_tessfaces || copy_tessface_data) {
cddm->mface = source->dupTessFaceArray(source);
CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
+ }
+ if (!faces_from_tessfaces) {
+ DM_DupPolys(source, dm);
+ }
+ else {
CDDM_tessfaces_to_faces(dm);
}
@@ -2457,12 +2464,17 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
DerivedMesh *CDDM_copy(DerivedMesh *source)
{
- return cddm_copy_ex(source, 0);
+ return cddm_copy_ex(source, false, false);
}
DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
{
- return cddm_copy_ex(source, 1);
+ return cddm_copy_ex(source, false, true);
+}
+
+DerivedMesh *CDDM_copy_with_tessface(DerivedMesh *source)
+{
+ return cddm_copy_ex(source, true, false);
}
/* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 98d37fb07bf..c9f0b8ec9ca 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2595,7 +2595,7 @@ bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *pdata, Custom
if (!LAYER_CMP(ldata, CD_TANGENT, fdata, CD_TANGENT))
return false;
-#undef TEST_RET
+#undef LAYER_CMP
/* if no layers are on either CustomData's,
* then there was nothing to do... */
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index d098366aef4..69a2067f4e6 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -174,15 +174,10 @@ void BKE_lamp_make_local(Main *bmain, Lamp *la, const bool lib_local)
void BKE_lamp_free(Lamp *la)
{
- MTex *mtex;
int a;
for (a = 0; a < MAX_MTEX; a++) {
- mtex = la->mtex[a];
- if (mtex && mtex->tex)
- id_us_min(&mtex->tex->id);
- if (mtex)
- MEM_freeN(mtex);
+ MEM_SAFE_FREE(la->mtex[a]);
}
BKE_animdata_free((ID *)la, false);
@@ -193,6 +188,7 @@ void BKE_lamp_free(Lamp *la)
if (la->nodetree) {
ntreeFreeTree(la->nodetree);
MEM_freeN(la->nodetree);
+ la->nodetree = NULL;
}
BKE_previewimg_free(&la->preview);
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 1ea27558545..228ae6afaba 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -633,8 +633,9 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[4][4], floa
data->childcachebufs.last = psys->childcachebufs.last;
data->totchildcache = psys->totchildcache;
- if (psmd->dm_final)
- data->dm = CDDM_copy(psmd->dm_final);
+ if (psmd->dm_final) {
+ data->dm = CDDM_copy_with_tessface(psmd->dm_final);
+ }
data->totdmvert = psmd->totdmvert;
data->totdmedge = psmd->totdmedge;
data->totdmface = psmd->totdmface;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 1d2f5aee440..6a491ba5ec4 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -480,55 +480,74 @@ void BKE_sequencer_editing_free(Scene *scene)
static void sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf)
{
- if (ibuf->rect_float) {
+ if (ibuf->rect != NULL) {
+ IMB_colormanagement_assign_rect_colorspace(ibuf, scene->sequencer_colorspace_settings.name);
+ }
+ if (ibuf->rect_float != NULL) {
IMB_colormanagement_assign_float_colorspace(ibuf, scene->sequencer_colorspace_settings.name);
}
}
void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float)
{
- const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+ /* Early output check: if both buffers are NULL we have nothing to convert. */
+ if (ibuf->rect_float == NULL && ibuf->rect == NULL) {
+ return;
+ }
+ /* Get common conversion settings. */
const char *to_colorspace = scene->sequencer_colorspace_settings.name;
- const char *float_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
-
- if (!ibuf->rect_float) {
- if (ibuf->rect) {
- const char *byte_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
- if (make_float || !STREQ(to_colorspace, byte_colorspace)) {
- /* If byte space is not in sequencer's working space, we deliver float color space,
- * this is to to prevent data loss.
- */
-
- /* when converting byte buffer to float in sequencer we need to make float
- * buffer be in sequencer's working space, which is currently only doable
- * from linear space.
- */
-
- /*
- * OCIO_TODO: would be nice to support direct single transform from byte to sequencer's
- */
-
- IMB_float_from_rect(ibuf);
- }
- else {
- return;
- }
+ /* Perform actual conversion logic. */
+ if (ibuf->rect_float == NULL) {
+ /* We are not requested to give float buffer and byte buffer is already
+ * in thee required colorspace. Can skip doing anything here.
+ */
+ const char *from_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
+ if (!make_float && STREQ(from_colorspace, to_colorspace)) {
+ return;
+ }
+ if (false) {
+ /* The idea here is to provide as fast playback as possible and
+ * enforcing float buffer here (a) uses more cache memory (b) might
+ * make some other effects slower to apply.
+ *
+ * However, this might also have negative effect by adding weird
+ * artifacts which will then not happen in final render.
+ */
+ IMB_colormanagement_transform_byte_threaded(
+ (unsigned char*)ibuf->rect, ibuf->x, ibuf->y, ibuf->channels,
+ from_colorspace, to_colorspace);
}
else {
- return;
+ /* We perform conversion to a float buffer so we don't worry about
+ * precision loss.
+ */
+ imb_addrectfloatImBuf(ibuf);
+ IMB_colormanagement_transform_from_byte_threaded(
+ ibuf->rect_float, (unsigned char*)ibuf->rect,
+ ibuf->x, ibuf->y, ibuf->channels,
+ from_colorspace, to_colorspace);
+ /* We don't need byte buffer anymore. */
+ imb_freerectImBuf(ibuf);
}
}
-
- if (from_colorspace && from_colorspace[0] != '\0') {
- if (ibuf->rect)
+ else {
+ const char *from_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
+ /* Unknown input color space, can't perform conversion. */
+ if (from_colorspace == NULL || from_colorspace[0] == '\0') {
+ return;
+ }
+ /* We don't want both byte and float buffers around: they'll either run
+ * out of sync or conversion of byte buffer will loose precision in there.
+ */
+ if (ibuf->rect != NULL) {
imb_freerectImBuf(ibuf);
-
- if (!STREQ(float_colorspace, to_colorspace)) {
- IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, true);
- sequencer_imbuf_assign_spaces(scene, ibuf);
}
+ IMB_colormanagement_transform_threaded(ibuf->rect_float,
+ ibuf->x, ibuf->y, ibuf->channels,
+ from_colorspace, to_colorspace,
+ true);
}
+ sequencer_imbuf_assign_spaces(scene, ibuf);
}
void BKE_sequencer_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf)
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index e10f9207896..fe4bcc738c6 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -147,12 +147,12 @@ void BKE_sound_free(bSound *sound)
BKE_sound_free_waveform(sound);
+#endif /* WITH_AUDASPACE */
if (sound->spinlock) {
BLI_spin_end(sound->spinlock);
MEM_freeN(sound->spinlock);
sound->spinlock = NULL;
- }
-#endif /* WITH_AUDASPACE */
+ }
}
void BKE_sound_make_local(Main *bmain, bSound *sound, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 88575c7d3be..298790a9e9b 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -1935,7 +1935,7 @@ void txt_do_undo(Text *text)
int op = text->undo_buf[text->undo_pos];
int prev_flags;
unsigned int linep;
- unsigned int uchar;
+ unsigned int uni_char;
unsigned int curln, selln;
unsigned short curc, selc;
unsigned short charp;
@@ -1971,14 +1971,14 @@ void txt_do_undo(Text *text)
case UNDO_BS_3:
case UNDO_BS_4:
charp = op - UNDO_BS_1 + 1;
- uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp);
+ uni_char = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp);
/* get and restore the cursors */
txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
txt_move_to(text, curln, curc, 0);
txt_move_to(text, curln, curc, 1);
- txt_add_char(text, uchar);
+ txt_add_char(text, uni_char);
text->undo_pos--;
break;
@@ -1988,14 +1988,14 @@ void txt_do_undo(Text *text)
case UNDO_DEL_3:
case UNDO_DEL_4:
charp = op - UNDO_DEL_1 + 1;
- uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp);
+ uni_char = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp);
/* get and restore the cursors */
txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
txt_move_to(text, curln, curc, 0);
txt_move_to(text, curln, curc, 1);
- txt_add_char(text, uchar);
+ txt_add_char(text, uni_char);
txt_move_left(text, 0);
@@ -2163,7 +2163,7 @@ void txt_do_redo(Text *text)
char *buf;
unsigned int linep;
unsigned short charp;
- unsigned int uchar;
+ unsigned int uni_uchar;
unsigned int curln, selln;
unsigned short curc, selc;
@@ -2190,9 +2190,9 @@ void txt_do_redo(Text *text)
txt_move_to(text, curln, curc, 1);
charp = op - UNDO_INSERT_1 + 1;
- uchar = txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp);
+ uni_uchar = txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp);
- txt_add_char(text, uchar);
+ txt_add_char(text, uni_uchar);
break;
case UNDO_BS_1:
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 2d3ecad19ad..60990c03b0e 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -1485,9 +1485,11 @@ bool BKE_texture_dependsOnTime(const struct Tex *texture)
/* ------------------------------------------------------------------------- */
-void BKE_texture_get_value(
+void BKE_texture_get_value_ex(
const Scene *scene, Tex *texture,
- float *tex_co, TexResult *texres, bool use_color_management)
+ float *tex_co, TexResult *texres,
+ struct ImagePool *pool,
+ bool use_color_management)
{
int result_type;
bool do_color_manage = false;
@@ -1497,7 +1499,7 @@ void BKE_texture_get_value(
}
/* no node textures for now */
- result_type = multitex_ext_safe(texture, tex_co, texres, NULL, do_color_manage, false);
+ result_type = multitex_ext_safe(texture, tex_co, texres, pool, do_color_manage, false);
/* if the texture gave an RGB value, we assume it didn't give a valid
* intensity, since this is in the context of modifiers don't use perceptual color conversion.
@@ -1510,3 +1512,10 @@ void BKE_texture_get_value(
copy_v3_fl(&texres->tr, texres->tin);
}
}
+
+void BKE_texture_get_value(
+ const Scene *scene, Tex *texture,
+ float *tex_co, TexResult *texres, bool use_color_management)
+{
+ BKE_texture_get_value_ex(scene, texture, tex_co, texres, NULL, use_color_management);
+}
diff --git a/source/blender/blenlib/BLI_dynlib.h b/source/blender/blenlib/BLI_dynlib.h
index 7d5eb888021..310db9ea051 100644
--- a/source/blender/blenlib/BLI_dynlib.h
+++ b/source/blender/blenlib/BLI_dynlib.h
@@ -34,7 +34,7 @@
typedef struct DynamicLibrary DynamicLibrary;
-DynamicLibrary *BLI_dynlib_open(char *name);
+DynamicLibrary *BLI_dynlib_open(const char *name);
void *BLI_dynlib_find_symbol(DynamicLibrary *lib, const char *symname);
char *BLI_dynlib_get_error_as_string(DynamicLibrary *lib);
void BLI_dynlib_close(DynamicLibrary *lib);
diff --git a/source/blender/blenlib/BLI_sys_types.h b/source/blender/blenlib/BLI_sys_types.h
index 7929e1d6551..9d8222c575d 100644
--- a/source/blender/blenlib/BLI_sys_types.h
+++ b/source/blender/blenlib/BLI_sys_types.h
@@ -80,6 +80,11 @@ typedef uint64_t u_int64_t;
#include <stddef.h> /* size_t define */
#include <stdbool.h>
+typedef unsigned int uint;
+typedef unsigned short ushort;
+typedef unsigned long ulong;
+typedef unsigned char uchar;
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/PIL_time_utildefines.h b/source/blender/blenlib/PIL_time_utildefines.h
index 9157e04a7bf..412cfb3a090 100644
--- a/source/blender/blenlib/PIL_time_utildefines.h
+++ b/source/blender/blenlib/PIL_time_utildefines.h
@@ -80,9 +80,10 @@
} \
const float _delta_##var = TIMEIT_VALUE(var); \
_sum_##var += _delta_##var; \
+ _num_##var++; \
printf("time end (" #var "): %.6f" " " AT "\n", _delta_##var); \
- printf("time averaged (" #var "): %.6f" " " AT "\n", \
- (_sum_##var / ++_num_##var)); \
+ printf("time averaged (" #var "): %.6f (total: %.6f, in %d runs)\n", \
+ (_sum_##var / _num_##var), _sum_##var, (int)_num_##var); \
fflush(stdout); \
} (void)0
diff --git a/source/blender/blenlib/intern/dynlib.c b/source/blender/blenlib/intern/dynlib.c
index b47c2ee60a6..51b91fb360f 100644
--- a/source/blender/blenlib/intern/dynlib.c
+++ b/source/blender/blenlib/intern/dynlib.c
@@ -50,7 +50,7 @@ struct DynamicLibrary {
#include "utf_winfunc.h"
#include "utfconv.h"
-DynamicLibrary *BLI_dynlib_open(char *name)
+DynamicLibrary *BLI_dynlib_open(const char *name)
{
DynamicLibrary *lib;
void *handle;
@@ -106,7 +106,7 @@ void BLI_dynlib_close(DynamicLibrary *lib)
#include <dlfcn.h>
-DynamicLibrary *BLI_dynlib_open(char *name)
+DynamicLibrary *BLI_dynlib_open(const char *name)
{
DynamicLibrary *lib;
void *handle = dlopen(name, RTLD_LAZY);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index bc567edd7ad..16d73557bb0 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -800,22 +800,18 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
static void write_actions(WriteData *wd, ListBase *idbase)
{
- bAction *act;
- bActionGroup *grp;
- TimeMarker *marker;
-
- for (act = idbase->first; act; act = act->id.next) {
+ for (bAction *act = idbase->first; act; act = act->id.next) {
if (act->id.us > 0 || wd->current) {
writestruct(wd, ID_AC, bAction, 1, act);
write_iddata(wd, &act->id);
write_fcurves(wd, &act->curves);
- for (grp = act->groups.first; grp; grp = grp->next) {
+ for (bActionGroup *grp = act->groups.first; grp; grp = grp->next) {
writestruct(wd, DATA, bActionGroup, 1, grp);
}
- for (marker = act->markers.first; marker; marker = marker->next) {
+ for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) {
writestruct(wd, DATA, TimeMarker, 1, marker);
}
}
@@ -1281,13 +1277,7 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches)
}
static void write_particlesettings(WriteData *wd, ListBase *idbase)
{
- ParticleSettings *part;
- ParticleDupliWeight *dw;
- GroupObject *go;
- int a;
-
- part = idbase->first;
- while (part) {
+ for (ParticleSettings *part = idbase->first; part; part = part->id.next) {
if (part->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_PA, ParticleSettings, 1, part);
@@ -1307,24 +1297,23 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
write_curvemapping(wd, part->roughcurve);
}
- dw = part->dupliweights.first;
- for (; dw; dw = dw->next) {
+ for (ParticleDupliWeight *dw = part->dupliweights.first; dw; dw = dw->next) {
/* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */
if (dw->ob != NULL) {
dw->index = 0;
if (part->dup_group) { /* can be NULL if lining fails or set to None */
- for (go = part->dup_group->gobject.first; go && go->ob != dw->ob; go = go->next, dw->index++);
+ for (GroupObject *go = part->dup_group->gobject.first;
+ go && go->ob != dw->ob;
+ go = go->next, dw->index++);
}
}
writestruct(wd, DATA, ParticleDupliWeight, 1, dw);
}
if (part->boids && part->phystype == PART_PHYS_BOIDS) {
- BoidState *state = part->boids->states.first;
-
writestruct(wd, DATA, BoidSettings, 1, part->boids);
- for (; state; state = state->next) {
+ for (BoidState *state = part->boids->states.first; state; state = state->next) {
write_boid_state(wd, state);
}
}
@@ -1332,13 +1321,12 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, SPHFluidSettings, 1, part->fluid);
}
- for (a = 0; a < MAX_MTEX; a++) {
+ for (int a = 0; a < MAX_MTEX; a++) {
if (part->mtex[a]) {
writestruct(wd, DATA, MTex, 1, part->mtex[a]);
}
}
}
- part = part->id.next;
}
}
static void write_particlesystems(WriteData *wd, ListBase *particles)
@@ -1835,10 +1823,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
static void write_objects(WriteData *wd, ListBase *idbase)
{
- Object *ob;
-
- ob = idbase->first;
- while (ob) {
+ for (Object *ob = idbase->first; ob; ob = ob->id.next) {
if (ob->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_OB, Object, 1, ob);
@@ -1894,11 +1879,9 @@ static void write_objects(WriteData *wd, ListBase *idbase)
writelist(wd, DATA, LinkData, &ob->pc_ids);
writelist(wd, DATA, LodLevel, &ob->lodlevels);
- }
- write_previews(wd, ob->preview);
-
- ob = ob->id.next;
+ write_previews(wd, ob->preview);
+ }
}
mywrite_flush(wd);
@@ -1907,26 +1890,19 @@ static void write_objects(WriteData *wd, ListBase *idbase)
static void write_vfonts(WriteData *wd, ListBase *idbase)
{
- VFont *vf;
- PackedFile *pf;
-
- vf = idbase->first;
- while (vf) {
+ for (VFont *vf = idbase->first; vf; vf = vf->id.next) {
if (vf->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_VF, VFont, 1, vf);
write_iddata(wd, &vf->id);
/* direct data */
-
if (vf->packedfile) {
- pf = vf->packedfile;
+ PackedFile *pf = vf->packedfile;
writestruct(wd, DATA, PackedFile, 1, pf);
writedata(wd, DATA, pf->size, pf->data);
}
}
-
- vf = vf->id.next;
}
mywrite_flush(wd);
@@ -1935,11 +1911,7 @@ static void write_vfonts(WriteData *wd, ListBase *idbase)
static void write_keys(WriteData *wd, ListBase *idbase)
{
- Key *key;
- KeyBlock *kb;
-
- key = idbase->first;
- while (key) {
+ for (Key *key = idbase->first; key; key = key->id.next) {
if (key->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_KE, Key, 1, key);
@@ -1950,17 +1922,13 @@ static void write_keys(WriteData *wd, ListBase *idbase)
}
/* direct data */
- kb = key->block.first;
- while (kb) {
+ for (KeyBlock *kb = key->block.first; kb; kb = kb->next) {
writestruct(wd, DATA, KeyBlock, 1, kb);
if (kb->data) {
writedata(wd, DATA, kb->totelem * key->elemsize, kb->data);
}
- kb = kb->next;
}
}
-
- key = key->id.next;
}
mywrite_flush(wd);
@@ -1968,10 +1936,7 @@ static void write_keys(WriteData *wd, ListBase *idbase)
static void write_cameras(WriteData *wd, ListBase *idbase)
{
- Camera *cam;
-
- cam = idbase->first;
- while (cam) {
+ for (Camera *cam = idbase->first; cam; cam = cam->id.next) {
if (cam->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_CA, Camera, 1, cam);
@@ -1981,18 +1946,12 @@ static void write_cameras(WriteData *wd, ListBase *idbase)
write_animdata(wd, cam->adt);
}
}
-
- cam = cam->id.next;
}
}
static void write_mballs(WriteData *wd, ListBase *idbase)
{
- MetaBall *mb;
- MetaElem *ml;
-
- mb = idbase->first;
- while (mb) {
+ for (MetaBall *mb = idbase->first; mb; mb = mb->id.next) {
if (mb->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_MB, MetaBall, 1, mb);
@@ -2004,23 +1963,16 @@ static void write_mballs(WriteData *wd, ListBase *idbase)
write_animdata(wd, mb->adt);
}
- ml = mb->elems.first;
- while (ml) {
+ for (MetaElem *ml = mb->elems.first; ml; ml = ml->next) {
writestruct(wd, DATA, MetaElem, 1, ml);
- ml = ml->next;
}
}
- mb = mb->id.next;
}
}
static void write_curves(WriteData *wd, ListBase *idbase)
{
- Curve *cu;
- Nurb *nu;
-
- cu = idbase->first;
- while (cu) {
+ for (Curve *cu = idbase->first; cu; cu = cu->id.next) {
if (cu->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_CU, Curve, 1, cu);
@@ -2039,13 +1991,10 @@ static void write_curves(WriteData *wd, ListBase *idbase)
}
else {
/* is also the order of reading */
- nu = cu->nurb.first;
- while (nu) {
+ for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) {
writestruct(wd, DATA, Nurb, 1, nu);
- nu = nu->next;
}
- nu = cu->nurb.first;
- while (nu) {
+ for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
writestruct(wd, DATA, BezTriple, nu->pntsu, nu->bezt);
}
@@ -2058,11 +2007,9 @@ static void write_curves(WriteData *wd, ListBase *idbase)
writedata(wd, DATA, KNOTSV(nu) * sizeof(float), nu->knotsv);
}
}
- nu = nu->next;
}
}
}
- cu = cu->id.next;
}
mywrite_flush(wd);
@@ -2184,15 +2131,13 @@ static void write_customdata(
static void write_meshes(WriteData *wd, ListBase *idbase)
{
- Mesh *mesh;
- bool save_for_old_blender = false;
-
#ifdef USE_BMESH_SAVE_AS_COMPAT
- save_for_old_blender = wd->use_mesh_compat; /* option to save with older mesh format */
+ const bool save_for_old_blender = wd->use_mesh_compat; /* option to save with older mesh format */
+#else
+ const bool save_for_old_blender = false;
#endif
- mesh = idbase->first;
- while (mesh) {
+ for (Mesh *mesh = idbase->first; mesh; mesh = mesh->id.next) {
CustomDataLayer *vlayers = NULL, vlayers_buff[CD_TEMP_CHUNK_SIZE];
CustomDataLayer *elayers = NULL, elayers_buff[CD_TEMP_CHUNK_SIZE];
CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE];
@@ -2337,8 +2282,6 @@ static void write_meshes(WriteData *wd, ListBase *idbase)
if (players && players != players_buff) {
MEM_freeN(players);
}
-
- mesh = mesh->id.next;
}
mywrite_flush(wd);
@@ -2346,10 +2289,7 @@ static void write_meshes(WriteData *wd, ListBase *idbase)
static void write_lattices(WriteData *wd, ListBase *idbase)
{
- Lattice *lt;
-
- lt = idbase->first;
- while (lt) {
+ for (Lattice *lt = idbase->first; lt; lt = lt->id.next) {
if (lt->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_LT, Lattice, 1, lt);
@@ -2364,9 +2304,7 @@ static void write_lattices(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, lt->def);
write_dverts(wd, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
-
}
- lt = lt->id.next;
}
mywrite_flush(wd);
@@ -2374,14 +2312,10 @@ static void write_lattices(WriteData *wd, ListBase *idbase)
static void write_images(WriteData *wd, ListBase *idbase)
{
- Image *ima;
- PackedFile *pf;
- ImageView *iv;
- ImagePackedFile *imapf;
-
- ima = idbase->first;
- while (ima) {
+ for (Image *ima = idbase->first; ima; ima = ima->id.next) {
if (ima->id.us > 0 || wd->current) {
+ ImagePackedFile *imapf;
+
/* Some trickery to keep forward compatibility of packed images. */
BLI_assert(ima->packedfile == NULL);
if (ima->packedfiles.first != NULL) {
@@ -2396,7 +2330,7 @@ static void write_images(WriteData *wd, ListBase *idbase)
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
writestruct(wd, DATA, ImagePackedFile, 1, imapf);
if (imapf->packedfile) {
- pf = imapf->packedfile;
+ PackedFile *pf = imapf->packedfile;
writestruct(wd, DATA, PackedFile, 1, pf);
writedata(wd, DATA, pf->size, pf->data);
}
@@ -2404,14 +2338,13 @@ static void write_images(WriteData *wd, ListBase *idbase)
write_previews(wd, ima->preview);
- for (iv = ima->views.first; iv; iv = iv->next) {
+ for (ImageView *iv = ima->views.first; iv; iv = iv->next) {
writestruct(wd, DATA, ImageView, 1, iv);
}
writestruct(wd, DATA, Stereo3dFormat, 1, ima->stereo3d_format);
ima->packedfile = NULL;
}
- ima = ima->id.next;
}
mywrite_flush(wd);
@@ -2419,10 +2352,7 @@ static void write_images(WriteData *wd, ListBase *idbase)
static void write_textures(WriteData *wd, ListBase *idbase)
{
- Tex *tex;
-
- tex = idbase->first;
- while (tex) {
+ for (Tex *tex = idbase->first; tex; tex = tex->id.next) {
if (tex->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_TE, Tex, 1, tex);
@@ -2463,7 +2393,6 @@ static void write_textures(WriteData *wd, ListBase *idbase)
write_previews(wd, tex->preview);
}
- tex = tex->id.next;
}
mywrite_flush(wd);
@@ -2486,11 +2415,7 @@ static void write_material_engines_settings(WriteData *wd, ListBase *lb)
static void write_materials(WriteData *wd, ListBase *idbase)
{
- Material *ma;
- int a;
-
- ma = idbase->first;
- while (ma) {
+ for (Material *ma = idbase->first; ma; ma = ma->id.next) {
if (ma->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_MA, Material, 1, ma);
@@ -2500,7 +2425,7 @@ static void write_materials(WriteData *wd, ListBase *idbase)
write_animdata(wd, ma->adt);
}
- for (a = 0; a < MAX_MTEX; a++) {
+ for (int a = 0; a < MAX_MTEX; a++) {
if (ma->mtex[a]) {
writestruct(wd, DATA, MTex, 1, ma->mtex[a]);
}
@@ -2523,17 +2448,12 @@ static void write_materials(WriteData *wd, ListBase *idbase)
write_material_engines_settings(wd, &ma->engines_settings);
}
- ma = ma->id.next;
}
}
static void write_worlds(WriteData *wd, ListBase *idbase)
{
- World *wrld;
- int a;
-
- wrld = idbase->first;
- while (wrld) {
+ for (World *wrld = idbase->first; wrld; wrld = wrld->id.next) {
if (wrld->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_WO, World, 1, wrld);
@@ -2543,7 +2463,7 @@ static void write_worlds(WriteData *wd, ListBase *idbase)
write_animdata(wd, wrld->adt);
}
- for (a = 0; a < MAX_MTEX; a++) {
+ for (int a = 0; a < MAX_MTEX; a++) {
if (wrld->mtex[a]) {
writestruct(wd, DATA, MTex, 1, wrld->mtex[a]);
}
@@ -2557,17 +2477,12 @@ static void write_worlds(WriteData *wd, ListBase *idbase)
write_previews(wd, wrld->preview);
}
- wrld = wrld->id.next;
}
}
static void write_lamps(WriteData *wd, ListBase *idbase)
{
- Lamp *la;
- int a;
-
- la = idbase->first;
- while (la) {
+ for (Lamp *la = idbase->first; la; la = la->id.next) {
if (la->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_LA, Lamp, 1, la);
@@ -2578,7 +2493,7 @@ static void write_lamps(WriteData *wd, ListBase *idbase)
}
/* direct data */
- for (a = 0; a < MAX_MTEX; a++) {
+ for (int a = 0; a < MAX_MTEX; a++) {
if (la->mtex[a]) {
writestruct(wd, DATA, MTex, 1, la->mtex[a]);
}
@@ -2595,9 +2510,7 @@ static void write_lamps(WriteData *wd, ListBase *idbase)
}
write_previews(wd, la->preview);
-
}
- la = la->id.next;
}
mywrite_flush(wd);
@@ -2707,23 +2620,7 @@ static void write_render_engines_settings(WriteData *wd, ListBase *lb)
static void write_scenes(WriteData *wd, ListBase *scebase)
{
- Scene *sce;
- BaseLegacy *base;
- Editing *ed;
- Sequence *seq;
- MetaStack *ms;
- Strip *strip;
- TimeMarker *marker;
- TransformOrientation *ts;
- SceneRenderLayer *srl;
- SceneRenderView *srv;
- ToolSettings *tos;
- FreestyleModuleConfig *fmc;
- FreestyleLineSet *fls;
- SceneLayer *sl;
-
- sce = scebase->first;
- while (sce) {
+ for (Scene *sce = scebase->first; sce; sce = sce->id.next) {
/* write LibData */
writestruct(wd, ID_SCE, Scene, 1, sce);
write_iddata(wd, &sce->id);
@@ -2734,13 +2631,11 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
write_keyingsets(wd, &sce->keyingsets);
/* direct data */
- base = sce->base.first;
- while (base) {
+ for (BaseLegacy *base = sce->base.first; base; base = base->next) {
writestruct(wd, DATA, BaseLegacy, 1, base);
- base = base->next;
}
- tos = sce->toolsettings;
+ ToolSettings *tos = sce->toolsettings;
writestruct(wd, DATA, ToolSettings, 1, tos);
if (tos->vpaint) {
writestruct(wd, DATA, VPaint, 1, tos->vpaint);
@@ -2779,8 +2674,10 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
write_paint(wd, &tos->imapaint.paint);
- ed = sce->ed;
+ Editing *ed = sce->ed;
if (ed) {
+ Sequence *seq;
+
writestruct(wd, DATA, Editing, 1, ed);
/* reset write flags too */
@@ -2827,7 +2724,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
writestruct(wd, DATA, Stereo3dFormat, 1, seq->stereo3d_format);
- strip = seq->strip;
+ Strip *strip = seq->strip;
writestruct(wd, DATA, Strip, 1, strip);
if (seq->flag & SEQ_USE_CROP && strip->crop) {
writestruct(wd, DATA, StripCrop, 1, strip->crop);
@@ -2859,7 +2756,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
SEQ_END
/* new; meta stack too, even when its nasty restore code */
- for (ms = ed->metastack.first; ms; ms = ms->next) {
+ for (MetaStack *ms = ed->metastack.first; ms; ms = ms->next) {
writestruct(wd, DATA, MetaStack, 1, ms);
}
}
@@ -2885,27 +2782,27 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
}
/* writing dynamic list of TimeMarkers to the blend file */
- for (marker = sce->markers.first; marker; marker = marker->next) {
+ for (TimeMarker *marker = sce->markers.first; marker; marker = marker->next) {
writestruct(wd, DATA, TimeMarker, 1, marker);
}
/* writing dynamic list of TransformOrientations to the blend file */
- for (ts = sce->transform_spaces.first; ts; ts = ts->next) {
+ for (TransformOrientation *ts = sce->transform_spaces.first; ts; ts = ts->next) {
writestruct(wd, DATA, TransformOrientation, 1, ts);
}
- for (srl = sce->r.layers.first; srl; srl = srl->next) {
+ for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) {
writestruct(wd, DATA, SceneRenderLayer, 1, srl);
- for (fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
+ for (FreestyleModuleConfig *fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc);
}
- for (fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
+ for (FreestyleLineSet *fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
writestruct(wd, DATA, FreestyleLineSet, 1, fls);
}
}
/* writing MultiView to the blend file */
- for (srv = sce->r.views.first; srv; srv = srv->next) {
+ for (SceneRenderView *srv = sce->r.views.first; srv; srv = srv->next) {
writestruct(wd, DATA, SceneRenderView, 1, srv);
}
@@ -2925,10 +2822,9 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
write_previews(wd, sce->preview);
write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve);
-
write_scene_collection(wd, sce->collection);
- for (sl = sce->render_layers.first; sl; sl = sl->next) {
+ for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
writestruct(wd, DATA, SceneLayer, 1, sl);
writelist(wd, DATA, Base, &sl->object_bases);
write_layer_collections(wd, &sl->layer_collections);
@@ -2936,7 +2832,6 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
write_render_engines_settings(wd, &sce->engines_settings);
- sce = sce->id.next;
}
mywrite_flush(wd);
@@ -2944,13 +2839,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
static void write_gpencils(WriteData *wd, ListBase *lb)
{
- bGPdata *gpd;
- bGPDlayer *gpl;
- bGPDframe *gpf;
- bGPDstroke *gps;
- bGPDpalette *palette;
-
- for (gpd = lb->first; gpd; gpd = gpd->id.next) {
+ for (bGPdata *gpd = lb->first; gpd; gpd = gpd->id.next) {
if (gpd->id.us > 0 || wd->current) {
/* write gpd data block to file */
writestruct(wd, ID_GD, bGPdata, 1, gpd);
@@ -2962,22 +2851,21 @@ static void write_gpencils(WriteData *wd, ListBase *lb)
/* write grease-pencil layers to file */
writelist(wd, DATA, bGPDlayer, &gpd->layers);
- for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
-
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* write this layer's frames to file */
writelist(wd, DATA, bGPDframe, &gpl->frames);
- for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
-
+ for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
/* write strokes */
writelist(wd, DATA, bGPDstroke, &gpf->strokes);
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
writestruct(wd, DATA, bGPDspoint, gps->totpoints, gps->points);
}
}
}
+
/* write grease-pencil palettes */
writelist(wd, DATA, bGPDpalette, &gpd->palettes);
- for (palette = gpd->palettes.first; palette; palette = palette->next) {
+ for (bGPDpalette *palette = gpd->palettes.first; palette; palette = palette->next) {
writelist(wd, DATA, bGPDpalettecolor, &palette->colors);
}
}
@@ -2988,14 +2876,11 @@ static void write_gpencils(WriteData *wd, ListBase *lb)
static void write_windowmanagers(WriteData *wd, ListBase *lb)
{
- wmWindowManager *wm;
- wmWindow *win;
-
- for (wm = lb->first; wm; wm = wm->id.next) {
+ for (wmWindowManager *wm = lb->first; wm; wm = wm->id.next) {
writestruct(wd, ID_WM, wmWindowManager, 1, wm);
write_iddata(wd, &wm->id);
- for (win = wm->windows.first; win; win = win->next) {
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
writestruct(wd, DATA, wmWindow, 1, win);
writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format);
}
@@ -3088,14 +2973,7 @@ static void write_soops(WriteData *wd, SpaceOops *so)
static void write_screens(WriteData *wd, ListBase *scrbase)
{
- bScreen *sc;
- ScrArea *sa;
- ScrVert *sv;
- ScrEdge *se;
-
- sc = scrbase->first;
- while (sc) {
-
+ for (bScreen *sc = scrbase->first; sc; sc = sc->id.next) {
/* write LibData */
/* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
writestruct(wd, ID_SCRN, bScreen, 1, sc);
@@ -3104,15 +2982,15 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
write_previews(wd, sc->preview);
/* direct data */
- for (sv = sc->vertbase.first; sv; sv = sv->next) {
+ for (ScrVert *sv = sc->vertbase.first; sv; sv = sv->next) {
writestruct(wd, DATA, ScrVert, 1, sv);
}
- for (se = sc->edgebase.first; se; se = se->next) {
+ for (ScrEdge *se = sc->edgebase.first; se; se = se->next) {
writestruct(wd, DATA, ScrEdge, 1, se);
}
- for (sa = sc->areabase.first; sa; sa = sa->next) {
+ for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
Panel *pa;
uiList *ui_list;
@@ -3142,8 +3020,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
}
}
- sl = sa->spacedata.first;
- while (sl) {
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
for (ar = sl->regionbase.first; ar; ar = ar->next) {
write_region(wd, ar, sl->spacetype);
}
@@ -3260,12 +3137,8 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
else if (sl->spacetype == SPACE_COLLECTIONS) {
writestruct(wd, DATA, SpaceCollections, 1, sl);
}
-
- sl = sl->next;
}
}
-
- sc = sc->id.next;
}
mywrite_flush(wd);
@@ -3293,11 +3166,7 @@ static void write_bone(WriteData *wd, Bone *bone)
static void write_armatures(WriteData *wd, ListBase *idbase)
{
- bArmature *arm;
- Bone *bone;
-
- arm = idbase->first;
- while (arm) {
+ for (bArmature *arm = idbase->first; arm; arm = arm->id.next) {
if (arm->id.us > 0 || wd->current) {
writestruct(wd, ID_AR, bArmature, 1, arm);
write_iddata(wd, &arm->id);
@@ -3307,13 +3176,10 @@ static void write_armatures(WriteData *wd, ListBase *idbase)
}
/* Direct data */
- bone = arm->bonebase.first;
- while (bone) {
+ for (Bone *bone = arm->bonebase.first; bone; bone = bone->next) {
write_bone(wd, bone);
- bone = bone->next;
}
}
- arm = arm->id.next;
}
mywrite_flush(wd);
@@ -3321,12 +3187,8 @@ static void write_armatures(WriteData *wd, ListBase *idbase)
static void write_texts(WriteData *wd, ListBase *idbase)
{
- Text *text;
- TextLine *tmp;
-
- text = idbase->first;
- while (text) {
- if ( (text->flags & TXT_ISMEM) && (text->flags & TXT_ISEXT)) {
+ for (Text *text = idbase->first; text; text = text->id.next) {
+ if ((text->flags & TXT_ISMEM) && (text->flags & TXT_ISEXT)) {
text->flags &= ~TXT_ISEXT;
}
@@ -3340,21 +3202,14 @@ static void write_texts(WriteData *wd, ListBase *idbase)
if (!(text->flags & TXT_ISEXT)) {
/* now write the text data, in two steps for optimization in the readfunction */
- tmp = text->lines.first;
- while (tmp) {
+ for (TextLine *tmp = text->lines.first; tmp; tmp = tmp->next) {
writestruct(wd, DATA, TextLine, 1, tmp);
- tmp = tmp->next;
}
- tmp = text->lines.first;
- while (tmp) {
+ for (TextLine *tmp = text->lines.first; tmp; tmp = tmp->next) {
writedata(wd, DATA, tmp->len + 1, tmp->line);
- tmp = tmp->next;
}
}
-
-
- text = text->id.next;
}
mywrite_flush(wd);
@@ -3362,10 +3217,7 @@ static void write_texts(WriteData *wd, ListBase *idbase)
static void write_speakers(WriteData *wd, ListBase *idbase)
{
- Speaker *spk;
-
- spk = idbase->first;
- while (spk) {
+ for (Speaker *spk = idbase->first; spk; spk = spk->id.next) {
if (spk->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_SPK, Speaker, 1, spk);
@@ -3375,30 +3227,23 @@ static void write_speakers(WriteData *wd, ListBase *idbase)
write_animdata(wd, spk->adt);
}
}
- spk = spk->id.next;
}
}
static void write_sounds(WriteData *wd, ListBase *idbase)
{
- bSound *sound;
-
- PackedFile *pf;
-
- sound = idbase->first;
- while (sound) {
+ for (bSound *sound = idbase->first; sound; sound = sound->id.next) {
if (sound->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_SO, bSound, 1, sound);
write_iddata(wd, &sound->id);
if (sound->packedfile) {
- pf = sound->packedfile;
+ PackedFile *pf = sound->packedfile;
writestruct(wd, DATA, PackedFile, 1, pf);
writedata(wd, DATA, pf->size, pf->data);
}
}
- sound = sound->id.next;
}
mywrite_flush(wd);
@@ -3406,10 +3251,7 @@ static void write_sounds(WriteData *wd, ListBase *idbase)
static void write_groups(WriteData *wd, ListBase *idbase)
{
- Group *group;
- GroupObject *go;
-
- for (group = idbase->first; group; group = group->id.next) {
+ for (Group *group = idbase->first; group; group = group->id.next) {
if (group->id.us > 0 || wd->current) {
/* write LibData */
writestruct(wd, ID_GR, Group, 1, group);
@@ -3417,10 +3259,8 @@ static void write_groups(WriteData *wd, ListBase *idbase)
write_previews(wd, group->preview);
- go = group->gobject.first;
- while (go) {
+ for (GroupObject *go = group->gobject.first; go; go = go->next) {
writestruct(wd, DATA, GroupObject, 1, go);
- go = go->next;
}
}
}
@@ -3430,9 +3270,7 @@ static void write_groups(WriteData *wd, ListBase *idbase)
static void write_nodetrees(WriteData *wd, ListBase *idbase)
{
- bNodeTree *ntree;
-
- for (ntree = idbase->first; ntree; ntree = ntree->id.next) {
+ for (bNodeTree *ntree = idbase->first; ntree; ntree = ntree->id.next) {
if (ntree->id.us > 0 || wd->current) {
writestruct(wd, ID_NT, bNodeTree, 1, ntree);
/* Note that trees directly used by other IDs (materials etc.) are not 'real' ID, they cannot
@@ -3516,9 +3354,7 @@ static void customnodes_free_deprecated_data(Main *mainvar)
static void write_brushes(WriteData *wd, ListBase *idbase)
{
- Brush *brush;
-
- for (brush = idbase->first; brush; brush = brush->id.next) {
+ for (Brush *brush = idbase->first; brush; brush = brush->id.next) {
if (brush->id.us > 0 || wd->current) {
writestruct(wd, ID_BR, Brush, 1, brush);
write_iddata(wd, &brush->id);
@@ -3535,9 +3371,7 @@ static void write_brushes(WriteData *wd, ListBase *idbase)
static void write_palettes(WriteData *wd, ListBase *idbase)
{
- Palette *palette;
-
- for (palette = idbase->first; palette; palette = palette->id.next) {
+ for (Palette *palette = idbase->first; palette; palette = palette->id.next) {
if (palette->id.us > 0 || wd->current) {
PaletteColor *color;
writestruct(wd, ID_PAL, Palette, 1, palette);
@@ -3552,9 +3386,7 @@ static void write_palettes(WriteData *wd, ListBase *idbase)
static void write_paintcurves(WriteData *wd, ListBase *idbase)
{
- PaintCurve *pc;
-
- for (pc = idbase->first; pc; pc = pc->id.next) {
+ for (PaintCurve *pc = idbase->first; pc; pc = pc->id.next) {
if (pc->id.us > 0 || wd->current) {
writestruct(wd, ID_PC, PaintCurve, 1, pc);
write_iddata(wd, &pc->id);
@@ -3604,10 +3436,7 @@ static void write_movieReconstruction(WriteData *wd, MovieTrackingReconstruction
static void write_movieclips(WriteData *wd, ListBase *idbase)
{
- MovieClip *clip;
-
- clip = idbase->first;
- while (clip) {
+ for (MovieClip *clip = idbase->first; clip; clip = clip->id.next) {
if (clip->id.us > 0 || wd->current) {
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *object;
@@ -3634,8 +3463,6 @@ static void write_movieclips(WriteData *wd, ListBase *idbase)
object = object->next;
}
}
-
- clip = clip->id.next;
}
mywrite_flush(wd);
@@ -3643,10 +3470,7 @@ static void write_movieclips(WriteData *wd, ListBase *idbase)
static void write_masks(WriteData *wd, ListBase *idbase)
{
- Mask *mask;
-
- mask = idbase->first;
- while (mask) {
+ for (Mask *mask = idbase->first; mask; mask = mask->id.next) {
if (mask->id.us > 0 || wd->current) {
MaskLayer *masklay;
@@ -3694,8 +3518,6 @@ static void write_masks(WriteData *wd, ListBase *idbase)
}
}
}
-
- mask = mask->id.next;
}
mywrite_flush(wd);
@@ -3957,10 +3779,7 @@ static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifier
static void write_linestyles(WriteData *wd, ListBase *idbase)
{
- FreestyleLineStyle *linestyle;
- int a;
-
- for (linestyle = idbase->first; linestyle; linestyle = linestyle->id.next) {
+ for (FreestyleLineStyle *linestyle = idbase->first; linestyle; linestyle = linestyle->id.next) {
if (linestyle->id.us > 0 || wd->current) {
writestruct(wd, ID_LS, FreestyleLineStyle, 1, linestyle);
write_iddata(wd, &linestyle->id);
@@ -3973,7 +3792,7 @@ static void write_linestyles(WriteData *wd, ListBase *idbase)
write_linestyle_alpha_modifiers(wd, &linestyle->alpha_modifiers);
write_linestyle_thickness_modifiers(wd, &linestyle->thickness_modifiers);
write_linestyle_geometry_modifiers(wd, &linestyle->geometry_modifiers);
- for (a = 0; a < MAX_MTEX; a++) {
+ for (int a = 0; a < MAX_MTEX; a++) {
if (linestyle->mtex[a]) {
writestruct(wd, DATA, MTex, 1, linestyle->mtex[a]);
}
@@ -3988,9 +3807,7 @@ static void write_linestyles(WriteData *wd, ListBase *idbase)
static void write_cachefiles(WriteData *wd, ListBase *idbase)
{
- CacheFile *cache_file;
-
- for (cache_file = idbase->first; cache_file; cache_file = cache_file->id.next) {
+ for (CacheFile *cache_file = idbase->first; cache_file; cache_file = cache_file->id.next) {
if (cache_file->id.us > 0 || wd->current) {
writestruct(wd, ID_CF, CacheFile, 1, cache_file);
@@ -4010,7 +3827,6 @@ static void write_libraries(WriteData *wd, Main *main)
bool found_one;
for (; main; main = main->next) {
-
a = tot = set_listbasepointers(main, lbarray);
/* test: is lib being used */
@@ -4019,16 +3835,13 @@ static void write_libraries(WriteData *wd, Main *main)
}
else {
found_one = false;
- while (tot--) {
+ while (!found_one && tot--) {
for (id = lbarray[tot]->first; id; id = id->next) {
if (id->us > 0 && (id->tag & LIB_TAG_EXTERN)) {
found_one = true;
break;
}
}
- if (found_one) {
- break;
- }
}
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index 065f65659e6..3a042535d26 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -53,6 +53,7 @@ extern "C" {
#include "intern/nodes/deg_node_component.h"
#include "intern/nodes/deg_node_operation.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_intern.h"
#include "util/deg_util_foreach.h"
/* Unfinished and unused, and takes quite some pre-processing time. */
@@ -362,6 +363,11 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
return;
}
+ DEG_DEBUG_PRINTF("%s: layers:%u, graph->layers:%u\n",
+ __func__,
+ layers,
+ graph->layers);
+
/* Set time for the current graph evaluation context. */
TimeSourceDepsNode *time_src = graph->find_time_source();
eval_ctx->ctime = time_src->cfra;
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index caa18b91775..4d9ba351c3a 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -970,6 +970,9 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S
ToolSettings *ts = CTX_data_tool_settings(C);
int point_added = 0;
+ /* TODO: Since the function `ED_transform_snap_object_context_create_view3d` creates a cache,
+ * the ideal would be to call this function only at the beginning of the snap operation,
+ * or at the beginning of the operator itself */
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
CTX_data_main(C), CTX_data_scene(C), 0,
CTX_wm_region(C), CTX_wm_view3d(C));
@@ -1038,6 +1041,8 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S
}
}
+ /* TODO: The ideal would be to call this function only once.
+ * At the end of the operator */
ED_transform_snap_object_context_destroy(snap_context);
return point_added;
}
diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h
index 7944b434057..6eaae49912c 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -65,10 +65,6 @@ struct SnapObjectParams {
unsigned int use_object_edit_cage : 1;
};
-enum {
- SNAP_OBJECT_USE_CACHE = (1 << 0),
-};
-
typedef struct SnapObjectContext SnapObjectContext;
SnapObjectContext *ED_transform_snap_object_context_create(
struct Main *bmain, struct Scene *scene, int flag);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 549bcd4c4b6..d76dba4088a 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -307,7 +307,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
ED_view3d_init_mats_rv3d(obedit, ar->regiondata);
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), CTX_data_scene(C), SNAP_OBJECT_USE_CACHE,
+ CTX_data_main(C), CTX_data_scene(C), 0,
ar, CTX_wm_view3d(C));
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 5454a930485..67ef4515c18 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -363,8 +363,8 @@ void ED_vgroup_parray_remove_zero(MDeformVert **dvert_array, const int dvert_tot
/* matching index only */
bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
{
- MDeformVert **dvert_array_from, **dvf;
- MDeformVert **dvert_array, **dv;
+ MDeformVert **dvert_array_from = NULL, **dvf;
+ MDeformVert **dvert_array = NULL, **dv;
int dvert_tot_from;
int dvert_tot;
int i;
@@ -375,26 +375,30 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
if (ob == ob_from)
return true;
- ED_vgroup_parray_alloc(ob_from->data, &dvert_array_from, &dvert_tot_from, false);
- ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
-
- if ((dvert_array == NULL) && (dvert_array_from != NULL) && BKE_object_defgroup_data_create(ob->data)) {
+ /* in case we copy vgroup between two objects using same data, we only have to care about object side of things. */
+ if (ob->data != ob_from->data) {
+ ED_vgroup_parray_alloc(ob_from->data, &dvert_array_from, &dvert_tot_from, false);
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
- new_vgroup = true;
- }
- if (dvert_tot == 0 || (dvert_tot != dvert_tot_from) || dvert_array_from == NULL || dvert_array == NULL) {
+ if ((dvert_array == NULL) && (dvert_array_from != NULL) && BKE_object_defgroup_data_create(ob->data)) {
+ ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
+ new_vgroup = true;
+ }
- if (dvert_array) MEM_freeN(dvert_array);
- if (dvert_array_from) MEM_freeN(dvert_array_from);
+ if (dvert_tot == 0 || (dvert_tot != dvert_tot_from) || dvert_array_from == NULL || dvert_array == NULL) {
+ if (dvert_array)
+ MEM_freeN(dvert_array);
+ if (dvert_array_from)
+ MEM_freeN(dvert_array_from);
- if (new_vgroup == true) {
- /* free the newly added vgroup since it wasn't compatible */
- BKE_object_defgroup_remove_all(ob);
- }
+ if (new_vgroup == true) {
+ /* free the newly added vgroup since it wasn't compatible */
+ BKE_object_defgroup_remove_all(ob);
+ }
- /* if true: both are 0 and nothing needs changing, consider this a success */
- return (dvert_tot == dvert_tot_from);
+ /* if true: both are 0 and nothing needs changing, consider this a success */
+ return (dvert_tot == dvert_tot_from);
+ }
}
/* do the copy */
@@ -412,22 +416,23 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
MEM_freeN(remap);
}
- dvf = dvert_array_from;
- dv = dvert_array;
+ if (dvert_array_from != NULL && dvert_array != NULL) {
+ dvf = dvert_array_from;
+ dv = dvert_array;
- for (i = 0; i < dvert_tot; i++, dvf++, dv++) {
- if ((*dv)->dw)
- MEM_freeN((*dv)->dw);
+ for (i = 0; i < dvert_tot; i++, dvf++, dv++) {
+ MEM_SAFE_FREE((*dv)->dw);
+ *(*dv) = *(*dvf);
- *(*dv) = *(*dvf);
+ if ((*dv)->dw) {
+ (*dv)->dw = MEM_dupallocN((*dv)->dw);
+ }
+ }
- if ((*dv)->dw)
- (*dv)->dw = MEM_dupallocN((*dv)->dw);
+ MEM_freeN(dvert_array);
+ MEM_freeN(dvert_array_from);
}
- MEM_freeN(dvert_array);
- MEM_freeN(dvert_array_from);
-
return true;
}
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index 482fe356b46..4a4d008f779 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -282,7 +282,7 @@ static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
}
else if (state == RULER_STATE_DRAG) {
ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), CTX_data_scene(C), SNAP_OBJECT_USE_CACHE,
+ CTX_data_main(C), CTX_data_scene(C), 0,
ruler_info->ar, CTX_wm_view3d(C));
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 4131a5c33c7..d4e78035b84 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -599,7 +599,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->rv3d->rflag |= RV3D_NAVIGATING;
walk->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), walk->scene, SNAP_OBJECT_USE_CACHE,
+ CTX_data_main(C), walk->scene, 0,
walk->ar, walk->v3d);
walk->v3d_camera_control = ED_view3d_cameracontrol_acquire(
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 65ef3393d05..1aa1bd341d7 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -3736,6 +3736,12 @@ static void initRotation(TransInfo *t)
copy_v3_v3(t->axis_orig, t->axis);
}
+/**
+ * Applies values of rotation to `td->loc` and `td->ext->quat`
+ * based on a rotation matrix (mat) and a pivot (center).
+ *
+ * Protected axis and other transform settings are taken into account.
+ */
static void ElementRotation_ex(TransInfo *t, TransData *td, float mat[3][3], const float *center)
{
float vec[3], totmat[3][3], smat[3][3];
@@ -4353,9 +4359,22 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
{
TransData *td = t->data;
float tvec[3];
- int i;
- for (i = 0; i < t->total; i++, td++) {
+ /* The ideal would be "apply_snap_align_rotation" only when a snap point is found
+ * so, maybe inside this function is not the best place to apply this rotation.
+ * but you need "handle snapping rotation before doing the translation" (really?) */
+ const bool apply_snap_align_rotation = usingSnappingNormal(t);// && (t->tsnap.status & POINT_INIT);
+ float pivot[3];
+ if (apply_snap_align_rotation) {
+ copy_v3_v3(pivot, t->tsnap.snapTarget);
+ /* The pivot has to be in local-space (see T49494) */
+ if (t->flag & (T_EDIT | T_POSE)) {
+ Object *ob = t->obedit ? t->obedit : t->poseobj;
+ mul_m4_v3(ob->imat, pivot);
+ }
+ }
+
+ for (int i = 0; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
@@ -4366,7 +4385,7 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
bool use_rotate_offset = false;
/* handle snapping rotation before doing the translation */
- if (usingSnappingNormal(t)) {
+ if (apply_snap_align_rotation) {
float mat[3][3];
if (validSnappingNormal(t)) {
@@ -4384,7 +4403,7 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
unit_m3(mat);
}
- ElementRotation_ex(t, td, mat, t->tsnap.snapTarget);
+ ElementRotation_ex(t, td, mat, pivot);
if (td->loc) {
use_rotate_offset = true;
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 7ea4448a44e..d60eb2f0778 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -84,8 +84,8 @@ typedef struct TransSnap {
bool peel;
bool snap_spatial_grid;
short status;
- float snapPoint[3]; /* snapping from this point */
- float snapTarget[3]; /* to this point */
+ float snapPoint[3]; /* snapping from this point (in global-space)*/
+ float snapTarget[3]; /* to this point (in global-space)*/
float snapNormal[3];
char snapNodeBorder;
ListBase points;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index cb828914735..4260b877e90 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2381,7 +2381,12 @@ static void createTransEditVerts(TransInfo *t)
editmesh_set_connectivity_distance(em->bm, mtx, dists);
}
- if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
+ /* Only in case of rotation and resize, we want the elements of the edited
+ * object to behave as groups whose pivot are the individual origins
+ *
+ * TODO: use island_info to detect the closest point when the "Snap Target"
+ * in Blender UI is "Closest" */
+ if ((t->around == V3D_AROUND_LOCAL_ORIGINS) && (t->mode != TFM_TRANSLATION)) {
island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map);
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 8ffcc41258a..bd640463da2 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -613,7 +613,7 @@ static void initSnappingMode(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D) {
if (t->tsnap.object_context == NULL) {
t->tsnap.object_context = ED_transform_snap_object_context_create_view3d(
- G.main, t->scene, SNAP_OBJECT_USE_CACHE,
+ G.main, t->scene, 0,
t->ar, t->view);
ED_transform_snap_object_context_set_editmesh_callbacks(
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 90c8b236397..2e95b67d508 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -235,21 +235,6 @@ static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVH
/** \Common utilities
* \{ */
-MINLINE float depth_get(const float co[3], const float ray_start[3], const float ray_dir[3])
-{
- float dvec[3];
- sub_v3_v3v3(dvec, co, ray_start);
- return dot_v3v3(dvec, ray_dir);
-}
-
-/**
- * Struct that kepts basic information about a BVHTree build from a editmesh.
- */
-typedef struct BVHTreeFromMeshType {
- void *userdata;
- char type;
-} BVHTreeFromMeshType;
-
/**
* Generates a struct with the immutable parameters that will be used on all objects.
*
@@ -286,52 +271,42 @@ static void snap_data_set(
copy_v2_v2(snapdata->depth_range, depth_range);
}
-static void copy_vert_no(const BVHTreeFromMeshType *meshdata, const int index, float r_no[3])
+MINLINE float depth_get(const float co[3], const float ray_start[3], const float ray_dir[3])
{
- switch (meshdata->type) {
- case SNAP_MESH:
- {
- BVHTreeFromMesh *data = meshdata->userdata;
- const MVert *vert = data->vert + index;
- normal_short_to_float_v3(r_no, vert->no);
- break;
- }
- case SNAP_EDIT_MESH:
- {
- BVHTreeFromEditMesh *data = meshdata->userdata;
- BMVert *eve = BM_vert_at_index(data->em->bm, index);
- copy_v3_v3(r_no, eve->no);
- break;
- }
- }
+ float dvec[3];
+ sub_v3_v3v3(dvec, co, ray_start);
+ return dot_v3v3(dvec, ray_dir);
}
-static void get_edge_verts(
- const BVHTreeFromMeshType *meshdata, const int index,
- const float *v_pair[2])
+static void copy_dm_vert_no(const int index, float r_no[3], const BVHTreeFromMesh *data)
{
- switch (meshdata->type) {
- case SNAP_MESH:
- {
- BVHTreeFromMesh *data = meshdata->userdata;
+ const MVert *vert = data->vert + index;
- const MVert *vert = data->vert;
- const MEdge *edge = data->edge + index;
+ normal_short_to_float_v3(r_no, vert->no);
+}
- v_pair[0] = vert[edge->v1].co;
- v_pair[1] = vert[edge->v2].co;
- break;
- }
- case SNAP_EDIT_MESH:
- {
- BVHTreeFromEditMesh *data = meshdata->userdata;
- BMEdge *eed = BM_edge_at_index(data->em->bm, index);
+static void copy_bvert_no(const int index, float r_no[3], const BVHTreeFromEditMesh *data)
+{
+ BMVert *eve = BM_vert_at_index(data->em->bm, index);
- v_pair[0] = eed->v1->co;
- v_pair[1] = eed->v2->co;
- break;
- }
- }
+ copy_v3_v3(r_no, eve->no);
+}
+
+static void get_dm_edge_verts(const int index, const float *v_pair[2], const BVHTreeFromMesh *data)
+{
+ const MVert *vert = data->vert;
+ const MEdge *edge = data->edge + index;
+
+ v_pair[0] = vert[edge->v1].co;
+ v_pair[1] = vert[edge->v2].co;
+}
+
+static void get_bedge_verts(const int index, const float *v_pair[2], const BVHTreeFromEditMesh *data)
+{
+ BMEdge *eed = BM_edge_at_index(data->em->bm, index);
+
+ v_pair[0] = eed->v1->co;
+ v_pair[1] = eed->v2->co;
}
static bool test_projected_vert_dist(
@@ -422,6 +397,7 @@ static void dist_squared_to_projected_aabb_precalc(
}
}
+/* Returns the distance from a 2d coordinate to a BoundBox (Projected) */
static float dist_squared_to_projected_aabb(
struct Nearest2dPrecalc *data,
const float bbmin[3], const float bbmax[3],
@@ -644,6 +620,10 @@ static float dist_aabb_to_plane(
/** \Walk DFS
* \{ */
+
+typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, const float *v_pair[2], void *data);
+typedef void (*Nearest2DCopyVertNoCallback)(const int index, float r_no[3], void *data);
+
typedef struct Nearest2dUserData {
struct Nearest2dPrecalc data_precalc;
@@ -652,7 +632,11 @@ typedef struct Nearest2dUserData {
bool r_axis_closest[3];
float depth_range[2];
+
void *userdata;
+ Nearest2DGetEdgeVertsCallback get_edge_verts;
+ Nearest2DCopyVertNoCallback copy_vert_no;
+
int index;
float co[3];
float no[3];
@@ -688,7 +672,7 @@ static bool cb_walk_leaf_snap_vert(const BVHTreeAxisRange *bounds, int index, vo
&data->dist_px_sq,
data->co))
{
- copy_vert_no(data->userdata, index, data->no);
+ data->copy_vert_no(index, data->no, data->userdata);
data->index = index;
}
return true;
@@ -700,7 +684,7 @@ static bool cb_walk_leaf_snap_edge(const BVHTreeAxisRange *UNUSED(bounds), int i
struct Nearest2dPrecalc *neasrest_precalc = &data->data_precalc;
const float *v_pair[2];
- get_edge_verts(data->userdata, index, v_pair);
+ data->get_edge_verts(index, v_pair, data->userdata);
if (test_projected_edge_dist(
data->depth_range,
@@ -1092,274 +1076,259 @@ static bool snapDerivedMesh(
}
}
- {
- bool need_ray_start_correction_init =
- (snapdata->snap_to == SCE_SNAP_MODE_FACE) &&
- (snapdata->view_proj == VIEW_PROJ_ORTHO);
+ bool need_ray_start_correction_init =
+ (snapdata->snap_to == SCE_SNAP_MODE_FACE) &&
+ (snapdata->view_proj == VIEW_PROJ_ORTHO);
- float imat[4][4];
- float timat[3][3]; /* transpose inverse matrix for normals */
- float ray_start_local[3], ray_normal_local[3];
- float local_scale, local_depth, len_diff;
+ float imat[4][4];
+ float timat[3][3]; /* transpose inverse matrix for normals */
+ float ray_start_local[3], ray_normal_local[3];
+ float local_scale, local_depth, len_diff;
- invert_m4_m4(imat, obmat);
- transpose_m3_m4(timat, imat);
+ invert_m4_m4(imat, obmat);
+ transpose_m3_m4(timat, imat);
- copy_v3_v3(ray_start_local, snapdata->ray_start);
- copy_v3_v3(ray_normal_local, snapdata->ray_dir);
+ copy_v3_v3(ray_start_local, snapdata->ray_start);
+ copy_v3_v3(ray_normal_local, snapdata->ray_dir);
- mul_m4_v3(imat, ray_start_local);
- mul_mat3_m4_v3(imat, ray_normal_local);
+ mul_m4_v3(imat, ray_start_local);
+ mul_mat3_m4_v3(imat, ray_normal_local);
- /* local scale in normal direction */
- local_scale = normalize_v3(ray_normal_local);
- local_depth = *ray_depth;
- if (local_depth != BVH_RAYCAST_DIST_MAX) {
- local_depth *= local_scale;
- }
+ /* local scale in normal direction */
+ local_scale = normalize_v3(ray_normal_local);
+ local_depth = *ray_depth;
+ if (local_depth != BVH_RAYCAST_DIST_MAX) {
+ local_depth *= local_scale;
+ }
- float lpmat[4][4];
- float ray_org_local[3];
- float ray_min_dist;
- if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
- mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
- ray_min_dist = snapdata->depth_range[0] * local_scale;
- }
+ float lpmat[4][4];
+ float ray_org_local[3];
+ float ray_min_dist;
+ if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
+ mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
+ ray_min_dist = snapdata->depth_range[0] * local_scale;
+ }
- copy_v3_v3(ray_org_local, snapdata->ray_origin);
- mul_m4_v3(imat, ray_org_local);
+ copy_v3_v3(ray_org_local, snapdata->ray_origin);
+ mul_m4_v3(imat, ray_org_local);
- if (do_bb) {
- BoundBox *bb = BKE_object_boundbox_get(ob);
+ if (do_bb) {
+ BoundBox *bb = BKE_object_boundbox_get(ob);
- if (bb) {
- BoundBox bb_temp;
+ if (bb) {
+ BoundBox bb_temp;
- /* We cannot afford a bounding box with some null dimension, which may happen in some cases...
- * Threshold is rather high, but seems to be needed to get good behavior, see T46099. */
- bb = BKE_boundbox_ensure_minimum_dimensions(bb, &bb_temp, 1e-1f);
+ /* We cannot afford a bounding box with some null dimension, which may happen in some cases...
+ * Threshold is rather high, but seems to be needed to get good behavior, see T46099. */
+ bb = BKE_boundbox_ensure_minimum_dimensions(bb, &bb_temp, 1e-1f);
- /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see T46816. */
- if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
- float dist_px_sq = dist_squared_to_projected_aabb_simple(
- lpmat, snapdata->win_half, ray_min_dist, snapdata->mval,
- ray_org_local, ray_normal_local, bb->vec[0], bb->vec[6]);
- if (dist_px_sq > SQUARE(*dist_px))
- {
- return retval;
- }
+ /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see T46816. */
+ if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
+ float dist_px_sq = dist_squared_to_projected_aabb_simple(
+ lpmat, snapdata->win_half, ray_min_dist, snapdata->mval,
+ ray_org_local, ray_normal_local, bb->vec[0], bb->vec[6]);
+ if (dist_px_sq > SQUARE(*dist_px))
+ {
+ return retval;
}
- else {
- /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
- if (!isect_ray_aabb_v3_simple(
- ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], NULL, NULL))
- {
- return retval;
- }
+ }
+ else {
+ /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
+ if (!isect_ray_aabb_v3_simple(
+ ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], NULL, NULL))
+ {
+ return retval;
}
- /* was local_depth, see: T47838 */
- len_diff = dist_aabb_to_plane(bb->vec[0], bb->vec[6], ray_start_local, ray_normal_local);
- if (len_diff < 0) len_diff = 0.0f;
- need_ray_start_correction_init = false;
}
+ /* was local_depth, see: T47838 */
+ len_diff = dist_aabb_to_plane(bb->vec[0], bb->vec[6], ray_start_local, ray_normal_local);
+ if (len_diff < 0) len_diff = 0.0f;
+ need_ray_start_correction_init = false;
}
+ }
- SnapObjectData_Mesh *sod = NULL;
- BVHTreeFromMesh *treedata = NULL, treedata_stack;
+ SnapObjectData_Mesh *sod = NULL;
+ BVHTreeFromMesh *treedata = NULL;
- if (sctx->flag & SNAP_OBJECT_USE_CACHE) {
- void **sod_p;
- if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
- sod = *sod_p;
- }
- else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_MESH;
- }
-
- int tree_index = -1;
- switch (snapdata->snap_to) {
- case SCE_SNAP_MODE_FACE:
- tree_index = 2;
- break;
- case SCE_SNAP_MODE_EDGE:
- tree_index = 1;
- break;
- case SCE_SNAP_MODE_VERTEX:
- tree_index = 0;
- break;
- }
- if (tree_index != -1) {
- if (sod->bvh_trees[tree_index] == NULL) {
- sod->bvh_trees[tree_index] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
- }
- treedata = sod->bvh_trees[tree_index];
+ void **sod_p;
+ if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
+ sod = *sod_p;
+ }
+ else {
+ sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod->sd.type = SNAP_MESH;
+ }
- /* the tree is owned by the DM and may have been freed since we last used! */
- if (treedata && treedata->tree) {
- if (treedata->cached && !bvhcache_has_tree(dm->bvhCache, treedata->tree)) {
- free_bvhtree_from_mesh(treedata);
- }
- }
- }
- }
- else {
- treedata = &treedata_stack;
- memset(treedata, 0, sizeof(*treedata));
+ int tree_index = -1;
+ switch (snapdata->snap_to) {
+ case SCE_SNAP_MODE_FACE:
+ tree_index = 2;
+ break;
+ case SCE_SNAP_MODE_EDGE:
+ tree_index = 1;
+ break;
+ case SCE_SNAP_MODE_VERTEX:
+ tree_index = 0;
+ break;
+ }
+ if (tree_index != -1) {
+ if (sod->bvh_trees[tree_index] == NULL) {
+ sod->bvh_trees[tree_index] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
}
+ treedata = sod->bvh_trees[tree_index];
- if (treedata && treedata->tree == NULL) {
- switch (snapdata->snap_to) {
- case SCE_SNAP_MODE_FACE:
- bvhtree_from_mesh_looptri(treedata, dm, 0.0f, 4, 6);
- break;
- case SCE_SNAP_MODE_EDGE:
- bvhtree_from_mesh_edges(treedata, dm, 0.0f, 2, 6);
- break;
- case SCE_SNAP_MODE_VERTEX:
- bvhtree_from_mesh_verts(treedata, dm, 0.0f, 2, 6);
- break;
+ /* the tree is owned by the DM and may have been freed since we last used! */
+ if (treedata && treedata->tree) {
+ if (treedata->cached && !bvhcache_has_tree(dm->bvhCache, treedata->tree)) {
+ free_bvhtree_from_mesh(treedata);
}
}
+ }
- if (!treedata || !treedata->tree) {
- return retval;
+ if (treedata && treedata->tree == NULL) {
+ switch (snapdata->snap_to) {
+ case SCE_SNAP_MODE_FACE:
+ bvhtree_from_mesh_looptri(treedata, dm, 0.0f, 4, 6);
+ break;
+ case SCE_SNAP_MODE_EDGE:
+ bvhtree_from_mesh_edges(treedata, dm, 0.0f, 2, 6);
+ break;
+ case SCE_SNAP_MODE_VERTEX:
+ bvhtree_from_mesh_verts(treedata, dm, 0.0f, 2, 6);
+ break;
}
+ }
+ if (!treedata || !treedata->tree) {
+ return retval;
+ }
- if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
- /* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already
- * been *inside* boundbox, leading to snap failures (see T38409).
- * Note also ar might be null (see T38435), in this case we assume ray_start is ok!
- */
- if (snapdata->view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
- if (need_ray_start_correction_init) {
- /* We *need* a reasonably valid len_diff in this case.
- * Use BHVTree to find the closest face from ray_start_local.
- */
- BVHTreeNearest nearest;
- nearest.index = -1;
- nearest.dist_sq = FLT_MAX;
- /* Compute and store result. */
- BLI_bvhtree_find_nearest(
- treedata->tree, ray_start_local, &nearest, treedata->nearest_callback, treedata);
- if (nearest.index != -1) {
- float dvec[3];
- sub_v3_v3v3(dvec, nearest.co, ray_start_local);
- len_diff = dot_v3v3(dvec, ray_normal_local);
- }
- }
- /* You need to make sure that ray_start is really far away,
- * because even in the Orthografic view, in some cases,
- * the ray can start inside the object (see T50486) */
- if (len_diff > 400.0f) {
- /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with
- * very far away ray_start values (as returned in case of ortho view3d), see T38358.
- */
- len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
- madd_v3_v3v3fl(
- ray_start_local, ray_org_local, ray_normal_local,
- len_diff + snapdata->depth_range[0] * local_scale);
- local_depth -= len_diff;
+ if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
+ /* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already
+ * been *inside* boundbox, leading to snap failures (see T38409).
+ * Note also ar might be null (see T38435), in this case we assume ray_start is ok!
+ */
+ if (snapdata->view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
+ if (need_ray_start_correction_init) {
+ /* We *need* a reasonably valid len_diff in this case.
+ * Use BHVTree to find the closest face from ray_start_local.
+ */
+ BVHTreeNearest nearest;
+ nearest.index = -1;
+ nearest.dist_sq = FLT_MAX;
+ /* Compute and store result. */
+ BLI_bvhtree_find_nearest(
+ treedata->tree, ray_start_local, &nearest, treedata->nearest_callback, treedata);
+ if (nearest.index != -1) {
+ float dvec[3];
+ sub_v3_v3v3(dvec, nearest.co, ray_start_local);
+ len_diff = dot_v3v3(dvec, ray_normal_local);
}
- else len_diff = 0.0f;
- }
- else {
- len_diff = 0.0f;
}
- if (r_hit_list) {
- struct RayCastAll_Data data;
-
- data.bvhdata = treedata;
- data.raycast_callback = treedata->raycast_callback;
- data.obmat = obmat;
- data.timat = timat;
- data.len_diff = len_diff;
- data.local_scale = local_scale;
- data.ob = ob;
- data.ob_uuid = ob_index;
- data.hit_list = r_hit_list;
- data.retval = retval;
-
- BLI_bvhtree_ray_cast_all(
- treedata->tree, ray_start_local, ray_normal_local, 0.0f,
- *ray_depth, raycast_all_cb, &data);
-
- retval = data.retval;
+ /* You need to make sure that ray_start is really far away,
+ * because even in the Orthografic view, in some cases,
+ * the ray can start inside the object (see T50486) */
+ if (len_diff > 400.0f) {
+ /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with
+ * very far away ray_start values (as returned in case of ortho view3d), see T38358.
+ */
+ len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
+ madd_v3_v3v3fl(
+ ray_start_local, ray_org_local, ray_normal_local,
+ len_diff + snapdata->depth_range[0] * local_scale);
+ local_depth -= len_diff;
}
- else {
- BVHTreeRayHit hit = {.index = -1, .dist = local_depth};
+ else len_diff = 0.0f;
+ }
+ else {
+ len_diff = 0.0f;
+ }
+ if (r_hit_list) {
+ struct RayCastAll_Data data;
+
+ data.bvhdata = treedata;
+ data.raycast_callback = treedata->raycast_callback;
+ data.obmat = obmat;
+ data.timat = timat;
+ data.len_diff = len_diff;
+ data.local_scale = local_scale;
+ data.ob = ob;
+ data.ob_uuid = ob_index;
+ data.hit_list = r_hit_list;
+ data.retval = retval;
+
+ BLI_bvhtree_ray_cast_all(
+ treedata->tree, ray_start_local, ray_normal_local, 0.0f,
+ *ray_depth, raycast_all_cb, &data);
+
+ retval = data.retval;
+ }
+ else {
+ BVHTreeRayHit hit = {.index = -1, .dist = local_depth};
- if (BLI_bvhtree_ray_cast(
- treedata->tree, ray_start_local, ray_normal_local, 0.0f,
- &hit, treedata->raycast_callback, treedata) != -1)
- {
- hit.dist += len_diff;
- hit.dist /= local_scale;
- if (hit.dist <= *ray_depth) {
- *ray_depth = hit.dist;
- copy_v3_v3(r_loc, hit.co);
-
- /* back to worldspace */
- mul_m4_v3(obmat, r_loc);
-
- if (r_no) {
- copy_v3_v3(r_no, hit.no);
- mul_m3_v3(timat, r_no);
- normalize_v3(r_no);
- }
+ if (BLI_bvhtree_ray_cast(
+ treedata->tree, ray_start_local, ray_normal_local, 0.0f,
+ &hit, treedata->raycast_callback, treedata) != -1)
+ {
+ hit.dist += len_diff;
+ hit.dist /= local_scale;
+ if (hit.dist <= *ray_depth) {
+ *ray_depth = hit.dist;
+ copy_v3_v3(r_loc, hit.co);
+
+ /* back to worldspace */
+ mul_m4_v3(obmat, r_loc);
+
+ if (r_no) {
+ copy_v3_v3(r_no, hit.no);
+ mul_m3_v3(timat, r_no);
+ normalize_v3(r_no);
+ }
- retval = true;
+ retval = true;
- if (r_index) {
- *r_index = dm_looptri_to_poly_index(dm, &treedata->looptri[hit.index]);
- }
+ if (r_index) {
+ *r_index = dm_looptri_to_poly_index(dm, &treedata->looptri[hit.index]);
}
}
}
}
- /* SCE_SNAP_MODE_VERTEX or SCE_SNAP_MODE_EDGE */
- else {
- BVHTreeFromMeshType treedata_type = {.userdata = treedata, .type = SNAP_MESH};
-
- Nearest2dUserData neasrest2d = {
- .dist_px_sq = SQUARE(*dist_px),
- .r_axis_closest = {1.0f, 1.0f, 1.0f},
- .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
- .userdata = &treedata_type,
- .index = -1};
-
- dist_squared_to_projected_aabb_precalc(
- &neasrest2d.data_precalc, lpmat,
- snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
- ray_min_dist, snapdata->mval, ray_org_local, ray_normal_local);
-
- BVHTree_WalkLeafCallback cb_walk_leaf =
- (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
- cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
-
- BLI_bvhtree_walk_dfs(
- treedata->tree,
- cb_walk_parent_snap_project, cb_walk_leaf, cb_nearest_walk_order, &neasrest2d);
-
- if (neasrest2d.index != -1) {
- copy_v3_v3(r_loc, neasrest2d.co);
- mul_m4_v3(obmat, r_loc);
- if (r_no) {
- copy_v3_v3(r_no, neasrest2d.no);
- mul_m3_v3(timat, r_no);
- normalize_v3(r_no);
- }
- *dist_px = sqrtf(neasrest2d.dist_px_sq);
- *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
-
- retval = true;
+ }
+ /* SCE_SNAP_MODE_VERTEX or SCE_SNAP_MODE_EDGE */
+ else {
+ Nearest2dUserData neasrest2d = {
+ .dist_px_sq = SQUARE(*dist_px),
+ .r_axis_closest = {1.0f, 1.0f, 1.0f},
+ .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
+ .userdata = treedata,
+ .get_edge_verts = (Nearest2DGetEdgeVertsCallback)get_dm_edge_verts,
+ .copy_vert_no = (Nearest2DCopyVertNoCallback)copy_dm_vert_no,
+ .index = -1};
+
+ dist_squared_to_projected_aabb_precalc(
+ &neasrest2d.data_precalc, lpmat,
+ snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
+ ray_min_dist, snapdata->mval, ray_org_local, ray_normal_local);
+
+ BVHTree_WalkLeafCallback cb_walk_leaf =
+ (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
+ cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
+
+ BLI_bvhtree_walk_dfs(
+ treedata->tree,
+ cb_walk_parent_snap_project, cb_walk_leaf, cb_nearest_walk_order, &neasrest2d);
+
+ if (neasrest2d.index != -1) {
+ copy_v3_v3(r_loc, neasrest2d.co);
+ mul_m4_v3(obmat, r_loc);
+ if (r_no) {
+ copy_v3_v3(r_no, neasrest2d.no);
+ mul_m3_v3(timat, r_no);
+ normalize_v3(r_no);
}
- }
+ *dist_px = sqrtf(neasrest2d.dist_px_sq);
+ *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
- if ((sctx->flag & SNAP_OBJECT_USE_CACHE) == 0) {
- if (treedata) {
- free_bvhtree_from_mesh(treedata);
- }
+ retval = true;
}
}
@@ -1393,268 +1362,246 @@ static bool snapEditMesh(
}
}
- {
- float imat[4][4];
- float timat[3][3]; /* transpose inverse matrix for normals */
- float ray_normal_local[3];
+ float imat[4][4];
+ float timat[3][3]; /* transpose inverse matrix for normals */
+ float ray_normal_local[3];
- invert_m4_m4(imat, obmat);
- transpose_m3_m4(timat, imat);
+ invert_m4_m4(imat, obmat);
+ transpose_m3_m4(timat, imat);
- copy_v3_v3(ray_normal_local, snapdata->ray_dir);
+ copy_v3_v3(ray_normal_local, snapdata->ray_dir);
- mul_mat3_m4_v3(imat, ray_normal_local);
+ mul_mat3_m4_v3(imat, ray_normal_local);
- /* local scale in normal direction */
- float local_scale = normalize_v3(ray_normal_local);
- float local_depth = *ray_depth;
- if (local_depth != BVH_RAYCAST_DIST_MAX) {
- local_depth *= local_scale;
- }
+ /* local scale in normal direction */
+ float local_scale = normalize_v3(ray_normal_local);
+ float local_depth = *ray_depth;
+ if (local_depth != BVH_RAYCAST_DIST_MAX) {
+ local_depth *= local_scale;
+ }
- SnapObjectData_EditMesh *sod = NULL;
+ SnapObjectData_EditMesh *sod = NULL;
- BVHTreeFromEditMesh *treedata = NULL, treedata_stack;
+ BVHTreeFromEditMesh *treedata = NULL;
- if (sctx->flag & SNAP_OBJECT_USE_CACHE) {
- void **sod_p;
- if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
- sod = *sod_p;
- }
- else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_EDIT_MESH;
- }
+ void **sod_p;
+ if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
+ sod = *sod_p;
+ }
+ else {
+ sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod->sd.type = SNAP_EDIT_MESH;
+ }
- int tree_index = -1;
- switch (snapdata->snap_to) {
- case SCE_SNAP_MODE_FACE:
- tree_index = 2;
- break;
- case SCE_SNAP_MODE_EDGE:
- tree_index = 1;
- break;
- case SCE_SNAP_MODE_VERTEX:
- tree_index = 0;
- break;
- }
- if (tree_index != -1) {
- if (sod->bvh_trees[tree_index] == NULL) {
- sod->bvh_trees[tree_index] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
- }
- treedata = sod->bvh_trees[tree_index];
- }
- }
- else {
- treedata = &treedata_stack;
- memset(treedata, 0, sizeof(*treedata));
+ int tree_index = -1;
+ switch (snapdata->snap_to) {
+ case SCE_SNAP_MODE_FACE:
+ tree_index = 2;
+ break;
+ case SCE_SNAP_MODE_EDGE:
+ tree_index = 1;
+ break;
+ case SCE_SNAP_MODE_VERTEX:
+ tree_index = 0;
+ break;
+ }
+ if (tree_index != -1) {
+ if (sod->bvh_trees[tree_index] == NULL) {
+ sod->bvh_trees[tree_index] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
}
+ treedata = sod->bvh_trees[tree_index];
+ }
- if (treedata && treedata->tree == NULL) {
- switch (snapdata->snap_to) {
- case SCE_SNAP_MODE_FACE:
- {
- BLI_bitmap *looptri_mask = NULL;
- int looptri_num_active = -1;
- if (sctx->callbacks.edit_mesh.test_face_fn) {
- looptri_mask = BLI_BITMAP_NEW(em->tottri, __func__);
- looptri_num_active = BM_iter_mesh_bitmap_from_filter_tessface(
- em->bm, looptri_mask,
- sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data);
- }
- bvhtree_from_editmesh_looptri_ex(treedata, em, looptri_mask, looptri_num_active, 0.0f, 4, 6, NULL);
- if (looptri_mask) {
- MEM_freeN(looptri_mask);
- }
- break;
+ if (treedata && treedata->tree == NULL) {
+ BLI_bitmap *elem_mask = NULL;
+ switch (snapdata->snap_to) {
+ case SCE_SNAP_MODE_FACE:
+ {
+ int looptri_num_active = -1;
+ if (sctx->callbacks.edit_mesh.test_face_fn) {
+ elem_mask = BLI_BITMAP_NEW(em->tottri, __func__);
+ looptri_num_active = BM_iter_mesh_bitmap_from_filter_tessface(
+ em->bm, elem_mask,
+ sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data);
}
- case SCE_SNAP_MODE_EDGE:
- {
- BLI_bitmap *edges_mask = NULL;
- int edges_num_active = -1;
- if (sctx->callbacks.edit_mesh.test_edge_fn) {
- edges_mask = BLI_BITMAP_NEW(em->bm->totedge, __func__);
- edges_num_active = BM_iter_mesh_bitmap_from_filter(
- BM_EDGES_OF_MESH, em->bm, edges_mask,
- (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn,
- sctx->callbacks.edit_mesh.user_data);
- }
- bvhtree_from_editmesh_edges_ex(treedata, em, edges_mask, edges_num_active, 0.0f, 2, 6);
- if (edges_mask) {
- MEM_freeN(edges_mask);
- }
- break;
+ bvhtree_from_editmesh_looptri_ex(treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6, NULL);
+ break;
+ }
+ case SCE_SNAP_MODE_EDGE:
+ {
+ int edges_num_active = -1;
+ if (sctx->callbacks.edit_mesh.test_edge_fn) {
+ elem_mask = BLI_BITMAP_NEW(em->bm->totedge, __func__);
+ edges_num_active = BM_iter_mesh_bitmap_from_filter(
+ BM_EDGES_OF_MESH, em->bm, elem_mask,
+ (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn,
+ sctx->callbacks.edit_mesh.user_data);
}
- case SCE_SNAP_MODE_VERTEX:
- {
- BLI_bitmap *verts_mask = NULL;
- int verts_num_active = -1;
- if (sctx->callbacks.edit_mesh.test_vert_fn) {
- verts_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__);
- verts_num_active = BM_iter_mesh_bitmap_from_filter(
- BM_VERTS_OF_MESH, em->bm, verts_mask,
- (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
- sctx->callbacks.edit_mesh.user_data);
- }
- bvhtree_from_editmesh_verts_ex(treedata, em, verts_mask, verts_num_active, 0.0f, 2, 6);
- if (verts_mask) {
- MEM_freeN(verts_mask);
- }
- break;
+ bvhtree_from_editmesh_edges_ex(treedata, em, elem_mask, edges_num_active, 0.0f, 2, 6);
+ break;
+ }
+ case SCE_SNAP_MODE_VERTEX:
+ {
+ int verts_num_active = -1;
+ if (sctx->callbacks.edit_mesh.test_vert_fn) {
+ elem_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__);
+ verts_num_active = BM_iter_mesh_bitmap_from_filter(
+ BM_VERTS_OF_MESH, em->bm, elem_mask,
+ (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
+ sctx->callbacks.edit_mesh.user_data);
}
+ bvhtree_from_editmesh_verts_ex(treedata, em, elem_mask, verts_num_active, 0.0f, 2, 6);
+ break;
}
}
-
- if (!treedata || !treedata->tree) {
- return retval;
+ if (elem_mask) {
+ MEM_freeN(elem_mask);
}
+ }
- if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
- float ray_start_local[3];
- copy_v3_v3(ray_start_local, snapdata->ray_start);
- mul_m4_v3(imat, ray_start_local);
+ if (!treedata || !treedata->tree) {
+ return retval;
+ }
- /* Only use closer ray_start in case of ortho view! In perspective one, ray_start
- * may already been *inside* boundbox, leading to snap failures (see T38409).
- * Note also ar might be null (see T38435), in this case we assume ray_start is ok!
+ if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
+ float ray_start_local[3];
+ copy_v3_v3(ray_start_local, snapdata->ray_start);
+ mul_m4_v3(imat, ray_start_local);
+
+ /* Only use closer ray_start in case of ortho view! In perspective one, ray_start
+ * may already been *inside* boundbox, leading to snap failures (see T38409).
+ * Note also ar might be null (see T38435), in this case we assume ray_start is ok!
+ */
+ float len_diff = 0.0f;
+ if (snapdata->view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
+ /* We *need* a reasonably valid len_diff in this case.
+ * Use BHVTree to find the closest face from ray_start_local.
*/
- float len_diff = 0.0f;
- if (snapdata->view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
- /* We *need* a reasonably valid len_diff in this case.
- * Use BHVTree to find the closest face from ray_start_local.
- */
- BVHTreeNearest nearest;
- nearest.index = -1;
- nearest.dist_sq = FLT_MAX;
- /* Compute and store result. */
- if (BLI_bvhtree_find_nearest(
- treedata->tree, ray_start_local, &nearest, NULL, NULL) != -1)
- {
- float dvec[3];
- sub_v3_v3v3(dvec, nearest.co, ray_start_local);
- len_diff = dot_v3v3(dvec, ray_normal_local);
- /* You need to make sure that ray_start is really far away,
- * because even in the Orthografic view, in some cases,
- * the ray can start inside the object (see T50486) */
- if (len_diff > 400.0f) {
- float ray_org_local[3];
-
- copy_v3_v3(ray_org_local, snapdata->ray_origin);
- mul_m4_v3(imat, ray_org_local);
-
- /* We pass a temp ray_start, set from object's boundbox,
- * to avoid precision issues with very far away ray_start values
- * (as returned in case of ortho view3d), see T38358.
- */
- len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
- madd_v3_v3v3fl(
- ray_start_local, ray_org_local, ray_normal_local,
- len_diff + snapdata->depth_range[0] * local_scale);
- local_depth -= len_diff;
- }
- else len_diff = 0.0f;
+ BVHTreeNearest nearest;
+ nearest.index = -1;
+ nearest.dist_sq = FLT_MAX;
+ /* Compute and store result. */
+ if (BLI_bvhtree_find_nearest(
+ treedata->tree, ray_start_local, &nearest, NULL, NULL) != -1)
+ {
+ float dvec[3];
+ sub_v3_v3v3(dvec, nearest.co, ray_start_local);
+ len_diff = dot_v3v3(dvec, ray_normal_local);
+ /* You need to make sure that ray_start is really far away,
+ * because even in the Orthografic view, in some cases,
+ * the ray can start inside the object (see T50486) */
+ if (len_diff > 400.0f) {
+ float ray_org_local[3];
+
+ copy_v3_v3(ray_org_local, snapdata->ray_origin);
+ mul_m4_v3(imat, ray_org_local);
+
+ /* We pass a temp ray_start, set from object's boundbox,
+ * to avoid precision issues with very far away ray_start values
+ * (as returned in case of ortho view3d), see T38358.
+ */
+ len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
+ madd_v3_v3v3fl(
+ ray_start_local, ray_org_local, ray_normal_local,
+ len_diff + snapdata->depth_range[0] * local_scale);
+ local_depth -= len_diff;
}
+ else len_diff = 0.0f;
}
- if (r_hit_list) {
- struct RayCastAll_Data data;
-
- data.bvhdata = treedata;
- data.raycast_callback = treedata->raycast_callback;
- data.obmat = obmat;
- data.timat = timat;
- data.len_diff = len_diff;
- data.local_scale = local_scale;
- data.ob = ob;
- data.ob_uuid = ob_index;
- data.hit_list = r_hit_list;
- data.retval = retval;
-
- BLI_bvhtree_ray_cast_all(
- treedata->tree, ray_start_local, ray_normal_local, 0.0f,
- *ray_depth, raycast_all_cb, &data);
-
- retval = data.retval;
- }
- else {
- BVHTreeRayHit hit = {.index = -1, .dist = local_depth};
+ }
+ if (r_hit_list) {
+ struct RayCastAll_Data data;
+
+ data.bvhdata = treedata;
+ data.raycast_callback = treedata->raycast_callback;
+ data.obmat = obmat;
+ data.timat = timat;
+ data.len_diff = len_diff;
+ data.local_scale = local_scale;
+ data.ob = ob;
+ data.ob_uuid = ob_index;
+ data.hit_list = r_hit_list;
+ data.retval = retval;
+
+ BLI_bvhtree_ray_cast_all(
+ treedata->tree, ray_start_local, ray_normal_local, 0.0f,
+ *ray_depth, raycast_all_cb, &data);
+
+ retval = data.retval;
+ }
+ else {
+ BVHTreeRayHit hit = {.index = -1, .dist = local_depth};
- if (BLI_bvhtree_ray_cast(
- treedata->tree, ray_start_local, ray_normal_local, 0.0f,
- &hit, treedata->raycast_callback, treedata) != -1)
- {
- hit.dist += len_diff;
- hit.dist /= local_scale;
- if (hit.dist <= *ray_depth) {
- *ray_depth = hit.dist;
- copy_v3_v3(r_loc, hit.co);
-
- /* back to worldspace */
- mul_m4_v3(obmat, r_loc);
-
- if (r_no) {
- copy_v3_v3(r_no, hit.no);
- mul_m3_v3(timat, r_no);
- normalize_v3(r_no);
- }
+ if (BLI_bvhtree_ray_cast(
+ treedata->tree, ray_start_local, ray_normal_local, 0.0f,
+ &hit, treedata->raycast_callback, treedata) != -1)
+ {
+ hit.dist += len_diff;
+ hit.dist /= local_scale;
+ if (hit.dist <= *ray_depth) {
+ *ray_depth = hit.dist;
+ copy_v3_v3(r_loc, hit.co);
+
+ /* back to worldspace */
+ mul_m4_v3(obmat, r_loc);
+
+ if (r_no) {
+ copy_v3_v3(r_no, hit.no);
+ mul_m3_v3(timat, r_no);
+ normalize_v3(r_no);
+ }
- retval = true;
+ retval = true;
- if (r_index) {
- *r_index = hit.index;
- }
+ if (r_index) {
+ *r_index = hit.index;
}
}
}
}
- else {
- float ray_org_local[3];
- copy_v3_v3(ray_org_local, snapdata->ray_origin);
- mul_m4_v3(imat, ray_org_local);
-
- BVHTreeFromMeshType treedata_type = {.userdata = treedata, .type = SNAP_EDIT_MESH};
-
- Nearest2dUserData neasrest2d = {
- .dist_px_sq = SQUARE(*dist_px),
- .r_axis_closest = {1.0f, 1.0f, 1.0f},
- .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
- .userdata = &treedata_type,
- .index = -1};
-
- float lpmat[4][4];
- mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
- dist_squared_to_projected_aabb_precalc(
- &neasrest2d.data_precalc, lpmat,
- snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
- (snapdata->depth_range[0] * local_scale), snapdata->mval,
- ray_org_local, ray_normal_local);
-
- BVHTree_WalkLeafCallback cb_walk_leaf =
- (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
- cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
-
- BLI_bvhtree_walk_dfs(
- treedata->tree,
- cb_walk_parent_snap_project, cb_walk_leaf, cb_nearest_walk_order, &neasrest2d);
-
- if (neasrest2d.index != -1) {
- copy_v3_v3(r_loc, neasrest2d.co);
- mul_m4_v3(obmat, r_loc);
- if (r_no) {
- copy_v3_v3(r_no, neasrest2d.no);
- mul_m3_v3(timat, r_no);
- normalize_v3(r_no);
- }
- *dist_px = sqrtf(neasrest2d.dist_px_sq);
- *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
+ }
+ else {
+ float ray_org_local[3];
+ copy_v3_v3(ray_org_local, snapdata->ray_origin);
+ mul_m4_v3(imat, ray_org_local);
- retval = true;
- }
- }
+ Nearest2dUserData neasrest2d = {
+ .dist_px_sq = SQUARE(*dist_px),
+ .r_axis_closest = {1.0f, 1.0f, 1.0f},
+ .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
+ .userdata = treedata,
+ .get_edge_verts = (Nearest2DGetEdgeVertsCallback)get_bedge_verts,
+ .copy_vert_no = (Nearest2DCopyVertNoCallback)copy_bvert_no,
+ .index = -1};
- if ((sctx->flag & SNAP_OBJECT_USE_CACHE) == 0) {
- if (treedata) {
- free_bvhtree_from_editmesh(treedata);
+ float lpmat[4][4];
+ mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
+ dist_squared_to_projected_aabb_precalc(
+ &neasrest2d.data_precalc, lpmat,
+ snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
+ (snapdata->depth_range[0] * local_scale), snapdata->mval,
+ ray_org_local, ray_normal_local);
+
+ BVHTree_WalkLeafCallback cb_walk_leaf =
+ (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
+ cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
+
+ BLI_bvhtree_walk_dfs(
+ treedata->tree,
+ cb_walk_parent_snap_project, cb_walk_leaf, cb_nearest_walk_order, &neasrest2d);
+
+ if (neasrest2d.index != -1) {
+ copy_v3_v3(r_loc, neasrest2d.co);
+ mul_m4_v3(obmat, r_loc);
+ if (r_no) {
+ copy_v3_v3(r_no, neasrest2d.no);
+ mul_m3_v3(timat, r_no);
+ normalize_v3(r_no);
}
+ *dist_px = sqrtf(neasrest2d.dist_px_sq);
+ *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
+
+ retval = true;
}
}
@@ -1880,6 +1827,9 @@ SnapObjectContext *ED_transform_snap_object_context_create(
sctx->bmain = bmain;
sctx->scene = scene;
+ sctx->cache.object_map = BLI_ghash_ptr_new(__func__);
+ sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
return sctx;
}
@@ -1894,11 +1844,6 @@ SnapObjectContext *ED_transform_snap_object_context_create_view3d(
sctx->v3d_data.ar = ar;
sctx->v3d_data.v3d = v3d;
- if (sctx->flag & SNAP_OBJECT_USE_CACHE) {
- sctx->cache.object_map = BLI_ghash_ptr_new(__func__);
- sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- }
-
return sctx;
}
@@ -1930,10 +1875,8 @@ static void snap_object_data_free(void *sod_v)
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx)
{
- if (sctx->flag & SNAP_OBJECT_USE_CACHE) {
- BLI_ghash_free(sctx->cache.object_map, NULL, snap_object_data_free);
- BLI_memarena_free(sctx->cache.mem_arena);
- }
+ BLI_ghash_free(sctx->cache.object_map, NULL, snap_object_data_free);
+ BLI_memarena_free(sctx->cache.mem_arena);
MEM_freeN(sctx);
}
@@ -1956,7 +1899,7 @@ bool ED_transform_snap_object_project_ray_ex(
SnapObjectContext *sctx,
const unsigned short snap_to,
const struct SnapObjectParams *params,
- const float UNUSED(ray_start[3]), const float UNUSED(ray_normal[3]),
+ const float ray_start[3], const float ray_normal[3],
float *ray_depth,
float r_loc[3], float r_no[3], int *r_index,
Object **r_ob, float r_obmat[4][4])
@@ -1964,7 +1907,9 @@ bool ED_transform_snap_object_project_ray_ex(
const float depth_range[2] = {0.0f, FLT_MAX};
SnapData snapdata;
- snap_data_set(&snapdata, sctx->v3d_data.ar, snap_to, VIEW_PROJ_NONE, NULL, r_loc, r_loc, r_no, depth_range);
+ snap_data_set(
+ &snapdata, sctx->v3d_data.ar, snap_to, VIEW_PROJ_NONE,
+ NULL, ray_start, ray_start, ray_normal, depth_range);
return snapObjectsRay(
sctx, &snapdata,
@@ -2083,11 +2028,13 @@ static bool transform_snap_context_project_view3d_mixed_impl(
BLI_assert((snap_to_flag & ~(1 | 2 | 4)) == 0);
if (use_depth) {
- const float dist_px_orig = *dist_px;
+ const float dist_px_orig = dist_px ? *dist_px : 0;
for (int i = 2; i >= 0; i--) {
if (snap_to_flag & (1 << i)) {
- if (i == 0)
+ if (i == 0) {
+ BLI_assert(dist_px != NULL);
*dist_px = dist_px_orig;
+ }
if (ED_transform_snap_object_project_view3d(
sctx,
elem_type[i], params,
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 52febe642a0..4164f5fa75d 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -77,6 +77,16 @@ void IMB_colormanagement_transform(float *buffer, int width, int height, int cha
const char *from_colorspace, const char *to_colorspace, bool predivide);
void IMB_colormanagement_transform_threaded(float *buffer, int width, int height, int channels,
const char *from_colorspace, const char *to_colorspace, bool predivide);
+void IMB_colormanagement_transform_byte(unsigned char *buffer, int width, int height, int channels,
+ const char *from_colorspace, const char *to_colorspace);
+void IMB_colormanagement_transform_byte_threaded(unsigned char *buffer, int width, int height, int channels,
+ const char *from_colorspace, const char *to_colorspace);
+void IMB_colormanagement_transform_from_byte(float *float_buffer, unsigned char *byte_buffer,
+ int width, int height, int channels,
+ const char *from_colorspace, const char *to_colorspace);
+void IMB_colormanagement_transform_from_byte_threaded(float *float_buffer, unsigned char *byte_buffer,
+ int width, int height, int channels,
+ const char *from_colorspace, const char *to_colorspace);
void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspace, const char *to_colorspace);
void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], struct ColorSpace *colorspace);
@@ -185,6 +195,8 @@ void IMB_colormanagement_processor_apply_v3(struct ColormanageProcessor *cm_proc
void IMB_colormanagement_processor_apply_pixel(struct ColormanageProcessor *cm_processor, float *pixel, int channels);
void IMB_colormanagement_processor_apply(struct ColormanageProcessor *cm_processor, float *buffer, int width, int height,
int channels, bool predivide);
+void IMB_colormanagement_processor_apply_byte(struct ColormanageProcessor *cm_processor,
+ unsigned char *buffer, int width, int height, int channels);
void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processor);
/* ** OpenGL drawing routines using GLSL for color space transform ** */
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index a45346279d9..48cba3e0800 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -1555,21 +1555,25 @@ static void colormanage_display_buffer_process(ImBuf *ibuf, unsigned char *displ
typedef struct ProcessorTransformThread {
ColormanageProcessor *cm_processor;
- float *buffer;
+ unsigned char *byte_buffer;
+ float *float_buffer;
int width;
int start_line;
int tot_line;
int channels;
bool predivide;
+ bool float_from_byte;
} ProcessorTransformThread;
typedef struct ProcessorTransformInit {
ColormanageProcessor *cm_processor;
- float *buffer;
+ unsigned char *byte_buffer;
+ float *float_buffer;
int width;
int height;
int channels;
bool predivide;
+ bool float_from_byte;
} ProcessorTransformInitData;
static void processor_transform_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
@@ -1577,17 +1581,24 @@ static void processor_transform_init_handle(void *handle_v, int start_line, int
ProcessorTransformThread *handle = (ProcessorTransformThread *) handle_v;
ProcessorTransformInitData *init_data = (ProcessorTransformInitData *) init_data_v;
- int channels = init_data->channels;
- int width = init_data->width;
- bool predivide = init_data->predivide;
+ const int channels = init_data->channels;
+ const int width = init_data->width;
+ const bool predivide = init_data->predivide;
+ const bool float_from_byte = init_data->float_from_byte;
- size_t offset = ((size_t)channels) * start_line * width;
+ const size_t offset = ((size_t)channels) * start_line * width;
memset(handle, 0, sizeof(ProcessorTransformThread));
handle->cm_processor = init_data->cm_processor;
- handle->buffer = init_data->buffer + offset;
+ if (init_data->byte_buffer != NULL) {
+ /* TODO(serge): Offset might be different for byte and float buffers. */
+ handle->byte_buffer = init_data->byte_buffer + offset;
+ }
+ if (init_data->float_buffer != NULL) {
+ handle->float_buffer = init_data->float_buffer + offset;
+ }
handle->width = width;
@@ -1596,33 +1607,62 @@ static void processor_transform_init_handle(void *handle_v, int start_line, int
handle->channels = channels;
handle->predivide = predivide;
+ handle->float_from_byte = float_from_byte;
}
static void *do_processor_transform_thread(void *handle_v)
{
ProcessorTransformThread *handle = (ProcessorTransformThread *) handle_v;
- float *buffer = handle->buffer;
- int channels = handle->channels;
- int width = handle->width;
- int height = handle->tot_line;
- bool predivide = handle->predivide;
-
- IMB_colormanagement_processor_apply(handle->cm_processor, buffer, width, height, channels, predivide);
+ unsigned char *byte_buffer = handle->byte_buffer;
+ float *float_buffer = handle->float_buffer;
+ const int channels = handle->channels;
+ const int width = handle->width;
+ const int height = handle->tot_line;
+ const bool predivide = handle->predivide;
+ const bool float_from_byte = handle->float_from_byte;
+
+ if (float_from_byte) {
+ IMB_buffer_float_from_byte(float_buffer, byte_buffer,
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+ true,
+ width, height, width, width);
+ IMB_colormanagement_processor_apply(handle->cm_processor,
+ float_buffer,
+ width, height, channels,
+ predivide);
+ }
+ else {
+ if (byte_buffer != NULL) {
+ IMB_colormanagement_processor_apply_byte(handle->cm_processor,
+ byte_buffer,
+ width, height, channels);
+ }
+ if (float_buffer != NULL) {
+ IMB_colormanagement_processor_apply(handle->cm_processor,
+ float_buffer,
+ width, height, channels,
+ predivide);
+ }
+ }
return NULL;
}
-static void processor_transform_apply_threaded(float *buffer, int width, int height, int channels,
- ColormanageProcessor *cm_processor, bool predivide)
+static void processor_transform_apply_threaded(unsigned char *byte_buffer, float *float_buffer,
+ const int width, const int height, const int channels,
+ ColormanageProcessor *cm_processor,
+ const bool predivide, const bool float_from_byte)
{
ProcessorTransformInitData init_data;
init_data.cm_processor = cm_processor;
- init_data.buffer = buffer;
+ init_data.byte_buffer = byte_buffer;
+ init_data.float_buffer = float_buffer;
init_data.width = width;
init_data.height = height;
init_data.channels = channels;
init_data.predivide = predivide;
+ init_data.float_from_byte = float_from_byte;
IMB_processor_apply_threaded(height, sizeof(ProcessorTransformThread), &init_data,
processor_transform_init_handle, do_processor_transform_thread);
@@ -1631,8 +1671,10 @@ static void processor_transform_apply_threaded(float *buffer, int width, int hei
/*********************** Color space transformation functions *************************/
/* convert the whole buffer from specified by name color space to another - internal implementation */
-static void colormanagement_transform_ex(float *buffer, int width, int height, int channels, const char *from_colorspace,
- const char *to_colorspace, bool predivide, bool do_threaded)
+static void colormanagement_transform_ex(unsigned char *byte_buffer, float *float_buffer,
+ int width, int height, int channels,
+ const char *from_colorspace, const char *to_colorspace,
+ bool predivide, bool do_threaded)
{
ColormanageProcessor *cm_processor;
@@ -1649,10 +1691,19 @@ static void colormanagement_transform_ex(float *buffer, int width, int height, i
cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
- if (do_threaded)
- processor_transform_apply_threaded(buffer, width, height, channels, cm_processor, predivide);
- else
- IMB_colormanagement_processor_apply(cm_processor, buffer, width, height, channels, predivide);
+ if (do_threaded) {
+ processor_transform_apply_threaded(byte_buffer, float_buffer,
+ width, height, channels,
+ cm_processor, predivide, false);
+ }
+ else {
+ if (byte_buffer != NULL) {
+ IMB_colormanagement_processor_apply_byte(cm_processor, byte_buffer, width, height, channels);
+ }
+ if (float_buffer != NULL) {
+ IMB_colormanagement_processor_apply(cm_processor, float_buffer, width, height, channels, predivide);
+ }
+ }
IMB_colormanagement_processor_free(cm_processor);
}
@@ -1661,7 +1712,7 @@ static void colormanagement_transform_ex(float *buffer, int width, int height, i
void IMB_colormanagement_transform(float *buffer, int width, int height, int channels,
const char *from_colorspace, const char *to_colorspace, bool predivide)
{
- colormanagement_transform_ex(buffer, width, height, channels, from_colorspace, to_colorspace, predivide, false);
+ colormanagement_transform_ex(NULL, buffer, width, height, channels, from_colorspace, to_colorspace, predivide, false);
}
/* convert the whole buffer from specified by name color space to another
@@ -1670,7 +1721,54 @@ void IMB_colormanagement_transform(float *buffer, int width, int height, int cha
void IMB_colormanagement_transform_threaded(float *buffer, int width, int height, int channels,
const char *from_colorspace, const char *to_colorspace, bool predivide)
{
- colormanagement_transform_ex(buffer, width, height, channels, from_colorspace, to_colorspace, predivide, true);
+ colormanagement_transform_ex(NULL, buffer, width, height, channels, from_colorspace, to_colorspace, predivide, true);
+}
+
+/* Similar to functions above, but operates on byte buffer. */
+void IMB_colormanagement_transform_byte(unsigned char *buffer, int width, int height, int channels,
+ const char *from_colorspace, const char *to_colorspace)
+{
+ colormanagement_transform_ex(buffer, NULL, width, height, channels, from_colorspace, to_colorspace, false, false);
+}
+void IMB_colormanagement_transform_byte_threaded(unsigned char *buffer, int width, int height, int channels,
+ const char *from_colorspace, const char *to_colorspace)
+{
+ colormanagement_transform_ex(buffer, NULL, width, height, channels, from_colorspace, to_colorspace, false, true);
+}
+
+/* Similar to above, but gets float buffer from display one. */
+void IMB_colormanagement_transform_from_byte(float *float_buffer, unsigned char *byte_buffer,
+ int width, int height, int channels,
+ const char *from_colorspace, const char *to_colorspace)
+{
+ IMB_buffer_float_from_byte(float_buffer, byte_buffer,
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+ true,
+ width, height, width, width);
+ IMB_colormanagement_transform(float_buffer,
+ width, height, channels,
+ from_colorspace, to_colorspace,
+ true);
+}
+void IMB_colormanagement_transform_from_byte_threaded(float *float_buffer, unsigned char *byte_buffer,
+ int width, int height, int channels,
+ const char *from_colorspace, const char *to_colorspace)
+{
+ ColormanageProcessor *cm_processor;
+ if (from_colorspace == NULL || from_colorspace[0] == '\0') {
+ return;
+ }
+ if (STREQ(from_colorspace, to_colorspace)) {
+ /* If source and destination color spaces are identical, skip
+ * threading overhead and simply do nothing
+ */
+ return;
+ }
+ cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
+ processor_transform_apply_threaded(byte_buffer, float_buffer,
+ width, height, channels,
+ cm_processor, true, true);
+ IMB_colormanagement_processor_free(cm_processor);
}
void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspace, const char *to_colorspace)
@@ -1974,12 +2072,14 @@ void IMB_colormanagement_buffer_make_display_space(float *buffer, unsigned char
size_t float_buffer_size = ((size_t)width) * height * channels * sizeof(float);
float *display_buffer_float = MEM_mallocN(float_buffer_size, "byte_buffer_make_display_space");
+ /* TODO(sergey): Convert float directly to byte buffer. */
+
memcpy(display_buffer_float, buffer, float_buffer_size);
cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
- processor_transform_apply_threaded(display_buffer_float, width, height, channels,
- cm_processor, true);
+ processor_transform_apply_threaded(NULL, display_buffer_float, width, height, channels,
+ cm_processor, true, false);
IMB_buffer_byte_from_float(display_buffer, display_buffer_float,
channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
@@ -3100,6 +3200,25 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo
}
}
+void IMB_colormanagement_processor_apply_byte(ColormanageProcessor *cm_processor,
+ unsigned char *buffer,
+ int width, int height, int channels)
+{
+ /* TODO(sergey): Would be nice to support arbitrary channels configurations,
+ * but for now it's not so important.
+ */
+ BLI_assert(channels == 4);
+ float pixel[4];
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ size_t offset = channels * (((size_t)y) * width + x);
+ rgba_uchar_to_float(pixel, buffer + offset);
+ IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+ rgba_float_to_uchar(buffer + offset, pixel);
+ }
+ }
+}
+
void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor)
{
if (cm_processor->curve_mapping)
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index c7e539200f6..43e7ac238d1 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -38,10 +38,12 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLI_task.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
+#include "BKE_image.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_texture.h"
@@ -175,21 +177,130 @@ static void updateDepsgraph(ModifierData *md,
}
}
+typedef struct DisplaceUserdata {
+ /*const*/ DisplaceModifierData *dmd;
+ struct ImagePool *pool;
+ MDeformVert *dvert;
+ float weight;
+ int defgrp_index;
+ int direction;
+ bool use_global_direction;
+ float (*tex_co)[3];
+ float (*vertexCos)[3];
+ float local_mat[4][4];
+ MVert *mvert;
+ float (*vert_clnors)[3];
+} DisplaceUserdata;
+
+static void displaceModifier_do_task(void *userdata, const int iter)
+{
+ DisplaceUserdata *data = (DisplaceUserdata *)userdata;
+ DisplaceModifierData *dmd = data->dmd;
+ MDeformVert *dvert = data->dvert;
+ float weight = data->weight;
+ int defgrp_index = data->defgrp_index;
+ int direction = data->direction;
+ bool use_global_direction = data->use_global_direction;
+ float (*tex_co)[3] = data->tex_co;
+ float (*vertexCos)[3] = data->vertexCos;
+ MVert *mvert = data->mvert;
+ float (*vert_clnors)[3] = data->vert_clnors;
+
+ const float delta_fixed = 1.0f - dmd->midlevel; /* when no texture is used, we fallback to white */
+
+ TexResult texres;
+ float strength = dmd->strength;
+ float delta;
+ float local_vec[3];
+
+ if (dvert) {
+ weight = defvert_find_weight(dvert + iter, defgrp_index);
+ if (weight == 0.0f) {
+ return;
+ }
+ }
+
+ if (dmd->texture) {
+ texres.nor = NULL;
+ BKE_texture_get_value_ex(dmd->modifier.scene, dmd->texture, tex_co[iter], &texres, data->pool, false);
+ delta = texres.tin - dmd->midlevel;
+ }
+ else {
+ delta = delta_fixed; /* (1.0f - dmd->midlevel) */ /* never changes */
+ }
+
+ if (dvert) {
+ strength *= weight;
+ }
+
+ delta *= strength;
+ CLAMP(delta, -10000, 10000);
+
+ switch (direction) {
+ case MOD_DISP_DIR_X:
+ if (use_global_direction) {
+ vertexCos[iter][0] += delta * data->local_mat[0][0];
+ vertexCos[iter][1] += delta * data->local_mat[1][0];
+ vertexCos[iter][2] += delta * data->local_mat[2][0];
+ }
+ else {
+ vertexCos[iter][0] += delta;
+ }
+ break;
+ case MOD_DISP_DIR_Y:
+ if (use_global_direction) {
+ vertexCos[iter][0] += delta * data->local_mat[0][1];
+ vertexCos[iter][1] += delta * data->local_mat[1][1];
+ vertexCos[iter][2] += delta * data->local_mat[2][1];
+ }
+ else {
+ vertexCos[iter][1] += delta;
+ }
+ break;
+ case MOD_DISP_DIR_Z:
+ if (use_global_direction) {
+ vertexCos[iter][0] += delta * data->local_mat[0][2];
+ vertexCos[iter][1] += delta * data->local_mat[1][2];
+ vertexCos[iter][2] += delta * data->local_mat[2][2];
+ }
+ else {
+ vertexCos[iter][2] += delta;
+ }
+ break;
+ case MOD_DISP_DIR_RGB_XYZ:
+ local_vec[0] = texres.tr - dmd->midlevel;
+ local_vec[1] = texres.tg - dmd->midlevel;
+ local_vec[2] = texres.tb - dmd->midlevel;
+ if (use_global_direction) {
+ mul_transposed_mat3_m4_v3(data->local_mat, local_vec);
+ }
+ mul_v3_fl(local_vec, strength);
+ add_v3_v3(vertexCos[iter], local_vec);
+ break;
+ case MOD_DISP_DIR_NOR:
+ vertexCos[iter][0] += delta * (mvert[iter].no[0] / 32767.0f);
+ vertexCos[iter][1] += delta * (mvert[iter].no[1] / 32767.0f);
+ vertexCos[iter][2] += delta * (mvert[iter].no[2] / 32767.0f);
+ break;
+ case MOD_DISP_DIR_CLNOR:
+ madd_v3_v3fl(vertexCos[iter], vert_clnors[iter], delta);
+ break;
+ }
+}
+
/* dm must be a CDDerivedMesh */
static void displaceModifier_do(
DisplaceModifierData *dmd, Object *ob,
DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
{
- int i;
MVert *mvert;
MDeformVert *dvert;
int direction = dmd->direction;
int defgrp_index;
float (*tex_co)[3];
float weight = 1.0f; /* init value unused but some compilers may complain */
- const float delta_fixed = 1.0f - dmd->midlevel; /* when no texture is used, we fallback to white */
float (*vert_clnors)[3] = NULL;
- float local_mat[4][4];
+ float local_mat[4][4] = {0};
const bool use_global_direction = dmd->space == MOD_DISP_SPACE_GLOBAL;
if (!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) return;
@@ -234,81 +345,25 @@ static void displaceModifier_do(
copy_m4_m4(local_mat, ob->obmat);
}
- for (i = 0; i < numVerts; i++) {
- TexResult texres;
- float strength = dmd->strength;
- float delta;
- float local_vec[3];
-
- if (dvert) {
- weight = defvert_find_weight(dvert + i, defgrp_index);
- if (weight == 0.0f) continue;
- }
-
- if (dmd->texture) {
- texres.nor = NULL;
- BKE_texture_get_value(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, false);
- delta = texres.tin - dmd->midlevel;
- }
- else {
- delta = delta_fixed; /* (1.0f - dmd->midlevel) */ /* never changes */
- }
+ DisplaceUserdata data = {NULL};
+ data.dmd = dmd;
+ data.dvert = dvert;
+ data.weight = weight;
+ data.defgrp_index = defgrp_index;
+ data.direction = direction;
+ data.use_global_direction = use_global_direction;
+ data.tex_co = tex_co;
+ data.vertexCos = vertexCos;
+ copy_m4_m4(data.local_mat, local_mat);
+ data.mvert = mvert;
+ data.vert_clnors = vert_clnors;
+ if (dmd->texture != NULL) {
+ data.pool = BKE_image_pool_new();
+ }
+ BLI_task_parallel_range(0, numVerts, &data, displaceModifier_do_task, numVerts > 512);
- if (dvert) strength *= weight;
-
- delta *= strength;
- CLAMP(delta, -10000, 10000);
-
- switch (direction) {
- case MOD_DISP_DIR_X:
- if (use_global_direction) {
- vertexCos[i][0] += delta * local_mat[0][0];
- vertexCos[i][1] += delta * local_mat[1][0];
- vertexCos[i][2] += delta * local_mat[2][0];
- }
- else {
- vertexCos[i][0] += delta;
- }
- break;
- case MOD_DISP_DIR_Y:
- if (use_global_direction) {
- vertexCos[i][0] += delta * local_mat[0][1];
- vertexCos[i][1] += delta * local_mat[1][1];
- vertexCos[i][2] += delta * local_mat[2][1];
- }
- else {
- vertexCos[i][1] += delta;
- }
- break;
- case MOD_DISP_DIR_Z:
- if (use_global_direction) {
- vertexCos[i][0] += delta * local_mat[0][2];
- vertexCos[i][1] += delta * local_mat[1][2];
- vertexCos[i][2] += delta * local_mat[2][2];
- }
- else {
- vertexCos[i][2] += delta;
- }
- break;
- case MOD_DISP_DIR_RGB_XYZ:
- local_vec[0] = texres.tr - dmd->midlevel;
- local_vec[1] = texres.tg - dmd->midlevel;
- local_vec[2] = texres.tb - dmd->midlevel;
- if (use_global_direction) {
- mul_transposed_mat3_m4_v3(local_mat, local_vec);
- }
- mul_v3_fl(local_vec, strength);
- add_v3_v3(vertexCos[i], local_vec);
- break;
- case MOD_DISP_DIR_NOR:
- vertexCos[i][0] += delta * (mvert[i].no[0] / 32767.0f);
- vertexCos[i][1] += delta * (mvert[i].no[1] / 32767.0f);
- vertexCos[i][2] += delta * (mvert[i].no[2] / 32767.0f);
- break;
- case MOD_DISP_DIR_CLNOR:
- madd_v3_v3fl(vertexCos[i], vert_clnors[i], delta);
- break;
- }
+ if (data.pool != NULL) {
+ BKE_image_pool_free(data.pool);
}
if (tex_co) {
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index dea1f9d8d4c..24ce2e3cc8e 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -1001,8 +1001,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
ExplodeModifierData *emd = (ExplodeModifierData *) md;
ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ob, md);
- DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
-
if (psmd) {
ParticleSystem *psys = psmd->psys;
@@ -1010,6 +1008,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (psys->part == NULL || psys->particles == NULL) return derivedData;
if (psmd->dm_final == NULL) return derivedData;
+ DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
+
/* 1. find faces to be exploded if needed */
if (emd->facepa == NULL ||
psmd->flag & eParticleSystemFlag_Pars ||