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:
authorLukas Tönne <lukas.toenne@gmail.com>2016-06-08 10:41:04 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2016-06-08 10:41:04 +0300
commita6fdd7d8765ca5b87db4f2a7e562e9f4525dcc5a (patch)
tree4ebcf5e4a137ccf96f227093ab52ed0c197b810a /source/blender/blenkernel
parent95a603c607b88f4527c7b8edf4eeacd1ba380867 (diff)
parentfc60689a258a4a9c7c73c0a91cdfeeb57ecc3ccb (diff)
Merge branch 'master' into object_nodes
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h8
-rw-r--r--source/blender/blenkernel/BKE_animsys.h2
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h2
-rw-r--r--source/blender/blenkernel/BKE_library_idmap.h50
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/BKE_object.h2
-rw-r--r--source/blender/blenkernel/BKE_scene.h1
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c21
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c28
-rw-r--r--source/blender/blenkernel/intern/autoexec.c5
-rw-r--r--source/blender/blenkernel/intern/brush.c2
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c7
-rw-r--r--source/blender/blenkernel/intern/customdata.c2
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c28
-rw-r--r--source/blender/blenkernel/intern/effect.c4
-rw-r--r--source/blender/blenkernel/intern/fcurve.c9
-rw-r--r--source/blender/blenkernel/intern/font.c2
-rw-r--r--source/blender/blenkernel/intern/idcode.c9
-rw-r--r--source/blender/blenkernel/intern/image.c4
-rw-r--r--source/blender/blenkernel/intern/library_idmap.c174
-rw-r--r--source/blender/blenkernel/intern/material.c3
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c13
-rw-r--r--source/blender/blenkernel/intern/object_update.c7
-rw-r--r--source/blender/blenkernel/intern/particle.c15
-rw-r--r--source/blender/blenkernel/intern/pbvh.c3
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h5
-rw-r--r--source/blender/blenkernel/intern/scene.c7
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c471
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c4
30 files changed, 623 insertions, 269 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 2b13a847e14..8ccc4a6eb0e 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -757,22 +757,22 @@ void DM_update_weight_mcol(
typedef struct DMVertexAttribs {
struct {
struct MLoopUV *array;
- int em_offset, gl_index, gl_texco;
+ int em_offset, gl_index, gl_texco, gl_info_index;
} tface[MAX_MTFACE];
struct {
struct MLoopCol *array;
- int em_offset, gl_index;
+ int em_offset, gl_index, gl_info_index;
} mcol[MAX_MCOL];
struct {
float (*array)[4];
- int em_offset, gl_index;
+ int em_offset, gl_index, gl_info_index;
} tang[MAX_MTFACE];
struct {
float (*array)[3];
- int em_offset, gl_index, gl_texco;
+ int em_offset, gl_index, gl_texco, gl_info_index;
} orco;
int tottface, totmcol, tottang, totorco;
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index dc751747f32..6524afff051 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -177,7 +177,7 @@ void BKE_animsys_evaluate_all_animation(struct Main *main, struct Scene *scene,
/* TODO(sergey): This is mainly a temp public function. */
struct FCurve;
-bool BKE_animsys_execute_fcurve(struct PointerRNA *ptr, struct AnimMapper *remap, struct FCurve *fcu);
+bool BKE_animsys_execute_fcurve(struct PointerRNA *ptr, struct AnimMapper *remap, struct FCurve *fcu, float curval);
/* ------------ Specialized API --------------- */
/* There are a few special tools which require these following functions. They are NOT to be used
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 2022d11d508..bb4eb652ae2 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -279,7 +279,7 @@ void correct_bezpart(float v1[2], float v2[2], float v3[2], float v4[2]);
/* evaluate fcurve */
float evaluate_fcurve(struct FCurve *fcu, float evaltime);
/* evaluate fcurve and store value */
-void calculate_fcurve(struct FCurve *fcu, float ctime);
+float calculate_fcurve(struct FCurve *fcu, float evaltime);
/* ************* F-Curve Samples API ******************** */
diff --git a/source/blender/blenkernel/BKE_library_idmap.h b/source/blender/blenkernel/BKE_library_idmap.h
new file mode 100644
index 00000000000..971586ea8b7
--- /dev/null
+++ b/source/blender/blenkernel/BKE_library_idmap.h
@@ -0,0 +1,50 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_LIBRARY_IDMAP_H__
+#define __BKE_LIBRARY_IDMAP_H__
+
+/** \file BKE_library_idmap.h
+ * \ingroup bke
+ */
+
+#include "BLI_compiler_attrs.h"
+
+struct ID;
+struct Main;
+struct IDNameLib_Map;
+
+struct IDNameLib_Map *BKE_main_idmap_create(
+ struct Main *bmain)
+ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void BKE_main_idmap_destroy(
+ struct IDNameLib_Map *id_typemap)
+ ATTR_NONNULL();
+struct Main *BKE_main_idmap_main_get(
+ struct IDNameLib_Map *id_typemap)
+ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+struct ID *BKE_main_idmap_lookup(
+ struct IDNameLib_Map *id_typemap,
+ short id_type, const char *name, const struct Library *lib)
+ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 3);
+struct ID *BKE_main_idmap_lookup_id(
+ struct IDNameLib_Map *id_typemap, const struct ID *id)
+ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
+
+#endif /* __BKE_LIBRARY_IDMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index c7d5857b873..d8d869015a3 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -323,7 +323,7 @@ void BKE_mesh_mdisp_flip(struct MDisps *md, const bool use_loop_mdisp_flip);
void BKE_mesh_polygon_flip_ex(
struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata,
- struct MDisps *mdisp, const bool use_loop_mdisp_flip);
+ float (*lnors)[3], struct MDisps *mdisp, const bool use_loop_mdisp_flip);
void BKE_mesh_polygon_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata);
void BKE_mesh_polygons_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata, int totpoly);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 7d6096407ff..c591ec2a0aa 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -208,6 +208,8 @@ void BKE_object_eval_uber_data(struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
+void BKE_object_eval_proxy_backlink(struct EvaluationContext *eval_ctx, struct Object *ob);
+
void BKE_object_handle_data_update(struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index a4c44b9934e..12bfc07e958 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -135,6 +135,7 @@ float get_render_aosss_error(const struct RenderData *r, float error);
bool BKE_scene_use_new_shading_nodes(const struct Scene *scene);
bool BKE_scene_use_shading_nodes_custom(struct Scene *scene);
+bool BKE_scene_use_world_space_shading(struct Scene *scene);
bool BKE_scene_use_spherical_stereo(struct Scene *scene);
bool BKE_scene_uses_blender_internal(const struct Scene *scene);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 1f0a93bdc30..f32172c2806 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -122,6 +122,7 @@ set(SRC
intern/lamp.c
intern/lattice.c
intern/library.c
+ intern/library_idmap.c
intern/library_query.c
intern/linestyle.c
intern/mask.c
@@ -245,6 +246,7 @@ set(SRC
BKE_lamp.h
BKE_lattice.h
BKE_library.h
+ BKE_library_idmap.h
BKE_library_query.h
BKE_linestyle.h
BKE_main.h
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 195b5e75352..09f4c286f48 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2067,15 +2067,10 @@ static void mesh_calc_modifiers(
DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
-#pragma omp parallel sections if (dm->numVertData + dm->numEdgeData + dm->numPolyData >= BKE_MESH_OMP_LIMIT)
- {
-#pragma omp section
- { range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); }
-#pragma omp section
- { range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); }
-#pragma omp section
- { range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0); }
- }
+ /* Not worth parallelizing this, gives less than 0.1% overall speedup in best of best cases... */
+ range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0);
+ range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0);
+ range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0);
}
}
@@ -3742,6 +3737,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
}
attribs->tface[a].gl_index = gattribs->layer[b].glindex;
+ attribs->tface[a].gl_info_index = gattribs->layer[b].glinfoindoex;
attribs->tface[a].gl_texco = gattribs->layer[b].gltexco;
}
else if (type == CD_MCOL) {
@@ -3765,6 +3761,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
}
attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
+ attribs->mcol[a].gl_info_index = gattribs->layer[b].glinfoindoex;
}
else if (type == CD_TANGENT) {
/* note, even with 'is_editmesh' this uses the derived-meshes loop data */
@@ -3787,6 +3784,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
}
attribs->tang[a].gl_index = gattribs->layer[b].glindex;
+ attribs->tang[a].gl_info_index = gattribs->layer[b].glinfoindoex;
}
else if (type == CD_ORCO) {
/* original coordinates */
@@ -3806,6 +3804,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
attribs->orco.gl_index = gattribs->layer[b].glindex;
attribs->orco.gl_texco = gattribs->layer[b].gltexco;
+ attribs->orco.gl_info_index = gattribs->layer[b].glinfoindoex;
}
}
}
@@ -3834,6 +3833,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
glTexCoord3fv(orco);
else
glVertexAttrib3fv(attribs->orco.gl_index, orco);
+ glUniform1i(attribs->orco.gl_info_index, 0);
}
/* uv texture coordinates */
@@ -3852,6 +3852,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
glTexCoord2fv(uv);
else
glVertexAttrib2fv(attribs->tface[b].gl_index, uv);
+ glUniform1i(attribs->tface[b].gl_info_index, 0);
}
/* vertex colors */
@@ -3867,6 +3868,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
}
glVertexAttrib4fv(attribs->mcol[b].gl_index, col);
+ glUniform1i(attribs->mcol[b].gl_info_index, GPU_ATTR_INFO_SRGB);
}
/* tangent for normal mapping */
@@ -3876,6 +3878,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
const float *tang = (array) ? array[a * 4 + vert] : zero;
glVertexAttrib4fv(attribs->tang[b].gl_index, tang);
}
+ glUniform1i(attribs->tang[b].gl_info_index, 0);
}
}
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 41950c59a22..99aae6239e8 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -730,14 +730,10 @@ static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *o
DynStr *ds = BLI_dynstr_new();
const char *postfixPtr = oldNamePtr + oldNameLen;
char *newPath = NULL;
- char oldChar;
-
+
/* add the part of the string that goes up to the start of the prefix */
if (prefixPtr > oldpath) {
- oldChar = prefixPtr[0];
- prefixPtr[0] = 0;
- BLI_dynstr_append(ds, oldpath);
- prefixPtr[0] = oldChar;
+ BLI_dynstr_nappend(ds, oldpath, prefixPtr - oldpath);
}
/* add the prefix */
@@ -1620,7 +1616,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
}
/* Simple replacement based data-setting of the FCurve using RNA */
-bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu)
+bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu, float curval)
{
char *path = NULL;
bool free_path = false;
@@ -1631,7 +1627,7 @@ bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu)
/* write value to setting */
if (path)
- ok = animsys_write_rna_setting(ptr, path, fcu->array_index, fcu->curval);
+ ok = animsys_write_rna_setting(ptr, path, fcu->array_index, curval);
/* free temp path-info */
if (free_path)
@@ -1654,8 +1650,8 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr, ListBase *list, AnimMapper
if ((fcu->grp == NULL) || (fcu->grp->flag & AGRP_MUTED) == 0) {
/* check if this curve should be skipped */
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
- calculate_fcurve(fcu, ctime);
- BKE_animsys_execute_fcurve(ptr, remap, fcu);
+ const float curval = calculate_fcurve(fcu, ctime);
+ BKE_animsys_execute_fcurve(ptr, remap, fcu, curval);
}
}
}
@@ -1684,8 +1680,8 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
/* evaluate this using values set already in other places
* NOTE: for 'layering' option later on, we should check if we should remove old value before adding
* new to only be done when drivers only changed */
- calculate_fcurve(fcu, ctime);
- ok = BKE_animsys_execute_fcurve(ptr, NULL, fcu);
+ const float curval = calculate_fcurve(fcu, ctime);
+ ok = BKE_animsys_execute_fcurve(ptr, NULL, fcu, curval);
/* clear recalc flag */
driver->flag &= ~DRIVER_FLAG_RECALC;
@@ -1753,8 +1749,8 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) {
/* check if this curve should be skipped */
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
- calculate_fcurve(fcu, ctime);
- BKE_animsys_execute_fcurve(ptr, remap, fcu);
+ const float curval = calculate_fcurve(fcu, ctime);
+ BKE_animsys_execute_fcurve(ptr, remap, fcu, curval);
}
}
}
@@ -2888,8 +2884,8 @@ void BKE_animsys_eval_driver(EvaluationContext *eval_ctx,
* NOTE: for 'layering' option later on, we should check if we should remove old value before adding
* new to only be done when drivers only changed */
//printf("\told val = %f\n", fcu->curval);
- calculate_fcurve(fcu, eval_ctx->ctime);
- ok = BKE_animsys_execute_fcurve(&id_ptr, NULL, fcu);
+ const float curval = calculate_fcurve(fcu, eval_ctx->ctime);
+ ok = BKE_animsys_execute_fcurve(&id_ptr, NULL, fcu, curval);
//printf("\tnew val = %f\n", fcu->curval);
/* clear recalc flag */
diff --git a/source/blender/blenkernel/intern/autoexec.c b/source/blender/blenkernel/intern/autoexec.c
index d9462cd0262..bde06b02ae8 100644
--- a/source/blender/blenkernel/intern/autoexec.c
+++ b/source/blender/blenkernel/intern/autoexec.c
@@ -59,7 +59,10 @@ bool BKE_autoexec_match(const char *path)
BLI_assert((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0);
for (path_cmp = U.autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) {
- if ((path_cmp->flag & USER_PATHCMP_GLOB)) {
+ if (path_cmp->path[0] == '\0') {
+ /* pass */
+ }
+ else if ((path_cmp->flag & USER_PATHCMP_GLOB)) {
if (fnmatch(path_cmp->path, path, fnmatch_flags) == 0) {
return true;
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 31dac038e43..da7863096e3 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -852,7 +852,7 @@ int BKE_brush_size_get(const Scene *scene, const Brush *brush)
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
int size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
- return (int)((float)size * U.pixelsize);
+ return size;
}
int BKE_brush_use_locked_size(const Scene *scene, const Brush *brush)
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index af1ad4900b3..392a38773e7 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1032,6 +1032,7 @@ static void cdDM_drawMappedFacesGLSL(
if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) {
matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index;
+ matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index;
matconv[a].datatypes[numdata].size = 3;
matconv[a].datatypes[numdata].type = GL_FLOAT;
numdata++;
@@ -1039,6 +1040,7 @@ static void cdDM_drawMappedFacesGLSL(
for (b = 0; b < matconv[a].attribs.tottface; b++) {
if (matconv[a].attribs.tface[b].array) {
matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index;
+ matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index;
matconv[a].datatypes[numdata].size = 2;
matconv[a].datatypes[numdata].type = GL_FLOAT;
numdata++;
@@ -1047,6 +1049,7 @@ static void cdDM_drawMappedFacesGLSL(
for (b = 0; b < matconv[a].attribs.totmcol; b++) {
if (matconv[a].attribs.mcol[b].array) {
matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index;
+ matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index;
matconv[a].datatypes[numdata].size = 4;
matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE;
numdata++;
@@ -1055,6 +1058,7 @@ static void cdDM_drawMappedFacesGLSL(
for (b = 0; b < matconv[a].attribs.tottang; b++) {
if (matconv[a].attribs.tang[b].array) {
matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index;
+ matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index;
matconv[a].datatypes[numdata].size = 4;
matconv[a].datatypes[numdata].type = GL_FLOAT;
numdata++;
@@ -2656,6 +2660,9 @@ void CDDM_calc_loop_normals(DerivedMesh *dm, const bool use_split_normals, const
}
/* #define DEBUG_CLNORS */
+#ifdef DEBUG_CLNORS
+# include "BLI_linklist.h"
+#endif
void CDDM_calc_loop_normals_spacearr(
DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr)
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index de79a30bd60..612f1f477e1 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1853,8 +1853,6 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, int typ
(alloctype == CD_DUPLICATE) ||
(alloctype == CD_REFERENCE));
- BLI_assert(size >= 0);
-
if (!typeInfo->defaultname && CustomData_has_layer(data, type))
return &data->layers[CustomData_get_layer_index(data, type)];
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 6c117447664..ffd000eed88 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -57,6 +57,7 @@
#include "MEM_guardedalloc.h"
#include "GPU_glew.h"
+#include "GPU_buffers.h"
#include "GPU_shader.h"
#include "GPU_basic_shader.h"
@@ -1405,6 +1406,24 @@ static void emDM_drawMappedFacesTex(
emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
}
+static void emdm_pass_attrib_update_uniforms(const DMVertexAttribs *attribs)
+{
+ int i;
+ if (attribs->totorco) {
+ glUniform1i(attribs->orco.gl_info_index, 0);
+ }
+ for (i = 0; i < attribs->tottface; i++) {
+ glUniform1i(attribs->tface[i].gl_info_index, 0);
+ }
+ for (i = 0; i < attribs->totmcol; i++) {
+ glUniform1i(attribs->mcol[i].gl_info_index, GPU_ATTR_INFO_SRGB);
+ }
+
+ for (i = 0; i < attribs->tottang; i++) {
+ glUniform1i(attribs->tang[i].gl_info_index, 0);
+ }
+}
+
/**
* \note
*
@@ -1449,15 +1468,15 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B
glVertexAttrib2fv(attribs->tface[i].gl_index, uv);
}
for (i = 0; i < attribs->totmcol; i++) {
- GLubyte col[4];
+ float col[4];
if (attribs->mcol[i].em_offset != -1) {
const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
- copy_v4_v4_uchar(col, &cp->r);
+ rgba_uchar_to_float(col, &cp->r);
}
else {
- col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
+ col[0] = 0.0f; col[1] = 0.0f; col[2] = 0.0f; col[3] = 0.0f;
}
- glVertexAttrib4ubv(attribs->mcol[i].gl_index, col);
+ glVertexAttrib4fv(attribs->mcol[i].gl_index, col);
}
for (i = 0; i < attribs->tottang; i++) {
@@ -1527,6 +1546,7 @@ static void emDM_drawMappedFacesGLSL(
do_draw = setMaterial(matnr = new_matnr, &gattribs);
if (do_draw) {
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
+ emdm_pass_attrib_update_uniforms(&attribs);
if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) {
BM_mesh_elem_index_ensure(bm, BM_LOOP);
}
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index e00d19b2b01..a5c4be364d2 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -596,7 +596,9 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
float cfra = eff->scene->r.cfra;
int ret = 0;
- if (eff->pd && eff->pd->shape==PFIELD_SHAPE_SURFACE && eff->surmd) {
+ /* In case surface object is in Edit mode when loading the .blend, surface modifier is never executed
+ * and bvhtree never built, see T48415. */
+ if (eff->pd && eff->pd->shape==PFIELD_SHAPE_SURFACE && eff->surmd && eff->surmd->bvhtree) {
/* closest point in the object surface is an effector */
float vec[3];
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index a2b5a05feac..395161aa6ed 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -2671,7 +2671,7 @@ float evaluate_fcurve(FCurve *fcu, float evaltime)
}
/* Calculate the value of the given F-Curve at the given frame, and set its curval */
-void calculate_fcurve(FCurve *fcu, float ctime)
+float calculate_fcurve(FCurve *fcu, float evaltime)
{
/* only calculate + set curval (overriding the existing value) if curve has
* any data which warrants this...
@@ -2680,7 +2680,12 @@ void calculate_fcurve(FCurve *fcu, float ctime)
list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE))
{
/* calculate and set curval (evaluates driver too if necessary) */
- fcu->curval = evaluate_fcurve(fcu, ctime);
+ float curval = evaluate_fcurve(fcu, evaltime);
+ fcu->curval = curval; /* debug display only, not thread safe! */
+ return curval;
+ }
+ else {
+ return 0.0f;
}
}
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index aed33d2c64d..98757407e89 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -541,7 +541,7 @@ int BKE_vfont_select_get(Object *ob, int *r_start, int *r_end)
BLI_assert(ef->len >= 0);
BLI_assert(ef->selstart >= 0 && ef->selstart <= ef->len + 1);
- BLI_assert(ef->selend >= 0 && ef->selend <= ef->len);
+ BLI_assert(ef->selend >= 0 && ef->selend <= ef->len + 1);
BLI_assert(ef->pos >= 0 && ef->pos <= ef->len);
if (ef->selstart == 0) {
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index 68a741bc3fc..899ed548783 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -39,6 +39,7 @@
#include "BLT_translation.h"
+#include "BKE_library.h"
#include "BKE_idcode.h"
typedef struct {
@@ -54,6 +55,7 @@ typedef struct {
/* plural need to match rna_main.c's MainCollectionDef */
/* WARNING! Keep it in sync with i18n contexts in BLT_translation.h */
static IDType idtypes[] = {
+ /** ID's directly below must all be in #Main, and be kept in sync with #MAX_LIBARRAY (membership, not order) */
{ ID_AC, "Action", "actions", BLT_I18NCONTEXT_ID_ACTION, IDTYPE_FLAGS_ISLINKABLE },
{ ID_AR, "Armature", "armatures", BLT_I18NCONTEXT_ID_ARMATURE, IDTYPE_FLAGS_ISLINKABLE },
{ ID_BR, "Brush", "brushes", BLT_I18NCONTEXT_ID_BRUSH, IDTYPE_FLAGS_ISLINKABLE },
@@ -61,7 +63,6 @@ static IDType idtypes[] = {
{ ID_CU, "Curve", "curves", BLT_I18NCONTEXT_ID_CURVE, IDTYPE_FLAGS_ISLINKABLE },
{ ID_GD, "GPencil", "grease_pencil", BLT_I18NCONTEXT_ID_GPENCIL, IDTYPE_FLAGS_ISLINKABLE }, /* rename gpencil */
{ ID_GR, "Group", "groups", BLT_I18NCONTEXT_ID_GROUP, IDTYPE_FLAGS_ISLINKABLE },
- { ID_ID, "ID", "ids", BLT_I18NCONTEXT_ID_ID, 0 }, /* plural is fake */
{ ID_IM, "Image", "images", BLT_I18NCONTEXT_ID_IMAGE, IDTYPE_FLAGS_ISLINKABLE },
{ ID_IP, "Ipo", "ipos", "", IDTYPE_FLAGS_ISLINKABLE }, /* deprecated */
{ ID_KE, "Key", "shape_keys", BLT_I18NCONTEXT_ID_SHAPEKEY, 0 },
@@ -89,8 +90,14 @@ static IDType idtypes[] = {
{ ID_VF, "VFont", "fonts", BLT_I18NCONTEXT_ID_VFONT, IDTYPE_FLAGS_ISLINKABLE },
{ ID_WO, "World", "worlds", BLT_I18NCONTEXT_ID_WORLD, IDTYPE_FLAGS_ISLINKABLE },
{ ID_WM, "WindowManager", "window_managers", BLT_I18NCONTEXT_ID_WINDOWMANAGER, 0 },
+
+ /** Keep last, not an ID exactly, only include for completeness */
+ { ID_ID, "ID", "ids", BLT_I18NCONTEXT_ID_ID, 0 }, /* plural is fake */
};
+/* -1 for ID_ID */
+BLI_STATIC_ASSERT((ARRAY_SIZE(idtypes) - 1 == MAX_LIBARRAY), "Missing IDType");
+
static IDType *idtype_from_name(const char *str)
{
int i = ARRAY_SIZE(idtypes);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 911bf21b731..ecebc7336a2 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -109,8 +109,8 @@ static void image_add_view(Image *ima, const char *viewname, const char *filepat
#define IMA_NO_INDEX 0x7FEFEFEF
/* quick lookup: supports 1 million frames, thousand passes */
-#define IMA_MAKE_INDEX(frame, index) ((frame) << 10) + index
-#define IMA_INDEX_FRAME(index) (index >> 10)
+#define IMA_MAKE_INDEX(frame, index) (((frame) << 10) + (index))
+#define IMA_INDEX_FRAME(index) ((index) >> 10)
/*
#define IMA_INDEX_PASS(index) (index & ~1023)
*/
diff --git a/source/blender/blenkernel/intern/library_idmap.c b/source/blender/blenkernel/intern/library_idmap.c
new file mode 100644
index 00000000000..fd78d9b23ce
--- /dev/null
+++ b/source/blender/blenkernel/intern/library_idmap.c
@@ -0,0 +1,174 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+#include "BLI_listbase.h"
+
+#include "DNA_ID.h"
+
+#include "BKE_idcode.h"
+#include "BKE_library.h"
+#include "BKE_library_idmap.h" /* own include */
+
+/** \file blender/blenkernel/intern/library_map.c
+ * \ingroup bke
+ *
+ * Utility functions for faster ID lookups.
+ */
+
+/** \name BKE_main_idmap API
+ *
+ * Cache ID (name, library lookups).
+ * This doesn't account for adding/removing data-blocks,
+ * and should only be used when performing many lookups.
+ *
+ * \note GHash's are initialized on demand,
+ * since its likely some types will never have lookups run on them,
+ * so its a waste to create and never use.
+ * \{ */
+
+struct IDNameLib_Key {
+ /** ``ID.name + 2``: without the ID type prefix, since each id type gets it's own 'map' */
+ const char *name;
+ /** ``ID.lib``: */
+ const Library *lib;
+};
+
+struct IDNameLib_TypeMap {
+ GHash *map;
+ short id_type;
+ /* only for storage of keys in the ghash, avoid many single allocs */
+ struct IDNameLib_Key *keys;
+};
+
+/**
+ * Opaque structure, external API users only see this.
+ */
+struct IDNameLib_Map {
+ struct IDNameLib_TypeMap type_maps[MAX_LIBARRAY];
+ struct Main *bmain;
+};
+
+static struct IDNameLib_TypeMap *main_idmap_from_idcode(struct IDNameLib_Map *id_map, short id_type)
+{
+ for (int i = 0; i < MAX_LIBARRAY; i++) {
+ if (id_map->type_maps[i].id_type == id_type) {
+ return &id_map->type_maps[i];
+ }
+ }
+ return NULL;
+}
+
+struct IDNameLib_Map *BKE_main_idmap_create(struct Main *bmain)
+{
+ struct IDNameLib_Map *id_map = MEM_mallocN(sizeof(*id_map), __func__);
+
+ int index = 0;
+ while (index < MAX_LIBARRAY) {
+ id_map->type_maps[index].map = NULL;
+ id_map->type_maps[index].id_type = BKE_idcode_iter_step(&index);
+ }
+ BLI_assert(index == MAX_LIBARRAY);
+
+ id_map->bmain = bmain;
+
+ return id_map;
+}
+
+struct Main *BKE_main_idmap_main_get(struct IDNameLib_Map *id_map)
+{
+ return id_map->bmain;
+}
+
+static unsigned int idkey_hash(const void *ptr)
+{
+ const struct IDNameLib_Key *idkey = ptr;
+ unsigned int key = BLI_ghashutil_strhash(idkey->name);
+ if (idkey->lib) {
+ key ^= BLI_ghashutil_ptrhash(idkey->lib);
+ }
+ return key;
+}
+
+static bool idkey_cmp(const void *a, const void *b)
+{
+ const struct IDNameLib_Key *idkey_a = a;
+ const struct IDNameLib_Key *idkey_b = b;
+ return strcmp(idkey_a->name, idkey_b->name) || (idkey_a->lib != idkey_b->lib);
+}
+
+ID *BKE_main_idmap_lookup(struct IDNameLib_Map *id_map, short id_type, const char *name, const Library *lib)
+{
+ struct IDNameLib_TypeMap *type_map = main_idmap_from_idcode(id_map, id_type);
+
+ if (UNLIKELY(type_map == NULL)) {
+ return NULL;
+ }
+
+ /* lazy init */
+ if (type_map->map == NULL) {
+ ListBase *lb = which_libbase(id_map->bmain, id_type);
+ const int lb_len = BLI_listbase_count(lb);
+ if (lb_len == 0) {
+ return NULL;
+ }
+ type_map->map = BLI_ghash_new_ex(idkey_hash, idkey_cmp, __func__, lb_len);
+ type_map->keys = MEM_mallocN(sizeof(struct IDNameLib_Key) * lb_len, __func__);
+
+ GHash *map = type_map->map;
+ struct IDNameLib_Key *key = type_map->keys;
+
+ for (ID *id = lb->first; id; id = id->next, key++) {
+ key->name = id->name + 2;
+ key->lib = id->lib;
+ BLI_ghash_insert(map, key, id);
+ }
+ }
+
+ const struct IDNameLib_Key key_lookup = {name, lib};
+ return BLI_ghash_lookup(type_map->map, &key_lookup);
+}
+
+ID *BKE_main_idmap_lookup_id(struct IDNameLib_Map *id_map, const ID *id)
+{
+ return BKE_main_idmap_lookup(id_map, GS(id->name), id->name + 2, id->lib);
+}
+
+void BKE_main_idmap_destroy(struct IDNameLib_Map *id_map)
+{
+ struct IDNameLib_TypeMap *type_map = id_map->type_maps;
+ for (int i = 0; i < MAX_LIBARRAY; i++, type_map++) {
+ if (type_map->map) {
+ BLI_ghash_free(type_map->map, NULL, NULL);
+ type_map->map = NULL;
+ MEM_freeN(type_map->keys);
+ }
+ }
+
+ MEM_freeN(id_map);
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 1fec725dbb7..30f82a50ed9 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -1148,7 +1148,6 @@ static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode
/* parses the geom+tex nodes */
ntreeShaderGetTexcoMode(ntree, r_mode, &basemat->texco, &basemat->mode_l);
- basemat->nmap_tangent_names_count = 0;
for (node = ntree->nodes.first; node; node = node->next) {
if (node->id) {
if (GS(node->id->name) == ID_MA) {
@@ -1199,7 +1198,7 @@ void init_render_material(Material *mat, int r_mode, float *amb)
* mode_l will have it set when all node materials are shadeless. */
mat->mode_l = (mat->mode & MA_MODE_PIPELINE) | MA_SHLESS;
mat->mode2_l = mat->mode2 & MA_MODE2_PIPELINE;
-
+ mat->nmap_tangent_names_count = 0;
init_render_nodetree(mat->nodetree, mat, r_mode, amb);
if (!mat->nodetree->execdata)
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 577a21285f8..1c86fbcfe8e 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -677,7 +677,7 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS
*/
copy_v3_v3(*lnor, polynors[mp_index]);
- /* printf("BASIC: handling loop %d / edge %d / vert %d\n", ml_curr_index, ml_curr->e, ml_curr->v); */
+ /* printf("BASIC: handling loop %d / edge %d / vert %d / poly %d\n", ml_curr_index, ml_curr->e, ml_curr->v, mp_index); */
/* If needed, generate this (simple!) lnor space. */
if (lnors_spacearr) {
@@ -3262,14 +3262,14 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
*/
void BKE_mesh_polygon_flip_ex(
MPoly *mpoly, MLoop *mloop, CustomData *ldata,
- MDisps *mdisp, const bool use_loop_mdisp_flip)
+ float (*lnors)[3], MDisps *mdisp, const bool use_loop_mdisp_flip)
{
int loopstart = mpoly->loopstart;
int loopend = loopstart + mpoly->totloop - 1;
const bool loops_in_ldata = (CustomData_get_layer(ldata, CD_MLOOP) == mloop);
if (mdisp) {
- for (int i = mpoly->loopstart; i <= loopend; i++) {
+ for (int i = loopstart; i <= loopend; i++) {
BKE_mesh_mdisp_flip(&mdisp[i], use_loop_mdisp_flip);
}
}
@@ -3288,6 +3288,9 @@ void BKE_mesh_polygon_flip_ex(
if (!loops_in_ldata) {
SWAP(MLoop, mloop[loopstart], mloop[loopend]);
}
+ if (lnors) {
+ swap_v3_v3(lnors[loopstart], lnors[loopend]);
+ }
CustomData_swap(ldata, loopstart, loopend);
}
/* Even if we did not swap the other 'pivot' loop, we need to set its swapped edge. */
@@ -3299,7 +3302,7 @@ void BKE_mesh_polygon_flip_ex(
void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata)
{
MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS);
- BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, mdisp, true);
+ BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, NULL, mdisp, true);
}
/**
@@ -3315,7 +3318,7 @@ void BKE_mesh_polygons_flip(
int i;
for (mp = mpoly, i = 0; i < totpoly; mp++, i++) {
- BKE_mesh_polygon_flip_ex(mp, mloop, ldata, mdisp, true);
+ BKE_mesh_polygon_flip_ex(mp, mloop, ldata, NULL, mdisp, true);
}
}
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 03348adeabc..2468cb8b697 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -347,3 +347,10 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx,
ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME);
}
+
+void BKE_object_eval_proxy_backlink(EvaluationContext *UNUSED(eval_ctx), Object *ob)
+{
+ if (ob->proxy) {
+ ob->proxy->proxy_from = ob;
+ }
+}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index af30c1af66b..106720c4f1f 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -141,6 +141,11 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur)
#define PATH_CACHE_BUF_SIZE 1024
+static ParticleCacheKey *pcache_key_segment_endpoint_safe(ParticleCacheKey *key)
+{
+ return (key->segments > 0) ? (key + (key->segments - 1)) : key;
+}
+
static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot, int totkeys)
{
LinkData *buf;
@@ -2205,20 +2210,22 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp
/* modify weights to create parting */
if (p_fac > 0.f) {
+ const ParticleCacheKey *key_0_last = pcache_key_segment_endpoint_safe(key[0]);
for (w = 0; w < 4; w++) {
- if (w && weight[w] > 0.f) {
+ if (w && (weight[w] > 0.f)) {
+ const ParticleCacheKey *key_w_last = pcache_key_segment_endpoint_safe(key[w]);
float d;
if (part->flag & PART_CHILD_LONG_HAIR) {
/* For long hair use tip distance/root distance as parting factor instead of root to tip angle. */
float d1 = len_v3v3(key[0]->co, key[w]->co);
- float d2 = len_v3v3((key[0] + key[0]->segments - 1)->co, (key[w] + key[w]->segments - 1)->co);
+ float d2 = len_v3v3(key_0_last->co, key_w_last->co);
d = d1 > 0.f ? d2 / d1 - 1.f : 10000.f;
}
else {
float v1[3], v2[3];
- sub_v3_v3v3(v1, (key[0] + key[0]->segments - 1)->co, key[0]->co);
- sub_v3_v3v3(v2, (key[w] + key[w]->segments - 1)->co, key[w]->co);
+ sub_v3_v3v3(v1, key_0_last->co, key[0]->co);
+ sub_v3_v3v3(v2, key_w_last->co, key[w]->co);
normalize_v3(v1);
normalize_v3(v2);
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index d73f087a3fe..58ec75dc706 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -637,6 +637,7 @@ void BKE_pbvh_free(PBVH *bvh)
BLI_gset_free(node->bm_other_verts, NULL);
}
}
+ GPU_free_pbvh_buffer_multires(&bvh->grid_common_gpu_buffer);
if (bvh->deformed) {
if (bvh->verts) {
@@ -1100,7 +1101,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
node->totprim,
bvh->grid_hidden,
bvh->gridkey.grid_size,
- &bvh->gridkey);
+ &bvh->gridkey, &bvh->grid_common_gpu_buffer);
break;
case PBVH_FACES:
node->draw_buffers =
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index bae323dedef..4d2307c3e12 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -145,6 +145,11 @@ struct PBVH {
const DMFlagMat *grid_flag_mats;
int totgrid;
BLI_bitmap **grid_hidden;
+ /* index_buf of GPU_PBVH_Buffers can be the same for all 'fully drawn' nodes (same size).
+ * Previously was stored in a static var in gpu_buffer.c, but this breaks in case we handle several different
+ * objects in sculpt mode with different sizes at the same time, so now storing that common gpu buffer
+ * in an opaque pointer per pbvh. See T47637. */
+ struct GridCommonGPUBuffer *grid_common_gpu_buffer;
/* Only used during BVH build and update,
* don't need to remain valid after */
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index d307ba1811b..a3393b6b9c0 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -2193,6 +2193,13 @@ bool BKE_scene_use_shading_nodes_custom(Scene *scene)
return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM);
}
+bool BKE_scene_use_world_space_shading(Scene *scene)
+{
+ const RenderEngineType *type = RE_engines_find(scene->r.engine);
+ return ((scene->r.mode & R_USE_WS_SHADING) ||
+ (type && (type->flag & RE_USE_SHADING_NODES)));
+}
+
bool BKE_scene_use_spherical_stereo(Scene *scene)
{
RenderEngineType *type = RE_engines_find(scene->r.engine);
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index e855f6faa22..518d8d68919 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -44,6 +44,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_task.h"
#include "BKE_shrinkwrap.h"
#include "BKE_DerivedMesh.h"
@@ -58,7 +59,7 @@
/* for timing... */
#if 0
-# include "PIL_time.h"
+# include "PIL_time_utildefines.h"
#else
# define TIMEIT_BENCH(expr, id) (expr)
#endif
@@ -66,16 +67,88 @@
/* Util macros */
#define OUT_OF_MEMORY() ((void)printf("Shrinkwrap: Out of memory\n"))
+typedef struct ShrinkwrapCalcCBData {
+ ShrinkwrapCalcData *calc;
+
+ void *treeData;
+ void *auxData;
+ BVHTree *targ_tree;
+ BVHTree *aux_tree;
+ void *targ_callback;
+ void *aux_callback;
+
+ float *proj_axis;
+ SpaceTransform *local2aux;
+} ShrinkwrapCalcCBData;
+
/*
* Shrinkwrap to the nearest vertex
*
* it builds a kdtree of vertexs we can attach to and then
* for each vertex performs a nearest vertex search on the tree
*/
-static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
+static void shrinkwrap_calc_nearest_vertex_cb_ex(
+ void *userdata, void *userdata_chunk, const int i, const int UNUSED(threadid))
{
- int i;
+ ShrinkwrapCalcCBData *data = userdata;
+
+ ShrinkwrapCalcData *calc = data->calc;
+ BVHTreeFromMesh *treeData = data->treeData;
+ BVHTreeNearest *nearest = userdata_chunk;
+
+ float *co = calc->vertexCos[i];
+ float tmp_co[3];
+ float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
+
+ if (calc->invert_vgroup) {
+ weight = 1.0f - weight;
+ }
+
+ if (weight == 0.0f) {
+ return;
+ }
+
+ /* Convert the vertex to tree coordinates */
+ if (calc->vert) {
+ copy_v3_v3(tmp_co, calc->vert[i].co);
+ }
+ else {
+ copy_v3_v3(tmp_co, co);
+ }
+ BLI_space_transform_apply(&calc->local2target, tmp_co);
+
+ /* Use local proximity heuristics (to reduce the nearest search)
+ *
+ * If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex
+ * so we can initiate the "nearest.dist" with the expected value to that last hit.
+ * This will lead in pruning of the search tree. */
+ if (nearest->index != -1)
+ nearest->dist_sq = len_squared_v3v3(tmp_co, nearest->co);
+ else
+ nearest->dist_sq = FLT_MAX;
+
+ BLI_bvhtree_find_nearest(treeData->tree, tmp_co, nearest, treeData->nearest_callback, treeData);
+
+
+ /* Found the nearest vertex */
+ if (nearest->index != -1) {
+ /* Adjusting the vertex weight,
+ * so that after interpolating it keeps a certain distance from the nearest position */
+ if (nearest->dist_sq > FLT_EPSILON) {
+ const float dist = sqrtf(nearest->dist_sq);
+ weight *= (dist - calc->keepDist) / dist;
+ }
+
+ /* Convert the coordinates back to mesh coordinates */
+ copy_v3_v3(tmp_co, nearest->co);
+ BLI_space_transform_invert(&calc->local2target, tmp_co);
+
+ interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
+ }
+}
+static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
+{
BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
BVHTreeNearest nearest = NULL_BVHTreeNearest;
@@ -89,61 +162,11 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
/* Setup nearest */
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
-#ifndef __APPLE__
-#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(treeData, calc) schedule(static) if (calc->numVerts > BKE_MESH_OMP_LIMIT)
-#endif
- for (i = 0; i < calc->numVerts; ++i) {
- float *co = calc->vertexCos[i];
- float tmp_co[3];
- float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
-
- if (calc->invert_vgroup) {
- weight = 1.0f - weight;
- }
-
- if (weight == 0.0f) {
- continue;
- }
-
-
- /* Convert the vertex to tree coordinates */
- if (calc->vert) {
- copy_v3_v3(tmp_co, calc->vert[i].co);
- }
- else {
- copy_v3_v3(tmp_co, co);
- }
- BLI_space_transform_apply(&calc->local2target, tmp_co);
-
- /* Use local proximity heuristics (to reduce the nearest search)
- *
- * If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex
- * so we can initiate the "nearest.dist" with the expected value to that last hit.
- * This will lead in pruning of the search tree. */
- if (nearest.index != -1)
- nearest.dist_sq = len_squared_v3v3(tmp_co, nearest.co);
- else
- nearest.dist_sq = FLT_MAX;
-
- BLI_bvhtree_find_nearest(treeData.tree, tmp_co, &nearest, treeData.nearest_callback, &treeData);
-
-
- /* Found the nearest vertex */
- if (nearest.index != -1) {
- /* Adjusting the vertex weight,
- * so that after interpolating it keeps a certain distance from the nearest position */
- if (nearest.dist_sq > FLT_EPSILON) {
- const float dist = sqrtf(nearest.dist_sq);
- weight *= (dist - calc->keepDist) / dist;
- }
- /* Convert the coordinates back to mesh coordinates */
- copy_v3_v3(tmp_co, nearest.co);
- BLI_space_transform_invert(&calc->local2target, tmp_co);
-
- interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
- }
- }
+ ShrinkwrapCalcCBData data = {.calc = calc, .treeData = &treeData};
+ BLI_task_parallel_range_ex(
+ 0, calc->numVerts, &data, &nearest, sizeof(nearest), shrinkwrap_calc_nearest_vertex_cb_ex,
+ calc->numVerts > BKE_MESH_OMP_LIMIT, false);
free_bvhtree_from_mesh(&treeData);
}
@@ -230,13 +253,109 @@ bool BKE_shrinkwrap_project_normal(
return false;
}
+static void shrinkwrap_calc_normal_projection_cb_ex(
+ void *userdata, void *userdata_chunk, const int i, const int UNUSED(threadid))
+{
+ ShrinkwrapCalcCBData *data = userdata;
+
+ ShrinkwrapCalcData *calc = data->calc;
+ void *treeData = data->treeData;
+ void *auxData = data->auxData;
+ BVHTree *targ_tree = data->targ_tree;
+ BVHTree *aux_tree = data->aux_tree;
+ void *targ_callback = data->targ_callback;
+ void *aux_callback = data->aux_callback;
+
+ float *proj_axis = data->proj_axis;
+ SpaceTransform *local2aux = data->local2aux;
+
+ BVHTreeRayHit *hit = userdata_chunk;
+
+ const float proj_limit_squared = calc->smd->projLimit * calc->smd->projLimit;
+ float *co = calc->vertexCos[i];
+ float tmp_co[3], tmp_no[3];
+ float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
+
+ if (calc->invert_vgroup) {
+ weight = 1.0f - weight;
+ }
+
+ if (weight == 0.0f) {
+ return;
+ }
+
+ if (calc->vert) {
+ /* calc->vert contains verts from derivedMesh */
+ /* this coordinated are deformed by vertexCos only for normal projection (to get correct normals) */
+ /* for other cases calc->varts contains undeformed coordinates and vertexCos should be used */
+ if (calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
+ copy_v3_v3(tmp_co, calc->vert[i].co);
+ normal_short_to_float_v3(tmp_no, calc->vert[i].no);
+ }
+ else {
+ copy_v3_v3(tmp_co, co);
+ copy_v3_v3(tmp_no, proj_axis);
+ }
+ }
+ else {
+ copy_v3_v3(tmp_co, co);
+ copy_v3_v3(tmp_no, proj_axis);
+ }
+
+
+ hit->index = -1;
+ hit->dist = BVH_RAYCAST_DIST_MAX; /* TODO: we should use FLT_MAX here, but sweepsphere code isn't prepared for that */
+
+ /* Project over positive direction of axis */
+ if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR) {
+ if (aux_tree) {
+ BKE_shrinkwrap_project_normal(
+ 0, tmp_co, tmp_no,
+ local2aux, aux_tree, hit,
+ aux_callback, auxData);
+ }
+
+ BKE_shrinkwrap_project_normal(
+ calc->smd->shrinkOpts, tmp_co, tmp_no,
+ &calc->local2target, targ_tree, hit,
+ targ_callback, treeData);
+ }
+
+ /* Project over negative direction of axis */
+ if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR) {
+ float inv_no[3];
+ negate_v3_v3(inv_no, tmp_no);
+
+ if (aux_tree) {
+ BKE_shrinkwrap_project_normal(
+ 0, tmp_co, inv_no,
+ local2aux, aux_tree, hit,
+ aux_callback, auxData);
+ }
+
+ BKE_shrinkwrap_project_normal(
+ calc->smd->shrinkOpts, tmp_co, inv_no,
+ &calc->local2target, targ_tree, hit,
+ targ_callback, treeData);
+ }
+
+ /* don't set the initial dist (which is more efficient),
+ * because its calculated in the targets space, we want the dist in our own space */
+ if (proj_limit_squared != 0.0f) {
+ if (len_squared_v3v3(hit->co, co) > proj_limit_squared) {
+ hit->index = -1;
+ }
+ }
+
+ if (hit->index != -1) {
+ madd_v3_v3v3fl(hit->co, hit->co, tmp_no, calc->keepDist);
+ interp_v3_v3v3(co, co, hit->co, weight);
+ }
+}
static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for_render)
{
- int i;
-
/* Options about projection direction */
- const float proj_limit_squared = calc->smd->projLimit * calc->smd->projLimit;
float proj_axis[3] = {0.0f, 0.0f, 0.0f};
/* Raycast and tree stuff */
@@ -305,7 +424,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for
}
if (targ_tree) {
BVHTree *aux_tree = NULL;
- void *aux_callback;
+ void *aux_callback = NULL;
if (auxMesh != NULL) {
/* use editmesh to avoid array allocation */
if (calc->smd->auxTarget && auxMesh->type == DM_TYPE_EDITBMESH) {
@@ -316,99 +435,22 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for
}
}
else {
- if ((aux_tree = bvhtree_from_mesh_looptri(&dmauxdata_stack, calc->target, 0.0, 4, 6)) != NULL) {
+ if ((aux_tree = bvhtree_from_mesh_looptri(&dmauxdata_stack, auxMesh, 0.0, 4, 6)) != NULL) {
aux_callback = dmauxdata_stack.raycast_callback;
auxData = &dmauxdata_stack;
}
}
}
/* After sucessufuly build the trees, start projection vertexs */
-
-#ifndef __APPLE__
-#pragma omp parallel for private(i, hit) schedule(static) if (calc->numVerts > BKE_MESH_OMP_LIMIT)
-#endif
- for (i = 0; i < calc->numVerts; ++i) {
- float *co = calc->vertexCos[i];
- float tmp_co[3], tmp_no[3];
- float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
-
- if (calc->invert_vgroup) {
- weight = 1.0f - weight;
- }
-
- if (weight == 0.0f) {
- continue;
- }
-
- if (calc->vert) {
- /* calc->vert contains verts from derivedMesh */
- /* this coordinated are deformed by vertexCos only for normal projection (to get correct normals) */
- /* for other cases calc->varts contains undeformed coordinates and vertexCos should be used */
- if (calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
- copy_v3_v3(tmp_co, calc->vert[i].co);
- normal_short_to_float_v3(tmp_no, calc->vert[i].no);
- }
- else {
- copy_v3_v3(tmp_co, co);
- copy_v3_v3(tmp_no, proj_axis);
- }
- }
- else {
- copy_v3_v3(tmp_co, co);
- copy_v3_v3(tmp_no, proj_axis);
- }
-
-
- hit.index = -1;
- hit.dist = BVH_RAYCAST_DIST_MAX; /* TODO: we should use FLT_MAX here, but sweepsphere code isn't prepared for that */
-
- /* Project over positive direction of axis */
- if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR) {
-
- if (aux_tree) {
- BKE_shrinkwrap_project_normal(
- 0, tmp_co, tmp_no,
- &local2aux, aux_tree, &hit,
- aux_callback, auxData);
- }
-
- BKE_shrinkwrap_project_normal(
- calc->smd->shrinkOpts, tmp_co, tmp_no,
- &calc->local2target, targ_tree, &hit,
- targ_callback, treeData);
- }
-
- /* Project over negative direction of axis */
- if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR) {
- float inv_no[3];
- negate_v3_v3(inv_no, tmp_no);
-
- if (aux_tree) {
- BKE_shrinkwrap_project_normal(
- 0, tmp_co, inv_no,
- &local2aux, aux_tree, &hit,
- aux_callback, auxData);
- }
-
- BKE_shrinkwrap_project_normal(
- calc->smd->shrinkOpts, tmp_co, inv_no,
- &calc->local2target, targ_tree, &hit,
- targ_callback, treeData);
- }
-
- /* don't set the initial dist (which is more efficient),
- * because its calculated in the targets space, we want the dist in our own space */
- if (proj_limit_squared != 0.0f) {
- if (len_squared_v3v3(hit.co, co) > proj_limit_squared) {
- hit.index = -1;
- }
- }
-
- if (hit.index != -1) {
- madd_v3_v3v3fl(hit.co, hit.co, tmp_no, calc->keepDist);
- interp_v3_v3v3(co, co, hit.co, weight);
- }
- }
+ ShrinkwrapCalcCBData data = {
+ .calc = calc,
+ .treeData = treeData, .targ_tree = targ_tree, .targ_callback = targ_callback,
+ .auxData = auxData, .aux_tree = aux_tree, .aux_callback = aux_callback,
+ .proj_axis = proj_axis, .local2aux = &local2aux,
+ };
+ BLI_task_parallel_range_ex(
+ 0, calc->numVerts, &data, &hit, sizeof(hit), shrinkwrap_calc_normal_projection_cb_ex,
+ calc->numVerts > BKE_MESH_OMP_LIMIT, false);
}
/* free data structures */
@@ -428,10 +470,75 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for
* it builds a BVHTree from the target mesh and then performs a
* NN matches for each vertex
*/
-static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
+static void shrinkwrap_calc_nearest_surface_point_cb_ex(
+ void *userdata, void *userdata_chunk, const int i, const int UNUSED(threadid))
{
- int i;
+ ShrinkwrapCalcCBData *data = userdata;
+
+ ShrinkwrapCalcData *calc = data->calc;
+ BVHTreeFromMesh *treeData = data->treeData;
+ BVHTreeNearest *nearest = userdata_chunk;
+
+ float *co = calc->vertexCos[i];
+ float tmp_co[3];
+ float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
+
+ if (calc->invert_vgroup) {
+ weight = 1.0f - weight;
+ }
+
+ if (weight == 0.0f) {
+ return;
+ }
+
+ /* Convert the vertex to tree coordinates */
+ if (calc->vert) {
+ copy_v3_v3(tmp_co, calc->vert[i].co);
+ }
+ else {
+ copy_v3_v3(tmp_co, co);
+ }
+ BLI_space_transform_apply(&calc->local2target, tmp_co);
+
+ /* Use local proximity heuristics (to reduce the nearest search)
+ *
+ * If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex
+ * so we can initiate the "nearest.dist" with the expected value to that last hit.
+ * This will lead in pruning of the search tree. */
+ if (nearest->index != -1)
+ nearest->dist_sq = len_squared_v3v3(tmp_co, nearest->co);
+ else
+ nearest->dist_sq = FLT_MAX;
+
+ BLI_bvhtree_find_nearest(treeData->tree, tmp_co, nearest, treeData->nearest_callback, treeData);
+
+ /* Found the nearest vertex */
+ if (nearest->index != -1) {
+ if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE) {
+ /* Make the vertex stay on the front side of the face */
+ madd_v3_v3v3fl(tmp_co, nearest->co, nearest->no, calc->keepDist);
+ }
+ else {
+ /* Adjusting the vertex weight,
+ * so that after interpolating it keeps a certain distance from the nearest position */
+ const float dist = sasqrt(nearest->dist_sq);
+ if (dist > FLT_EPSILON) {
+ /* linear interpolation */
+ interp_v3_v3v3(tmp_co, tmp_co, nearest->co, (dist - calc->keepDist) / dist);
+ }
+ else {
+ copy_v3_v3(tmp_co, nearest->co);
+ }
+ }
+ /* Convert the coordinates back to mesh coordinates */
+ BLI_space_transform_invert(&calc->local2target, tmp_co);
+ interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
+ }
+}
+
+static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
+{
BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
BVHTreeNearest nearest = NULL_BVHTreeNearest;
@@ -446,67 +553,11 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
-
/* Find the nearest vertex */
-#ifndef __APPLE__
-#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(calc, treeData) schedule(static) if (calc->numVerts > BKE_MESH_OMP_LIMIT)
-#endif
- for (i = 0; i < calc->numVerts; ++i) {
- float *co = calc->vertexCos[i];
- float tmp_co[3];
- float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
-
- if (calc->invert_vgroup) {
- weight = 1.0f - weight;
- }
-
- if (weight == 0.0f) continue;
-
- /* Convert the vertex to tree coordinates */
- if (calc->vert) {
- copy_v3_v3(tmp_co, calc->vert[i].co);
- }
- else {
- copy_v3_v3(tmp_co, co);
- }
- BLI_space_transform_apply(&calc->local2target, tmp_co);
-
- /* Use local proximity heuristics (to reduce the nearest search)
- *
- * If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex
- * so we can initiate the "nearest.dist" with the expected value to that last hit.
- * This will lead in pruning of the search tree. */
- if (nearest.index != -1)
- nearest.dist_sq = len_squared_v3v3(tmp_co, nearest.co);
- else
- nearest.dist_sq = FLT_MAX;
-
- BLI_bvhtree_find_nearest(treeData.tree, tmp_co, &nearest, treeData.nearest_callback, &treeData);
-
- /* Found the nearest vertex */
- if (nearest.index != -1) {
- if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE) {
- /* Make the vertex stay on the front side of the face */
- madd_v3_v3v3fl(tmp_co, nearest.co, nearest.no, calc->keepDist);
- }
- else {
- /* Adjusting the vertex weight,
- * so that after interpolating it keeps a certain distance from the nearest position */
- const float dist = sasqrt(nearest.dist_sq);
- if (dist > FLT_EPSILON) {
- /* linear interpolation */
- interp_v3_v3v3(tmp_co, tmp_co, nearest.co, (dist - calc->keepDist) / dist);
- }
- else {
- copy_v3_v3(tmp_co, nearest.co);
- }
- }
-
- /* Convert the coordinates back to mesh coordinates */
- BLI_space_transform_invert(&calc->local2target, tmp_co);
- interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
- }
- }
+ ShrinkwrapCalcCBData data = {.calc = calc, .treeData = &treeData};
+ BLI_task_parallel_range_ex(
+ 0, calc->numVerts, &data, &nearest, sizeof(nearest), shrinkwrap_calc_nearest_surface_point_cb_ex,
+ calc->numVerts > BKE_MESH_OMP_LIMIT, false);
free_bvhtree_from_mesh(&treeData);
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 5fd418fadfc..88bc3fb9854 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -2996,6 +2996,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) {
matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index;
+ matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index;
matconv[a].datatypes[numdata].size = 3;
matconv[a].datatypes[numdata].type = GL_FLOAT;
numdata++;
@@ -3003,6 +3004,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
for (b = 0; b < matconv[a].attribs.tottface; b++) {
if (matconv[a].attribs.tface[b].array) {
matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index;
+ matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index;
matconv[a].datatypes[numdata].size = 2;
matconv[a].datatypes[numdata].type = GL_FLOAT;
numdata++;
@@ -3011,6 +3013,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
for (b = 0; b < matconv[a].attribs.totmcol; b++) {
if (matconv[a].attribs.mcol[b].array) {
matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index;
+ matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index;
matconv[a].datatypes[numdata].size = 4;
matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE;
numdata++;
@@ -3019,6 +3022,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
for (b = 0; b < matconv[a].attribs.tottang; b++) {
if (matconv[a].attribs.tottang && matconv[a].attribs.tang[b].array) {
matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index;
+ matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index;
matconv[a].datatypes[numdata].size = 4;
matconv[a].datatypes[numdata].type = GL_FLOAT;
numdata++;