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:
authorRohan Rathi <rohanrathi08@gmail.com>2018-07-21 16:59:15 +0300
committerRohan Rathi <rohanrathi08@gmail.com>2018-07-21 16:59:15 +0300
commit4e6bcd10e559ab541df53a3d7b645faac1a7fe27 (patch)
treeba214c23868fe76ec5d2199b83846814bf79be25 /source/blender/blenkernel
parentb6b185691f018f6b175ffb58c65418991cda75f2 (diff)
parente361e9e99c5b6140b6284e81fa315bdcc48cee58 (diff)
Merge branch 'blender2.8' into soc-2018-bevel
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h7
-rw-r--r--source/blender/blenkernel/BKE_addon.h1
-rw-r--r--source/blender/blenkernel/BKE_animsys.h2
-rw-r--r--source/blender/blenkernel/BKE_armature.h2
-rw-r--r--source/blender/blenkernel/BKE_context.h4
-rw-r--r--source/blender/blenkernel/BKE_global.h4
-rw-r--r--source/blender/blenkernel/BKE_image.h2
-rw-r--r--source/blender/blenkernel/BKE_layer.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h4
-rw-r--r--source/blender/blenkernel/BKE_mesh_mapping.h18
-rw-r--r--source/blender/blenkernel/BKE_mesh_runtime.h18
-rw-r--r--source/blender/blenkernel/BKE_modifier.h8
-rw-r--r--source/blender/blenkernel/BKE_node.h23
-rw-r--r--source/blender/blenkernel/BKE_object.h5
-rw-r--r--source/blender/blenkernel/BKE_ocean.h6
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h4
-rw-r--r--source/blender/blenkernel/BKE_scene.h1
-rw-r--r--source/blender/blenkernel/BKE_screen.h30
-rw-r--r--source/blender/blenkernel/BKE_softbody.h2
-rw-r--r--source/blender/blenkernel/BKE_studiolight.h2
-rw-r--r--source/blender/blenkernel/BKE_subdiv.h230
-rw-r--r--source/blender/blenkernel/BKE_workspace.h28
-rw-r--r--source/blender/blenkernel/BKE_world.h6
-rw-r--r--source/blender/blenkernel/CMakeLists.txt11
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c6
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_intern.h4
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c140
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c123
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c39
-rw-r--r--source/blender/blenkernel/intern/addon.c11
-rw-r--r--source/blender/blenkernel/intern/anim.c12
-rw-r--r--source/blender/blenkernel/intern/armature.c32
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/blendfile.c2
-rw-r--r--source/blender/blenkernel/intern/bpath.c2
-rw-r--r--source/blender/blenkernel/intern/camera.c1
-rw-r--r--source/blender/blenkernel/intern/cloth.c4
-rw-r--r--source/blender/blenkernel/intern/collection.c2
-rw-r--r--source/blender/blenkernel/intern/constraint.c36
-rw-r--r--source/blender/blenkernel/intern/context.c22
-rw-r--r--source/blender/blenkernel/intern/fluidsim.c35
-rw-r--r--source/blender/blenkernel/intern/idcode.c2
-rw-r--r--source/blender/blenkernel/intern/idprop.c6
-rw-r--r--source/blender/blenkernel/intern/image.c85
-rw-r--r--source/blender/blenkernel/intern/ipo.c7
-rw-r--r--source/blender/blenkernel/intern/lamp.c4
-rw-r--r--source/blender/blenkernel/intern/layer.c56
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/library_query.c4
-rw-r--r--source/blender/blenkernel/intern/lightprobe.c1
-rw-r--r--source/blender/blenkernel/intern/mesh.c69
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c56
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c369
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c100
-rw-r--r--source/blender/blenkernel/intern/mesh_merge.c7
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c81
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.c33
-rw-r--r--source/blender/blenkernel/intern/mesh_tangent.c15
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c51
-rw-r--r--source/blender/blenkernel/intern/modifier.c4
-rw-r--r--source/blender/blenkernel/intern/node.c7
-rw-r--r--source/blender/blenkernel/intern/object.c70
-rw-r--r--source/blender/blenkernel/intern/ocean.c42
-rw-r--r--source/blender/blenkernel/intern/paint.c15
-rw-r--r--source/blender/blenkernel/intern/pbvh.c6
-rw-r--r--source/blender/blenkernel/intern/pointcache.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c35
-rw-r--r--source/blender/blenkernel/intern/screen.c48
-rw-r--r--source/blender/blenkernel/intern/softbody.c32
-rw-r--r--source/blender/blenkernel/intern/sound.c22
-rw-r--r--source/blender/blenkernel/intern/studiolight.c92
-rw-r--r--source/blender/blenkernel/intern/subdiv.c119
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter.c65
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter.h57
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter_mesh.c471
-rw-r--r--source/blender/blenkernel/intern/subdiv_eval.c323
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.c952
-rw-r--r--source/blender/blenkernel/intern/subdiv_stats.c80
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c21
-rw-r--r--source/blender/blenkernel/intern/texture.c2
-rw-r--r--source/blender/blenkernel/intern/workspace.c109
-rw-r--r--source/blender/blenkernel/intern/world.c13
-rw-r--r--source/blender/blenkernel/intern/writeavi.c2
83 files changed, 3322 insertions, 1112 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 3099875c145..cdf0d683779 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -530,15 +530,8 @@ DerivedMesh *getEditDerivedBMesh(
struct BMEditMesh *em, struct Object *ob, CustomDataMask data_mask,
float (*vertexCos)[3]);
-DerivedMesh *mesh_create_derived_index_render(
- struct Depsgraph *depsgraph, struct Scene *scene,
- struct Object *ob, CustomDataMask dataMask, int index);
-
/* same as above but wont use render settings */
DerivedMesh *mesh_create_derived(struct Mesh *me, float (*vertCos)[3]);
-DerivedMesh *mesh_create_derived_view(
- struct Depsgraph *depsgraph, struct Scene *scene,
- struct Object *ob, CustomDataMask dataMask);
DerivedMesh *mesh_create_derived_no_deform(
struct Depsgraph *depsgraph, struct Scene *scene,
struct Object *ob, float (*vertCos)[3],
diff --git a/source/blender/blenkernel/BKE_addon.h b/source/blender/blenkernel/BKE_addon.h
index 3af6d3b61bf..a463525d644 100644
--- a/source/blender/blenkernel/BKE_addon.h
+++ b/source/blender/blenkernel/BKE_addon.h
@@ -53,6 +53,7 @@ void BKE_addon_pref_type_free(void);
struct bAddon *BKE_addon_new(void);
struct bAddon *BKE_addon_find(struct ListBase *addon_list, const char *module);
struct bAddon *BKE_addon_ensure(struct ListBase *addon_list, const char *module);
+bool BKE_addon_remove_safe(struct ListBase *addon_list, const char *module);
void BKE_addon_free(struct bAddon *addon);
#endif /* __BKE_ADDON_H__ */
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index b16e8c17a12..9e8e7f7b724 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -153,7 +153,7 @@ char *BKE_animdata_driver_path_hack(struct bContext *C, struct PointerRNA *ptr,
char *base_path);
/* ************************************* */
-/* Gwn_Batch AnimData API */
+/* GPUBatch AnimData API */
/* Define for callback looper used in BKE_animdata_main_cb */
typedef void (*ID_AnimData_Edit_Callback)(struct ID *id, struct AnimData *adt, void *user_data);
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index e1bfb05fb59..21d880cf2a7 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -100,7 +100,7 @@ void BKE_armature_where_is(struct bArmature *arm);
void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion);
void BKE_pose_clear_pointers(struct bPose *pose);
void BKE_pose_remap_bone_pointers(struct bArmature *armature, struct bPose *pose);
-void BKE_pose_rebuild(struct Object *ob, struct bArmature *arm);
+void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm);
void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
void BKE_pose_where_is_bone(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra);
void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan);
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 9fa00e7f63f..9f57859d318 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -157,7 +157,7 @@ struct SpaceLink *CTX_wm_space_data(const bContext *C);
struct ARegion *CTX_wm_region(const bContext *C);
void *CTX_wm_region_data(const bContext *C);
struct ARegion *CTX_wm_menu(const bContext *C);
-struct wmManipulatorGroup *CTX_wm_manipulator_group(const bContext *C);
+struct wmGizmoGroup *CTX_wm_gizmo_group(const bContext *C);
struct wmMsgBus *CTX_wm_message_bus(const bContext *C);
struct ReportList *CTX_wm_reports(const bContext *C);
@@ -185,7 +185,7 @@ void CTX_wm_screen_set(bContext *C, struct bScreen *screen); /* to be removed */
void CTX_wm_area_set(bContext *C, struct ScrArea *sa);
void CTX_wm_region_set(bContext *C, struct ARegion *region);
void CTX_wm_menu_set(bContext *C, struct ARegion *menu);
-void CTX_wm_manipulator_group_set(bContext *C, struct wmManipulatorGroup *mgroup);
+void CTX_wm_gizmo_group_set(bContext *C, struct wmGizmoGroup *gzgroup);
const char *CTX_wm_operator_poll_msg_get(struct bContext *C);
void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg);
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 82afbdefeab..7497a9f04e3 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -179,12 +179,12 @@ enum {
/* On write, make backup `.blend1`, `.blend2` ... files, when the users preference is enabled */
#define G_FILE_HISTORY (1 << 25)
/* BMesh option to save as older mesh format */
-#define G_FILE_MESH_COMPAT (1 << 26)
+// #define G_FILE_MESH_COMPAT (1 << 26)
/* On write, restore paths after editing them (G_FILE_RELATIVE_REMAP) */
#define G_FILE_SAVE_COPY (1 << 27)
#define G_FILE_GLSL_NO_ENV_LIGHTING (1 << 28)
-#define G_FILE_FLAGS_RUNTIME (G_FILE_NO_UI | G_FILE_RELATIVE_REMAP | G_FILE_MESH_COMPAT | G_FILE_SAVE_COPY)
+#define G_FILE_FLAGS_RUNTIME (G_FILE_NO_UI | G_FILE_RELATIVE_REMAP | G_FILE_SAVE_COPY)
/* ENDIAN_ORDER: indicates what endianness the platform where the file was
* written had. */
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 060ed4536a4..a41d9582add 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -114,8 +114,6 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const struc
struct anim *openanim(const char *name, int flags, int streamindex, char colorspace[IMA_MAX_SPACE]);
struct anim *openanim_noload(const char *name, int flags, int streamindex, char colorspace[IMA_MAX_SPACE]);
-void BKE_image_de_interlace(struct Image *ima, int odd);
-
void BKE_image_make_local(struct Main *bmain, struct Image *ima, const bool lib_local);
void BKE_image_tag_time(struct Image *ima);
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 9e89033894d..db0e5f21284 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -58,7 +58,7 @@ struct WorkSpace;
struct ViewLayer *BKE_view_layer_default_view(const struct Scene *scene);
struct ViewLayer *BKE_view_layer_default_render(const struct Scene *scene);
-struct ViewLayer *BKE_view_layer_from_workspace_get(const struct Scene *scene, const struct WorkSpace *workspace);
+struct ViewLayer *BKE_view_layer_find(const struct Scene *scene, const char *layer_name);
struct ViewLayer *BKE_view_layer_add(struct Scene *scene, const char *name);
/* DEPRECATED */
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index a577b5e4ae3..66b0b550744 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -204,6 +204,7 @@ int BKE_mesh_mselect_active_get(struct Mesh *me, int type);
void BKE_mesh_mselect_active_set(struct Mesh *me, int index, int type);
void BKE_mesh_apply_vert_coords(struct Mesh *mesh, float (*vertCoords)[3]);
+void BKE_mesh_apply_vert_normals(struct Mesh *mesh, short (*vertNormals)[3]);
/* *** mesh_evaluate.c *** */
@@ -395,9 +396,6 @@ void BKE_mesh_recalc_looptri(
const struct MVert *mvert,
int totloop, int totpoly,
struct MLoopTri *mlooptri);
-int BKE_mesh_mpoly_to_mface(
- struct CustomData *fdata, struct CustomData *ldata,
- struct CustomData *pdata, int totface, int totloop, int totpoly);
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
void BKE_mesh_do_versions_convert_mfaces_to_mpolys(struct Mesh *mesh);
void BKE_mesh_convert_mfaces_to_mpolys_ex(
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index b5b5443574c..1005a50a214 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -50,8 +50,12 @@ typedef struct UvVertMap {
typedef struct UvMapVert {
struct UvMapVert *next;
- unsigned int f;
- unsigned char tfindex, separate, flag;
+ unsigned int poly_index;
+ unsigned short loop_of_poly_index;
+ bool separate;
+ /* Zero-ed by map creation, left for use by specific areas. Is not
+ * initialized to anything. */
+ unsigned char flag;
} UvMapVert;
/* UvElement stores per uv information so that we can quickly access information for a uv.
@@ -63,9 +67,9 @@ typedef struct UvElement {
/* Face the element belongs to */
struct BMLoop *l;
/* index in loop. */
- unsigned short tfindex;
+ unsigned short loop_of_poly_index;
/* Whether this element is the first of coincident elements */
- unsigned char separate;
+ bool separate;
/* general use flag */
unsigned char flag;
/* If generating element map with island sorting, this stores the island index */
@@ -100,9 +104,9 @@ typedef struct MeshElemMap {
/* mapping */
UvVertMap *BKE_mesh_uv_vert_map_create(
- struct MPoly *mpoly, struct MLoop *mloop, struct MLoopUV *mloopuv,
- unsigned int totpoly, unsigned int totvert,
- const float limit[2], const bool selected, const bool use_winding);
+ const struct MPoly *mpoly, const struct MLoop *mloop, const struct MLoopUV *mloopuv,
+ unsigned int totpoly, unsigned int totvert, const float limit[2],
+ const bool selected, const bool use_winding);
UvMapVert *BKE_mesh_uv_vert_map_get_vert(UvVertMap *vmap, unsigned int v);
void BKE_mesh_uv_vert_map_free(UvVertMap *vmap);
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index f894f72e648..e673a30c0b3 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -85,6 +85,24 @@ struct Mesh *mesh_get_eval_deform(
struct Depsgraph *depsgraph, struct Scene *scene,
struct Object *ob, CustomDataMask dataMask);
+#ifdef USE_DERIVEDMESH
+struct DerivedMesh *mesh_create_derived_index_render(
+ struct Depsgraph *depsgraph, struct Scene *scene,
+ struct Object *ob, CustomDataMask dataMask, int index);
+#endif
+struct Mesh *mesh_create_eval_final_index_render(
+ struct Depsgraph *depsgraph, struct Scene *scene,
+ struct Object *ob, CustomDataMask dataMask, int index);
+
+#ifdef USE_DERIVEDMESH
+struct DerivedMesh *mesh_create_derived_view(
+ struct Depsgraph *depsgraph, struct Scene *scene,
+ struct Object *ob, CustomDataMask dataMask);
+#endif
+struct Mesh *mesh_create_eval_final_view(
+ struct Depsgraph *depsgraph, struct Scene *scene,
+ struct Object *ob, CustomDataMask dataMask);
+
void BKE_mesh_runtime_eval_to_meshkey(struct Mesh *me_deformed, struct Mesh *me, struct KeyBlock *kb);
/* Temporary? A function to give a colorband to derivedmesh for vertexcolor ranges */
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index c9f724a9bc4..d0b9d2adc5b 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -162,8 +162,10 @@ typedef struct ModifierTypeInfo {
/* Copy instance data for this modifier type. Should copy all user
* level settings to the target modifier.
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
*/
- void (*copyData)(const struct ModifierData *md, struct ModifierData *target);
+ void (*copyData)(const struct ModifierData *md, struct ModifierData *target, const int flag);
/********************* Deform modifier functions *********************/ /* DEPRECATED */
@@ -315,7 +317,7 @@ typedef struct ModifierTypeInfo {
*
* This function is optional (assumes never disabled if not present).
*/
- bool (*isDisabled)(const struct Scene *scene, struct ModifierData *md, int userRenderParams);
+ bool (*isDisabled)(const struct Scene *scene, struct ModifierData *md, bool userRenderParams);
/* Add the appropriate relations to the dependency graph.
*
@@ -387,7 +389,7 @@ void modifier_free(struct ModifierData *md);
bool modifier_unique_name(struct ListBase *modifiers, struct ModifierData *md);
-void modifier_copyData_generic(const struct ModifierData *md, struct ModifierData *target);
+void modifier_copyData_generic(const struct ModifierData *md, struct ModifierData *target, const int flag);
void modifier_copyData(struct ModifierData *md, struct ModifierData *target);
void modifier_copyData_ex(struct ModifierData *md, struct ModifierData *target, const int flag);
bool modifier_dependsOnTime(struct ModifierData *md);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 1578176d465..cf55885a5ef 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -152,7 +152,7 @@ typedef struct bNodeType {
float width, minwidth, maxwidth;
float height, minheight, maxheight;
- short nclass, flag, compatibility;
+ short nclass, flag;
/* templates for static sockets */
bNodeSocketTemplate *inputs, *outputs;
@@ -251,11 +251,6 @@ typedef struct bNodeType {
#define NODE_CLASS_SHADER 40
#define NODE_CLASS_LAYOUT 100
-/* nodetype->compatibility */
-#define NODE_OLD_SHADING (1 << 0)
-#define NODE_NEW_SHADING (1 << 1)
-#define NODE_NEWER_SHADING (1 << 2)
-
/* node resize directions */
#define NODE_RESIZE_TOP 1
#define NODE_RESIZE_BOTTOM 2
@@ -601,7 +596,6 @@ void node_type_update(struct bNodeType *ntype,
void node_type_exec(struct bNodeType *ntype, NodeInitExecFunction initexecfunc, NodeFreeExecFunction freeexecfunc, NodeExecFunction execfunc);
void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpufunc);
void node_type_internal_links(struct bNodeType *ntype, void (*update_internal_links)(struct bNodeTree *, struct bNode *));
-void node_type_compatibility(struct bNodeType *ntype, short compatibility);
/** \} */
@@ -734,7 +728,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, c
#define SH_NODE_OUTPUT_MATERIAL 124
#define SH_NODE_OUTPUT_WORLD 125
-#define SH_NODE_OUTPUT_LAMP 126
+#define SH_NODE_OUTPUT_LIGHT 126
#define SH_NODE_FRESNEL 127
#define SH_NODE_MIX_SHADER 128
#define SH_NODE_ATTRIBUTE 129
@@ -802,6 +796,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, c
#define SH_NODE_DISPLACEMENT 198
#define SH_NODE_VECTOR_DISPLACEMENT 199
#define SH_NODE_VOLUME_PRINCIPLED 200
+/* 201..700 occupied by other node types, continue from 701 */
+#define SH_NODE_BSDF_HAIR_PRINCIPLED 701
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
@@ -813,9 +809,10 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, c
struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree);
void ntreeShaderEndExecTree(struct bNodeTreeExec *exec);
bool ntreeShaderExecTree(struct bNodeTree *ntree, int thread);
+struct bNode *ntreeShaderOutputNode(struct bNodeTree *ntree, int target);
-void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat, short compatibility);
-void ntreeGPUMaterialDomain(struct bNodeTree *ntree, bool *has_surface_output, bool *has_volume_output);
+void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat,
+ bool *has_surface_output, bool *has_volume_output);
/** \} */
@@ -949,6 +946,7 @@ void ntreeGPUMaterialDomain(struct bNodeTree *ntree, bool *has_surfac
#define CMP_NODE_PLANETRACKDEFORM 320
#define CMP_NODE_CORNERPIN 321
#define CMP_NODE_SWITCH_VIEW 322
+#define CMP_NODE_CRYPTOMATTE 323
/* channel toggles */
#define CMP_CHAN_RGB 1
@@ -1001,6 +999,11 @@ void ntreeCompositOutputFileUniqueLayer(struct ListBase *list, struct bNodeSocke
void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *ntree, bNode *node);
void ntreeCompositColorBalanceSyncFromCDL(bNodeTree *ntree, bNode *node);
+void ntreeCompositCryptomatteSyncFromAdd(bNodeTree *ntree, bNode *node);
+void ntreeCompositCryptomatteSyncFromRemove(bNodeTree *ntree, bNode *node);
+struct bNodeSocket *ntreeCompositCryptomatteAddSocket(struct bNodeTree *ntree, struct bNode *node);
+int ntreeCompositCryptomatteRemoveSocket(struct bNodeTree *ntree, struct bNode *node);
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index a54b244f5fd..79e4f1d448a 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -56,10 +56,9 @@ void BKE_object_workob_clear(struct Object *workob);
void BKE_object_workob_calc_parent(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct Object *workob);
void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src);
-struct SoftBody *copy_softbody(const struct SoftBody *sb, const int flag);
+void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src, const int flag);
struct ParticleSystem *BKE_object_copy_particlesystem(struct ParticleSystem *psys, const int flag);
void BKE_object_copy_particlesystems(struct Object *ob_dst, const struct Object *ob_src, const int flag);
-void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src);
void BKE_object_free_particlesystems(struct Object *ob);
void BKE_object_free_softbody(struct Object *ob);
void BKE_object_free_curve_cache(struct Object *ob);
@@ -76,7 +75,7 @@ bool BKE_object_support_modifier_type_check(const struct Object *ob, int modifie
void BKE_object_link_modifiers(struct Scene *scene, struct Object *ob_dst, const struct Object *ob_src);
void BKE_object_free_modifiers(struct Object *ob, const int flag);
-void BKE_object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob);
+void BKE_object_make_proxy(struct Main *bmain, struct Object *ob, struct Object *target, struct Object *gob);
void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
bool BKE_object_exists_check(struct Main *bmain, const struct Object *obtest);
diff --git a/source/blender/blenkernel/BKE_ocean.h b/source/blender/blenkernel/BKE_ocean.h
index 3ea104e656a..e18a063ff52 100644
--- a/source/blender/blenkernel/BKE_ocean.h
+++ b/source/blender/blenkernel/BKE_ocean.h
@@ -31,6 +31,8 @@
extern "C" {
#endif
+struct OceanModifierData;
+
typedef struct OceanResult {
float disp[3];
float normal[3];
@@ -72,6 +74,8 @@ typedef struct OceanCache {
struct Ocean *BKE_ocean_add(void);
void BKE_ocean_free_data(struct Ocean *oc);
void BKE_ocean_free(struct Ocean *oc);
+bool BKE_ocean_ensure(struct OceanModifierData *omd);
+void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd);
void BKE_ocean_init(
struct Ocean *o, int M, int N, float Lx, float Lz, float V, float l, float A, float w, float damp,
@@ -99,6 +103,8 @@ void BKE_ocean_cache_eval_uv(struct OceanCache *och, struct OceanResult *ocr, in
void BKE_ocean_cache_eval_ij(struct OceanCache *och, struct OceanResult *ocr, int f, int i, int j);
void BKE_ocean_free_cache(struct OceanCache *och);
+void BKE_ocean_free_modifier_cache(struct OceanModifierData *omd);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 78c766f6115..095f442ca50 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -30,7 +30,7 @@
#include "BLI_ghash.h"
#include "BLI_utildefines.h"
-struct Gwn_Batch;
+struct GPUBatch;
struct CCGElem;
struct CCGKey;
struct CCGDerivedMesh;
@@ -131,7 +131,7 @@ bool BKE_pbvh_node_find_nearest_to_ray(
void BKE_pbvh_draw_cb(
PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast,
- void (*draw_fn)(void *user_data, struct Gwn_Batch *batch), void *user_data);
+ void (*draw_fn)(void *user_data, struct GPUBatch *batch), void *user_data);
/* PBVH Access */
typedef enum {
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 270ab60c02b..adccfda8e25 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -156,6 +156,7 @@ bool BKE_scene_use_shading_nodes_custom(struct Scene *scene);
bool BKE_scene_use_spherical_stereo(struct Scene *scene);
bool BKE_scene_uses_blender_eevee(const struct Scene *scene);
+bool BKE_scene_uses_blender_opengl(const struct Scene *scene);
bool BKE_scene_uses_cycles(const struct Scene *scene);
void BKE_scene_disable_color_management(struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 861b47aebc6..c74170becb4 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -45,13 +45,14 @@ struct ScrVert;
struct SpaceType;
struct TransformOrientation;
struct View3D;
+struct View3DShading;
struct bContext;
struct bContextDataResult;
struct bScreen;
struct uiLayout;
struct uiList;
struct wmKeyConfig;
-struct wmManipulatorMap;
+struct wmGizmoMap;
struct wmNotifier;
struct wmWindow;
struct wmWindowManager;
@@ -88,9 +89,8 @@ typedef struct SpaceType {
/* exit is called when the area is hidden or removed */
void (*exit)(struct wmWindowManager *wm, struct ScrArea *sa);
/* Listeners can react to bContext changes */
- void (*listener)(struct bScreen *sc, struct ScrArea *sa,
- struct wmNotifier *wmn, struct Scene *scene,
- struct WorkSpace *workspace);
+ void (*listener)(struct wmWindow *win, struct ScrArea *sa,
+ struct wmNotifier *wmn, struct Scene *scene);
/* refresh context, called after filereads, ED_area_tag_refresh() */
void (*refresh)(const struct bContext *C, struct ScrArea *sa);
@@ -105,8 +105,8 @@ typedef struct SpaceType {
/* on startup, define dropboxes for spacetype+regions */
void (*dropboxes)(void);
- /* initialize manipulator-map-types and manipulator-group-types with the region */
- void (*manipulators)(void);
+ /* initialize gizmo-map-types and gizmo-group-types with the region */
+ void (*gizmos)(void);
/* return context data */
int (*context)(const struct bContext *C, const char *member, struct bContextDataResult *result);
@@ -146,7 +146,7 @@ typedef struct ARegionType {
/* snap the size of the region (can be NULL for no snapping). */
int (*snap_size)(const struct ARegion *ar, int size, int axis);
/* contextual changes should be handled here */
- void (*listener)(struct bScreen *sc, struct ScrArea *sa, struct ARegion *ar,
+ void (*listener)(struct wmWindow *win, struct ScrArea *sa, struct ARegion *ar,
struct wmNotifier *wmn, const struct Scene *scene);
/* Optional callback to generate subscriptions. */
void (*message_subscribe)(
@@ -204,8 +204,10 @@ typedef struct PanelType {
char category[BKE_ST_MAXNAME]; /* for category tabs */
char owner_id[BKE_ST_MAXNAME]; /* for work-spaces to selectively show. */
char parent_id[BKE_ST_MAXNAME]; /* parent idname for subpanels */
- int space_type;
- int region_type;
+ short space_type;
+ short region_type;
+ /* For popovers, 0 for default. */
+ int ui_units_x;
int flag;
@@ -324,9 +326,9 @@ void BKE_spacedata_id_unref(struct ScrArea *sa, struct SpaceLink *sl, struct ID
struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar);
void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar);
void BKE_screen_area_free(struct ScrArea *sa);
-/* Manipulator-maps of a region need to be freed with the region. Uses callback to avoid low-level call. */
-void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManipulatorMap *));
-void BKE_region_callback_refresh_tag_manipulatormap_set(void (*callback)(struct wmManipulatorMap *));
+/* Gizmo-maps of a region need to be freed with the region. Uses callback to avoid low-level call. */
+void BKE_region_callback_free_gizmomap_set(void (*callback)(struct wmGizmoMap *));
+void BKE_region_callback_refresh_tag_gizmomap_set(void (*callback)(struct wmGizmoMap *));
struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type);
struct ARegion *BKE_area_find_region_active_win(struct ScrArea *sa);
@@ -343,7 +345,7 @@ unsigned int BKE_screen_view3d_layer_active(
unsigned int BKE_screen_view3d_layer_all(const struct bScreen *sc) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-void BKE_screen_manipulator_tag_refresh(struct bScreen *sc);
+void BKE_screen_gizmo_tag_refresh(struct bScreen *sc);
void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene);
void BKE_screen_view3d_scene_sync(struct bScreen *sc, struct Scene *scene);
@@ -354,6 +356,8 @@ bool BKE_screen_is_used(const struct bScreen *screen) ATTR_WARN_UNUSED_RESULT AT
float BKE_screen_view3d_zoom_to_fac(float camzoom);
float BKE_screen_view3d_zoom_from_fac(float zoomfac);
+void BKE_screen_view3d_shading_init(struct View3DShading *shading);
+
/* screen */
void BKE_screen_free(struct bScreen *sc);
void BKE_screen_area_map_free(struct ScrAreaMap *area_map) ATTR_NONNULL();
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index ff9d079c8e1..b173c995727 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -54,7 +54,7 @@ typedef struct BodyPoint {
extern struct SoftBody *sbNew(struct Scene *scene);
/* frees internal data and softbody itself */
-extern void sbFree(struct SoftBody *sb);
+extern void sbFree(struct Object *ob);
/* frees simulation data to reset simulation */
extern void sbFreeSimulation(struct SoftBody *sb);
diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h
index f8a9498724e..fee01fa8abb 100644
--- a/source/blender/blenkernel/BKE_studiolight.h
+++ b/source/blender/blenkernel/BKE_studiolight.h
@@ -103,7 +103,7 @@ enum StudioLightFlag {
#define STUDIOLIGHT_FLAG_ALL (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_EXTERNAL_FILE)
#define STUDIOLIGHT_FLAG_ORIENTATIONS (STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_VIEWNORMAL)
-#define STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_ORIENTATION_WORLD)
+#define STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE (STUDIOLIGHT_ORIENTATION_WORLD)
#define STUDIOLIGHT_ORIENTATIONS_SOLID (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD)
typedef void StudioLightFreeFunction(struct StudioLight *, void *data);
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
new file mode 100644
index 00000000000..a1792866255
--- /dev/null
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -0,0 +1,230 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_SUBDIV_H__
+#define __BKE_SUBDIV_H__
+
+#include "BLI_sys_types.h"
+
+struct Mesh;
+struct OpenSubdiv_Converter;
+struct OpenSubdiv_Evaluator;
+struct OpenSubdiv_TopologyRefiner;
+
+/** \file BKE_subdiv.h
+ * \ingroup bke
+ * \since July 2018
+ * \author Sergey Sharybin
+ */
+
+typedef enum {
+ SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE,
+ SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY,
+ SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES,
+ SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL,
+} eSubdivFVarLinearInterpolation;
+
+typedef struct SubdivSettings {
+ bool is_simple;
+ bool is_adaptive;
+ int level;
+ eSubdivFVarLinearInterpolation fvar_linear_interpolation;
+} SubdivSettings;
+
+/* NOTE: Order of enumerators MUST match order of values in SubdivStats. */
+typedef enum eSubdivStatsValue {
+ SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME = 0,
+ SUBDIV_STATS_SUBDIV_TO_MESH,
+ SUBDIV_STATS_EVALUATOR_CREATE,
+ SUBDIV_STATS_EVALUATOR_REFINE,
+
+ NUM_SUBDIV_STATS_VALUES,
+} eSubdivStatsValue;
+
+typedef struct SubdivStats {
+ union {
+ struct {
+ /* Time spend on creating topology refiner, which includes time
+ * spend on conversion from Blender data to OpenSubdiv data, and
+ * time spend on topology orientation on OpenSubdiv C-API side.
+ */
+ double topology_refiner_creation_time;
+ /* Total time spent in BKE_subdiv_to_mesh(). */
+ double subdiv_to_mesh_time;
+ /* Time spent on evaluator creation from topology refiner. */
+ double evaluator_creation_time;
+ /* Time spent on evaluator->refine(). */
+ double evaluator_refine_time;
+ };
+ double values_[NUM_SUBDIV_STATS_VALUES];
+ };
+
+ /* Per-value timestamp on when corresponding BKE_subdiv_stats_begin() was
+ * called.
+ */
+ double begin_timestamp_[NUM_SUBDIV_STATS_VALUES];
+} SubdivStats;
+
+typedef struct Subdiv {
+ /* Settings this subdivision surface is created for.
+ *
+ * It is read-only after assignment in BKE_subdiv_new_from_FOO().
+ */
+ SubdivSettings settings;
+
+ /* Total number of ptex faces on subdivision level 0.
+ *
+ * Ptex face is what is internally used by OpenSubdiv for evaluator. It is
+ * a quad face, which corresponds to Blender's legacy Catmull Clark grids.
+ *
+ * Basically, here is a correspondence between polygons and ptex faces:
+ * - Triangle consists of 3 PTex faces.
+ * - Quad is a single PTex face.
+ * - N-gon is N PTex faces.
+ *
+ * This value is initialized in BKE_subdiv_new_from_FOO() and is read-only
+ * after this.
+ */
+ int num_ptex_faces;
+
+ /* Indexed by base face index, element indicates total number of ptex faces
+ * created for preceding base faces.
+ */
+ int *face_ptex_offset;
+
+ /* Topology refiner includes all the glue logic to feed Blender side
+ * topology to OpenSubdiv. It can be shared by both evaluator and GL mesh
+ * drawer.
+ */
+ struct OpenSubdiv_TopologyRefiner *topology_refiner;
+
+ /* CPU side evaluator. */
+ struct OpenSubdiv_Evaluator *evaluator;
+
+ SubdivStats stats;
+} Subdiv;
+
+/* =============================== STATISTICS =============================== */
+
+void BKE_subdiv_stats_init(SubdivStats *stats);
+
+void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value);
+void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value);
+
+void BKE_subdiv_stats_print(const SubdivStats *stats);
+
+/* ============================== CONSTRUCTION ============================== */
+
+Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
+ struct OpenSubdiv_Converter *converter);
+
+Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings,
+ struct Mesh *mesh);
+
+void BKE_subdiv_free(Subdiv *subdiv);
+
+/* ============================= EVALUATION API ============================= */
+
+void BKE_subdiv_eval_begin(Subdiv *subdiv);
+void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const struct Mesh *mesh);
+
+/* Single point queries. */
+
+void BKE_subdiv_eval_limit_point(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float P[3]);
+void BKE_subdiv_eval_limit_point_and_derivatives(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float P[3], float dPdu[3], float dPdv[3]);
+void BKE_subdiv_eval_limit_point_and_normal(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float P[3], float N[3]);
+void BKE_subdiv_eval_limit_point_and_short_normal(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float P[3], short N[3]);
+
+void BKE_subdiv_eval_face_varying(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float varying[2]);
+
+/* Patch queries at given resolution.
+ *
+ * Will evaluate patch at uniformly distributed (u, v) coordinates on a grid
+ * of given resolution, producing resolution^2 evaluation points. The order
+ * goes as u in rows, v in columns.
+ */
+
+void BKE_subdiv_eval_limit_patch_resolution_point(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const int resolution,
+ void *buffer, const int offset, const int stride);
+void BKE_subdiv_eval_limit_patch_resolution_point_and_derivatives(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const int resolution,
+ void *point_buffer, const int point_offset, const int point_stride,
+ void *du_buffer, const int du_offset, const int du_stride,
+ void *dv_buffer, const int dv_offset, const int dv_stride);
+void BKE_subdiv_eval_limit_patch_resolution_point_and_normal(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const int resolution,
+ void *point_buffer, const int point_offset, const int point_stride,
+ void *normal_buffer, const int normal_offset, const int normal_stride);
+void BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const int resolution,
+ void *point_buffer, const int point_offset, const int point_stride,
+ void *normal_buffer, const int normal_offset, const int normal_stride);
+
+/* =========================== SUBDIV TO MESH API =========================== */
+
+typedef struct SubdivToMeshSettings {
+ /* Resolution at which ptex are being evaluated.
+ * This defines how many vertices final mesh will have: every ptex has
+ * resolution^2 vertices.
+ */
+ int resolution;
+} SubdivToMeshSettings;
+
+/* Create real hi-res mesh from subdivision, all geometry is "real". */
+struct Mesh *BKE_subdiv_to_mesh(
+ Subdiv *subdiv,
+ const SubdivToMeshSettings *settings,
+ const struct Mesh *coarse_mesh);
+
+#endif /* __BKE_SUBDIV_H__ */
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 03d24ac53d1..4f4ae9f375b 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -54,23 +54,11 @@ void BKE_workspace_layout_remove(
void BKE_workspace_relations_free(
ListBase *relation_list);
-void BKE_workspace_scene_relations_free_invalid(
- struct WorkSpace *workspace);
/* -------------------------------------------------------------------- */
/* General Utils */
-void BKE_workspace_view_layer_rename(
- const struct Main *bmain,
- const struct Scene *scene,
- const char *old_name,
- const char *new_name) ATTR_NONNULL();
-
-void BKE_workspace_view_layer_remove(
- const struct Main *bmain,
- const struct ViewLayer *view_layer) ATTR_NONNULL();
-
struct WorkSpaceLayout *BKE_workspace_layout_find(
const struct WorkSpace *workspace, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
struct WorkSpaceLayout *BKE_workspace_layout_find_global(
@@ -97,17 +85,6 @@ struct bScreen *BKE_workspace_active_screen_get(const struct WorkSpaceInstanceHo
void BKE_workspace_active_screen_set(
struct WorkSpaceInstanceHook *hook, struct WorkSpace *workspace, struct bScreen *screen) SETTER_ATTRS;
-struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace, const struct Scene *scene);
-struct ViewLayer *BKE_workspace_view_layer_get(
- const struct WorkSpace *workspace,
- const struct Scene *scene) GETTER_ATTRS;
-struct ViewLayer *BKE_workspace_view_layer_exists(
- const struct WorkSpace *workspace,
- const struct Scene *scene) GETTER_ATTRS;
-void BKE_workspace_view_layer_set(
- struct WorkSpace *workspace,
- struct ViewLayer *layer,
- struct Scene *scene) SETTER_ATTRS;
struct ListBase *BKE_workspace_layouts_get(struct WorkSpace *workspace) GETTER_ATTRS;
const char *BKE_workspace_layout_name_get(const struct WorkSpaceLayout *layout) GETTER_ATTRS;
@@ -121,11 +98,6 @@ struct WorkSpaceLayout *BKE_workspace_hook_layout_for_workspace_get(
void BKE_workspace_hook_layout_for_workspace_set(
struct WorkSpaceInstanceHook *hook, struct WorkSpace *workspace, struct WorkSpaceLayout *layout) ATTR_NONNULL();
-/* Update / evaluate */
-void BKE_workspace_update_tagged(struct Main *bmain,
- struct WorkSpace *workspace,
- struct Scene *scene);
-
bool BKE_workspace_owner_id_check(
const struct WorkSpace *workspace, const char *owner_id) ATTR_NONNULL();
diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h
index f703fefec97..6a9a75828e5 100644
--- a/source/blender/blenkernel/BKE_world.h
+++ b/source/blender/blenkernel/BKE_world.h
@@ -44,10 +44,4 @@ struct World *BKE_world_copy(struct Main *bmain, const struct World *wrld);
struct World *BKE_world_localize(struct World *wrld);
void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local);
-/* Evaluation. */
-
-struct Depsgraph;
-
-void BKE_world_eval(struct Depsgraph *depsgraph, struct World *world);
-
#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index d2654e32fa7..01910bffdb0 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -186,6 +186,12 @@ set(SRC
intern/sound.c
intern/speaker.c
intern/studiolight.c
+ intern/subdiv.c
+ intern/subdiv_converter.c
+ intern/subdiv_converter_mesh.c
+ intern/subdiv_eval.c
+ intern/subdiv_mesh.c
+ intern/subdiv_stats.c
intern/subsurf_ccg.c
intern/suggestions.c
intern/text.c
@@ -276,6 +282,7 @@ set(SRC
BKE_mesh_iterators.h
BKE_mesh_mapping.h
BKE_mesh_remap.h
+ BKE_mesh_runtime.h
BKE_mesh_tangent.h
BKE_modifier.h
BKE_movieclip.h
@@ -305,6 +312,7 @@ set(SRC
BKE_sound.h
BKE_speaker.h
BKE_studiolight.h
+ BKE_subdiv.h
BKE_subsurf.h
BKE_suggestions.h
BKE_text.h
@@ -322,8 +330,9 @@ set(SRC
intern/CCGSubSurf.h
intern/CCGSubSurf_inline.h
intern/CCGSubSurf_intern.h
- intern/pbvh_intern.h
intern/data_transfer_intern.h
+ intern/pbvh_intern.h
+ intern/subdiv_converter.h
)
if(WITH_BINRELOC)
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 81b1afa3621..dd5a87a445d 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -40,6 +40,8 @@
#ifdef WITH_OPENSUBDIV
# include "opensubdiv_capi.h"
# include "opensubdiv_converter_capi.h"
+# include "opensubdiv_evaluator_capi.h"
+# include "opensubdiv_topology_refiner_capi.h"
#endif
#include "GPU_glew.h"
@@ -329,7 +331,7 @@ void ccgSubSurf_free(CCGSubSurf *ss)
CCGAllocatorHDL allocator = ss->allocator;
#ifdef WITH_OPENSUBDIV
if (ss->osd_evaluator != NULL) {
- openSubdiv_deleteEvaluatorDescr(ss->osd_evaluator);
+ openSubdiv_deleteEvaluator(ss->osd_evaluator);
}
if (ss->osd_mesh != NULL) {
ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
@@ -341,7 +343,7 @@ void ccgSubSurf_free(CCGSubSurf *ss)
MEM_freeN(ss->osd_coarse_coords);
}
if (ss->osd_topology_refiner != NULL) {
- openSubdiv_deleteTopologyRefinerDescr(ss->osd_topology_refiner);
+ openSubdiv_deleteTopologyRefiner(ss->osd_topology_refiner);
}
#endif
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
index 9df1c9021ef..29e327d8973 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
@@ -236,7 +236,7 @@ struct CCGSubSurf {
* Refiner is created from the modifier stack and used later from the main
* thread to construct GL mesh to avoid threaded access to GL.
*/
- struct OpenSubdiv_TopologyRefinerDescr *osd_topology_refiner; /* Only used at synchronization stage. */
+ struct OpenSubdiv_TopologyRefiner *osd_topology_refiner; /* Only used at synchronization stage. */
/* Denotes whether osd_mesh is invalid now due to topology changes and needs
* to be reconstructed.
*
@@ -249,7 +249,7 @@ struct CCGSubSurf {
/* ** CPU backend. ** */
/* Limit evaluator, used to evaluate CCG. */
- struct OpenSubdiv_EvaluatorDescr *osd_evaluator;
+ struct OpenSubdiv_Evaluator *osd_evaluator;
/* Next PTex face index, used while CCG synchronization
* to fill in PTex index of CCGFace.
*/
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
index fc4220277eb..98a17ad8009 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
@@ -42,6 +42,9 @@
#include "opensubdiv_capi.h"
#include "opensubdiv_converter_capi.h"
+#include "opensubdiv_evaluator_capi.h"
+#include "opensubdiv_gl_mesh_capi.h"
+#include "opensubdiv_topology_refiner_capi.h"
#include "GPU_glew.h"
#include "GPU_extensions.h"
@@ -131,7 +134,6 @@ static bool compare_ccg_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm)
static bool compare_osd_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm)
{
- const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
OpenSubdiv_Converter converter;
bool result;
if (ss->osd_mesh == NULL && ss->osd_topology_refiner == NULL) {
@@ -140,15 +142,10 @@ static bool compare_osd_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm)
/* TODO(sergey): De-duplicate with topology counter at the bottom of
* the file.
*/
- if (ss->osd_topology_refiner != NULL) {
- topology_refiner = ss->osd_topology_refiner;
- }
- else {
- topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
- }
ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
- result = openSubdiv_topologyRefnerCompareConverter(topology_refiner,
- &converter);
+ result = openSubdiv_topologyRefinerCompareWithConverter(
+ ss->osd_topology_refiner,
+ &converter);
ccgSubSurf_converter_free(&converter);
return result;
}
@@ -159,22 +156,13 @@ static bool opensubdiv_is_topology_changed(CCGSubSurf *ss, DerivedMesh *dm)
return true;
}
if (ss->osd_topology_refiner != NULL) {
- int levels = openSubdiv_topologyRefinerGetSubdivLevel(
+ const int levels = ss->osd_topology_refiner->getSubdivisionLevel(
ss->osd_topology_refiner);
BLI_assert(ss->osd_mesh_invalid == true);
if (levels != ss->subdivLevels) {
return true;
}
}
- if (ss->osd_mesh != NULL && ss->osd_mesh_invalid == false) {
- const OpenSubdiv_TopologyRefinerDescr *topology_refiner =
- openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
- int levels = openSubdiv_topologyRefinerGetSubdivLevel(topology_refiner);
- BLI_assert(ss->osd_topology_refiner == NULL);
- if (levels != ss->subdivLevels) {
- return true;
- }
- }
if (ss->skip_grids == false) {
return compare_ccg_derivedmesh_topology(ss, dm) == false;
}
@@ -194,13 +182,13 @@ void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, DerivedMesh *dm)
/* Reset GPU part. */
ss->osd_mesh_invalid = true;
if (ss->osd_topology_refiner != NULL) {
- openSubdiv_deleteTopologyRefinerDescr(ss->osd_topology_refiner);
+ openSubdiv_deleteTopologyRefiner(ss->osd_topology_refiner);
ss->osd_topology_refiner = NULL;
}
- /* Reste CPU side. */
+ /* Reset CPU side. */
if (ss->osd_evaluator != NULL) {
- openSubdiv_deleteEvaluatorDescr(ss->osd_evaluator);
+ openSubdiv_deleteEvaluator(ss->osd_evaluator);
ss->osd_evaluator = NULL;
}
}
@@ -209,10 +197,10 @@ void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, DerivedMesh *dm)
static void ccgSubSurf__updateGLMeshCoords(CCGSubSurf *ss)
{
BLI_assert(ss->meshIFC.numLayers == 3);
- openSubdiv_osdGLMeshUpdateVertexBuffer(ss->osd_mesh,
- (float *) ss->osd_coarse_coords,
- 0,
- ss->osd_num_coarse_coords);
+ ss->osd_mesh->setCoarsePositions(ss->osd_mesh,
+ (float *) ss->osd_coarse_coords,
+ 0,
+ ss->osd_num_coarse_coords);
}
bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss,
@@ -259,9 +247,7 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss,
ss->osd_mesh = openSubdiv_createOsdGLMeshFromTopologyRefiner(
ss->osd_topology_refiner,
- compute_type,
- ss->subdivLevels);
- ss->osd_topology_refiner = NULL;
+ compute_type);
if (UNLIKELY(ss->osd_mesh == NULL)) {
/* Most likely compute device is not available. */
@@ -269,13 +255,12 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss,
}
ccgSubSurf__updateGLMeshCoords(ss);
- openSubdiv_osdGLMeshRefine(ss->osd_mesh);
- openSubdiv_osdGLMeshSynchronize(ss->osd_mesh);
+ ss->osd_mesh->refine(ss->osd_mesh);
+ ss->osd_mesh->synchronize(ss->osd_mesh);
ss->osd_coarse_coords_invalid = false;
glBindVertexArray(ss->osd_vao);
- glBindBuffer(GL_ARRAY_BUFFER,
- openSubdiv_getOsdGLMeshVertexBuffer(ss->osd_mesh));
+ ss->osd_mesh->bindVertexBuffer(ss->osd_mesh);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
@@ -289,12 +274,12 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss,
}
else if (ss->osd_coarse_coords_invalid) {
ccgSubSurf__updateGLMeshCoords(ss);
- openSubdiv_osdGLMeshRefine(ss->osd_mesh);
- openSubdiv_osdGLMeshSynchronize(ss->osd_mesh);
+ ss->osd_mesh->refine(ss->osd_mesh);
+ ss->osd_mesh->synchronize(ss->osd_mesh);
ss->osd_coarse_coords_invalid = false;
}
- openSubdiv_osdGLMeshDisplayPrepare(use_osd_glsl, active_uv_index);
+ ss->osd_mesh->prepareDraw(ss->osd_mesh, use_osd_glsl, active_uv_index);
return true;
}
@@ -305,12 +290,12 @@ void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
if (LIKELY(ss->osd_mesh != NULL)) {
glBindVertexArray(ss->osd_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
- openSubdiv_getOsdGLMeshPatchIndexBuffer(ss->osd_mesh));
+ ss->osd_mesh->getPatchIndexBuffer(ss->osd_mesh));
- openSubdiv_osdGLMeshBindVertexBuffer(ss->osd_mesh);
+ ss->osd_mesh->bindVertexBuffer(ss->osd_mesh);
glBindVertexArray(ss->osd_vao);
- openSubdiv_osdGLMeshDisplay(ss->osd_mesh, fill_quads,
- start_partition, num_partitions);
+ ss->osd_mesh->drawPatches(ss->osd_mesh, fill_quads,
+ start_partition, num_partitions);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -319,33 +304,21 @@ void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss)
{
- const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
if (ss->osd_topology_refiner != NULL) {
- topology_refiner = ss->osd_topology_refiner;
- }
- else if (ss->osd_mesh != NULL) {
- topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
- }
- else {
- return 0;
+ return ss->osd_topology_refiner->getNumFaces(
+ ss->osd_topology_refiner);
}
- return openSubdiv_topologyRefinerGetNumFaces(topology_refiner);
+ return 0;
}
/* Get number of vertices in base faces in a particular GL mesh. */
int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face)
{
- const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
if (ss->osd_topology_refiner != NULL) {
- topology_refiner = ss->osd_topology_refiner;
- }
- else if (ss->osd_mesh != NULL) {
- topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
- }
- else {
- return 0;
+ return ss->osd_topology_refiner->getNumFaceVertices(
+ ss->osd_topology_refiner, face);
}
- return openSubdiv_topologyRefinerGetNumFaceVerts(topology_refiner, face);
+ return 0;
}
void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids)
@@ -453,17 +426,21 @@ void ccgSubSurf_evaluatorFVarUV(CCGSubSurf *ss,
static bool opensubdiv_createEvaluator(CCGSubSurf *ss)
{
OpenSubdiv_Converter converter;
- OpenSubdiv_TopologyRefinerDescr *topology_refiner;
+ OpenSubdiv_TopologyRefiner *topology_refiner;
if (ss->fMap->numEntries == 0) {
/* OpenSubdiv doesn't support meshes without faces. */
return false;
}
ccgSubSurf_converter_setup_from_ccg(ss, &converter);
- topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter);
+ OpenSubdiv_TopologyRefinerSettings settings;
+ settings.level = ss->subdivLevels;
+ settings.is_adaptive = false;
+ topology_refiner =
+ openSubdiv_createTopologyRefinerFromConverter(
+ &converter, &settings);
ccgSubSurf_converter_free(&converter);
ss->osd_evaluator =
- openSubdiv_createEvaluatorDescr(topology_refiner,
- ss->subdivLevels);
+ openSubdiv_createEvaluatorFromTopologyRefiner(topology_refiner);
if (ss->osd_evaluator == NULL) {
BLI_assert(!"OpenSubdiv initialization failed, should not happen.");
return false;
@@ -519,10 +496,11 @@ static void opensubdiv_updateEvaluatorCoarsePositions(CCGSubSurf *ss)
}
}
- openSubdiv_setEvaluatorCoarsePositions(ss->osd_evaluator,
- (float *)positions,
- 0,
- num_basis_verts);
+ ss->osd_evaluator->setCoarsePositions(ss->osd_evaluator,
+ (float *)positions,
+ 0,
+ num_basis_verts);
+ ss->osd_evaluator->refine(ss->osd_evaluator);
MEM_freeN(positions);
}
@@ -557,11 +535,12 @@ static void opensubdiv_evaluateQuadFaceGrids(CCGSubSurf *ss,
ccgSubSurf__mapGridToFace(S, grid_u, grid_v, &face_u, &face_v);
/* TODO(sergey): Need proper port. */
- openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index,
- face_u, face_v,
- P,
- do_normals ? dPdu : NULL,
- do_normals ? dPdv : NULL);
+ ss->osd_evaluator->evaluateLimit(
+ ss->osd_evaluator, osd_face_index,
+ face_u, face_v,
+ P,
+ do_normals ? dPdu : NULL,
+ do_normals ? dPdv : NULL);
OSD_LOG("face=%d, corner=%d, grid_u=%f, grid_v=%f, face_u=%f, face_v=%f, P=(%f, %f, %f)\n",
osd_face_index, S, grid_u, grid_v, face_u, face_v, P[0], P[1], P[2]);
@@ -635,7 +614,11 @@ static void opensubdiv_evaluateQuadFaceGrids(CCGSubSurf *ss,
* let's just re-evaluate for simplicity.
*/
/* TODO(sergey): Need proper port. */
- openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index, u, v, P, dPdu, dPdv);
+ ss->osd_evaluator->evaluateLimit(
+ ss->osd_evaluator,
+ osd_face_index,
+ u, v,
+ P, dPdu, dPdv);
VertDataCopy(co, P, ss);
if (do_normals) {
cross_v3_v3v3(no, dPdu, dPdv);
@@ -699,7 +682,11 @@ static void opensubdiv_evaluateNGonFaceGrids(CCGSubSurf *ss,
float P[3], dPdu[3], dPdv[3];
/* TODO(sergey): Need proper port. */
- openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index + S, u, v, P, dPdu, dPdv);
+ ss->osd_evaluator->evaluateLimit(
+ ss->osd_evaluator,
+ osd_face_index + S,
+ u, v,
+ P, dPdu, dPdv);
OSD_LOG("face=%d, corner=%d, u=%f, v=%f, P=(%f, %f, %f)\n",
osd_face_index + S, S, u, v, P[0], P[1], P[2]);
@@ -837,7 +824,12 @@ void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss, DerivedMesh *dm)
OpenSubdiv_Converter converter;
ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
/* TODO(sergey): Remove possibly previously allocated refiner. */
- ss->osd_topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter);
+ OpenSubdiv_TopologyRefinerSettings settings;
+ settings.level = ss->subdivLevels;
+ settings.is_adaptive = false;
+ ss->osd_topology_refiner =
+ openSubdiv_createTopologyRefinerFromConverter(
+ &converter, &settings);
ccgSubSurf_converter_free(&converter);
}
}
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
index f1f82f458aa..649b7c7fa4c 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
@@ -84,11 +84,14 @@ static OpenSubdiv_SchemeType conv_dm_get_type(
return OSD_SCHEME_CATMARK;
}
-static bool conv_dm_get_subdiv_uvs(
+static OpenSubdiv_FVarLinearInterpolation conv_dm_get_fvar_linear_interpolation(
const OpenSubdiv_Converter *converter)
{
ConvDMStorage *storage = converter->user_data;
- return (storage->ss->osd_subdiv_uvs);
+ if (storage->ss->osd_subdiv_uvs) {
+ return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY;
+ }
+ return OSD_FVAR_LINEAR_INTERPOLATION_ALL;
}
static int conv_dm_get_num_faces(const OpenSubdiv_Converter *converter)
@@ -386,12 +389,6 @@ static int conv_dm_get_num_uvs(const OpenSubdiv_Converter *converter)
return storage->num_uvs;
}
-static void conv_dm_get_uvs(const OpenSubdiv_Converter *converter, float *uvs)
-{
- ConvDMStorage *storage = converter->user_data;
- memcpy(uvs, storage->uvs, sizeof(float) * 2 * storage->num_uvs);
-}
-
static int conv_dm_get_face_corner_uv_index(const OpenSubdiv_Converter *converter,
int face,
int corner)
@@ -429,34 +426,34 @@ void ccgSubSurf_converter_setup_from_derivedmesh(
{
ConvDMStorage *user_data;
- converter->get_type = conv_dm_get_type;
+ converter->getSchemeType = conv_dm_get_type;
- converter->get_subdiv_uvs = conv_dm_get_subdiv_uvs;
+ converter->getFVarLinearInterpolation =
+ conv_dm_get_fvar_linear_interpolation;
- converter->get_num_faces = conv_dm_get_num_faces;
- converter->get_num_edges = conv_dm_get_num_edges;
- converter->get_num_verts = conv_dm_get_num_verts;
+ converter->getNumFaces = conv_dm_get_num_faces;
+ converter->getNumEdges = conv_dm_get_num_edges;
+ converter->getNumVertices = conv_dm_get_num_verts;
- converter->get_num_face_verts = conv_dm_get_num_face_verts;
- converter->get_face_verts = conv_dm_get_face_verts;
- converter->get_face_edges = conv_dm_get_face_edges;
+ converter->getNumFaceVertices = conv_dm_get_num_face_verts;
+ converter->getFaceVertices = conv_dm_get_face_verts;
+ converter->getFaceEdges = conv_dm_get_face_edges;
- converter->get_edge_verts = conv_dm_get_edge_verts;
- converter->get_num_edge_faces = conv_dm_get_num_edge_faces;
- converter->get_edge_faces = conv_dm_get_edge_faces;
- converter->get_edge_sharpness = conv_dm_get_edge_sharpness;
+ converter->getEdgeVertices = conv_dm_get_edge_verts;
+ converter->getNumEdgeFaces = conv_dm_get_num_edge_faces;
+ converter->getEdgeFaces = conv_dm_get_edge_faces;
+ converter->getEdgeSharpness = conv_dm_get_edge_sharpness;
- converter->get_num_vert_edges = conv_dm_get_num_vert_edges;
- converter->get_vert_edges = conv_dm_get_vert_edges;
- converter->get_num_vert_faces = conv_dm_get_num_vert_faces;
- converter->get_vert_faces = conv_dm_get_vert_faces;
+ converter->getNumVertexEdges = conv_dm_get_num_vert_edges;
+ converter->getVertexEdges = conv_dm_get_vert_edges;
+ converter->getNumVertexFaces = conv_dm_get_num_vert_faces;
+ converter->getVertexFaces = conv_dm_get_vert_faces;
- converter->get_num_uv_layers = conv_dm_get_num_uv_layers;
- converter->precalc_uv_layer = conv_dm_precalc_uv_layer;
- converter->finish_uv_layer = conv_dm_finish_uv_layer;
- converter->get_num_uvs = conv_dm_get_num_uvs;
- converter->get_uvs = conv_dm_get_uvs;
- converter->get_face_corner_uv_index = conv_dm_get_face_corner_uv_index;
+ converter->getNumUVLayers = conv_dm_get_num_uv_layers;
+ converter->precalcUVLayer = conv_dm_precalc_uv_layer;
+ converter->finishUVLayer = conv_dm_finish_uv_layer;
+ converter->getNumUVCoordinates = conv_dm_get_num_uvs;
+ converter->getFaceCornerUVIndex = conv_dm_get_face_corner_uv_index;
user_data = MEM_mallocN(sizeof(ConvDMStorage), __func__);
user_data->ss = ss;
@@ -472,7 +469,7 @@ void ccgSubSurf_converter_setup_from_derivedmesh(
user_data->uvs = NULL;
user_data->face_uvs = NULL;
- converter->free_user_data = conv_dm_free_user_data;
+ converter->freeUserData = conv_dm_free_user_data;
converter->user_data = user_data;
#ifdef USE_MESH_ELEMENT_MAPPING
@@ -526,11 +523,14 @@ static OpenSubdiv_SchemeType conv_ccg_get_bilinear_type(
}
}
-static bool conv_ccg_get_subdiv_uvs(
- const OpenSubdiv_Converter *converter)
+static OpenSubdiv_FVarLinearInterpolation
+conv_ccg_get_fvar_linear_interpolation(const OpenSubdiv_Converter *converter)
{
CCGSubSurf *ss = converter->user_data;
- return (ss->osd_subdiv_uvs);
+ if (ss->osd_subdiv_uvs) {
+ return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY;
+ }
+ return OSD_FVAR_LINEAR_INTERPOLATION_ALL;
}
static int conv_ccg_get_num_faces(const OpenSubdiv_Converter *converter)
@@ -695,11 +695,6 @@ static int conv_ccg_get_num_uvs(const OpenSubdiv_Converter *UNUSED(converter))
return 0;
}
-static void conv_ccg_get_uvs(const OpenSubdiv_Converter * UNUSED(converter),
- float *UNUSED(uvs))
-{
-}
-
static int conv_ccg_get_face_corner_uv_index(const OpenSubdiv_Converter *UNUSED(converter),
int UNUSED(face),
int UNUSED(corner_))
@@ -710,44 +705,44 @@ static int conv_ccg_get_face_corner_uv_index(const OpenSubdiv_Converter *UNUSED(
void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss,
OpenSubdiv_Converter *converter)
{
- converter->get_type = conv_ccg_get_bilinear_type;
+ converter->getSchemeType = conv_ccg_get_bilinear_type;
- converter->get_subdiv_uvs = conv_ccg_get_subdiv_uvs;
+ converter->getFVarLinearInterpolation =
+ conv_ccg_get_fvar_linear_interpolation;
- converter->get_num_faces = conv_ccg_get_num_faces;
- converter->get_num_edges = conv_ccg_get_num_edges;
- converter->get_num_verts = conv_ccg_get_num_verts;
+ converter->getNumFaces = conv_ccg_get_num_faces;
+ converter->getNumEdges = conv_ccg_get_num_edges;
+ converter->getNumVertices = conv_ccg_get_num_verts;
- converter->get_num_face_verts = conv_ccg_get_num_face_verts;
- converter->get_face_verts = conv_ccg_get_face_verts;
- converter->get_face_edges = conv_ccg_get_face_edges;
+ converter->getNumFaceVertices = conv_ccg_get_num_face_verts;
+ converter->getFaceVertices = conv_ccg_get_face_verts;
+ converter->getFaceEdges = conv_ccg_get_face_edges;
- converter->get_edge_verts = conv_ccg_get_edge_verts;
- converter->get_num_edge_faces = conv_ccg_get_num_edge_faces;
- converter->get_edge_faces = conv_ccg_get_edge_faces;
- converter->get_edge_sharpness = conv_ccg_get_edge_sharpness;
+ converter->getEdgeVertices = conv_ccg_get_edge_verts;
+ converter->getNumEdgeFaces = conv_ccg_get_num_edge_faces;
+ converter->getEdgeFaces = conv_ccg_get_edge_faces;
+ converter->getEdgeSharpness = conv_ccg_get_edge_sharpness;
- converter->get_num_vert_edges = conv_ccg_get_num_vert_edges;
- converter->get_vert_edges = conv_ccg_get_vert_edges;
- converter->get_num_vert_faces = conv_ccg_get_num_vert_faces;
- converter->get_vert_faces = conv_ccg_get_vert_faces;
+ converter->getNumVertexEdges = conv_ccg_get_num_vert_edges;
+ converter->getVertexEdges = conv_ccg_get_vert_edges;
+ converter->getNumVertexFaces = conv_ccg_get_num_vert_faces;
+ converter->getVertexFaces = conv_ccg_get_vert_faces;
- converter->get_num_uv_layers = conv_ccg_get_num_uv_layers;
- converter->precalc_uv_layer = conv_ccg_precalc_uv_layer;
- converter->finish_uv_layer = conv_ccg_finish_uv_layer;
- converter->get_num_uvs = conv_ccg_get_num_uvs;
- converter->get_uvs = conv_ccg_get_uvs;
- converter->get_face_corner_uv_index = conv_ccg_get_face_corner_uv_index;
+ converter->getNumUVLayers = conv_ccg_get_num_uv_layers;
+ converter->precalcUVLayer = conv_ccg_precalc_uv_layer;
+ converter->finishUVLayer = conv_ccg_finish_uv_layer;
+ converter->getNumUVCoordinates = conv_ccg_get_num_uvs;
+ converter->getFaceCornerUVIndex = conv_ccg_get_face_corner_uv_index;
- converter->free_user_data = NULL;
+ converter->freeUserData = NULL;
converter->user_data = ss;
}
void ccgSubSurf_converter_free(
struct OpenSubdiv_Converter *converter)
{
- if (converter->free_user_data) {
- converter->free_user_data(converter);
+ if (converter->freeUserData) {
+ converter->freeUserData(converter);
}
}
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 4aee616580e..9c4aae7cda5 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -3156,6 +3156,8 @@ DerivedMesh *mesh_create_derived_render(struct Depsgraph *depsgraph, Scene *scen
return final;
}
+#ifdef USE_DERIVEDMESH
+/* Deprecated, use `mesh_create_eval_final_index_render` instead. */
DerivedMesh *mesh_create_derived_index_render(struct Depsgraph *depsgraph, Scene *scene, Object *ob, CustomDataMask dataMask, int index)
{
DerivedMesh *final;
@@ -3166,7 +3168,22 @@ DerivedMesh *mesh_create_derived_index_render(struct Depsgraph *depsgraph, Scene
return final;
}
+#endif
+struct Mesh *mesh_create_eval_final_index_render(
+ struct Depsgraph *depsgraph, struct Scene *scene,
+ struct Object *ob, CustomDataMask dataMask, int index)
+{
+ Mesh *final;
+
+ mesh_calc_modifiers(
+ depsgraph, scene, ob, NULL, 1, false, dataMask, index, false, false, false,
+ NULL, &final);
+
+ return final;
+}
+#ifdef USE_DERIVEDMESH
+/* Deprecated, use `mesh_create_eval_final_view` instead. */
DerivedMesh *mesh_create_derived_view(
struct Depsgraph *depsgraph, Scene *scene,
Object *ob, CustomDataMask dataMask)
@@ -3187,6 +3204,28 @@ DerivedMesh *mesh_create_derived_view(
return final;
}
+#endif
+
+Mesh *mesh_create_eval_final_view(
+ struct Depsgraph *depsgraph, Scene *scene,
+ Object *ob, CustomDataMask dataMask)
+{
+ Mesh *final;
+
+ /* XXX hack
+ * psys modifier updates particle state when called during dupli-list generation,
+ * which can lead to wrong transforms. This disables particle system modifier execution.
+ */
+ ob->transflag |= OB_NO_PSYS_UPDATE;
+
+ mesh_calc_modifiers(
+ depsgraph, scene, ob, NULL, 1, false, dataMask, -1, false, false, false,
+ NULL, &final);
+
+ ob->transflag &= ~OB_NO_PSYS_UPDATE;
+
+ return final;
+}
DerivedMesh *mesh_create_derived_no_deform(
struct Depsgraph *depsgraph, Scene *scene, Object *ob,
diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c
index a9bb193a7a1..854bf62c061 100644
--- a/source/blender/blenkernel/intern/addon.c
+++ b/source/blender/blenkernel/intern/addon.c
@@ -69,6 +69,17 @@ bAddon *BKE_addon_ensure(ListBase *addon_list, const char *module)
return addon;
}
+bool BKE_addon_remove_safe(ListBase *addon_list, const char *module)
+{
+ bAddon *addon = BLI_findstring(addon_list, module, offsetof(bAddon, module));
+ if (addon) {
+ BLI_remlink(addon_list, addon);
+ BKE_addon_free(addon);
+ return true;
+ }
+ return false;
+}
+
void BKE_addon_free(bAddon *addon)
{
if (addon->prop) {
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 07b8b69bc70..eed8943cd5b 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -114,9 +114,9 @@ void animviz_free_motionpath_cache(bMotionPath *mpath)
if (mpath->points)
MEM_freeN(mpath->points);
- GWN_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
- GWN_BATCH_DISCARD_SAFE(mpath->batch_line);
- GWN_BATCH_DISCARD_SAFE(mpath->batch_points);
+ GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
+ GPU_BATCH_DISCARD_SAFE(mpath->batch_line);
+ GPU_BATCH_DISCARD_SAFE(mpath->batch_points);
/* reset the relevant parameters */
mpath->points = NULL;
@@ -495,9 +495,9 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
BLI_dlrbTree_free(&mpt->keys);
/* Free previous batches to force update. */
- GWN_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
- GWN_BATCH_DISCARD_SAFE(mpath->batch_line);
- GWN_BATCH_DISCARD_SAFE(mpath->batch_points);
+ GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
+ GPU_BATCH_DISCARD_SAFE(mpath->batch_line);
+ GPU_BATCH_DISCARD_SAFE(mpath->batch_points);
}
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index bd9ee7c9e5f..6be4574a62e 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -71,6 +71,8 @@
#include "BKE_object.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph_build.h"
+
#include "BIK_api.h"
/* **************** Generic Functions, data level *************** */
@@ -1951,9 +1953,14 @@ void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose)
BLI_ghash_free(bone_hash, NULL, NULL);
}
-/* only after leave editmode, duplicating, validating older files, library syncing */
-/* NOTE: pose->flag is set for it */
-void BKE_pose_rebuild(Object *ob, bArmature *arm)
+/**
+ * Only after leave editmode, duplicating, validating older files, library syncing.
+ *
+ * \note pose->flag is set for it.
+ *
+ * \param bmain May be NULL, only used to tag depsgraph as being dirty...
+ */
+void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm)
{
Bone *bone;
bPose *pose;
@@ -1998,12 +2005,17 @@ void BKE_pose_rebuild(Object *ob, bArmature *arm)
pose_proxy_synchronize(ob, ob->proxy, arm->layer_protected);
}
- BKE_pose_update_constraint_flags(ob->pose); /* for IK detection for example */
+ BKE_pose_update_constraint_flags(pose); /* for IK detection for example */
+
+ pose->flag &= ~POSE_RECALC;
+ pose->flag |= POSE_WAS_REBUILT;
- ob->pose->flag &= ~POSE_RECALC;
- ob->pose->flag |= POSE_WAS_REBUILT;
+ BKE_pose_channels_hash_make(pose);
- BKE_pose_channels_hash_make(ob->pose);
+ /* Rebuilding poses forces us to also rebuild the dependency graph, since there is one node per pose/bone... */
+ if (bmain != NULL) {
+ DEG_relations_tag_update(bmain);
+ }
}
/* ********************** THE POSE SOLVER ******************* */
@@ -2277,8 +2289,10 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
if (ELEM(NULL, arm, scene))
return;
- if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC))
- BKE_pose_rebuild(ob, arm);
+ if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC)) {
+ /* WARNING! passing NULL bmain here means we won't tag depsgraph's as dirty - hopefully this is OK. */
+ BKE_pose_rebuild(NULL, ob, arm);
+ }
ctime = BKE_scene_frame_get(scene); /* not accurate... */
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 23c2147ff7e..66020679bf7 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -300,7 +300,7 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
DATA_SWAP(font_path_ui_mono);
DATA_SWAP(keyconfigstr);
- DATA_SWAP(manipulator_flag);
+ DATA_SWAP(gizmo_flag);
DATA_SWAP(app_flag);
/* We could add others. */
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index 27b5089b092..b16648fd73f 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -226,7 +226,7 @@ static void setup_app_data(
* only the current screen is important because we wont have to handle
* events from multiple screens at once.*/
{
- BKE_screen_manipulator_tag_refresh(curscreen);
+ BKE_screen_gizmo_tag_refresh(curscreen);
}
}
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 7c9e57b039e..34f54704f75 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -513,7 +513,7 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
}
if (ob->soft) {
- BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches);
+ BPATH_TRAVERSE_POINTCACHE(ob->soft->shared->ptcaches);
}
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 778eb17f822..4203e0455f8 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -977,7 +977,6 @@ CameraBGImage *BKE_camera_background_image_new(Camera *cam)
bgpic->scale = 1.0f;
bgpic->alpha = 0.5f;
- bgpic->iuser.fie_ima = 2;
bgpic->iuser.ok = 1;
bgpic->iuser.flag |= IMA_ANIM_ALWAYS;
bgpic->flag |= CAM_BGIMG_FLAG_EXPANDED;
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index ccef747a31c..caf5b94b30e 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -924,7 +924,7 @@ static void cloth_from_mesh ( ClothModifierData *clmd, Mesh *mesh )
}
/***************************************************************************************
- * SPRING NETWORK GWN_BATCH_BUILDING IMPLEMENTATION BEGIN
+ * SPRING NETWORK GPU_BATCH_BUILDING IMPLEMENTATION BEGIN
***************************************************************************************/
BLI_INLINE void spring_verts_ordered_set(ClothSpring *spring, int v0, int v1)
@@ -1506,5 +1506,5 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh )
} /* cloth_build_springs */
/***************************************************************************************
- * SPRING NETWORK GWN_BATCH_BUILDING IMPLEMENTATION END
+ * SPRING NETWORK GPU_BATCH_BUILDING IMPLEMENTATION END
***************************************************************************************/
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 1d9cc9bb8d0..0c93f304218 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -473,7 +473,7 @@ static bool collection_object_add(Main *bmain, Collection *collection, Object *o
{
if (ob->dup_group) {
/* Cyclic dependency check. */
- if (collection_find_child_recursive(collection, ob->dup_group)) {
+ if (collection_find_child_recursive(ob->dup_group, collection)) {
return false;
}
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 0cbd77b67d2..5aa192d527a 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -463,8 +463,8 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
}
/* derive the rotation from the average normal:
- * - code taken from transform_manipulator.c,
- * calc_manipulator_stats, V3D_MANIP_NORMAL case
+ * - code taken from transform_gizmo.c,
+ * calc_gizmo_stats, V3D_MANIP_NORMAL case
*/
/* we need the transpose of the inverse for a normal... */
copy_m3_m4(imat, ob->obmat);
@@ -3641,7 +3641,7 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
* - the min/max wrappers around (obvec . tarvec) result (stored temporarily in rangle)
* are used to ensure that the smallest angle is chosen
*/
- cross_v3_v3v3(raxis, obvec, tarvec);
+ cross_v3_v3v3_hi_prec(raxis, obvec, tarvec);
rangle = dot_v3v3(obvec, tarvec);
rangle = acosf(max_ff(-1.0f, min_ff(1.0f, rangle)));
@@ -3649,7 +3649,35 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
/* construct rotation matrix from the axis-angle rotation found above
* - this call takes care to make sure that the axis provided is a unit vector first
*/
- axis_angle_to_mat3(rmat, raxis, rangle);
+ float norm = normalize_v3(raxis);
+
+ if (norm < FLT_EPSILON) {
+ /* if dot product is nonzero, while cross is zero, we have two opposite vectors!
+ * - this is an ambiguity in the math that needs to be resolved arbitrarily,
+ * or there will be a case where damped track strangely does nothing
+ * - to do that, rotate around a different local axis
+ */
+ float tmpvec[3];
+
+ if (fabsf(rangle) < M_PI - 0.01f) {
+ return;
+ }
+
+ rangle = M_PI;
+ copy_v3_v3(tmpvec, track_dir_vecs[(data->trackflag + 1) % 6]);
+ mul_mat3_m4_v3(cob->matrix, tmpvec);
+ cross_v3_v3v3(raxis, obvec, tmpvec);
+
+ if (normalize_v3(raxis) == 0.0f) {
+ return;
+ }
+ }
+ else if (norm < 0.1f) {
+ /* near 0 and Pi arcsin has way better precision than arccos */
+ rangle = (rangle > M_PI_2) ? M_PI - asinf(norm) : asinf(norm);
+ }
+
+ axis_angle_normalized_to_mat3(rmat, raxis, rangle);
/* rotate the owner in the way defined by this rotation matrix, then reapply the location since
* we may have destroyed that in the process of multiplying the matrix
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index ee907fa496f..3dfe9732062 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -80,7 +80,7 @@ struct bContext {
struct ScrArea *area;
struct ARegion *region;
struct ARegion *menu;
- struct wmManipulatorGroup *manipulator_group;
+ struct wmGizmoGroup *gizmo_group;
struct bContextStore *store;
const char *operator_poll_msg; /* reason for poll failing */
} wm;
@@ -675,9 +675,9 @@ struct ARegion *CTX_wm_menu(const bContext *C)
return C->wm.menu;
}
-struct wmManipulatorGroup *CTX_wm_manipulator_group(const bContext *C)
+struct wmGizmoGroup *CTX_wm_gizmo_group(const bContext *C)
{
- return C->wm.manipulator_group;
+ return C->wm.gizmo_group;
}
struct wmMsgBus *CTX_wm_message_bus(const bContext *C)
@@ -876,9 +876,9 @@ void CTX_wm_menu_set(bContext *C, ARegion *menu)
C->wm.menu = menu;
}
-void CTX_wm_manipulator_group_set(bContext *C, struct wmManipulatorGroup *mgroup)
+void CTX_wm_gizmo_group_set(bContext *C, struct wmGizmoGroup *gzgroup)
{
- C->wm.manipulator_group = mgroup;
+ C->wm.gizmo_group = gzgroup;
}
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
@@ -926,9 +926,17 @@ ViewLayer *CTX_data_view_layer(const bContext *C)
if (ctx_data_pointer_verify(C, "view_layer", (void *)&view_layer)) {
return view_layer;
}
- else {
- return BKE_view_layer_from_workspace_get(CTX_data_scene(C), CTX_wm_workspace(C));
+
+ wmWindow *win = CTX_wm_window(C);
+ Scene *scene = CTX_data_scene(C);
+ if (win) {
+ view_layer = BKE_view_layer_find(scene, win->view_layer_name);
+ if (view_layer) {
+ return view_layer;
+ }
}
+
+ return BKE_view_layer_default_view(scene);
}
RenderEngineType *CTX_data_engine_type(const bContext *C)
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index 87bc819c34f..bf1532bab42 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -30,36 +30,21 @@
*/
-// headers for fluidsim bobj meshes
-#include <stdlib.h>
-#include <zlib.h>
-#include <string.h>
-#include <stdio.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_object_fluidsim_types.h"
-#include "DNA_object_force_types.h" // for pointcache
#include "DNA_object_types.h"
-#include "DNA_particle_types.h"
-#include "DNA_scene_types.h"
#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_fluidsim.h"
-#include "BKE_modifier.h"
-#include "BKE_mesh.h"
+#include "BKE_library.h"
+#include "BKE_mesh_runtime.h"
/* ************************* fluidsim bobj file handling **************************** */
-
//-------------------------------------------------------------------------------
// file handling
//-------------------------------------------------------------------------------
@@ -69,7 +54,7 @@ void initElbeemMesh(struct Depsgraph *depsgraph, struct Scene *scene, struct Obj
int *numTriangles, int **triangles,
int useGlobalCoords, int modifierIndex)
{
- DerivedMesh *dm;
+ Mesh *mesh;
const MVert *mvert;
const MLoop *mloop;
const MLoopTri *looptri, *lt;
@@ -77,13 +62,13 @@ void initElbeemMesh(struct Depsgraph *depsgraph, struct Scene *scene, struct Obj
float *verts;
int *tris;
- dm = mesh_create_derived_index_render(depsgraph, scene, ob, CD_MASK_BAREMESH, modifierIndex);
+ mesh = mesh_create_eval_final_index_render(depsgraph, scene, ob, CD_MASK_BAREMESH, modifierIndex);
- mvert = dm->getVertArray(dm);
- mloop = dm->getLoopArray(dm);
- looptri = dm->getLoopTriArray(dm);
- mvert_num = dm->getNumVerts(dm);
- looptri_num = dm->getNumLoopTri(dm);
+ mvert = mesh->mvert;
+ mloop = mesh->mloop;
+ looptri = BKE_mesh_runtime_looptri_ensure(mesh);
+ mvert_num = mesh->totvert;
+ looptri_num = mesh->runtime.looptris.len;
*numVertices = mvert_num;
verts = MEM_mallocN(mvert_num * sizeof(float[3]), "elbeemmesh_vertices");
@@ -102,5 +87,5 @@ void initElbeemMesh(struct Depsgraph *depsgraph, struct Scene *scene, struct Obj
}
*triangles = tris;
- dm->release(dm);
+ BKE_id_free(NULL, mesh);
}
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index 0edeaab8900..8328d71128a 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -67,7 +67,7 @@ static IDType idtypes[] = {
{ 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 },
- { ID_LA, "Lamp", "lamps", BLT_I18NCONTEXT_ID_LAMP, IDTYPE_FLAGS_ISLINKABLE },
+ { ID_LA, "Light", "lights", BLT_I18NCONTEXT_ID_LAMP, IDTYPE_FLAGS_ISLINKABLE },
{ ID_LI, "Library", "libraries", BLT_I18NCONTEXT_ID_LIBRARY, 0 },
{ ID_LS, "FreestyleLineStyle", "linestyles", BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE, IDTYPE_FLAGS_ISLINKABLE },
{ ID_LT, "Lattice", "lattices", BLT_I18NCONTEXT_ID_LATTICE, IDTYPE_FLAGS_ISLINKABLE },
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index e164e1862d5..8cc40d4e74c 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -913,7 +913,6 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
case IDP_ID:
return (IDP_Id(prop1) == IDP_Id(prop2));
default:
- /* should never get here */
BLI_assert(0);
break;
}
@@ -1015,7 +1014,8 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
prop->data.pointer = MEM_mallocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1");
*IDP_String(prop) = '\0';
prop->totallen = DEFAULT_ALLOC_FOR_NULL_STRINGS;
- prop->len = 1; /*NULL string, has len of 1 to account for null byte.*/
+ /* NULL string, has len of 1 to account for null byte. */
+ prop->len = 1;
}
else {
BLI_assert((int)val->string.len <= (int)strlen(st) + 1);
@@ -1030,8 +1030,8 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
}
case IDP_GROUP:
{
+ /* Values are set properly by calloc. */
prop = MEM_callocN(sizeof(IDProperty), "IDProperty group");
- /* heh I think all needed values are set properly by calloc anyway :) */
break;
}
case IDP_ID:
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index b5abdcae2d4..aedbd0673c2 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -186,76 +186,6 @@ void BKE_images_exit(void)
BLI_spin_end(&image_spin);
}
-/* ******** IMAGE PROCESSING ************* */
-
-static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */
-{
- struct ImBuf *tbuf1, *tbuf2;
-
- if (ibuf == NULL) return;
- if (ibuf->flags & IB_fields) return;
- ibuf->flags |= IB_fields;
-
- if (ibuf->rect) {
- /* make copies */
- tbuf1 = IMB_allocImBuf(ibuf->x, (ibuf->y >> 1), (unsigned char)32, (int)IB_rect);
- tbuf2 = IMB_allocImBuf(ibuf->x, (ibuf->y >> 1), (unsigned char)32, (int)IB_rect);
-
- ibuf->x *= 2;
-
- IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
- IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
-
- ibuf->x /= 2;
- IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y);
- IMB_rectcpy(ibuf, tbuf2, 0, tbuf2->y, 0, 0, tbuf2->x, tbuf2->y);
-
- IMB_freeImBuf(tbuf1);
- IMB_freeImBuf(tbuf2);
- }
- ibuf->y /= 2;
-}
-
-static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */
-{
- struct ImBuf *tbuf1, *tbuf2;
-
- if (ibuf == NULL) return;
- if (ibuf->flags & IB_fields) return;
- ibuf->flags |= IB_fields;
-
- if (ibuf->rect) {
- /* make copies */
- tbuf1 = IMB_allocImBuf(ibuf->x, (ibuf->y >> 1), (unsigned char)32, IB_rect);
- tbuf2 = IMB_allocImBuf(ibuf->x, (ibuf->y >> 1), (unsigned char)32, IB_rect);
-
- ibuf->x *= 2;
-
- IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
- IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
-
- ibuf->x /= 2;
- IMB_rectcpy(ibuf, tbuf2, 0, 0, 0, 0, tbuf2->x, tbuf2->y);
- IMB_rectcpy(ibuf, tbuf1, 0, tbuf2->y, 0, 0, tbuf1->x, tbuf1->y);
-
- IMB_freeImBuf(tbuf1);
- IMB_freeImBuf(tbuf2);
- }
- ibuf->y /= 2;
-}
-
-void BKE_image_de_interlace(Image *ima, int odd)
-{
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- if (ibuf) {
- if (odd)
- de_interlace_st(ibuf);
- else
- de_interlace_ng(ibuf);
- }
- BKE_image_release_ibuf(ima, ibuf, NULL);
-}
-
/* ***************** ALLOC & FREE, DATA MANAGING *************** */
static void image_free_cached_frames(Image *image)
@@ -3129,7 +3059,7 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
#endif /* WITH_OPENEXR */
/* common stuff to do with images after loading */
-static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
+static void image_initialize_after_load(Image *ima, ImBuf *UNUSED(ibuf))
{
/* Preview is NULL when it has never been used as an icon before.
* Never handle previews/icons outside of main thread. */
@@ -3137,11 +3067,6 @@ static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
BKE_icon_changed(BKE_icon_id_ensure(&ima->id));
}
- /* fields */
- if (ima->flag & IMA_FIELDS) {
- if (ima->flag & IMA_STD_FIELD) de_interlace_st(ibuf);
- else de_interlace_ng(ibuf);
- }
/* timer */
BKE_image_tag_time(ima);
@@ -4093,12 +4018,12 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
{
- if (lock) {
+ if (lock != NULL) {
/* for getting image during threaded render / compositing, need to release */
if (lock == ima) {
BLI_thread_unlock(LOCK_VIEWER); /* viewer image */
}
- else if (lock) {
+ else {
RE_ReleaseResultImage(lock); /* render result */
BLI_thread_unlock(LOCK_VIEWER); /* view image imbuf */
}
@@ -4249,7 +4174,7 @@ void BKE_image_pool_release_ibuf(Image *ima, ImBuf *ibuf, ImagePool *pool)
int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, bool *r_is_in_range)
{
- const int len = (iuser->fie_ima * iuser->frames) / 2;
+ const int len = iuser->frames;
if (r_is_in_range) {
*r_is_in_range = false;
@@ -4290,7 +4215,7 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, bool
if (fieldnr) cfra++;
/* transform to images space */
- framenr = (cfra + iuser->fie_ima - 2) / iuser->fie_ima;
+ framenr = cfra;
if (framenr > iuser->frames) framenr = iuser->frames;
if (iuser->cycl) {
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index f8040f0cf24..3be40b414a6 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1717,8 +1717,7 @@ void do_versions_ipos_to_animato(Main *bmain)
/* IPO first to take into any non-NLA'd Object Animation */
if (ob->ipo) {
ipo_to_animdata(bmain, id, ob->ipo, NULL, NULL, NULL);
-
- id_us_min(&ob->ipo->id);
+ /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */
ob->ipo = NULL;
}
@@ -1751,7 +1750,7 @@ void do_versions_ipos_to_animato(Main *bmain)
/* IPO second... */
if (ob->ipo) {
ipo_to_animdata(bmain, id, ob->ipo, NULL, NULL, NULL);
- id_us_min(&ob->ipo->id);
+ /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */
ob->ipo = NULL;
}
}
@@ -1999,7 +1998,7 @@ void do_versions_ipos_to_animato(Main *bmain)
for (id = bmain->lamp.first; id; id = id->next) {
Lamp *la = (Lamp *)id;
- if (G.debug & G_DEBUG) printf("\tconverting lamp %s\n", id->name + 2);
+ if (G.debug & G_DEBUG) printf("\tconverting light %s\n", id->name + 2);
/* we're only interested in the IPO */
if (la->ipo) {
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 1d5b6de22f4..2c1b36d3496 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -84,10 +84,10 @@ void BKE_lamp_init(Lamp *la)
la->cascade_count = 4;
la->cascade_exponent = 0.8f;
la->cascade_fade = 0.1f;
- la->contact_dist = 1.0f;
+ la->contact_dist = 0.2f;
la->contact_bias = 0.03f;
la->contact_spread = 0.2f;
- la->contact_thickness = 0.5f;
+ la->contact_thickness = 0.2f;
la->spec_fac = 1.0f;
curvemapping_initialize(la->curfalloff);
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 22188d25df5..2f5c8e7817e 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -42,7 +42,6 @@
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_workspace.h"
#include "BKE_object.h"
#include "DNA_group_types.h"
@@ -130,17 +129,22 @@ ViewLayer *BKE_view_layer_default_render(const Scene *scene)
return scene->view_layers.first;
}
-/**
- * Returns the ViewLayer to be used for drawing, outliner, and other context related areas.
- */
-ViewLayer *BKE_view_layer_from_workspace_get(const struct Scene *scene, const struct WorkSpace *workspace)
+/* Returns view layer with matching name, or NULL if not found. */
+ViewLayer *BKE_view_layer_find(const Scene *scene, const char *layer_name)
{
- return BKE_workspace_view_layer_get(workspace, scene);
+ for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ if (STREQ(view_layer->name, layer_name)) {
+ return view_layer;
+ }
+ }
+
+ return NULL;
}
/**
- * This is a placeholder to know which areas of the code need to be addressed for the Workspace changes.
- * Never use this, you should either use BKE_view_layer_from_workspace_get or get ViewLayer explicitly.
+ * This is a placeholder to know which areas of the code need to be addressed
+ * for the Workspace changes. Never use this, you should typically get the
+ * active layer from the context or window.
*/
ViewLayer *BKE_view_layer_context_active_PLACEHOLDER(const Scene *scene)
{
@@ -342,7 +346,9 @@ void BKE_view_layer_base_select(struct ViewLayer *view_layer, Base *selbase)
/**************************** Copy View Layer and Layer Collections ***********************/
-static void layer_collections_copy_data(ListBase *layer_collections_dst, const ListBase *layer_collections_src)
+static void layer_collections_copy_data(
+ ViewLayer *view_layer_dst, const ViewLayer *view_layer_src,
+ ListBase *layer_collections_dst, const ListBase *layer_collections_src)
{
BLI_duplicatelist(layer_collections_dst, layer_collections_src);
@@ -351,9 +357,15 @@ static void layer_collections_copy_data(ListBase *layer_collections_dst, const L
while (layer_collection_dst != NULL) {
layer_collections_copy_data(
+ view_layer_dst,
+ view_layer_src,
&layer_collection_dst->layer_collections,
&layer_collection_src->layer_collections);
+ if (layer_collection_src == view_layer_src->active_collection) {
+ view_layer_dst->active_collection = layer_collection_dst;
+ }
+
layer_collection_dst = layer_collection_dst->next;
layer_collection_src = layer_collection_src->next;
}
@@ -365,7 +377,7 @@ static void layer_collections_copy_data(ListBase *layer_collections_dst, const L
* \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
*/
void BKE_view_layer_copy_data(
- Scene *UNUSED(scene_dst), const Scene *UNUSED(scene_src),
+ Scene *scene_dst, const Scene *UNUSED(scene_src),
ViewLayer *view_layer_dst, const ViewLayer *view_layer_src,
const int flag)
{
@@ -392,9 +404,15 @@ void BKE_view_layer_copy_data(
}
}
- layer_collections_copy_data(&view_layer_dst->layer_collections, &view_layer_src->layer_collections);
+ view_layer_dst->active_collection = NULL;
+ layer_collections_copy_data(
+ view_layer_dst,
+ view_layer_src,
+ &view_layer_dst->layer_collections,
+ &view_layer_src->layer_collections);
- // TODO: not always safe to free BKE_layer_collection_sync(scene_dst, view_layer_dst);
+ LayerCollection *lc_scene_dst = view_layer_dst->layer_collections.first;
+ lc_scene_dst->collection = scene_dst->master_collection;
}
void BKE_view_layer_rename(Main *bmain, Scene *scene, ViewLayer *view_layer, const char *newname)
@@ -418,9 +436,15 @@ void BKE_view_layer_rename(Main *bmain, Scene *scene, ViewLayer *view_layer, con
}
}
- /* fix all the animation data and workspace which may link to this */
+ /* fix all the animation data and windows which may link to this */
BKE_animdata_fix_paths_rename_all(NULL, "view_layers", oldname, view_layer->name);
- BKE_workspace_view_layer_rename(bmain, scene, oldname, view_layer->name);
+
+ wmWindowManager *wm = bmain->wm.first;
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ if (win->scene == scene && STREQ(win->view_layer_name, oldname)) {
+ STRNCPY(win->view_layer_name, view_layer->name);
+ }
+ }
/* Dependency graph uses view layer name based lookups. */
DEG_id_tag_update(&scene->id, 0);
@@ -588,6 +612,10 @@ static int layer_collection_sync(
BLI_findptr(lb_scene, lc->collection, offsetof(CollectionChild, collection)) : NULL;
if (!collection) {
+ if (lc == view_layer->active_collection) {
+ view_layer->active_collection = NULL;
+ }
+
/* Free recursively. */
layer_collection_free(view_layer, lc);
BLI_freelinkN(lb_layer, lc);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index c2cdc8df1e6..351214ed72b 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -2464,7 +2464,7 @@ void BKE_library_make_local(
* Try "make all local" in 04_01_H.lighting.blend from Agent327 without this, e.g. */
for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->data != NULL && ob->type == OB_ARMATURE && ob->pose != NULL && ob->pose->flag & POSE_RECALC) {
- BKE_pose_rebuild(ob, ob->data);
+ BKE_pose_rebuild(bmain, ob, ob->data);
}
}
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 54b73dad982..93fdd3349bf 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -936,10 +936,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
/* allow callback to set a different screen */
BKE_workspace_layout_screen_set(layout, screen);
}
-
- for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first; relation; relation = relation->next) {
- CALLBACK_INVOKE(relation->scene, IDWALK_CB_NOP);
- }
break;
}
case ID_GD:
diff --git a/source/blender/blenkernel/intern/lightprobe.c b/source/blender/blenkernel/intern/lightprobe.c
index 057b6aaaf65..baf0cdbe62f 100644
--- a/source/blender/blenkernel/intern/lightprobe.c
+++ b/source/blender/blenkernel/intern/lightprobe.c
@@ -53,7 +53,6 @@ void BKE_lightprobe_init(LightProbe *probe)
probe->vis_bias = 1.0f;
probe->vis_blur = 0.2f;
probe->intensity = 1.0f;
- probe->data_draw_size = 1.0f;
probe->flag = LIGHTPROBE_FLAG_SHOW_INFLUENCE | LIGHTPROBE_FLAG_SHOW_DATA;
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index b13f45499f1..df20d5a2b5d 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -349,8 +349,9 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
/* Mark an arbitrary vertex as root */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- vs = CustomData_bmesh_get(&bm->vdata, v->head.data,
- CD_MVERT_SKIN);
+ vs = CustomData_bmesh_get(
+ &bm->vdata, v->head.data,
+ CD_MVERT_SKIN);
vs->flag |= MVERT_SKIN_ROOT;
break;
}
@@ -358,11 +359,12 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
}
else {
if (!CustomData_has_layer(&me->vdata, CD_MVERT_SKIN)) {
- vs = CustomData_add_layer(&me->vdata,
- CD_MVERT_SKIN,
- CD_DEFAULT,
- NULL,
- me->totvert);
+ vs = CustomData_add_layer(
+ &me->vdata,
+ CD_MVERT_SKIN,
+ CD_DEFAULT,
+ NULL,
+ me->totvert);
/* Mark an arbitrary vertex as root */
if (vs) {
@@ -384,11 +386,12 @@ bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me)
}
else {
if (!CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
- CustomData_add_layer(&me->pdata,
- CD_FACEMAP,
- CD_DEFAULT,
- NULL,
- me->totpoly);
+ CustomData_add_layer(
+ &me->pdata,
+ CD_FACEMAP,
+ CD_DEFAULT,
+ NULL,
+ me->totpoly);
changed = true;
}
}
@@ -1200,9 +1203,10 @@ int poly_get_adj_loops_from_vert(
const MLoop *mloop, unsigned int vert,
unsigned int r_adj[2])
{
- int corner = poly_find_loop_from_vert(poly,
- &mloop[poly->loopstart],
- vert);
+ int corner = poly_find_loop_from_vert(
+ poly,
+ &mloop[poly->loopstart],
+ vert);
if (corner != -1) {
#if 0 /* unused - this loop */
@@ -1310,11 +1314,12 @@ void BKE_mesh_ensure_navmesh(Mesh *me)
void BKE_mesh_tessface_calc(Mesh *mesh)
{
- mesh->totface = BKE_mesh_recalc_tessellation(&mesh->fdata, &mesh->ldata, &mesh->pdata,
- mesh->mvert,
- mesh->totface, mesh->totloop, mesh->totpoly,
- /* calc normals right after, don't copy from polys here */
- false);
+ mesh->totface = BKE_mesh_recalc_tessellation(
+ &mesh->fdata, &mesh->ldata, &mesh->pdata,
+ mesh->mvert,
+ mesh->totface, mesh->totloop, mesh->totpoly,
+ /* calc normals right after, don't copy from polys here */
+ false);
BKE_mesh_update_customdata_pointers(mesh, true);
}
@@ -1511,6 +1516,21 @@ void BKE_mesh_apply_vert_coords(Mesh *mesh, float (*vertCoords)[3])
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
+void BKE_mesh_apply_vert_normals(Mesh *mesh, short (*vertNormals)[3])
+{
+ MVert *vert;
+ int i;
+
+ /* this will just return the pointer if it wasn't a referenced layer */
+ vert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert);
+ mesh->mvert = vert;
+
+ for (i = 0; i < mesh->totvert; ++i, ++vert)
+ copy_v3_v3_short(vert->no, vertNormals[i]);
+
+ mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
+}
+
/**
* Compute 'split' (aka loop, or per face corner's) normals.
*
@@ -1549,8 +1569,8 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spac
else {
polynors = MEM_malloc_arrayN(mesh->totpoly, sizeof(float[3]), __func__);
BKE_mesh_calc_normals_poly(
- mesh->mvert, NULL, mesh->totvert,
- mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, polynors, false);
+ mesh->mvert, NULL, mesh->totvert,
+ mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, polynors, false);
free_polynors = true;
}
@@ -1830,8 +1850,9 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
/* **** Depsgraph evaluation **** */
-void BKE_mesh_eval_geometry(Depsgraph *depsgraph,
- Mesh *mesh)
+void BKE_mesh_eval_geometry(
+ Depsgraph *depsgraph,
+ Mesh *mesh)
{
DEG_debug_print_eval(depsgraph, __func__, mesh->id.name, mesh);
if (mesh->bb == NULL || (mesh->bb->flag & BOUNDBOX_DIRTY)) {
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 3fc5d1ca51c..738f116310b 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -134,9 +134,10 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
/**
* Specialized function to use when we _know_ existing edges don't overlap with poly edges.
*/
-static void make_edges_mdata_extend(MEdge **r_alledge, int *r_totedge,
- const MPoly *mpoly, MLoop *mloop,
- const int totpoly)
+static void make_edges_mdata_extend(
+ MEdge **r_alledge, int *r_totedge,
+ const MPoly *mpoly, MLoop *mloop,
+ const int totpoly)
{
int totedge = *r_totedge;
int totedge_new;
@@ -561,10 +562,11 @@ void BKE_mesh_from_nurbs_displist(
cu = ob->data;
if (dm == NULL) {
- if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert,
- &alledge, &totedge, &allloop,
- &allpoly, (use_orco_uv) ? &alluv : NULL,
- &totloop, &totpoly) != 0)
+ if (BKE_mesh_nurbs_displist_to_mdata(
+ ob, dispbase, &allvert, &totvert,
+ &alledge, &totedge, &allloop,
+ &allpoly, (use_orco_uv) ? &alluv : NULL,
+ &totloop, &totpoly) != 0)
{
/* Error initializing */
return;
@@ -1143,12 +1145,13 @@ Mesh *BKE_mesh_create_derived_for_modifier(
float (*deformedVerts)[3] = BKE_mesh_vertexCos_get(me, &numVerts);
modifier_deformVerts(md, &mectx, NULL, deformedVerts, numVerts);
- BKE_id_copy_ex(NULL, &me->id, (ID **)&result,
- LIB_ID_CREATE_NO_MAIN |
- LIB_ID_CREATE_NO_USER_REFCOUNT |
- LIB_ID_CREATE_NO_DEG_TAG |
- LIB_ID_COPY_NO_PREVIEW,
- false);
+ BKE_id_copy_ex(
+ NULL, &me->id, (ID **)&result,
+ LIB_ID_CREATE_NO_MAIN |
+ LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG |
+ LIB_ID_COPY_NO_PREVIEW,
+ false);
BKE_mesh_apply_vert_coords(result, deformedVerts);
if (build_shapekey_layers)
@@ -1158,12 +1161,13 @@ Mesh *BKE_mesh_create_derived_for_modifier(
}
else {
Mesh *mesh_temp;
- BKE_id_copy_ex(NULL, &me->id, (ID **)&mesh_temp,
- LIB_ID_CREATE_NO_MAIN |
- LIB_ID_CREATE_NO_USER_REFCOUNT |
- LIB_ID_CREATE_NO_DEG_TAG |
- LIB_ID_COPY_NO_PREVIEW,
- false);
+ BKE_id_copy_ex(
+ NULL, &me->id, (ID **)&mesh_temp,
+ LIB_ID_CREATE_NO_MAIN |
+ LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG |
+ LIB_ID_COPY_NO_PREVIEW,
+ false);
if (build_shapekey_layers)
add_shapekey_layers(mesh_temp, me);
@@ -1314,14 +1318,16 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob, CustomD
/* TODO(Sybren): we could probably replace CD_ASSIGN with alloctype and always directly pass mesh_src->mxxx,
* instead of using a ternary operator. */
if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) {
- CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN,
- (alloctype == CD_ASSIGN) ? mesh_src->mvert : MEM_dupallocN(mesh_src->mvert),
- totvert);
+ CustomData_add_layer(
+ &tmp.vdata, CD_MVERT, CD_ASSIGN,
+ (alloctype == CD_ASSIGN) ? mesh_src->mvert : MEM_dupallocN(mesh_src->mvert),
+ totvert);
}
if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
- CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN,
- (alloctype == CD_ASSIGN) ? mesh_src->medge : MEM_dupallocN(mesh_src->medge),
- totedge);
+ CustomData_add_layer(
+ &tmp.edata, CD_MEDGE, CD_ASSIGN,
+ (alloctype == CD_ASSIGN) ? mesh_src->medge : MEM_dupallocN(mesh_src->medge),
+ totedge);
}
if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
/* TODO(Sybren): assigment to tmp.mxxx is probably not necessary due to the
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 3062cd13f5f..66419b03e01 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -96,10 +96,10 @@ void BKE_mesh_calc_normals_mapping_simple(struct Mesh *mesh)
const bool only_face_normals = CustomData_is_referenced_layer(&mesh->vdata, CD_MVERT);
BKE_mesh_calc_normals_mapping_ex(
- mesh->mvert, mesh->totvert,
- mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, NULL,
- mesh->mface, mesh->totface, NULL, NULL,
- only_face_normals);
+ mesh->mvert, mesh->totvert,
+ mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, NULL,
+ mesh->mface, mesh->totface, NULL, NULL,
+ only_face_normals);
}
/* Calculate vertex and face normals, face normals are returned in *r_faceNors if non-NULL
@@ -360,9 +360,10 @@ void BKE_mesh_calc_normals(Mesh *mesh)
#ifdef DEBUG_TIME
TIMEIT_START_AVERAGED(BKE_mesh_calc_normals);
#endif
- BKE_mesh_calc_normals_poly(mesh->mvert, NULL, mesh->totvert,
- mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
- NULL, false);
+ BKE_mesh_calc_normals_poly(
+ mesh->mvert, NULL, mesh->totvert,
+ mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
+ NULL, false);
#ifdef DEBUG_TIME
TIMEIT_END_AVERAGED(BKE_mesh_calc_normals);
#endif
@@ -516,8 +517,9 @@ MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr)
* Beware, this modifies ref_vec and other_vec in place!
* In case no valid space can be generated, ref_alpha and ref_beta are set to zero (which means 'use auto lnors').
*/
-void BKE_lnor_space_define(MLoopNorSpace *lnor_space, const float lnor[3],
- float vec_ref[3], float vec_other[3], BLI_Stack *edge_vectors)
+void BKE_lnor_space_define(
+ MLoopNorSpace *lnor_space, const float lnor[3],
+ float vec_ref[3], float vec_other[3], BLI_Stack *edge_vectors)
{
const float pi2 = (float)M_PI * 2.0f;
float tvec[3], dtp;
@@ -799,8 +801,9 @@ static void mesh_edges_sharp_tag(
e2l[1] = (mp->flag & ME_SMOOTH) ? INDEX_UNSET : INDEX_INVALID;
}
else if (e2l[1] == INDEX_UNSET) {
- const bool is_angle_sharp = (check_angle &&
- dot_v3v3(polynors[loop_to_poly[e2l[0]]], polynors[mp_index]) < split_angle_cos);
+ const bool is_angle_sharp = (
+ check_angle &&
+ dot_v3v3(polynors[loop_to_poly[e2l[0]]], polynors[mp_index]) < split_angle_cos);
/* Second loop using this edge, time to test its sharpness.
* An edge is sharp if it is tagged as such, or its face is not smooth,
@@ -1133,8 +1136,8 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli
/* Find next loop of the smooth fan. */
BKE_mesh_loop_manifold_fan_around_vert_next(
- mloops, mpolys, loop_to_poly, e2lfan_curr, mv_pivot_index,
- &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index);
+ mloops, mpolys, loop_to_poly, e2lfan_curr, mv_pivot_index,
+ &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index);
e2lfan_curr = edge_to_loops[mlfan_curr->e];
}
@@ -1270,8 +1273,8 @@ static bool loop_split_generator_check_cyclic_smooth_fan(
while (true) {
/* Find next loop of the smooth fan. */
BKE_mesh_loop_manifold_fan_around_vert_next(
- mloops, mpolys, loop_to_poly, e2lfan_curr, mv_pivot_index,
- &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index);
+ mloops, mpolys, loop_to_poly, e2lfan_curr, mv_pivot_index,
+ &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index);
e2lfan_curr = edge_to_loops[mlfan_curr->e];
@@ -1620,9 +1623,10 @@ static void mesh_normals_loop_custom_set(
BLI_SMALLSTACK_DECLARE(clnors_data, short *);
/* Compute current lnor spacearr. */
- BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops, lnors, numLoops,
- mpolys, polynors, numPolys, use_split_normals, split_angle,
- &lnors_spacearr, NULL, loop_to_poly);
+ BKE_mesh_normals_loop_split(
+ mverts, numVerts, medges, numEdges, mloops, lnors, numLoops,
+ mpolys, polynors, numPolys, use_split_normals, split_angle,
+ &lnors_spacearr, NULL, loop_to_poly);
/* Set all given zero vectors to their default value. */
if (use_vertices) {
@@ -1730,9 +1734,10 @@ static void mesh_normals_loop_custom_set(
/* And now, recompute our new auto lnors and lnor spacearr! */
BKE_lnor_spacearr_clear(&lnors_spacearr);
- BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops, lnors, numLoops,
- mpolys, polynors, numPolys, use_split_normals, split_angle,
- &lnors_spacearr, NULL, loop_to_poly);
+ BKE_mesh_normals_loop_split(
+ mverts, numVerts, medges, numEdges, mloops, lnors, numLoops,
+ mpolys, polynors, numPolys, use_split_normals, split_angle,
+ &lnors_spacearr, NULL, loop_to_poly);
}
else {
BLI_BITMAP_SET_ALL(done_loops, true, (size_t)numLoops);
@@ -1804,8 +1809,9 @@ void BKE_mesh_normals_loop_custom_set(
MPoly *mpolys, const float (*polynors)[3], const int numPolys,
short (*r_clnors_data)[2])
{
- mesh_normals_loop_custom_set(mverts, numVerts, medges, numEdges, mloops, r_custom_loopnors, numLoops,
- mpolys, polynors, numPolys, r_clnors_data, false);
+ mesh_normals_loop_custom_set(
+ mverts, numVerts, medges, numEdges, mloops, r_custom_loopnors, numLoops,
+ mpolys, polynors, numPolys, r_clnors_data, false);
}
void BKE_mesh_normals_loop_custom_from_vertices_set(
@@ -1814,8 +1820,9 @@ void BKE_mesh_normals_loop_custom_from_vertices_set(
MPoly *mpolys, const float (*polynors)[3], const int numPolys,
short (*r_clnors_data)[2])
{
- mesh_normals_loop_custom_set(mverts, numVerts, medges, numEdges, mloops, r_custom_vertnors, numLoops,
- mpolys, polynors, numPolys, r_clnors_data, true);
+ mesh_normals_loop_custom_set(
+ mverts, numVerts, medges, numEdges, mloops, r_custom_vertnors, numLoops,
+ mpolys, polynors, numPolys, r_clnors_data, true);
}
/**
@@ -1899,19 +1906,19 @@ void BKE_mesh_calc_poly_normal(
mesh_calc_ngon_normal(mpoly, loopstart, mvarray, r_no);
}
else if (mpoly->totloop == 3) {
- normal_tri_v3(r_no,
- mvarray[loopstart[0].v].co,
- mvarray[loopstart[1].v].co,
- mvarray[loopstart[2].v].co
- );
+ normal_tri_v3(
+ r_no,
+ mvarray[loopstart[0].v].co,
+ mvarray[loopstart[1].v].co,
+ mvarray[loopstart[2].v].co);
}
else if (mpoly->totloop == 4) {
- normal_quad_v3(r_no,
- mvarray[loopstart[0].v].co,
- mvarray[loopstart[1].v].co,
- mvarray[loopstart[2].v].co,
- mvarray[loopstart[3].v].co
- );
+ normal_quad_v3(
+ r_no,
+ mvarray[loopstart[0].v].co,
+ mvarray[loopstart[1].v].co,
+ mvarray[loopstart[2].v].co,
+ mvarray[loopstart[3].v].co);
}
else { /* horrible, two sided face! */
r_no[0] = 0.0;
@@ -1951,19 +1958,19 @@ void BKE_mesh_calc_poly_normal_coords(
mesh_calc_ngon_normal_coords(mpoly, loopstart, vertex_coords, r_no);
}
else if (mpoly->totloop == 3) {
- normal_tri_v3(r_no,
- vertex_coords[loopstart[0].v],
- vertex_coords[loopstart[1].v],
- vertex_coords[loopstart[2].v]
- );
+ normal_tri_v3(
+ r_no,
+ vertex_coords[loopstart[0].v],
+ vertex_coords[loopstart[1].v],
+ vertex_coords[loopstart[2].v]);
}
else if (mpoly->totloop == 4) {
- normal_quad_v3(r_no,
- vertex_coords[loopstart[0].v],
- vertex_coords[loopstart[1].v],
- vertex_coords[loopstart[2].v],
- vertex_coords[loopstart[3].v]
- );
+ normal_quad_v3(
+ r_no,
+ vertex_coords[loopstart[0].v],
+ vertex_coords[loopstart[1].v],
+ vertex_coords[loopstart[2].v],
+ vertex_coords[loopstart[3].v]);
}
else { /* horrible, two sided face! */
r_no[0] = 0.0;
@@ -1991,19 +1998,19 @@ void BKE_mesh_calc_poly_center(
const MVert *mvarray, float r_cent[3])
{
if (mpoly->totloop == 3) {
- mid_v3_v3v3v3(r_cent,
- mvarray[loopstart[0].v].co,
- mvarray[loopstart[1].v].co,
- mvarray[loopstart[2].v].co
- );
+ mid_v3_v3v3v3(
+ r_cent,
+ mvarray[loopstart[0].v].co,
+ mvarray[loopstart[1].v].co,
+ mvarray[loopstart[2].v].co);
}
else if (mpoly->totloop == 4) {
- mid_v3_v3v3v3v3(r_cent,
- mvarray[loopstart[0].v].co,
- mvarray[loopstart[1].v].co,
- mvarray[loopstart[2].v].co,
- mvarray[loopstart[3].v].co
- );
+ mid_v3_v3v3v3v3(
+ r_cent,
+ mvarray[loopstart[0].v].co,
+ mvarray[loopstart[1].v].co,
+ mvarray[loopstart[2].v].co,
+ mvarray[loopstart[3].v].co);
}
else {
mesh_calc_ngon_center(mpoly, loopstart, mvarray, r_cent);
@@ -2016,10 +2023,10 @@ float BKE_mesh_calc_poly_area(
const MVert *mvarray)
{
if (mpoly->totloop == 3) {
- return area_tri_v3(mvarray[loopstart[0].v].co,
- mvarray[loopstart[1].v].co,
- mvarray[loopstart[2].v].co
- );
+ return area_tri_v3(
+ mvarray[loopstart[0].v].co,
+ mvarray[loopstart[1].v].co,
+ mvarray[loopstart[2].v].co);
}
else {
int i;
@@ -2130,8 +2137,9 @@ static float mesh_calc_poly_area_centroid(
}
#if 0 /* slow version of the function below */
-void BKE_mesh_calc_poly_angles(MPoly *mpoly, MLoop *loopstart,
- MVert *mvarray, float angles[])
+void BKE_mesh_calc_poly_angles(
+ MPoly *mpoly, MLoop *loopstart,
+ MVert *mvarray, float angles[])
{
MLoop *ml;
MLoop *mloop = &loopstart[-mpoly->loopstart];
@@ -2499,8 +2507,9 @@ void BKE_mesh_loops_to_mface_corners(
*
* \note when mface is not NULL, mface[face_index].v4 is used to test quads, else, loopindices[face_index][3] is used.
*/
-void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, MFace *mface,
- int *polyindices, unsigned int (*loopindices)[4], const int num_faces)
+void BKE_mesh_loops_to_tessdata(
+ CustomData *fdata, CustomData *ldata, MFace *mface,
+ int *polyindices, unsigned int (*loopindices)[4], const int num_faces)
{
/* Note: performances are sub-optimal when we get a NULL mface, we could be ~25% quicker with dedicated code...
* Issue is, unless having two different functions with nearly the same code, there's not much ways to solve
@@ -3036,130 +3045,6 @@ void BKE_mesh_recalc_looptri(
#undef ML_TO_MLT
}
-/* -------------------------------------------------------------------- */
-
-
-#ifdef USE_BMESH_SAVE_AS_COMPAT
-
-/**
- * This function recreates a tessellation.
- * returns number of tessellation faces.
- *
- * for forwards compat only quad->tri polys to mface, skip ngons.
- */
-int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
- struct CustomData *pdata, int totface, int UNUSED(totloop), int totpoly)
-{
- MLoop *mloop;
-
- unsigned int lindex[4];
- int i;
- int k;
-
- MPoly *mp, *mpoly;
- MFace *mface, *mf;
-
- const int numUV = CustomData_number_of_layers(ldata, CD_MLOOPUV);
- const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
- const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
- const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
- const bool hasLNor = CustomData_has_layer(ldata, CD_NORMAL);
-
- /* over-alloc, ngons will be skipped */
- mface = MEM_malloc_arrayN((size_t)totpoly, sizeof(*mface), __func__);
-
- mpoly = CustomData_get_layer(pdata, CD_MPOLY);
- mloop = CustomData_get_layer(ldata, CD_MLOOP);
-
- mp = mpoly;
- k = 0;
- for (i = 0; i < totpoly; i++, mp++) {
- if (ELEM(mp->totloop, 3, 4)) {
- const unsigned int mp_loopstart = (unsigned int)mp->loopstart;
- mf = &mface[k];
-
- mf->mat_nr = mp->mat_nr;
- mf->flag = mp->flag;
-
- mf->v1 = mp_loopstart + 0;
- mf->v2 = mp_loopstart + 1;
- mf->v3 = mp_loopstart + 2;
- mf->v4 = (mp->totloop == 4) ? (mp_loopstart + 3) : 0;
-
- /* abuse edcode for temp storage and clear next loop */
- mf->edcode = (char)mp->totloop; /* only ever 3 or 4 */
-
- k++;
- }
- }
-
- CustomData_free(fdata, totface);
-
- totface = k;
-
- CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface);
-
- CustomData_from_bmeshpoly(fdata, ldata, totface);
-
- mp = mpoly;
- k = 0;
- for (i = 0; i < totpoly; i++, mp++) {
- if (ELEM(mp->totloop, 3, 4)) {
- mf = &mface[k];
-
- if (mf->edcode == 3) {
- /* sort loop indices to ensure winding is correct */
- /* NO SORT - looks like we can skip this */
-
- lindex[0] = mf->v1;
- lindex[1] = mf->v2;
- lindex[2] = mf->v3;
- lindex[3] = 0; /* unused */
-
- /* transform loop indices to vert indices */
- mf->v1 = mloop[mf->v1].v;
- mf->v2 = mloop[mf->v2].v;
- mf->v3 = mloop[mf->v3].v;
-
- BKE_mesh_loops_to_mface_corners(
- fdata, ldata, pdata,
- lindex, k, i, 3,
- numUV, numCol, hasPCol, hasOrigSpace, hasLNor);
- test_index_face(mf, fdata, k, 3);
- }
- else {
- /* sort loop indices to ensure winding is correct */
- /* NO SORT - looks like we can skip this */
-
- lindex[0] = mf->v1;
- lindex[1] = mf->v2;
- lindex[2] = mf->v3;
- lindex[3] = mf->v4;
-
- /* transform loop indices to vert indices */
- mf->v1 = mloop[mf->v1].v;
- mf->v2 = mloop[mf->v2].v;
- mf->v3 = mloop[mf->v3].v;
- mf->v4 = mloop[mf->v4].v;
-
- BKE_mesh_loops_to_mface_corners(
- fdata, ldata, pdata,
- lindex, k, i, 4,
- numUV, numCol, hasPCol, hasOrigSpace, hasLNor);
- test_index_face(mf, fdata, k, 4);
- }
-
- mf->edcode = 0;
-
- k++;
- }
- }
-
- return k;
-}
-#endif /* USE_BMESH_SAVE_AS_COMPAT */
-
-
static void bm_corners_to_loops_ex(
ID *id, CustomData *fdata, CustomData *ldata,
MFace *mface, int totloop, int findex, int loopstart, int numTex, int numCol)
@@ -3217,8 +3102,9 @@ static void bm_corners_to_loops_ex(
if (CustomData_external_test(fdata, CD_MDISPS)) {
if (id && fdata->external) {
- CustomData_external_add(ldata, id, CD_MDISPS,
- totloop, fdata->external->filename);
+ CustomData_external_add(
+ ldata, id, CD_MDISPS,
+ totloop, fdata->external->filename);
}
}
@@ -3256,10 +3142,11 @@ static void bm_corners_to_loops_ex(
void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh)
{
- BKE_mesh_convert_mfaces_to_mpolys_ex(&mesh->id, &mesh->fdata, &mesh->ldata, &mesh->pdata,
- mesh->totedge, mesh->totface, mesh->totloop, mesh->totpoly,
- mesh->medge, mesh->mface,
- &mesh->totloop, &mesh->totpoly, &mesh->mloop, &mesh->mpoly);
+ BKE_mesh_convert_mfaces_to_mpolys_ex(
+ &mesh->id, &mesh->fdata, &mesh->ldata, &mesh->pdata,
+ mesh->totedge, mesh->totface, mesh->totloop, mesh->totpoly,
+ mesh->medge, mesh->mface,
+ &mesh->totloop, &mesh->totpoly, &mesh->mloop, &mesh->mpoly);
BKE_mesh_update_customdata_pointers(mesh, true);
}
@@ -3276,21 +3163,23 @@ void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh)
*/
void BKE_mesh_do_versions_convert_mfaces_to_mpolys(Mesh *mesh)
{
- BKE_mesh_convert_mfaces_to_mpolys_ex(&mesh->id, &mesh->fdata, &mesh->ldata, &mesh->pdata,
- mesh->totedge, mesh->totface, mesh->totloop, mesh->totpoly,
- mesh->medge, mesh->mface,
- &mesh->totloop, &mesh->totpoly, &mesh->mloop, &mesh->mpoly);
+ BKE_mesh_convert_mfaces_to_mpolys_ex(
+ &mesh->id, &mesh->fdata, &mesh->ldata, &mesh->pdata,
+ mesh->totedge, mesh->totface, mesh->totloop, mesh->totpoly,
+ mesh->medge, mesh->mface,
+ &mesh->totloop, &mesh->totpoly, &mesh->mloop, &mesh->mpoly);
CustomData_bmesh_do_versions_update_active_layers(&mesh->fdata, &mesh->ldata);
BKE_mesh_update_customdata_pointers(mesh, true);
}
-void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData *ldata, CustomData *pdata,
- int totedge_i, int totface_i, int totloop_i, int totpoly_i,
- MEdge *medge, MFace *mface,
- int *r_totloop, int *r_totpoly,
- MLoop **r_mloop, MPoly **r_mpoly)
+void BKE_mesh_convert_mfaces_to_mpolys_ex(
+ ID *id, CustomData *fdata, CustomData *ldata, CustomData *pdata,
+ int totedge_i, int totface_i, int totloop_i, int totpoly_i,
+ MEdge *medge, MFace *mface,
+ int *r_totloop, int *r_totpoly,
+ MLoop **r_mloop, MPoly **r_mpoly)
{
MFace *mf;
MLoop *ml, *mloop;
@@ -3514,10 +3403,11 @@ void BKE_mesh_polygons_flip(
/* update the hide flag for edges and faces from the corresponding
* flag in verts */
-void BKE_mesh_flush_hidden_from_verts_ex(const MVert *mvert,
- const MLoop *mloop,
- MEdge *medge, const int totedge,
- MPoly *mpoly, const int totpoly)
+void BKE_mesh_flush_hidden_from_verts_ex(
+ const MVert *mvert,
+ const MLoop *mloop,
+ MEdge *medge, const int totedge,
+ MPoly *mpoly, const int totpoly)
{
int i, j;
@@ -3543,15 +3433,17 @@ void BKE_mesh_flush_hidden_from_verts_ex(const MVert *mvert,
}
void BKE_mesh_flush_hidden_from_verts(Mesh *me)
{
- BKE_mesh_flush_hidden_from_verts_ex(me->mvert, me->mloop,
- me->medge, me->totedge,
- me->mpoly, me->totpoly);
+ BKE_mesh_flush_hidden_from_verts_ex(
+ me->mvert, me->mloop,
+ me->medge, me->totedge,
+ me->mpoly, me->totpoly);
}
-void BKE_mesh_flush_hidden_from_polys_ex(MVert *mvert,
- const MLoop *mloop,
- MEdge *medge, const int UNUSED(totedge),
- const MPoly *mpoly, const int totpoly)
+void BKE_mesh_flush_hidden_from_polys_ex(
+ MVert *mvert,
+ const MLoop *mloop,
+ MEdge *medge, const int UNUSED(totedge),
+ const MPoly *mpoly, const int totpoly)
{
const MPoly *mp;
int i;
@@ -3584,18 +3476,20 @@ void BKE_mesh_flush_hidden_from_polys_ex(MVert *mvert,
}
void BKE_mesh_flush_hidden_from_polys(Mesh *me)
{
- BKE_mesh_flush_hidden_from_polys_ex(me->mvert, me->mloop,
- me->medge, me->totedge,
- me->mpoly, me->totpoly);
+ BKE_mesh_flush_hidden_from_polys_ex(
+ me->mvert, me->mloop,
+ me->medge, me->totedge,
+ me->mpoly, me->totpoly);
}
/**
* simple poly -> vert/edge selection.
*/
-void BKE_mesh_flush_select_from_polys_ex(MVert *mvert, const int totvert,
- const MLoop *mloop,
- MEdge *medge, const int totedge,
- const MPoly *mpoly, const int totpoly)
+void BKE_mesh_flush_select_from_polys_ex(
+ MVert *mvert, const int totvert,
+ const MLoop *mloop,
+ MEdge *medge, const int totedge,
+ const MPoly *mpoly, const int totpoly)
{
MVert *mv;
MEdge *med;
@@ -3629,16 +3523,18 @@ void BKE_mesh_flush_select_from_polys_ex(MVert *mvert, const int totvert,
}
void BKE_mesh_flush_select_from_polys(Mesh *me)
{
- BKE_mesh_flush_select_from_polys_ex(me->mvert, me->totvert,
- me->mloop,
- me->medge, me->totedge,
- me->mpoly, me->totpoly);
+ BKE_mesh_flush_select_from_polys_ex(
+ me->mvert, me->totvert,
+ me->mloop,
+ me->medge, me->totedge,
+ me->mpoly, me->totpoly);
}
-void BKE_mesh_flush_select_from_verts_ex(const MVert *mvert, const int UNUSED(totvert),
- const MLoop *mloop,
- MEdge *medge, const int totedge,
- MPoly *mpoly, const int totpoly)
+void BKE_mesh_flush_select_from_verts_ex(
+ const MVert *mvert, const int UNUSED(totvert),
+ const MLoop *mloop,
+ MEdge *medge, const int totedge,
+ MPoly *mpoly, const int totpoly)
{
MEdge *med;
MPoly *mp;
@@ -3683,10 +3579,11 @@ void BKE_mesh_flush_select_from_verts_ex(const MVert *mvert, const int UNUSED(to
}
void BKE_mesh_flush_select_from_verts(Mesh *me)
{
- BKE_mesh_flush_select_from_verts_ex(me->mvert, me->totvert,
- me->mloop,
- me->medge, me->totedge,
- me->mpoly, me->totpoly);
+ BKE_mesh_flush_select_from_verts_ex(
+ me->mvert, me->totvert,
+ me->mloop,
+ me->medge, me->totedge,
+ me->mpoly, me->totpoly);
}
/** \} */
@@ -3714,7 +3611,7 @@ void BKE_mesh_calc_relative_deform(
const float (*vert_cos_dst)[3],
const float (*vert_cos_org)[3],
- float (*vert_cos_new)[3])
+ float (*vert_cos_new)[3])
{
const MPoly *mp;
int i;
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 0143125490e..5c9849f6b74 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -55,13 +55,13 @@
* but for now this replaces it because its unused. */
UvVertMap *BKE_mesh_uv_vert_map_create(
- struct MPoly *mpoly, struct MLoop *mloop, struct MLoopUV *mloopuv,
+ const MPoly *mpoly, const MLoop *mloop, const MLoopUV *mloopuv,
unsigned int totpoly, unsigned int totvert,
const float limit[2], const bool selected, const bool use_winding)
{
UvVertMap *vmap;
UvMapVert *buf;
- MPoly *mp;
+ const MPoly *mp;
unsigned int a;
int i, totuv, nverts;
@@ -103,8 +103,8 @@ UvVertMap *BKE_mesh_uv_vert_map_create(
nverts = mp->totloop;
for (i = 0; i < nverts; i++) {
- buf->tfindex = (unsigned char)i;
- buf->f = a;
+ buf->loop_of_poly_index = (unsigned short)i;
+ buf->poly_index = a;
buf->separate = 0;
buf->next = vmap->vert[mloop[mp->loopstart + i].v];
vmap->vert[mloop[mp->loopstart + i].v] = buf;
@@ -126,7 +126,8 @@ UvVertMap *BKE_mesh_uv_vert_map_create(
for (a = 0; a < totvert; a++) {
UvMapVert *newvlist = NULL, *vlist = vmap->vert[a];
UvMapVert *iterv, *v, *lastv, *next;
- float *uv, *uv2, uvdiff[2];
+ const float *uv, *uv2;
+ float uvdiff[2];
while (vlist) {
v = vlist;
@@ -134,19 +135,19 @@ UvVertMap *BKE_mesh_uv_vert_map_create(
v->next = newvlist;
newvlist = v;
- uv = mloopuv[mpoly[v->f].loopstart + v->tfindex].uv;
+ uv = mloopuv[mpoly[v->poly_index].loopstart + v->loop_of_poly_index].uv;
lastv = NULL;
iterv = vlist;
while (iterv) {
next = iterv->next;
- uv2 = mloopuv[mpoly[iterv->f].loopstart + iterv->tfindex].uv;
+ uv2 = mloopuv[mpoly[iterv->poly_index].loopstart + iterv->loop_of_poly_index].uv;
sub_v2_v2v2(uvdiff, uv2, uv);
if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1] &&
- (!use_winding || winding[iterv->f] == winding[v->f]))
+ (!use_winding || winding[iterv->poly_index] == winding[v->poly_index]))
{
if (lastv) lastv->next = next;
else vlist = next;
@@ -243,9 +244,10 @@ static void mesh_vert_poly_or_loop_map_create(
* Generates a map where the key is the vertex and the value is a list of polys that use that vertex as a corner.
* The lists are allocated from one memory pool.
*/
-void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem,
- const MPoly *mpoly, const MLoop *mloop,
- int totvert, int totpoly, int totloop)
+void BKE_mesh_vert_poly_map_create(
+ MeshElemMap **r_map, int **r_mem,
+ const MPoly *mpoly, const MLoop *mloop,
+ int totvert, int totpoly, int totloop)
{
mesh_vert_poly_or_loop_map_create(r_map, r_mem, mpoly, mloop, totvert, totpoly, totloop, false);
}
@@ -254,9 +256,10 @@ void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem,
* Generates a map where the key is the vertex and the value is a list of loops that use that vertex as a corner.
* The lists are allocated from one memory pool.
*/
-void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map, int **r_mem,
- const MPoly *mpoly, const MLoop *mloop,
- int totvert, int totpoly, int totloop)
+void BKE_mesh_vert_loop_map_create(
+ MeshElemMap **r_map, int **r_mem,
+ const MPoly *mpoly, const MLoop *mloop,
+ int totvert, int totpoly, int totloop)
{
mesh_vert_poly_or_loop_map_create(r_map, r_mem, mpoly, mloop, totvert, totpoly, totloop, true);
}
@@ -310,8 +313,9 @@ void BKE_mesh_vert_looptri_map_create(
* Generates a map where the key is the vertex and the value is a list of edges that use that vertex as an endpoint.
* The lists are allocated from one memory pool.
*/
-void BKE_mesh_vert_edge_map_create(MeshElemMap **r_map, int **r_mem,
- const MEdge *medge, int totvert, int totedge)
+void BKE_mesh_vert_edge_map_create(
+ MeshElemMap **r_map, int **r_mem,
+ const MEdge *medge, int totvert, int totedge)
{
MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totvert, "vert-edge map");
int *indices = MEM_mallocN(sizeof(int[2]) * (size_t)totedge, "vert-edge map mem");
@@ -397,10 +401,11 @@ void BKE_mesh_vert_edge_vert_map_create(
* Loops indices of a same poly are contiguous and in winding order.
* The lists are allocated from one memory pool.
*/
-void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map, int **r_mem,
- const MEdge *UNUSED(medge), const int totedge,
- const MPoly *mpoly, const int totpoly,
- const MLoop *mloop, const int totloop)
+void BKE_mesh_edge_loop_map_create(
+ MeshElemMap **r_map, int **r_mem,
+ const MEdge *UNUSED(medge), const int totedge,
+ const MPoly *mpoly, const int totpoly,
+ const MLoop *mloop, const int totloop)
{
MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totedge, "edge-poly map");
int *indices = MEM_mallocN(sizeof(int) * (size_t)totloop * 2, "edge-poly map mem");
@@ -450,10 +455,11 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map, int **r_mem,
* Generates a map where the key is the edge and the value is a list of polygons that use that edge.
* The lists are allocated from one memory pool.
*/
-void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map, int **r_mem,
- const MEdge *UNUSED(medge), const int totedge,
- const MPoly *mpoly, const int totpoly,
- const MLoop *mloop, const int totloop)
+void BKE_mesh_edge_poly_map_create(
+ MeshElemMap **r_map, int **r_mem,
+ const MEdge *UNUSED(medge), const int totedge,
+ const MPoly *mpoly, const int totpoly,
+ const MLoop *mloop, const int totloop)
{
MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totedge, "edge-poly map");
int *indices = MEM_mallocN(sizeof(int) * (size_t)totloop, "edge-poly map mem");
@@ -509,9 +515,10 @@ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map, int **r_mem,
* ``totfinal`` could be ``tottessface`` and ``final_origindex`` its ORIGINDEX customdata.
* This would allow an MPoly to loop over its tessfaces.
*/
-void BKE_mesh_origindex_map_create(MeshElemMap **r_map, int **r_mem,
- const int totsource,
- const int *final_origindex, const int totfinal)
+void BKE_mesh_origindex_map_create(
+ MeshElemMap **r_map, int **r_mem,
+ const int totsource,
+ const int *final_origindex, const int totfinal)
{
MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totsource, "poly-tessface map");
int *indices = MEM_mallocN(sizeof(int) * (size_t)totfinal, "poly-tessface map mem");
@@ -632,8 +639,9 @@ static void poly_edge_loop_islands_calc(
}
if (!edge_poly_map) {
- BKE_mesh_edge_poly_map_create(&edge_poly_map, &edge_poly_mem,
- medge, totedge, mpoly, totpoly, mloop, totloop);
+ BKE_mesh_edge_poly_map_create(
+ &edge_poly_map, &edge_poly_mem,
+ medge, totedge, mpoly, totpoly, mloop, totloop);
}
poly_groups = MEM_callocN(sizeof(int) * (size_t)totpoly, __func__);
@@ -786,10 +794,11 @@ static bool poly_is_island_boundary_smooth_cb(
* (0 being used as 'invalid' flag).
* Note it's callers's responsibility to MEM_freeN returned array.
*/
-int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
- const MPoly *mpoly, const int totpoly,
- const MLoop *mloop, const int totloop,
- int *r_totgroup, const bool use_bitflags)
+int *BKE_mesh_calc_smoothgroups(
+ const MEdge *medge, const int totedge,
+ const MPoly *mpoly, const int totpoly,
+ const MLoop *mloop, const int totloop,
+ int *r_totgroup, const bool use_bitflags)
{
int *poly_groups = NULL;
@@ -987,21 +996,23 @@ static bool mesh_calc_islands_loop_poly_uv(
BKE_mesh_loop_islands_clear(r_island_store);
BKE_mesh_loop_islands_init(r_island_store, MISLAND_TYPE_LOOP, totloop, MISLAND_TYPE_POLY, MISLAND_TYPE_EDGE);
- BKE_mesh_edge_poly_map_create(&edge_poly_map, &edge_poly_mem,
- edges, totedge, polys, totpoly, loops, totloop);
+ BKE_mesh_edge_poly_map_create(
+ &edge_poly_map, &edge_poly_mem,
+ edges, totedge, polys, totpoly, loops, totloop);
if (luvs) {
- BKE_mesh_edge_loop_map_create(&edge_loop_map, &edge_loop_mem,
- edges, totedge, polys, totpoly, loops, totloop);
+ BKE_mesh_edge_loop_map_create(
+ &edge_loop_map, &edge_loop_mem,
+ edges, totedge, polys, totpoly, loops, totloop);
edge_boundary_check_data.loops = loops;
edge_boundary_check_data.luvs = luvs;
edge_boundary_check_data.edge_loop_map = edge_loop_map;
}
poly_edge_loop_islands_calc(
- edges, totedge, polys, totpoly, loops, totloop, edge_poly_map, false,
- mesh_check_island_boundary_uv, luvs ? &edge_boundary_check_data : NULL,
- &poly_groups, &num_poly_groups, &edge_borders, &num_edge_borders);
+ edges, totedge, polys, totpoly, loops, totloop, edge_poly_map, false,
+ mesh_check_island_boundary_uv, luvs ? &edge_boundary_check_data : NULL,
+ &poly_groups, &num_poly_groups, &edge_borders, &num_edge_borders);
if (!num_poly_groups) {
/* Should never happen... */
@@ -1051,8 +1062,9 @@ static bool mesh_calc_islands_loop_poly_uv(
}
}
- BKE_mesh_loop_islands_add(r_island_store, num_lidx, loop_indices, num_pidx, poly_indices,
- num_einnercuts, edge_innercut_indices);
+ BKE_mesh_loop_islands_add(
+ r_island_store, num_lidx, loop_indices, num_pidx, poly_indices,
+ num_einnercuts, edge_innercut_indices);
}
MEM_freeN(edge_poly_map);
@@ -1089,7 +1101,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(
MeshIslandStore *r_island_store)
{
return mesh_calc_islands_loop_poly_uv(
- verts, totvert, edges, totedge, polys, totpoly, loops, totloop, NULL, r_island_store);
+ verts, totvert, edges, totedge, polys, totpoly, loops, totloop, NULL, r_island_store);
}
/**
@@ -1113,7 +1125,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(
{
BLI_assert(luvs != NULL);
return mesh_calc_islands_loop_poly_uv(
- verts, totvert, edges, totedge, polys, totpoly, loops, totloop, luvs, r_island_store);
+ verts, totvert, edges, totedge, polys, totpoly, loops, totloop, luvs, r_island_store);
}
/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c
index 27ba7e76fa3..d49ca507e02 100644
--- a/source/blender/blenkernel/intern/mesh_merge.c
+++ b/source/blender/blenkernel/intern/mesh_merge.c
@@ -383,9 +383,10 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, const int *vtargetmap, const int tot_vtar
/* Can we optimise by reusing an old pmap ? How do we know an old pmap is stale ? */
/* When called by MOD_array.c, the cddm has just been created, so it has no valid pmap. */
- BKE_mesh_vert_poly_map_create(&poly_map, &poly_map_mem,
- mesh->mpoly, mesh->mloop,
- totvert, totpoly, totloop);
+ BKE_mesh_vert_poly_map_create(
+ &poly_map, &poly_map_mem,
+ mesh->mpoly, mesh->mloop,
+ totvert, totpoly, totloop);
} /* done preparing for fast poly compare */
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index c882cc0a7fa..bf98b8040e3 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -666,8 +666,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(
v_dst_to_src_map[i].hit_dist = -1.0f;
}
- BKE_mesh_vert_edge_map_create(&vert_to_edge_src_map, &vert_to_edge_src_map_mem,
- edges_src, num_verts_src, num_edges_src);
+ BKE_mesh_vert_edge_map_create(
+ &vert_to_edge_src_map, &vert_to_edge_src_map_mem,
+ edges_src, num_verts_src, num_edges_src);
BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_VERTS, 2);
nearest.index = -1;
@@ -926,8 +927,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(
indices[sources_num] = j;
sources_num++;
}
- mesh_remap_item_define(r_map, i, hit_dist_accum / totweights, 0,
- sources_num, indices, weights);
+ mesh_remap_item_define(
+ r_map, i, hit_dist_accum / totweights, 0,
+ sources_num, indices, weights);
}
else {
/* No source for this dest edge! */
@@ -1141,8 +1143,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(
BLI_AStarGraph *as_graphdata = NULL;
BLI_AStarSolution as_solution = {0};
- const int isld_steps_src = islands_precision_src ?
- max_ii((int)(ASTAR_STEPS_MAX * islands_precision_src + 0.499f), 1) : 0;
+ const int isld_steps_src = (
+ islands_precision_src ?
+ max_ii((int)(ASTAR_STEPS_MAX * islands_precision_src + 0.499f), 1) : 0);
float (*poly_nors_src)[3] = NULL;
float (*loop_nors_src)[3] = NULL;
@@ -1210,8 +1213,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(
CustomData_set_layer_flag(pdata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
}
if (dirty_nors_dst || do_poly_nors_dst) {
- BKE_mesh_calc_normals_poly(verts_dst, NULL, numverts_dst, loops_dst, polys_dst,
- numloops_dst, numpolys_dst, poly_nors_dst, true);
+ BKE_mesh_calc_normals_poly(
+ verts_dst, NULL, numverts_dst, loops_dst, polys_dst,
+ numloops_dst, numpolys_dst, poly_nors_dst, true);
}
}
if (need_lnors_dst) {
@@ -1225,10 +1229,11 @@ void BKE_mesh_remap_calc_loops_from_mesh(
CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
}
if (dirty_nors_dst || do_loop_nors_dst) {
- BKE_mesh_normals_loop_split(verts_dst, numverts_dst, edges_dst, numedges_dst,
- loops_dst, loop_nors_dst, numloops_dst,
- polys_dst, (const float (*)[3])poly_nors_dst, numpolys_dst,
- use_split_nors_dst, split_angle_dst, NULL, custom_nors_dst, NULL);
+ BKE_mesh_normals_loop_split(
+ verts_dst, numverts_dst, edges_dst, numedges_dst,
+ loops_dst, loop_nors_dst, numloops_dst,
+ polys_dst, (const float (*)[3])poly_nors_dst, numpolys_dst,
+ use_split_nors_dst, split_angle_dst, NULL, custom_nors_dst, NULL);
}
}
if (need_pnors_src || need_lnors_src) {
@@ -1249,17 +1254,20 @@ void BKE_mesh_remap_calc_loops_from_mesh(
}
if (use_from_vert) {
- BKE_mesh_vert_loop_map_create(&vert_to_loop_map_src, &vert_to_loop_map_src_buff,
- polys_src, loops_src, num_verts_src, num_polys_src, num_loops_src);
+ BKE_mesh_vert_loop_map_create(
+ &vert_to_loop_map_src, &vert_to_loop_map_src_buff,
+ polys_src, loops_src, num_verts_src, num_polys_src, num_loops_src);
if (mode & MREMAP_USE_POLY) {
- BKE_mesh_vert_poly_map_create(&vert_to_poly_map_src, &vert_to_poly_map_src_buff,
- polys_src, loops_src, num_verts_src, num_polys_src, num_loops_src);
+ BKE_mesh_vert_poly_map_create(
+ &vert_to_poly_map_src, &vert_to_poly_map_src_buff,
+ polys_src, loops_src, num_verts_src, num_polys_src, num_loops_src);
}
}
/* Needed for islands (or plain mesh) to AStar graph conversion. */
- BKE_mesh_edge_poly_map_create(&edge_to_poly_map_src, &edge_to_poly_map_src_buff,
- edges_src, num_edges_src, polys_src, num_polys_src, loops_src, num_loops_src);
+ BKE_mesh_edge_poly_map_create(
+ &edge_to_poly_map_src, &edge_to_poly_map_src_buff,
+ edges_src, num_edges_src, polys_src, num_polys_src, loops_src, num_loops_src);
if (use_from_vert) {
loop_to_poly_map_src = MEM_mallocN(sizeof(*loop_to_poly_map_src) * (size_t)num_loops_src, __func__);
poly_cents_src = MEM_mallocN(sizeof(*poly_cents_src) * (size_t)num_polys_src, __func__);
@@ -1339,8 +1347,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(
}
}
}
- bvhtree_from_mesh_verts_ex(&treedata[tindex], verts_src, num_verts_src, false,
- verts_active, num_verts_active, 0.0, 2, 6);
+ bvhtree_from_mesh_verts_ex(
+ &treedata[tindex], verts_src, num_verts_src, false,
+ verts_active, num_verts_active, 0.0, 2, 6);
}
MEM_freeN(verts_active);
@@ -1456,13 +1465,15 @@ void BKE_mesh_remap_calc_loops_from_mesh(
BLI_assert(index_src != -1);
const float dot = dot_v3v3(nors_src[index_src], *nor_dst);
- pidx_src = (mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) ?
- loop_to_poly_map_src[index_src] : index_src;
+ pidx_src = (
+ (mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) ?
+ loop_to_poly_map_src[index_src] : index_src);
/* WARNING! This is not the *real* lidx_src in case of POLYNOR, we only use it
* to check we stay on current island (all loops from a given poly are
* on same island!). */
- lidx_src = (mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) ?
- index_src : polys_src[pidx_src].loopstart;
+ lidx_src = (
+ (mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) ?
+ index_src : polys_src[pidx_src].loopstart);
/* A same vert may be at the boundary of several islands! Hence, we have to ensure
* poly/loop we are currently considering *belongs* to current island! */
@@ -1481,7 +1492,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(
if (!pcent_dst_valid) {
BKE_mesh_calc_poly_center(
- mp_dst, &loops_dst[mp_dst->loopstart], verts_dst, pcent_dst);
+ mp_dst, &loops_dst[mp_dst->loopstart], verts_dst, pcent_dst);
pcent_dst_valid = true;
}
pcent_src = poly_cents_src[pidx_src];
@@ -1712,8 +1723,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(
BLI_space_transform_apply(space_transform, tmp_co);
}
- pidx_src = use_islands ? best_island->indices[last_valid_pidx_isld_src] :
- last_valid_pidx_isld_src;
+ pidx_src = (
+ use_islands ? best_island->indices[last_valid_pidx_isld_src] :
+ last_valid_pidx_isld_src);
mp_src = &polys_src[pidx_src];
ml_src = &loops_src[mp_src->loopstart];
for (j = 0; j < mp_src->totloop; j++, ml_src++) {
@@ -1797,8 +1809,9 @@ void BKE_mesh_remap_calc_loops_from_mesh(
BLI_space_transform_apply(space_transform, tmp_co);
}
- pidx_src = use_islands ? best_island->indices[last_valid_pidx_isld_src] :
- last_valid_pidx_isld_src;
+ pidx_src = (
+ use_islands ? best_island->indices[last_valid_pidx_isld_src] :
+ last_valid_pidx_isld_src);
mp_src = &polys_src[pidx_src];
/* Create that one on demand. */
@@ -1947,8 +1960,9 @@ void BKE_mesh_remap_calc_polys_from_mesh(
CustomData_set_layer_flag(pdata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
}
if (dirty_nors_dst) {
- BKE_mesh_calc_normals_poly(verts_dst, NULL, numverts_dst, loops_dst, polys_dst, numloops_dst, numpolys_dst,
- poly_nors_dst, true);
+ BKE_mesh_calc_normals_poly(
+ verts_dst, NULL, numverts_dst, loops_dst, polys_dst, numloops_dst, numpolys_dst,
+ poly_nors_dst, true);
}
}
@@ -2131,8 +2145,9 @@ void BKE_mesh_remap_calc_polys_from_mesh(
tri_vidx_2d[1][2] = 3;
}
else {
- BLI_polyfill_calc(poly_vcos_2d, (unsigned int)mp->totloop, -1,
- (unsigned int (*)[3])tri_vidx_2d);
+ BLI_polyfill_calc(
+ poly_vcos_2d, (unsigned int)mp->totloop, -1,
+ (unsigned int (*)[3])tri_vidx_2d);
}
for (j = 0; j < tris_num; j++) {
diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c
index 07c354559b8..a3fc422ade7 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.c
+++ b/source/blender/blenkernel/intern/mesh_runtime.c
@@ -246,9 +246,10 @@ static void mesh_runtime_debug_info_layers(
const char *structname;
int structnum;
CustomData_file_write_info(type, &structname, &structnum);
- BLI_dynstr_appendf(dynstr,
- " dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
- name, structname, type, (const void *)pt, size, pt_size);
+ BLI_dynstr_appendf(
+ dynstr,
+ " dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
+ name, structname, type, (const void *)pt, size, pt_size);
}
}
}
@@ -346,21 +347,21 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
}
is_valid &= BKE_mesh_validate_all_customdata(
- &me_eval->vdata, &me_eval->edata, &me_eval->ldata, &me_eval->pdata,
- false, /* setting mask here isn't useful, gives false positives */
- do_verbose, do_fixes,
- &changed);
+ &me_eval->vdata, &me_eval->edata, &me_eval->ldata, &me_eval->pdata,
+ false, /* setting mask here isn't useful, gives false positives */
+ do_verbose, do_fixes,
+ &changed);
is_valid &= BKE_mesh_validate_arrays(
- me_eval,
- me_eval->mvert, me_eval->totvert,
- me_eval->medge, me_eval->totedge,
- me_eval->mface, me_eval->totface,
- me_eval->mloop, me_eval->totloop,
- me_eval->mpoly, me_eval->totpoly,
- me_eval->dvert,
- do_verbose, do_fixes,
- &changed);
+ me_eval,
+ me_eval->mvert, me_eval->totvert,
+ me_eval->medge, me_eval->totedge,
+ me_eval->mface, me_eval->totface,
+ me_eval->mloop, me_eval->totloop,
+ me_eval->mpoly, me_eval->totpoly,
+ me_eval->dvert,
+ do_verbose, do_fixes,
+ &changed);
BLI_assert(changed == false);
diff --git a/source/blender/blenkernel/intern/mesh_tangent.c b/source/blender/blenkernel/intern/mesh_tangent.c
index 05a5a5e8703..9d6d0b90959 100644
--- a/source/blender/blenkernel/intern/mesh_tangent.c
+++ b/source/blender/blenkernel/intern/mesh_tangent.c
@@ -91,8 +91,9 @@ static void get_position(const SMikkTSpaceContext *pContext, float r_co[3], cons
copy_v3_v3(r_co, p_mesh->mverts[p_mesh->mloops[loop_idx].v].co);
}
-static void get_texture_coordinate(const SMikkTSpaceContext *pContext, float r_uv[2], const int face_idx,
- const int vert_idx)
+static void get_texture_coordinate(
+ const SMikkTSpaceContext *pContext, float r_uv[2], const int face_idx,
+ const int vert_idx)
{
BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
copy_v2_v2(r_uv, p_mesh->luvs[p_mesh->mpolys[face_idx].loopstart + vert_idx].uv);
@@ -104,8 +105,9 @@ static void get_normal(const SMikkTSpaceContext *pContext, float r_no[3], const
copy_v3_v3(r_no, p_mesh->lnors[p_mesh->mpolys[face_idx].loopstart + vert_idx]);
}
-static void set_tspace(const SMikkTSpaceContext *pContext, const float fv_tangent[3], const float face_sign,
- const int face_idx, const int vert_idx)
+static void set_tspace(
+ const SMikkTSpaceContext *pContext, const float fv_tangent[3], const float face_sign,
+ const int face_idx, const int vert_idx)
{
BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
float *p_res = p_mesh->tangents[p_mesh->mpolys[face_idx].loopstart + vert_idx];
@@ -192,8 +194,9 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, const char *uvmap, float (*r_
return;
}
- BKE_mesh_calc_loop_tangent_single_ex(mesh->mvert, mesh->totvert, mesh->mloop, r_looptangents,
- loopnors, loopuvs, mesh->totloop, mesh->mpoly, mesh->totpoly, reports);
+ BKE_mesh_calc_loop_tangent_single_ex(
+ mesh->mvert, mesh->totvert, mesh->mloop, r_looptangents,
+ loopnors, loopuvs, mesh->totloop, mesh->mpoly, mesh->totpoly, reports);
}
/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 0dca41e60e6..f974362e4be 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -212,15 +212,16 @@ static int search_polyloop_cmp(const void *v1, const void *v2)
*
* \return false if no changes needed to be made.
*/
-bool BKE_mesh_validate_arrays(Mesh *mesh,
- MVert *mverts, unsigned int totvert,
- MEdge *medges, unsigned int totedge,
- MFace *mfaces, unsigned int totface,
- MLoop *mloops, unsigned int totloop,
- MPoly *mpolys, unsigned int totpoly,
- MDeformVert *dverts, /* assume totvert length */
- const bool do_verbose, const bool do_fixes,
- bool *r_changed)
+bool BKE_mesh_validate_arrays(
+ Mesh *mesh,
+ MVert *mverts, unsigned int totvert,
+ MEdge *medges, unsigned int totedge,
+ MFace *mfaces, unsigned int totface,
+ MLoop *mloops, unsigned int totloop,
+ MPoly *mpolys, unsigned int totpoly,
+ MDeformVert *dverts, /* assume totvert length */
+ const bool do_verbose, const bool do_fixes,
+ bool *r_changed)
{
# define REMOVE_EDGE_TAG(_me) { _me->v2 = _me->v1; free_flag.edges = do_fixes; } (void)0
# define IS_REMOVED_EDGE(_me) (_me->v2 == _me->v1)
@@ -875,9 +876,10 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
return is_valid;
}
-static bool mesh_validate_customdata(CustomData *data, CustomDataMask mask,
- const bool do_verbose, const bool do_fixes,
- bool *r_change)
+static bool mesh_validate_customdata(
+ CustomData *data, CustomDataMask mask,
+ const bool do_verbose, const bool do_fixes,
+ bool *r_change)
{
bool is_valid = true;
bool has_fixes = false;
@@ -928,11 +930,12 @@ static bool mesh_validate_customdata(CustomData *data, CustomDataMask mask,
/**
* \returns is_valid.
*/
-bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata,
- CustomData *ldata, CustomData *pdata,
- const bool check_meshmask,
- const bool do_verbose, const bool do_fixes,
- bool *r_change)
+bool BKE_mesh_validate_all_customdata(
+ CustomData *vdata, CustomData *edata,
+ CustomData *ldata, CustomData *pdata,
+ const bool check_meshmask,
+ const bool do_verbose, const bool do_fixes,
+ bool *r_change)
{
bool is_valid = true;
bool is_change_v, is_change_e, is_change_l, is_change_p;
@@ -1229,9 +1232,10 @@ struct EdgeSort {
};
/* edges have to be added with lowest index first for sorting */
-static void to_edgesort(struct EdgeSort *ed,
- unsigned int v1, unsigned int v2,
- char is_loose, short is_draw)
+static void to_edgesort(
+ struct EdgeSort *ed,
+ unsigned int v1, unsigned int v2,
+ char is_loose, short is_draw)
{
if (v1 < v2) {
ed->v1 = v1; ed->v2 = v2;
@@ -1380,9 +1384,10 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
MEdge *medge;
int totedge = 0;
- mesh_calc_edges_mdata(me->mvert, me->mface, me->mloop, me->mpoly,
- me->totvert, me->totface, me->totloop, me->totpoly,
- use_old, &medge, &totedge);
+ mesh_calc_edges_mdata(
+ me->mvert, me->mface, me->mloop, me->mpoly,
+ me->totvert, me->totface, me->totloop, me->totpoly,
+ use_old, &medge, &totedge);
if (totedge == 0) {
/* flag that mesh has edges */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 4c2a58e7126..b877a08b6cf 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -293,7 +293,7 @@ void modifiers_foreachTexLink(Object *ob, TexWalkFunc walk, void *userData)
/* callback's can use this
* to avoid copying every member.
*/
-void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst)
+void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst, const int UNUSED(flag))
{
const ModifierTypeInfo *mti = modifierType_getInfo(md_src->type);
@@ -326,7 +326,7 @@ void modifier_copyData_ex(ModifierData *md, ModifierData *target, const int flag
target->flag = md->flag;
if (mti->copyData) {
- mti->copyData(md, target);
+ mti->copyData(md, target, flag);
}
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index f7cd2bd52dc..c81f5f425d8 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3333,11 +3333,6 @@ void node_type_internal_links(bNodeType *ntype, void (*update_internal_links)(bN
ntype->update_internal_links = update_internal_links;
}
-void node_type_compatibility(struct bNodeType *ntype, short compatibility)
-{
- ntype->compatibility = compatibility;
-}
-
/* callbacks for undefined types */
static bool node_undefined_poll(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(nodetree))
@@ -3437,6 +3432,7 @@ static void registerCompositNodes(void)
register_node_type_cmp_doubleedgemask();
register_node_type_cmp_keyingscreen();
register_node_type_cmp_keying();
+ register_node_type_cmp_cryptomatte();
register_node_type_cmp_translate();
register_node_type_cmp_rotate();
@@ -3525,6 +3521,7 @@ static void registerShaderNodes(void)
register_node_type_sh_bsdf_velvet();
register_node_type_sh_bsdf_toon();
register_node_type_sh_bsdf_hair();
+ register_node_type_sh_bsdf_hair_principled();
register_node_type_sh_emission();
register_node_type_sh_holdout();
register_node_type_sh_volume_absorption();
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 8295fccc810..33ea13c9a38 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -165,10 +165,7 @@ void BKE_object_free_particlesystems(Object *ob)
void BKE_object_free_softbody(Object *ob)
{
- if (ob->soft) {
- sbFree(ob->soft);
- ob->soft = NULL;
- }
+ sbFree(ob);
}
void BKE_object_free_curve_cache(Object *ob)
@@ -275,7 +272,7 @@ void BKE_object_link_modifiers(Scene *scene, struct Object *ob_dst, const struct
switch (md->type) {
case eModifierType_Softbody:
- BKE_object_copy_softbody(ob_dst, ob_src);
+ BKE_object_copy_softbody(ob_dst, ob_src, 0);
break;
case eModifierType_Skin:
/* ensure skin-node customdata exists */
@@ -427,6 +424,8 @@ void BKE_object_free(Object *ob)
{
BKE_animdata_free((ID *)ob, false);
+ DRW_drawdata_free((ID *)ob);
+
/* BKE_<id>_free shall never touch to ID->us. Never ever. */
BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
@@ -452,17 +451,7 @@ void BKE_object_free(Object *ob)
BKE_rigidbody_free_object(ob, NULL);
BKE_rigidbody_free_constraint(ob);
- if (ob->soft) {
- sbFree(ob->soft);
- ob->soft = NULL;
- }
-
- for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
- if (oed->free != NULL) {
- oed->free(oed);
- }
- }
- BLI_freelistN(&ob->drawdata);
+ sbFree(ob);
BKE_sculptsession_free(ob);
@@ -659,7 +648,7 @@ static const char *get_obdata_defname(int type)
case OB_FONT: return DATA_("Text");
case OB_MBALL: return DATA_("Mball");
case OB_CAMERA: return DATA_("Camera");
- case OB_LAMP: return DATA_("Lamp");
+ case OB_LAMP: return DATA_("Light");
case OB_LATTICE: return DATA_("Lattice");
case OB_ARMATURE: return DATA_("Armature");
case OB_SPEAKER: return DATA_("Speaker");
@@ -725,6 +714,9 @@ void BKE_object_init(Object *ob)
ob->dt = OB_TEXTURE;
ob->empty_drawtype = OB_PLAINAXES;
ob->empty_drawsize = 1.0;
+ if (ob->type == OB_EMPTY) {
+ copy_v2_fl(ob->ima_ofs, -0.5f);
+ }
if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) {
ob->trackflag = OB_NEGZ;
@@ -836,11 +828,17 @@ Object *BKE_object_add_from(
return ob;
}
-SoftBody *copy_softbody(const SoftBody *sb, const int flag)
+void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src, const int flag)
{
+ SoftBody *sb = ob_src->soft;
SoftBody *sbn;
+ bool tagged_no_main = ob_dst->id.tag & LIB_TAG_NO_MAIN;
- if (sb == NULL) return(NULL);
+ ob_dst->softflag = ob_src->softflag;
+ if (sb == NULL) {
+ ob_dst->soft = NULL;
+ return;
+ }
sbn = MEM_dupallocN(sb);
@@ -873,12 +871,15 @@ SoftBody *copy_softbody(const SoftBody *sb, const int flag)
sbn->scratch = NULL;
- sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, flag);
+ if (tagged_no_main == 0) {
+ sbn->shared = MEM_dupallocN(sb->shared);
+ sbn->shared->pointcache = BKE_ptcache_copy_list(&sbn->shared->ptcaches, &sb->shared->ptcaches, flag);
+ }
if (sb->effector_weights)
sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
- return sbn;
+ ob_dst->soft = sbn;
}
ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int flag)
@@ -967,14 +968,6 @@ void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src, const
}
}
-void BKE_object_copy_softbody(Object *ob_dst, const Object *ob_src)
-{
- if (ob_src->soft) {
- ob_dst->softflag = ob_src->softflag;
- ob_dst->soft = copy_softbody(ob_src->soft, 0);
- }
-}
-
static void copy_object_pose(Object *obn, const Object *ob, const int flag)
{
bPoseChannel *chan;
@@ -1157,7 +1150,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
*
* \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
*/
-void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_src, const int flag)
+void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag)
{
ModifierData *md;
@@ -1187,7 +1180,7 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
copy_object_pose(ob_dst, ob_src, flag_subdata);
/* backwards compat... non-armatures can get poses in older files? */
if (ob_src->type == OB_ARMATURE)
- BKE_pose_rebuild(ob_dst, ob_dst->data);
+ BKE_pose_rebuild(bmain, ob_dst, ob_dst->data);
}
defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase);
BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
@@ -1202,7 +1195,7 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
ob_dst->pd->rng = MEM_dupallocN(ob_src->pd->rng);
}
}
- ob_dst->soft = copy_softbody(ob_src->soft, flag_subdata);
+ BKE_object_copy_softbody(ob_dst, ob_src, flag_subdata);
ob_dst->rigidbody_object = BKE_rigidbody_copy_object(ob_src, flag_subdata);
ob_dst->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob_src, flag_subdata);
@@ -1212,7 +1205,7 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
ob_dst->derivedFinal = NULL;
BLI_listbase_clear(&ob_dst->gpulamp);
- BLI_listbase_clear(&ob_dst->drawdata);
+ BLI_listbase_clear((ListBase *)&ob_dst->drawdata);
BLI_listbase_clear(&ob_dst->pc_ids);
ob_dst->avs = ob_src->avs;
@@ -1366,7 +1359,7 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
/* local_object->proxy == pointer to library object, saved in files and read */
/* local_object->proxy_group == pointer to collection dupli-object, saved in files and read */
-void BKE_object_make_proxy(Object *ob, Object *target, Object *cob)
+void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob)
{
/* paranoia checks */
if (ID_IS_LINKED(ob) || !ID_IS_LINKED(target)) {
@@ -1441,7 +1434,7 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *cob)
if (target->type == OB_ARMATURE) {
copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */
BKE_pose_rest(ob->pose); /* clear all transforms in channels */
- BKE_pose_rebuild(ob, ob->data); /* set all internal links */
+ BKE_pose_rebuild(bmain, ob, ob->data); /* set all internal links */
armature_set_id_extern(ob);
}
@@ -2487,7 +2480,6 @@ void BKE_object_empty_draw_type_set(Object *ob, const int value)
ob->iuser->flag |= IMA_ANIM_ALWAYS;
ob->iuser->frames = 100;
ob->iuser->sfra = 1;
- ob->iuser->fie_ima = 2;
}
}
else {
@@ -2706,8 +2698,10 @@ void BKE_object_handle_update_ex(Depsgraph *depsgraph,
* with poses we do it ahead of BKE_object_where_is_calc to ensure animation
* is evaluated on the rebuilt pose, otherwise we get incorrect poses
* on file load */
- if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC))
- BKE_pose_rebuild(ob, ob->data);
+ if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
+ /* No need to pass bmain here, we assume we do not need to rebuild DEG from here... */
+ BKE_pose_rebuild(NULL, ob, ob->data);
+ }
}
}
/* XXX new animsys warning: depsgraph tag OB_RECALC_DATA should not skip drivers,
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 7f3f916964a..ab0130019b8 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -36,6 +36,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "BLI_math.h"
@@ -835,6 +836,35 @@ struct Ocean *BKE_ocean_add(void)
return oc;
}
+bool BKE_ocean_ensure(struct OceanModifierData *omd)
+{
+ if (omd->ocean) {
+ return false;
+ }
+
+ omd->ocean = BKE_ocean_add();
+ BKE_ocean_init_from_modifier(omd->ocean, omd);
+ return true;
+}
+
+void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd)
+{
+ short do_heightfield, do_chop, do_normals, do_jacobian;
+
+ do_heightfield = true;
+ do_chop = (omd->chop_amount > 0);
+ do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
+ do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
+
+ BKE_ocean_free_data(ocean);
+ BKE_ocean_init(ocean, omd->resolution * omd->resolution, omd->resolution * omd->resolution,
+ omd->spatial_size, omd->spatial_size,
+ omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment,
+ omd->depth, omd->time,
+ do_heightfield, do_chop, do_normals, do_jacobian,
+ omd->seed);
+}
+
void BKE_ocean_init(struct Ocean *o, int M, int N, float Lx, float Lz, float V, float l, float A, float w, float damp,
float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals,
short do_jacobian, int seed)
@@ -1511,4 +1541,16 @@ void BKE_ocean_bake(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och),
/* unused */
(void)update_cb;
}
+
+void BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean), struct OceanModifierData const *UNUSED(omd))
+{
+}
+
#endif /* WITH_OCEANSIM */
+
+void BKE_ocean_free_modifier_cache(struct OceanModifierData *omd)
+{
+ BKE_ocean_free_cache(omd->oceancache);
+ omd->oceancache = NULL;
+ omd->cached = false;
+}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 404a1a656d9..07aa21f44ff 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -68,6 +68,7 @@
#include "BKE_subsurf.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "bmesh.h"
@@ -857,21 +858,12 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
}
/**
- * \param need_mask So taht the evaluated mesh that is returned has mask data.
+ * \param need_mask So that the evaluated mesh that is returned has mask data.
*/
void BKE_sculpt_update_mesh_elements(
Depsgraph *depsgraph, Scene *scene, Sculpt *sd, Object *ob,
bool need_pmap, bool need_mask)
{
- if (depsgraph == NULL) {
- /* Happens on file load.
- *
- * We do nothing in this case, it will be taken care about on depsgraph
- * evaluation.
- */
- return;
- }
-
SculptSession *ss = ob->sculpt;
Mesh *me = BKE_object_get_original_mesh(ob);
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
@@ -947,13 +939,14 @@ void BKE_sculpt_update_mesh_elements(
if (ss->modifiers_active) {
if (!ss->orig_cos) {
+ Object *object_orig = DEG_get_original_object(ob);
int a;
BKE_sculptsession_free_deformMats(ss);
ss->orig_cos = (ss->kb) ? BKE_keyblock_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
- BKE_crazyspace_build_sculpt(depsgraph, scene, ob, &ss->deform_imats, &ss->deform_cos);
+ BKE_crazyspace_build_sculpt(depsgraph, scene, object_orig, &ss->deform_imats, &ss->deform_cos);
BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos, me->totvert);
for (a = 0; a < me->totvert; ++a) {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 0a4cd3ec3c1..3e7a9b7ce24 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -2077,7 +2077,7 @@ static void pbvh_node_check_mask_changed(PBVH *bvh, PBVHNode *node)
struct PBVHNodeDrawCallbackData {
- void (*draw_fn)(void *user_data, Gwn_Batch *batch);
+ void (*draw_fn)(void *user_data, GPUBatch *batch);
void *user_data;
bool fast;
};
@@ -2087,7 +2087,7 @@ static void pbvh_node_draw_cb(PBVHNode *node, void *data_v)
struct PBVHNodeDrawCallbackData *data = data_v;
if (!(node->flag & PBVH_FullyHidden)) {
- Gwn_Batch *triangles = GPU_pbvh_buffers_batch_get(node->draw_buffers, data->fast);
+ GPUBatch *triangles = GPU_pbvh_buffers_batch_get(node->draw_buffers, data->fast);
if (triangles != NULL) {
data->draw_fn(data->user_data, triangles);
}
@@ -2099,7 +2099,7 @@ static void pbvh_node_draw_cb(PBVHNode *node, void *data_v)
*/
void BKE_pbvh_draw_cb(
PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast,
- void (*draw_fn)(void *user_data, Gwn_Batch *batch), void *user_data)
+ void (*draw_fn)(void *user_data, GPUBatch *batch), void *user_data)
{
struct PBVHNodeDrawCallbackData draw_data = {
.fast = fast,
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index a8c6091124a..17e90d688a2 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1389,9 +1389,9 @@ void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
pid->ob= ob;
pid->calldata= sb;
pid->type= PTCACHE_TYPE_SOFTBODY;
- pid->cache= sb->pointcache;
- pid->cache_ptr= &sb->pointcache;
- pid->ptcaches= &sb->ptcaches;
+ pid->cache= sb->shared->pointcache;
+ pid->cache_ptr= &sb->shared->pointcache;
+ pid->ptcaches= &sb->shared->ptcaches;
pid->totpoint= pid->totwrite= ptcache_softbody_totpoint;
pid->error = ptcache_softbody_error;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index a38384f8f2b..3650fa21c1c 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -103,6 +103,8 @@
#include "RE_engine.h"
+#include "engines/eevee/eevee_lightcache.h"
+
#include "PIL_time.h"
#include "IMB_colormanagement.h"
@@ -111,7 +113,7 @@
#include "bmesh.h"
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
-const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH";
+const char *RE_engine_id_BLENDER_OPENGL = "BLENDER_OPENGL";
const char *RE_engine_id_CYCLES = "CYCLES";
void free_avicodecdata(AviCodecData *acd)
@@ -316,6 +318,9 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
else {
sce_dst->preview = NULL;
}
+
+ sce_dst->eevee.light_cache = NULL;
+ /* TODO Copy the cache. */
}
Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
@@ -356,6 +361,9 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
curvemapping_copy_data(&sce_copy->r.mblur_shutter_curve, &sce->r.mblur_shutter_curve);
+ /* viewport display settings */
+ sce_copy->display = sce->display;
+
/* tool settings */
sce_copy->toolsettings = BKE_toolsettings_copy(sce->toolsettings, 0);
@@ -511,6 +519,11 @@ void BKE_scene_free_ex(Scene *sce, const bool do_id_user)
sce->master_collection = NULL;
}
+ if (sce->eevee.light_cache) {
+ EEVEE_lightcache_free(sce->eevee.light_cache);
+ sce->eevee.light_cache = NULL;
+ }
+
/* These are freed on doversion. */
BLI_assert(sce->layer_properties == NULL);
}
@@ -635,7 +648,7 @@ void BKE_scene_init(Scene *sce)
sce->toolsettings->uvcalc_flag = UVCALC_TRANSFORM_CORRECT;
sce->toolsettings->unwrapper = 1;
sce->toolsettings->select_thresh = 0.01f;
- sce->toolsettings->manipulator_flag = SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE | SCE_MANIP_SCALE;
+ sce->toolsettings->gizmo_flag = SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE | SCE_MANIP_SCALE;
sce->toolsettings->selectmode = SCE_SELECT_VERTEX;
sce->toolsettings->uv_selectmode = UV_SELECT_VERTEX;
@@ -810,10 +823,15 @@ void BKE_scene_init(Scene *sce)
sce->display.matcap_ssao_attenuation = 1.0f;
sce->display.matcap_ssao_samples = 16;
+ /* OpenGL Render. */
+ BKE_screen_view3d_shading_init(&sce->display.shading);
+
/* SceneEEVEE */
sce->eevee.gi_diffuse_bounces = 3;
sce->eevee.gi_cubemap_resolution = 512;
sce->eevee.gi_visibility_resolution = 32;
+ sce->eevee.gi_cubemap_draw_size = 0.3f;
+ sce->eevee.gi_irradiance_draw_size = 0.1f;
sce->eevee.taa_samples = 16;
sce->eevee.taa_render_samples = 64;
@@ -856,6 +874,8 @@ void BKE_scene_init(Scene *sce)
sce->eevee.shadow_cube_size = 512;
sce->eevee.shadow_cascade_size = 1024;
+ sce->eevee.light_cache = NULL;
+
sce->eevee.flag =
SCE_EEVEE_VOLUMETRIC_LIGHTS |
SCE_EEVEE_VOLUMETRIC_COLORED |
@@ -906,7 +926,7 @@ Object *BKE_scene_object_find_by_name(Scene *scene, const char *name)
/**
* Sets the active scene, mainly used when running in background mode (``--scene`` command line argument).
* This is also called to set the scene directly, bypassing windowing code.
- * Otherwise #WM_window_change_active_scene is used when changing scenes by the user.
+ * Otherwise #WM_window_set_active_scene is used when changing scenes by the user.
*/
void BKE_scene_set_background(Main *bmain, Scene *scene)
{
@@ -1268,7 +1288,7 @@ static void scene_armature_depsgraph_workaround(Main *bmain, Depsgraph *depsgrap
for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->type == OB_ARMATURE && ob->adt && ob->adt->recalc & ADT_RECALC_ANIM) {
if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
- BKE_pose_rebuild(ob, ob->data);
+ BKE_pose_rebuild(bmain, ob, ob->data);
}
}
}
@@ -1293,7 +1313,7 @@ static bool check_rendered_viewport_visible(Main *bmain)
if (area->spacetype != SPACE_VIEW3D) {
continue;
}
- if (v3d->drawtype == OB_RENDER) {
+ if (v3d->shading.type == OB_RENDER) {
return true;
}
}
@@ -1527,6 +1547,11 @@ bool BKE_scene_uses_blender_eevee(const Scene *scene)
return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE);
}
+bool BKE_scene_uses_blender_opengl(const Scene *scene)
+{
+ return STREQ(scene->r.engine, RE_engine_id_BLENDER_OPENGL);
+}
+
bool BKE_scene_uses_cycles(const Scene *scene)
{
return STREQ(scene->r.engine, RE_engine_id_CYCLES);
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 1c8a93981c7..f8d926a13ed 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -45,9 +45,10 @@
#include "DNA_view3d_types.h"
#include "DNA_workspace_types.h"
+#include "BLI_math_vector.h"
#include "BLI_listbase.h"
-#include "BLI_utildefines.h"
#include "BLI_rect.h"
+#include "BLI_utildefines.h"
#include "BKE_icons.h"
#include "BKE_idprop.h"
@@ -222,7 +223,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
BLI_listbase_clear(&newar->panels_category_active);
BLI_listbase_clear(&newar->ui_lists);
newar->visible = 0;
- newar->manipulator_map = NULL;
+ newar->gizmo_map = NULL;
newar->regiontimer = NULL;
newar->headerstr = NULL;
newar->draw_buffer = NULL;
@@ -324,18 +325,18 @@ void BKE_spacedata_id_unref(struct ScrArea *sa, struct SpaceLink *sl, struct ID
}
/**
- * Avoid bad-level calls to #WM_manipulatormap_tag_refresh.
+ * Avoid bad-level calls to #WM_gizmomap_tag_refresh.
*/
-static void (*region_refresh_tag_manipulatormap_callback)(struct wmManipulatorMap *) = NULL;
+static void (*region_refresh_tag_gizmomap_callback)(struct wmGizmoMap *) = NULL;
-void BKE_region_callback_refresh_tag_manipulatormap_set(void (*callback)(struct wmManipulatorMap *))
+void BKE_region_callback_refresh_tag_gizmomap_set(void (*callback)(struct wmGizmoMap *))
{
- region_refresh_tag_manipulatormap_callback = callback;
+ region_refresh_tag_gizmomap_callback = callback;
}
-void BKE_screen_manipulator_tag_refresh(struct bScreen *sc)
+void BKE_screen_gizmo_tag_refresh(struct bScreen *sc)
{
- if (region_refresh_tag_manipulatormap_callback == NULL) {
+ if (region_refresh_tag_gizmomap_callback == NULL) {
return;
}
@@ -343,21 +344,21 @@ void BKE_screen_manipulator_tag_refresh(struct bScreen *sc)
ARegion *ar;
for (sa = sc->areabase.first; sa; sa = sa->next) {
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->manipulator_map != NULL) {
- region_refresh_tag_manipulatormap_callback(ar->manipulator_map);
+ if (ar->gizmo_map != NULL) {
+ region_refresh_tag_gizmomap_callback(ar->gizmo_map);
}
}
}
}
/**
- * Avoid bad-level calls to #WM_manipulatormap_delete.
+ * Avoid bad-level calls to #WM_gizmomap_delete.
*/
-static void (*region_free_manipulatormap_callback)(struct wmManipulatorMap *) = NULL;
+static void (*region_free_gizmomap_callback)(struct wmGizmoMap *) = NULL;
-void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManipulatorMap *))
+void BKE_region_callback_free_gizmomap_set(void (*callback)(struct wmGizmoMap *))
{
- region_free_manipulatormap_callback = callback;
+ region_free_gizmomap_callback = callback;
}
static void panel_list_free(ListBase *lb)
@@ -414,8 +415,8 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
}
}
- if (ar->manipulator_map != NULL) {
- region_free_manipulatormap_callback(ar->manipulator_map);
+ if (ar->gizmo_map != NULL) {
+ region_free_gizmomap_callback(ar->gizmo_map);
}
BLI_freelistN(&ar->ui_lists);
@@ -855,6 +856,21 @@ void BKE_screen_view3d_scene_sync(bScreen *sc, Scene *scene)
}
}
+void BKE_screen_view3d_shading_init(View3DShading *shading)
+{
+ memset(shading, 0, sizeof(*shading));
+
+ shading->type = OB_SOLID;
+ shading->prev_type = OB_SOLID;
+ shading->flag = V3D_SHADING_SPECULAR_HIGHLIGHT;
+ shading->light = V3D_LIGHTING_STUDIO;
+ shading->shadow_intensity = 0.5f;
+ shading->xray_alpha = 0.5f;
+ shading->cavity_valley_factor = 1.0f;
+ shading->cavity_ridge_factor = 1.0f;
+ copy_v3_fl(shading->single_color, 0.8f);
+}
+
/* magic zoom calculation, no idea what
* it signifies, if you find out, tell me! -zr
*/
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index a61b71f50eb..d3429622573 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -3276,7 +3276,8 @@ SoftBody *sbNew(Scene *scene)
sb->shearstiff = 1.0f;
sb->solverflags |= SBSO_OLDERR;
- sb->pointcache = BKE_ptcache_add(&sb->ptcaches);
+ sb->shared = MEM_callocN(sizeof(*sb->shared), "SoftBody_Shared");
+ sb->shared->pointcache = BKE_ptcache_add(&sb->shared->ptcaches);
if (!sb->effector_weights)
sb->effector_weights = BKE_add_effector_weights(NULL);
@@ -3287,14 +3288,26 @@ SoftBody *sbNew(Scene *scene)
}
/* frees all */
-void sbFree(SoftBody *sb)
+void sbFree(Object *ob)
{
+ SoftBody *sb = ob->soft;
+ if (sb == NULL) {
+ return;
+ }
+
free_softbody_intern(sb);
- BKE_ptcache_free_list(&sb->ptcaches);
- sb->pointcache = NULL;
+
+ if ((ob->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
+ /* Only free shared data on non-CoW copies */
+ BKE_ptcache_free_list(&sb->shared->ptcaches);
+ sb->shared->pointcache = NULL;
+ MEM_freeN(sb->shared);
+ }
if (sb->effector_weights)
MEM_freeN(sb->effector_weights);
MEM_freeN(sb);
+
+ ob->soft = NULL;
}
void sbFreeSimulation(SoftBody *sb)
@@ -3601,7 +3614,7 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c
float dtime, timescale;
int framedelta, framenr, startframe, endframe;
int cache_result;
- cache= sb->pointcache;
+ cache= sb->shared->pointcache;
framenr= (int)cfra;
framedelta= framenr - cache->simframe;
@@ -3669,7 +3682,8 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c
}
/* try to read from cache */
- bool can_simulate = (framenr == sb->last_frame + 1) && !(cache->flag & PTCACHE_BAKED);
+ bool can_write_cache = DEG_is_active(depsgraph);
+ bool can_simulate = (framenr == sb->last_frame + 1) && !(cache->flag & PTCACHE_BAKED) && can_write_cache;
cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe, can_simulate);
@@ -3680,7 +3694,7 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c
BKE_ptcache_validate(cache, framenr);
- if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
+ if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED && can_write_cache)
BKE_ptcache_write(&pid, framenr);
sb->last_frame = framenr;
@@ -3692,7 +3706,9 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c
}
else if (/*ob->id.lib || */(cache->flag & PTCACHE_BAKED)) { /* "library linking & pointcaches" has to be solved properly at some point */
/* if baked and nothing in cache, do nothing */
- BKE_ptcache_invalidate(cache);
+ if (can_write_cache) {
+ BKE_ptcache_invalidate(cache);
+ }
return;
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index ebb23f8d5c6..5135362bd69 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -756,15 +756,19 @@ int BKE_sound_scene_playing(struct Scene *scene)
void BKE_sound_free_waveform(bSound *sound)
{
- SoundWaveform *waveform = sound->waveform;
- if (waveform) {
- if (waveform->data) {
- MEM_freeN(waveform->data);
+ if ((sound->tags & SOUND_TAGS_WAVEFORM_NO_RELOAD) == 0) {
+ SoundWaveform *waveform = sound->waveform;
+ if (waveform) {
+ if (waveform->data) {
+ MEM_freeN(waveform->data);
+ }
+ MEM_freeN(waveform);
}
- MEM_freeN(waveform);
- }
- sound->waveform = NULL;
+ sound->waveform = NULL;
+ }
+ /* This tag is only valid once. */
+ sound->tags &= ~SOUND_TAGS_WAVEFORM_NO_RELOAD;
}
void BKE_sound_read_waveform(bSound *sound, short *stop)
@@ -793,7 +797,7 @@ void BKE_sound_read_waveform(bSound *sound, short *stop)
}
MEM_freeN(waveform);
BLI_spin_lock(sound->spinlock);
- sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+ sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
BLI_spin_unlock(sound->spinlock);
return;
}
@@ -802,7 +806,7 @@ void BKE_sound_read_waveform(bSound *sound, short *stop)
BLI_spin_lock(sound->spinlock);
sound->waveform = waveform;
- sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+ sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
BLI_spin_unlock(sound->spinlock);
}
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index 468a961627e..df5cc7551aa 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -120,7 +120,7 @@ static void studiolight_free(struct StudioLight *sl)
STUDIOLIGHT_DELETE_ICON(sl->icon_id_matcap_flipped);
#undef STUDIOLIGHT_DELETE_ICON
- for (int index = 0 ; index < 6 ; index ++) {
+ for (int index = 0; index < 6; index++) {
IMB_SAFE_FREE(sl->radiance_cubemap_buffers[index]);
}
GPU_TEXTURE_SAFE_FREE(sl->equirectangular_radiance_gputexture);
@@ -152,7 +152,7 @@ static struct StudioLight *studiolight_create(int flag)
sl->icon_id_irradiance = BKE_icon_ensure_studio_light(sl, STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE);
}
- for (int index = 0 ; index < 6 ; index ++) {
+ for (int index = 0; index < 6; index++) {
sl->radiance_cubemap_buffers[index] = NULL;
}
@@ -193,9 +193,9 @@ static void studiolight_calculate_radiance_buffer(
float xf;
float *color = colbuf;
- for (int y = 0; y < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; y ++, yf += add_y) {
+ for (int y = 0; y < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; y++, yf += add_y) {
xf = start_x;
- for (int x = 0; x < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; x ++, xf += add_x) {
+ for (int x = 0; x < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; x++, xf += add_x) {
direction[index_x] = xf;
direction[index_y] = yf;
direction[index_z] = z;
@@ -234,13 +234,13 @@ static void studiolight_create_equirectangular_radiance_gputexture(StudioLight *
float *offset4 = ibuf->rect_float;
float *offset3 = sl->gpu_matcap_3components;
- for (int i = 0 ; i < ibuf->x * ibuf->y; i++) {
+ for (int i = 0; i < ibuf->x * ibuf->y; i++) {
copy_v3_v3(offset3, offset4);
offset3 += 3;
offset4 += 4;
}
- sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(
- ibuf->x, ibuf->y, GPU_R11F_G11F_B10F, sl->gpu_matcap_3components, error);
+ sl->equirectangular_radiance_gputexture = GPU_texture_create_nD(
+ ibuf->x, ibuf->y, 0, 2, sl->gpu_matcap_3components, GPU_R11F_G11F_B10F, GPU_DATA_FLOAT, 0, false, error);
}
else {
sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(
@@ -336,8 +336,8 @@ BLI_INLINE void studiolight_evaluate_radiance_buffer(
float angle;
float *radiance_color = radiance_buffer->rect_float;
float direction[3];
- for (int y = 0; y < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; y ++) {
- for (int x = 0; x < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; x ++) {
+ for (int y = 0; y < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; y++) {
+ for (int x = 0; x < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; x++) {
// calculate light direction;
direction[zoffset] = zvalue;
direction[xoffset] = (x / (float)STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) - 0.5f;
@@ -345,7 +345,7 @@ BLI_INLINE void studiolight_evaluate_radiance_buffer(
normalize_v3(direction);
angle = fmax(0.0f, dot_v3v3(direction, normal));
madd_v3_v3fl(color, radiance_color, angle);
- (*hits) ++;
+ (*hits)++;
radiance_color += 4;
}
}
@@ -442,106 +442,64 @@ static void studiolight_calculate_spherical_harmonics_coefficient(StudioLight *s
switch (sh_component) {
/* L0 */
case 0:
- {
coef = 0.2822095f;
break;
- }
-
/* L1 */
case 1:
- {
coef = -0.488603f * nz * 2.0f / 3.0f;
break;
- }
case 2:
- {
coef = 0.488603f * ny * 2.0f / 3.0f;
break;
- }
case 3:
- {
coef = -0.488603f * nx * 2.0f / 3.0f;
break;
- }
-
/* L2 */
case 4:
- {
coef = 1.092548f * nx * nz * 1.0f / 4.0f;
break;
- }
case 5:
- {
coef = -1.092548f * nz * ny * 1.0f / 4.0f;
break;
- }
case 6:
- {
coef = 0.315392f * (3.0f * ny2 - 1.0f) * 1.0f / 4.0f;
break;
- }
case 7:
- {
coef = 1.092548f * nx * ny * 1.0f / 4.0f;
break;
- }
case 8:
- {
coef = 0.546274f * (nx2 - nz2) * 1.0f / 4.0f;
break;
- }
-
/* L4 */
case 9:
- {
coef = (2.5033429417967046f * nx * nz * (nx2 - nz2)) / -24.0f;
break;
- }
case 10:
- {
coef = (-1.7701307697799304f * nz * ny * (3.0f * nx2 - nz2)) / -24.0f;
break;
- }
case 11:
- {
- coef = (0.9461746957575601f * nz * nx * (-1.0f +7.0f*ny2)) / -24.0f;
+ coef = (0.9461746957575601f * nz * nx * (-1.0f + 7.0f * ny2)) / -24.0f;
break;
- }
case 12:
- {
coef = (-0.6690465435572892f * nz * ny * (-3.0f + 7.0f * ny2)) / -24.0f;
break;
- }
case 13:
- {
- coef = ((105.0f*ny4-90.0f*ny2+9.0f)/28.359261614f) / -24.0f;
+ coef = ((105.0f * ny4 - 90.0f * ny2 + 9.0f) / 28.359261614f) / -24.0f;
break;
- }
case 14:
- {
coef = (-0.6690465435572892f * nx * ny * (-3.0f + 7.0f * ny2)) / -24.0f;
break;
- }
case 15:
- {
coef = (0.9461746957575601f * (nx2 - nz2) * (-1.0f + 7.0f * ny2)) / -24.0f;
break;
- }
case 16:
- {
coef = (-1.7701307697799304f * nx * ny * (nx2 - 3.0f * nz2)) / -24.0f;
break;
- }
case 17:
- {
coef = (0.6258357354491761f * (nx4 - 6.0f * nz2 * nx2 + nz4)) / -24.0f;
break;
- }
-
default:
- {
coef = 0.0f;
- }
}
madd_v3_v3fl(sh, color, coef * weight);
@@ -621,7 +579,7 @@ static void studiolight_apply_spherical_harmonics_windowing(StudioLight *sl, flo
/* Apply windowing lambda */
index = 0;
- for (int level = 0; level <= STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL; level ++) {
+ for (int level = 0; level <= STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL; level++) {
float s = 1.0f / (1.0f + lambda * SQUARE(level) * SQUARE(level + 1.0f));
for (int m = -1; m <= level; m++) {
@@ -666,9 +624,9 @@ BLI_INLINE void studiolight_sample_spherical_harmonics(StudioLight *sl, float co
const float nz4 = SQUARE(nz2);
madd_v3_v3fl(color, sl->spherical_harmonics_coefs[9], 2.5033429417967046f * nx * nz * (nx2 - nz2));
madd_v3_v3fl(color, sl->spherical_harmonics_coefs[10], -1.7701307697799304f * nz * ny * (3.0f * nx2 - nz2));
- madd_v3_v3fl(color, sl->spherical_harmonics_coefs[11], 0.9461746957575601f * nz * nx * (-1.0f + 7.0f*ny2));
+ madd_v3_v3fl(color, sl->spherical_harmonics_coefs[11], 0.9461746957575601f * nz * nx * (-1.0f + 7.0f * ny2));
madd_v3_v3fl(color, sl->spherical_harmonics_coefs[12], -0.6690465435572892f * nz * ny * (-3.0f + 7.0f * ny2));
- madd_v3_v3fl(color, sl->spherical_harmonics_coefs[13], (105.0f*ny4-90.0f*ny2+9.0f)/28.359261614f);
+ madd_v3_v3fl(color, sl->spherical_harmonics_coefs[13], (105.0f * ny4 - 90.0f * ny2 + 9.0f) / 28.359261614f);
madd_v3_v3fl(color, sl->spherical_harmonics_coefs[14], -0.6690465435572892f * nx * ny * (-3.0f + 7.0f * ny2));
madd_v3_v3fl(color, sl->spherical_harmonics_coefs[15], 0.9461746957575601f * (nx2 - nz2) * (-1.0f + 7.0f * ny2));
madd_v3_v3fl(color, sl->spherical_harmonics_coefs[16], -1.7701307697799304f * nx * ny * (nx2 - 3.0f * nz2));
@@ -683,7 +641,7 @@ static void studiolight_calculate_diffuse_light(StudioLight *sl)
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED);
- for (int comp = 0; comp < STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS; comp ++) {
+ for (int comp = 0; comp < STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS; comp++) {
studiolight_calculate_spherical_harmonics_coefficient(sl, comp);
}
@@ -705,8 +663,8 @@ static void studiolight_calculate_diffuse_light(StudioLight *sl)
static float texel_coord_solid_angle(float a_U, float a_V, int a_Size)
{
//scale up to [-1, 1] range (inclusive), offset by 0.5 to point to texel center.
- float u = (2.0f * ((float)a_U + 0.5f) / (float)a_Size ) - 1.0f;
- float v = (2.0f * ((float)a_V + 0.5f) / (float)a_Size ) - 1.0f;
+ float u = (2.0f * ((float)a_U + 0.5f) / (float)a_Size) - 1.0f;
+ float v = (2.0f * ((float)a_V + 0.5f) / (float)a_Size) - 1.0f;
float resolution_inv = 1.0f / a_Size;
@@ -729,8 +687,8 @@ BLI_INLINE void studiolight_evaluate_specular_radiance_buffer(
float angle;
float *radiance_color = radiance_buffer->rect_float;
float direction[3];
- for (int y = 0; y < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; y ++) {
- for (int x = 0; x < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; x ++) {
+ for (int y = 0; y < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; y++) {
+ for (int x = 0; x < STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE; x++) {
// calculate light direction;
float u = (x / (float)STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) - 0.5f;
float v = (y / (float)STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) - 0.5f;
@@ -823,10 +781,10 @@ static void studiolight_calculate_irradiance_equirectangular_image(StudioLight *
float *colbuf = MEM_mallocN(STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH * STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT * sizeof(float[4]), __func__);
float *color = colbuf;
- for (int y = 0; y < STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT ; y ++) {
+ for (int y = 0; y < STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT; y++) {
float yf = y / (float)STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT;
- for (int x = 0; x < STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH ; x ++) {
+ for (int x = 0; x < STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH; x++) {
float xf = x / (float)STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH;
float dir[3];
equirectangular_to_direction(dir, xf, yf);
@@ -875,8 +833,8 @@ static void studiolight_calculate_light_direction(StudioLight *sl)
/* go over every pixel, determine light, if higher calc direction off the light */
float new_light;
float *color = ibuf->rect_float;
- for (int y = 0; y < STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT; y ++) {
- for (int x = 0; x < STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH; x ++) {
+ for (int y = 0; y < STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT; y++) {
+ for (int x = 0; x < STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH; x++) {
new_light = color[0] + color[1] + color[2];
if (new_light > best_light) {
float u = x / (float)STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH;
@@ -1037,7 +995,7 @@ static void studiolight_matcap_preview(uint *icon_buffer, StudioLight *sl, bool
if (flipped) {
fx = 1.0f - fx;
}
- nearest_interpolation_color(ibuf, NULL, color, fx * ibuf->x, fy * ibuf->y);
+ nearest_interpolation_color(ibuf, NULL, color, fx * ibuf->x - 1.0f, fy * ibuf->y - 1.0f);
uint alphamask = alpha_circle_mask(fx, fy, 0.5f - pixel_size, 0.5f);
diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c
new file mode 100644
index 00000000000..794da2d3477
--- /dev/null
+++ b/source/blender/blenkernel/intern/subdiv.c
@@ -0,0 +1,119 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/subdiv.c
+ * \ingroup bke
+ */
+
+#include "BKE_subdiv.h"
+
+#include "BLI_utildefines.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "subdiv_converter.h"
+
+#ifdef WITH_OPENSUBDIV
+# include "opensubdiv_capi.h"
+# include "opensubdiv_converter_capi.h"
+# include "opensubdiv_evaluator_capi.h"
+# include "opensubdiv_topology_refiner_capi.h"
+#endif
+
+#ifdef WITH_OPENSUBDIV
+static void update_subdiv_after_topology_change(Subdiv *subdiv)
+{
+ /* Count ptex faces. */
+ subdiv->num_ptex_faces = subdiv->topology_refiner->getNumPtexFaces(
+ subdiv->topology_refiner);
+ /* Initialize offset of base faces in ptex indices. */
+ MEM_SAFE_FREE(subdiv->face_ptex_offset);
+ subdiv->face_ptex_offset = MEM_malloc_arrayN(subdiv->num_ptex_faces,
+ sizeof(int),
+ "subdiv ptex offset");
+ subdiv->topology_refiner->fillFacePtexIndexOffset(
+ subdiv->topology_refiner,
+ subdiv->face_ptex_offset);
+}
+#endif
+
+Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
+ struct OpenSubdiv_Converter *converter)
+{
+#ifdef WITH_OPENSUBDIV
+ SubdivStats stats;
+ BKE_subdiv_stats_init(&stats);
+ BKE_subdiv_stats_begin(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME);
+ OpenSubdiv_TopologyRefinerSettings topology_refiner_settings;
+ topology_refiner_settings.level = settings->level;
+ topology_refiner_settings.is_adaptive = settings->is_adaptive;
+ struct OpenSubdiv_TopologyRefiner *osd_topology_refiner =
+ openSubdiv_createTopologyRefinerFromConverter(
+ converter, &topology_refiner_settings);
+ if (osd_topology_refiner == NULL) {
+ return NULL;
+ }
+ Subdiv *subdiv = MEM_callocN(sizeof(Subdiv), "subdiv from converetr");
+ subdiv->settings = *settings;
+ subdiv->topology_refiner = osd_topology_refiner;
+ subdiv->evaluator = NULL;
+ update_subdiv_after_topology_change(subdiv);
+ BKE_subdiv_stats_end(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME);
+ subdiv->stats = stats;
+ return subdiv;
+#else
+ UNUSED_VARS(settings, converter);
+ return NULL;
+#endif
+}
+
+Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings,
+ struct Mesh *mesh)
+{
+#ifdef WITH_OPENSUBDIV
+ OpenSubdiv_Converter converter;
+ BKE_subdiv_converter_init_for_mesh(&converter, settings, mesh);
+ Subdiv *subdiv = BKE_subdiv_new_from_converter(settings, &converter);
+ BKE_subdiv_converter_free(&converter);
+ return subdiv;
+#else
+ UNUSED_VARS(settings, mesh);
+ return NULL;
+#endif
+}
+
+void BKE_subdiv_free(Subdiv *subdiv)
+{
+#ifdef WITH_OPENSUBDIV
+ if (subdiv->evaluator != NULL) {
+ openSubdiv_deleteEvaluator(subdiv->evaluator);
+ }
+ if (subdiv->topology_refiner != NULL) {
+ openSubdiv_deleteTopologyRefiner(subdiv->topology_refiner);
+ }
+ MEM_SAFE_FREE(subdiv->face_ptex_offset);
+ MEM_freeN(subdiv);
+#endif
+}
diff --git a/source/blender/blenkernel/intern/subdiv_converter.c b/source/blender/blenkernel/intern/subdiv_converter.c
new file mode 100644
index 00000000000..f6dabfa1c80
--- /dev/null
+++ b/source/blender/blenkernel/intern/subdiv_converter.c
@@ -0,0 +1,65 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "subdiv_converter.h"
+
+#include "BLI_utildefines.h"
+
+#ifdef WITH_OPENSUBDIV
+# include "opensubdiv_converter_capi.h"
+#endif
+
+void BKE_subdiv_converter_free(struct OpenSubdiv_Converter *converter)
+{
+#ifdef WITH_OPENSUBDIV
+ if (converter->freeUserData) {
+ converter->freeUserData(converter);
+ }
+#else
+ UNUSED_VARS(converter);
+#endif
+}
+
+/*OpenSubdiv_FVarLinearInterpolation*/ int
+BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings)
+{
+#ifdef WITH_OPENSUBDIV
+ switch (settings->fvar_linear_interpolation) {
+ case SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE:
+ return OSD_FVAR_LINEAR_INTERPOLATION_NONE;
+ case SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY:
+ return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY;
+ case SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES:
+ return OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES;
+ case SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL:
+ return OSD_FVAR_LINEAR_INTERPOLATION_ALL;
+ }
+ BLI_assert(!"Unknown fvar linear interpolation");
+ return OSD_FVAR_LINEAR_INTERPOLATION_NONE;
+#else
+ UNUSED_VARS(settings);
+ return 0;
+#endif
+}
diff --git a/source/blender/blenkernel/intern/subdiv_converter.h b/source/blender/blenkernel/intern/subdiv_converter.h
new file mode 100644
index 00000000000..4c552a9164e
--- /dev/null
+++ b/source/blender/blenkernel/intern/subdiv_converter.h
@@ -0,0 +1,57 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __SUBDIV_CONVERTER_H__
+#define __SUBDIV_CONVERTER_H__
+
+#include "BKE_subdiv.h"
+
+/* NOTE: Was initially used to get proper enumerator types, but this makes
+ * it tricky to compile without OpenSubdiv.
+ */
+/* #include "opensubdiv_converter_capi.h" */
+
+struct Mesh;
+struct OpenSubdiv_Converter;
+struct SubdivSettings;
+
+void BKE_subdiv_converter_init_for_mesh(struct OpenSubdiv_Converter *converter,
+ const struct SubdivSettings *settings,
+ const struct Mesh *mesh);
+
+/* NOTE: Frees converter data, but not converter itself. This means, that if
+ * converter was allocated on heap, it is up to the user to free that memory.
+ */
+void BKE_subdiv_converter_free(struct OpenSubdiv_Converter *converter);
+
+/* ============================ INTERNAL HELPERS ============================ */
+
+/* TODO(sergey): Find a way to make it OpenSubdiv_FVarLinearInterpolation,
+ * without breaking compilation without OpenSubdiv.
+ */
+int BKE_subdiv_converter_fvar_linear_from_settings(
+ const SubdivSettings *settings);
+
+#endif /* __SUBDIV_CONVERTER_H__ */
diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
new file mode 100644
index 00000000000..1a2c26b3564
--- /dev/null
+++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
@@ -0,0 +1,471 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "subdiv_converter.h"
+
+#include <string.h>
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+
+#include "BKE_customdata.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_subdiv.h"
+
+#include "MEM_guardedalloc.h"
+
+#ifdef WITH_OPENSUBDIV
+# include "opensubdiv_capi.h"
+# include "opensubdiv_converter_capi.h"
+#endif
+
+/* Use mesh element mapping structures during conversion.
+ * Uses more memory but is much faster than naive algorithm.
+ */
+#define USE_MESH_ELEMENT_MAPPING
+
+#ifdef WITH_OPENSUBDIV
+typedef struct ConverterStorage {
+ SubdivSettings settings;
+ const Mesh *mesh;
+
+#ifdef USE_MESH_ELEMENT_MAPPING
+ MeshElemMap *vert_edge_map;
+ MeshElemMap *vert_poly_map;
+ MeshElemMap *edge_poly_map;
+ int *vert_edge_mem;
+ int *vert_poly_mem;
+ int *edge_poly_mem;
+#endif
+
+ /* Indexed by loop index, value denotes index of face-varying vertex
+ * which corresponds to the UV coordinate.
+ */
+ int *loop_uv_indices;
+ int num_uv_coordinates;
+} ConverterStorage;
+
+static OpenSubdiv_SchemeType get_scheme_type(
+ const OpenSubdiv_Converter *converter)
+{
+ ConverterStorage *storage = converter->user_data;
+ if (storage->settings.is_simple) {
+ return OSD_SCHEME_BILINEAR;
+ }
+ else {
+ return OSD_SCHEME_CATMARK;
+ }
+}
+
+static OpenSubdiv_FVarLinearInterpolation get_fvar_linear_interpolation(
+ const OpenSubdiv_Converter *converter)
+{
+ ConverterStorage *storage = converter->user_data;
+ return BKE_subdiv_converter_fvar_linear_from_settings(&storage->settings);
+}
+
+static int get_num_faces(const OpenSubdiv_Converter *converter)
+{
+ ConverterStorage *storage = converter->user_data;
+ return storage->mesh->totpoly;
+}
+
+static int get_num_edges(const OpenSubdiv_Converter *converter)
+{
+ ConverterStorage *storage = converter->user_data;
+ return storage->mesh->totedge;
+}
+
+static int get_num_verts(const OpenSubdiv_Converter *converter)
+{
+ ConverterStorage *storage = converter->user_data;
+ return storage->mesh->totvert;
+}
+
+static int get_num_face_verts(const OpenSubdiv_Converter *converter, int face)
+{
+ ConverterStorage *storage = converter->user_data;
+ return storage->mesh->mpoly[face].totloop;
+}
+
+static void get_face_verts(const OpenSubdiv_Converter *converter,
+ int face,
+ int *face_verts)
+{
+ ConverterStorage *storage = converter->user_data;
+ const MPoly *mp = &storage->mesh->mpoly[face];
+ const MLoop *mloop = storage->mesh->mloop;
+ for (int loop = 0; loop < mp->totloop; loop++) {
+ face_verts[loop] = mloop[mp->loopstart + loop].v;
+ }
+}
+
+static void get_face_edges(const OpenSubdiv_Converter *converter,
+ int face,
+ int *face_edges)
+{
+ ConverterStorage *storage = converter->user_data;
+ const MPoly *mp = &storage->mesh->mpoly[face];
+ const MLoop *mloop = storage->mesh->mloop;
+ for (int loop = 0; loop < mp->totloop; loop++) {
+ face_edges[loop] = mloop[mp->loopstart + loop].e;
+ }
+}
+
+static void get_edge_verts(const OpenSubdiv_Converter *converter,
+ int edge,
+ int *edge_verts)
+{
+ ConverterStorage *storage = converter->user_data;
+ const MEdge *me = &storage->mesh->medge[edge];
+ edge_verts[0] = me->v1;
+ edge_verts[1] = me->v2;
+}
+
+static int get_num_edge_faces(const OpenSubdiv_Converter *converter, int edge)
+{
+ ConverterStorage *storage = converter->user_data;
+#ifdef USE_MESH_ELEMENT_MAPPING
+ return storage->edge_poly_map[edge].count;
+#else
+ const Mesh *mesh = storage->mesh;
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+ int num = 0;
+ for (int poly = 0; poly < mesh->totpoly; poly++) {
+ const MPoly *mp = &mpoly[poly];
+ for (int loop = 0; loop < mp->totloop; loop++) {
+ const MLoop *ml = &mloop[mp->loopstart + loop];
+ if (ml->e == edge) {
+ ++num;
+ break;
+ }
+ }
+ }
+ return num;
+#endif
+}
+
+static void get_edge_faces(const OpenSubdiv_Converter *converter,
+ int edge,
+ int *edge_faces)
+{
+ ConverterStorage *storage = converter->user_data;
+#ifdef USE_MESH_ELEMENT_MAPPING
+ memcpy(edge_faces,
+ storage->edge_poly_map[edge].indices,
+ sizeof(int) * storage->edge_poly_map[edge].count);
+#else
+ const Mesh *mesh = storage->mesh;
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+ int num = 0;
+ for (int poly = 0; poly < mesh->totpoly; poly++) {
+ const MPoly *mp = &mpoly[poly];
+ for (int loop = 0; loop < mpoly->totloop; loop++) {
+ const MLoop *ml = &mloop[mp->loopstart + loop];
+ if (ml->e == edge) {
+ edge_faces[num++] = poly;
+ break;
+ }
+ }
+ }
+#endif
+}
+
+static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int edge)
+{
+ ConverterStorage *storage = converter->user_data;
+ const MEdge *medge = storage->mesh->medge;
+ const float edge_crease = (float)medge[edge].crease / 255.0f;
+ return edge_crease * storage->settings.level;
+}
+
+static int get_num_vert_edges(const OpenSubdiv_Converter *converter, int vert)
+{
+ ConverterStorage *storage = converter->user_data;
+#ifdef USE_MESH_ELEMENT_MAPPING
+ return storage->vert_edge_map[vert].count;
+#else
+ const Mesh *mesh = storage->mesh;
+ const MEdge *medge = mesh->medge;
+ int num = 0;
+ for (int edge = 0; edge < mesh->totedge; edge++) {
+ const MEdge *me = &medge[edge];
+ if (me->v1 == vert || me->v2 == vert) {
+ ++num;
+ }
+ }
+ return num;
+#endif
+}
+
+static void get_vert_edges(const OpenSubdiv_Converter *converter,
+ int vert,
+ int *vert_edges)
+{
+ ConverterStorage *storage = converter->user_data;
+#ifdef USE_MESH_ELEMENT_MAPPING
+ memcpy(vert_edges,
+ storage->vert_edge_map[vert].indices,
+ sizeof(int) * storage->vert_edge_map[vert].count);
+#else
+ const Mesh *mesh = storage->mesh;
+ const MEdge *medge = mesh->medge;
+ int num = 0;
+ for (int edge = 0; edge < mesh->totedge; edge++) {
+ const MEdge *me = &medge[edge];
+ if (me->v1 == vert || me->v2 == vert) {
+ vert_edges[num++] = edge;
+ }
+ }
+#endif
+}
+
+static int get_num_vert_faces(const OpenSubdiv_Converter *converter, int vert)
+{
+ ConverterStorage *storage = converter->user_data;
+#ifdef USE_MESH_ELEMENT_MAPPING
+ return storage->vert_poly_map[vert].count;
+#else
+ const Mesh *mesh = storage->mesh;
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+ int num = 0;
+ for (int poly = 0; poly < mesh->totpoly; poly++) {
+ const MPoly *mp = &mpoly[poly];
+ for (int loop = 0; loop < mpoly->totloop; loop++) {
+ const MLoop *ml = &mloop[mp->loopstart + loop];
+ if (ml->v == vert) {
+ ++num;
+ break;
+ }
+ }
+ }
+ return num;
+#endif
+}
+
+static void get_vert_faces(const OpenSubdiv_Converter *converter,
+ int vert,
+ int *vert_faces)
+{
+ ConverterStorage *storage = converter->user_data;
+#ifdef USE_MESH_ELEMENT_MAPPING
+ memcpy(vert_faces,
+ storage->vert_poly_map[vert].indices,
+ sizeof(int) * storage->vert_poly_map[vert].count);
+#else
+ const Mesh *mesh = storage->mesh;
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+ int num = 0;
+ for (int poly = 0; poly < mesh->totpoly; poly++) {
+ const MPoly *mp = &mpoly[poly];
+ for (int loop = 0; loop < mpoly->totloop; loop++) {
+ const MLoop *ml = &mloop[mp->loopstart + loop];
+ if (ml->v == vert) {
+ vert_faces[num++] = poly;
+ break;
+ }
+ }
+ }
+#endif
+}
+
+static int get_num_uv_layers(const OpenSubdiv_Converter *converter)
+{
+ ConverterStorage *storage = converter->user_data;
+ const Mesh *mesh = storage->mesh;
+ return CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV);
+}
+
+static void precalc_uv_layer(const OpenSubdiv_Converter *converter,
+ const int layer_index)
+{
+ ConverterStorage *storage = converter->user_data;
+ const Mesh *mesh = storage->mesh;
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+ const MLoopUV *mloopuv = CustomData_get_layer_n(
+ &mesh->ldata, CD_MLOOPUV, layer_index);
+ const int num_poly = mesh->totpoly;
+ const int num_vert = mesh->totvert;
+ const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
+ /* Initialize memory required for the operations. */
+ if (storage->loop_uv_indices == NULL) {
+ storage->loop_uv_indices = MEM_malloc_arrayN(
+ mesh->totloop, sizeof(int), "loop uv vertex index");
+ }
+ UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
+ mpoly, mloop, mloopuv,
+ num_poly, num_vert,
+ limit,
+ false, true);
+ /* NOTE: First UV vertex is supposed to be always marked as separate. */
+ storage->num_uv_coordinates = -1;
+ for (int vertex_index = 0; vertex_index < num_vert; ++vertex_index) {
+ const UvMapVert *uv_vert = BKE_mesh_uv_vert_map_get_vert(uv_vert_map,
+ vertex_index);
+ while (uv_vert != NULL) {
+ if (uv_vert->separate) {
+ storage->num_uv_coordinates++;
+ }
+ const MPoly *mp = &mpoly[uv_vert->poly_index];
+ const int global_loop_index = mp->loopstart +
+ uv_vert->loop_of_poly_index;
+ storage->loop_uv_indices[global_loop_index] =
+ storage->num_uv_coordinates;
+ uv_vert = uv_vert->next;
+ }
+ }
+ /* So far this value was used as a 0-based index, actual number of UV
+ * vertices is 1 more.
+ */
+ storage->num_uv_coordinates += 1;
+ BKE_mesh_uv_vert_map_free(uv_vert_map);
+}
+
+static void finish_uv_layer(const OpenSubdiv_Converter *UNUSED(converter))
+{
+}
+
+static int get_num_uvs(const OpenSubdiv_Converter *converter)
+{
+ ConverterStorage *storage = converter->user_data;
+ return storage->num_uv_coordinates;
+}
+
+static int get_face_corner_uv_index(const OpenSubdiv_Converter *converter,
+ const int face_index,
+ const int corner)
+{
+ ConverterStorage *storage = converter->user_data;
+ const MPoly *mp = &storage->mesh->mpoly[face_index];
+ return storage->loop_uv_indices[mp->loopstart + corner];
+}
+
+static void free_user_data(const OpenSubdiv_Converter *converter)
+{
+ ConverterStorage *user_data = converter->user_data;
+ MEM_SAFE_FREE(user_data->loop_uv_indices);
+#ifdef USE_MESH_ELEMENT_MAPPING
+ MEM_freeN(user_data->vert_edge_map);
+ MEM_freeN(user_data->vert_edge_mem);
+ MEM_freeN(user_data->vert_poly_map);
+ MEM_freeN(user_data->vert_poly_mem);
+ MEM_freeN(user_data->edge_poly_map);
+ MEM_freeN(user_data->edge_poly_mem);
+#endif
+ MEM_freeN(user_data);
+}
+
+static void init_functions(OpenSubdiv_Converter *converter)
+{
+ converter->getSchemeType = get_scheme_type;
+
+ converter->getFVarLinearInterpolation = get_fvar_linear_interpolation;
+
+ converter->getNumFaces = get_num_faces;
+ converter->getNumEdges = get_num_edges;
+ converter->getNumVertices = get_num_verts;
+
+ converter->getNumFaceVertices = get_num_face_verts;
+ converter->getFaceVertices = get_face_verts;
+ converter->getFaceEdges = get_face_edges;
+
+ converter->getEdgeVertices = get_edge_verts;
+ converter->getNumEdgeFaces = get_num_edge_faces;
+ converter->getEdgeFaces = get_edge_faces;
+ converter->getEdgeSharpness = get_edge_sharpness;
+
+ converter->getNumVertexEdges = get_num_vert_edges;
+ converter->getVertexEdges = get_vert_edges;
+ converter->getNumVertexFaces = get_num_vert_faces;
+ converter->getVertexFaces = get_vert_faces;
+
+ converter->getNumUVLayers = get_num_uv_layers;
+ converter->precalcUVLayer = precalc_uv_layer;
+ converter->finishUVLayer = finish_uv_layer;
+ converter->getNumUVCoordinates = get_num_uvs;
+ converter->getFaceCornerUVIndex = get_face_corner_uv_index;
+
+ converter->freeUserData = free_user_data;
+}
+
+static void create_element_maps_if_needed(ConverterStorage *storage)
+{
+#ifdef USE_MESH_ELEMENT_MAPPING
+ const Mesh *mesh = storage->mesh;
+ BKE_mesh_vert_edge_map_create(&storage->vert_edge_map,
+ &storage->vert_edge_mem,
+ mesh->medge,
+ mesh->totvert,
+ mesh->totedge);
+ BKE_mesh_vert_poly_map_create(&storage->vert_poly_map,
+ &storage->vert_poly_mem,
+ mesh->mpoly,
+ mesh->mloop,
+ mesh->totvert,
+ mesh->totpoly,
+ mesh->totloop);
+ BKE_mesh_edge_poly_map_create(&storage->edge_poly_map,
+ &storage->edge_poly_mem,
+ mesh->medge, mesh->totedge,
+ mesh->mpoly, mesh->totpoly,
+ mesh->mloop, mesh->totloop);
+#else
+ (void) storage; /* Ignored. */
+#endif
+}
+
+static void init_user_data(OpenSubdiv_Converter *converter,
+ const SubdivSettings *settings,
+ const Mesh *mesh)
+{
+ ConverterStorage *user_data =
+ MEM_mallocN(sizeof(ConverterStorage), __func__);
+ user_data->settings = *settings;
+ user_data->mesh = mesh;
+ user_data->loop_uv_indices = NULL;
+ create_element_maps_if_needed(user_data);
+ converter->user_data = user_data;
+}
+#endif
+
+void BKE_subdiv_converter_init_for_mesh(struct OpenSubdiv_Converter *converter,
+ const SubdivSettings *settings,
+ const Mesh *mesh)
+{
+#ifdef WITH_OPENSUBDIV
+ init_functions(converter);
+ init_user_data(converter, settings, mesh);
+#else
+ UNUSED_VARS(converter, settings, mesh);
+#endif
+}
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
new file mode 100644
index 00000000000..4c2ed07cdfa
--- /dev/null
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -0,0 +1,323 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/subdiv_eval.c
+ * \ingroup bke
+ */
+
+#include "BKE_subdiv.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+
+#include "BKE_customdata.h"
+
+#ifdef WITH_OPENSUBDIV
+# include "opensubdiv_evaluator_capi.h"
+# include "opensubdiv_topology_refiner_capi.h"
+#endif
+
+void BKE_subdiv_eval_begin(Subdiv *subdiv)
+{
+#ifdef WITH_OPENSUBDIV
+ if (subdiv->evaluator == NULL) {
+ BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
+ subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner(
+ subdiv->topology_refiner);
+ BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
+ }
+ else {
+ /* TODO(sergey): Check for topology change. */
+ }
+#else
+ UNUSED_VARS(subdiv);
+#endif
+}
+
+#ifdef WITH_OPENSUBDIV
+static void set_face_varying_data_from_uv(Subdiv *subdiv,
+ const MLoopUV *mloopuv,
+ const int layer_index)
+{
+ OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
+ OpenSubdiv_Evaluator *evaluator = subdiv->evaluator;
+ const int num_faces = topology_refiner->getNumFaces(topology_refiner);
+ const MLoopUV *mluv = mloopuv;
+ /* TODO(sergey): OpenSubdiv's C-API converter can change winding of
+ * loops of a face, need to watch for that, to prevent wrong UVs assigned.
+ */
+ for (int face_index = 0; face_index < num_faces; ++face_index) {
+ const int num_face_vertices = topology_refiner->getNumFaceVertices(
+ topology_refiner, face_index);
+ const int *uv_indicies = topology_refiner->getFaceFVarValueIndices(
+ topology_refiner, face_index, layer_index);
+ for (int vertex_index = 0;
+ vertex_index < num_face_vertices;
+ vertex_index++, mluv++)
+ {
+ evaluator->setFaceVaryingData(evaluator,
+ mluv->uv,
+ uv_indicies[vertex_index],
+ 1);
+ }
+ }
+}
+#endif
+
+void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh)
+{
+#ifdef WITH_OPENSUBDIV
+ BKE_subdiv_eval_begin(subdiv);
+ /* Set coordinates of base mesh vertices. */
+ subdiv->evaluator->setCoarsePositionsFromBuffer(
+ subdiv->evaluator,
+ mesh->mvert,
+ offsetof(MVert, co),
+ sizeof(MVert),
+ 0, mesh->totvert);
+ /* Set face-varyign data to UV maps. */
+ const int num_uv_layers =
+ CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV);
+ for (int layer_index = 0; layer_index < num_uv_layers; layer_index++) {
+ const MLoopUV *mloopuv = CustomData_get_layer_n(
+ &mesh->ldata, CD_MLOOPUV, layer_index);
+ set_face_varying_data_from_uv(subdiv, mloopuv, layer_index);
+ /* NOTE: Currently evaluator can only handle single face varying layer.
+ * This is a limitation of C-API and some underlying helper classes from
+ * our side which will get fixed.
+ */
+ break;
+ }
+ /* Update evaluator to the new coarse geometry. */
+ BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE);
+ subdiv->evaluator->refine(subdiv->evaluator);
+ BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE);
+#else
+ UNUSED_VARS(subdiv, mesh);
+#endif
+}
+
+/* ========================== Single point queries ========================== */
+
+void BKE_subdiv_eval_limit_point(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float P[3])
+{
+ BKE_subdiv_eval_limit_point_and_derivatives(subdiv,
+ ptex_face_index,
+ u, v,
+ P, NULL, NULL);
+}
+
+void BKE_subdiv_eval_limit_point_and_derivatives(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float P[3], float dPdu[3], float dPdv[3])
+{
+#ifdef WITH_OPENSUBDIV
+ subdiv->evaluator->evaluateLimit(subdiv->evaluator,
+ ptex_face_index,
+ u, v,
+ P, dPdu, dPdv);
+#else
+ UNUSED_VARS(subdiv, ptex_face_index, u, v, P, dPdu, dPdv);
+#endif
+}
+
+void BKE_subdiv_eval_limit_point_and_normal(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float P[3], float N[3])
+{
+ float dPdu[3], dPdv[3];
+ BKE_subdiv_eval_limit_point_and_derivatives(subdiv,
+ ptex_face_index,
+ u, v,
+ P, dPdu, dPdv);
+ cross_v3_v3v3(N, dPdu, dPdv);
+ normalize_v3(N);
+}
+
+void BKE_subdiv_eval_limit_point_and_short_normal(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float P[3], short N[3])
+{
+ float N_float[3];
+ BKE_subdiv_eval_limit_point_and_normal(subdiv,
+ ptex_face_index,
+ u, v,
+ P, N_float);
+ normal_float_to_short_v3(N, N_float);
+}
+
+void BKE_subdiv_eval_face_varying(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u, const float v,
+ float face_varying[2])
+{
+#ifdef WITH_OPENSUBDIV
+ subdiv->evaluator->evaluateFaceVarying(subdiv->evaluator,
+ ptex_face_index,
+ u, v,
+ face_varying);
+#else
+ UNUSED_VARS(subdiv, ptex_face_index, u, v, face_varying);
+#endif
+}
+
+/* =================== Patch queries at given resolution =================== */
+
+/* Move buffer forward by a given number of bytes. */
+static void buffer_apply_offset(void **buffer, const int offset)
+{
+ *buffer = ((unsigned char *)*buffer) + offset;
+}
+
+/* Write given number of floats to the beginning of given buffer. */
+static void buffer_write_float_value(void **buffer,
+ const float *values_buffer, int num_values)
+{
+ memcpy(*buffer, values_buffer, sizeof(float) * num_values);
+}
+
+/* Similar to above, just operates with short values. */
+static void buffer_write_short_value(void **buffer,
+ const short *values_buffer, int num_values)
+{
+ memcpy(*buffer, values_buffer, sizeof(short) * num_values);
+}
+
+void BKE_subdiv_eval_limit_patch_resolution_point(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const int resolution,
+ void *buffer, const int offset, const int stride)
+{
+ buffer_apply_offset(&buffer, offset);
+ const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
+ for (int y = 0; y < resolution; y++) {
+ const float v = y * inv_resolution_1;
+ for (int x = 0; x < resolution; x++) {
+ const float u = x * inv_resolution_1;
+ BKE_subdiv_eval_limit_point(subdiv,
+ ptex_face_index,
+ u, v,
+ buffer);
+ buffer_apply_offset(&buffer, stride);
+ }
+ }
+}
+
+void BKE_subdiv_eval_limit_patch_resolution_point_and_derivatives(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const int resolution,
+ void *point_buffer, const int point_offset, const int point_stride,
+ void *du_buffer, const int du_offset, const int du_stride,
+ void *dv_buffer, const int dv_offset, const int dv_stride)
+{
+ buffer_apply_offset(&point_buffer, point_offset);
+ buffer_apply_offset(&du_buffer, du_offset);
+ buffer_apply_offset(&dv_buffer, dv_offset);
+ const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
+ for (int y = 0; y < resolution; y++) {
+ const float v = y * inv_resolution_1;
+ for (int x = 0; x < resolution; x++) {
+ const float u = x * inv_resolution_1;
+ BKE_subdiv_eval_limit_point_and_derivatives(
+ subdiv,
+ ptex_face_index,
+ u, v,
+ point_buffer, du_buffer, dv_buffer);
+ buffer_apply_offset(&point_buffer, point_stride);
+ buffer_apply_offset(&du_buffer, du_stride);
+ buffer_apply_offset(&dv_buffer, dv_stride);
+ }
+ }
+}
+
+void BKE_subdiv_eval_limit_patch_resolution_point_and_normal(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const int resolution,
+ void *point_buffer, const int point_offset, const int point_stride,
+ void *normal_buffer, const int normal_offset, const int normal_stride)
+{
+ buffer_apply_offset(&point_buffer, point_offset);
+ buffer_apply_offset(&normal_buffer, normal_offset);
+ const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
+ for (int y = 0; y < resolution; y++) {
+ const float v = y * inv_resolution_1;
+ for (int x = 0; x < resolution; x++) {
+ const float u = x * inv_resolution_1;
+ float normal[3];
+ BKE_subdiv_eval_limit_point_and_normal(
+ subdiv,
+ ptex_face_index,
+ u, v,
+ point_buffer, normal);
+ buffer_write_float_value(&normal_buffer, normal, 3);
+ buffer_apply_offset(&point_buffer, point_stride);
+ buffer_apply_offset(&normal_buffer, normal_stride);
+ }
+ }
+}
+
+void BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal(
+ Subdiv *subdiv,
+ const int ptex_face_index,
+ const int resolution,
+ void *point_buffer, const int point_offset, const int point_stride,
+ void *normal_buffer, const int normal_offset, const int normal_stride)
+{
+ buffer_apply_offset(&point_buffer, point_offset);
+ buffer_apply_offset(&normal_buffer, normal_offset);
+ const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
+ for (int y = 0; y < resolution; y++) {
+ const float v = y * inv_resolution_1;
+ for (int x = 0; x < resolution; x++) {
+ const float u = x * inv_resolution_1;
+ short normal[3];
+ BKE_subdiv_eval_limit_point_and_short_normal(
+ subdiv,
+ ptex_face_index,
+ u, v,
+ point_buffer, normal);
+ buffer_write_short_value(&normal_buffer, normal, 3);
+ buffer_apply_offset(&point_buffer, point_stride);
+ buffer_apply_offset(&normal_buffer, normal_stride);
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
new file mode 100644
index 00000000000..83f2069ea0f
--- /dev/null
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -0,0 +1,952 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/subdiv_mesh.c
+ * \ingroup bke
+ */
+
+#include "BKE_subdiv.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_alloca.h"
+#include "BLI_math_vector.h"
+#include "BLI_task.h"
+
+#include "BKE_mesh.h"
+
+/* TODO(sergey): Somehow move this to subdiv code? */
+static int mpoly_ptex_faces_count_get(const MPoly *mp)
+{
+ if (mp->totloop == 4) {
+ return 1;
+ }
+ else {
+ return mp->totloop;
+ }
+}
+
+static int num_edges_per_ptex_get(const int resolution)
+{
+ return 2 * (resolution - 1) * resolution;
+}
+
+static int num_polys_per_ptex_get(const int resolution)
+{
+ return (resolution - 1) * (resolution - 1);
+}
+
+typedef struct SubdivMeshContext {
+ const Mesh *coarse_mesh;
+ Subdiv *subdiv;
+ Mesh *subdiv_mesh;
+ const SubdivToMeshSettings *settings;
+ /* Cached custom data arrays for fastter access. */
+ int *vert_origindex;
+ int *edge_origindex;
+ int *loop_origindex;
+ int *poly_origindex;
+ /* UV layers interpolation. */
+ int num_uv_layers;
+ MLoopUV *uv_layers[MAX_MTFACE];
+} SubdivMeshContext;
+
+typedef struct LoopsOfPtex {
+ /* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */
+ const MLoop *first_loop;
+ /* Last loop of the ptex, starts at ptex (0, 0) and goes in v direction. */
+ const MLoop *last_loop;
+ /* For quad coarse faces only. */
+ const MLoop *second_loop;
+ const MLoop *third_loop;
+} LoopsOfPtex;
+
+static void loops_of_ptex_get(
+ const SubdivMeshContext *ctx,
+ LoopsOfPtex *loops_of_ptex,
+ const MPoly *coarse_poly,
+ const int ptex_face_index)
+{
+ const MLoop *coarse_mloop = ctx->coarse_mesh->mloop;
+ const int first_ptex_loop_index = coarse_poly->loopstart + ptex_face_index;
+ /* Loop which look in the (opposite) V direction of the current
+ * ptex face.
+ *
+ * TOOD(sergey): Get rid of using module on every iteration.
+ */
+ const int last_ptex_loop_index =
+ coarse_poly->loopstart +
+ (ptex_face_index + coarse_poly->totloop - 1) % coarse_poly->totloop;
+ loops_of_ptex->first_loop = &coarse_mloop[first_ptex_loop_index];
+ loops_of_ptex->last_loop = &coarse_mloop[last_ptex_loop_index];
+ if (coarse_poly->totloop == 4) {
+ loops_of_ptex->second_loop = loops_of_ptex->first_loop + 1;
+ loops_of_ptex->third_loop = loops_of_ptex->first_loop + 2;
+ }
+ else {
+ loops_of_ptex->second_loop = NULL;
+ loops_of_ptex->third_loop = NULL;
+ }
+}
+
+typedef struct EdgesOfPtex {
+ /* First edge of the ptex, starts at ptex (0, 0) and goes in u direction. */
+ const MEdge *first_edge;
+ /* Last edge of the ptex, starts at ptex (0, 0) and goes in v direction. */
+ const MEdge *last_edge;
+ /* For quad coarse faces only. */
+ const MEdge *second_edge;
+ const MEdge *third_edge;
+} EdgesOfPtex;
+
+static void edges_of_ptex_get(
+ const SubdivMeshContext *ctx,
+ EdgesOfPtex *edges_of_ptex,
+ const MPoly *coarse_poly,
+ const int ptex_face_index)
+{
+ const MEdge *coarse_medge = ctx->coarse_mesh->medge;
+ LoopsOfPtex loops_of_ptex;
+ loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, ptex_face_index);
+ edges_of_ptex->first_edge = &coarse_medge[loops_of_ptex.first_loop->e];
+ edges_of_ptex->last_edge = &coarse_medge[loops_of_ptex.last_loop->e];
+ if (coarse_poly->totloop == 4) {
+ edges_of_ptex->second_edge =
+ &coarse_medge[loops_of_ptex.second_loop->e];
+ edges_of_ptex->third_edge =
+ &coarse_medge[loops_of_ptex.third_loop->e];
+ }
+ else {
+ edges_of_ptex->second_edge = NULL;
+ edges_of_ptex->third_edge = NULL;
+ }
+}
+
+/* TODO(sergey): Somehow de-duplicate with loops storage, without too much
+ * exception cases all over the code.
+ */
+
+typedef struct VerticesForInterpolation {
+ /* This field points to a vertex data which is to be used for interpolation.
+ * The idea is to avoid unnecessary allocations for regular faces, where
+ * we can simply
+ */
+ const CustomData *vertex_data;
+ /* Vertices data calculated for ptex corners. There are always 4 elements
+ * in this custom data, aligned the following way:
+ *
+ * index 0 -> uv (0, 0)
+ * index 1 -> uv (0, 1)
+ * index 2 -> uv (1, 1)
+ * index 3 -> uv (1, 0)
+ *
+ * Is allocated for non-regular faces (triangles and n-gons).
+ */
+ CustomData vertex_data_storage;
+ bool vertex_data_storage_allocated;
+ /* Infices within vertex_data to interpolate for. The indices are aligned
+ * with uv coordinates in a similar way as indices in loop_data_storage.
+ */
+ int vertex_indices[4];
+} VerticesForInterpolation;
+
+static void vertex_interpolation_init(
+ const SubdivMeshContext *ctx,
+ VerticesForInterpolation *vertex_interpolation,
+ const MPoly *coarse_poly)
+{
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MLoop *coarse_mloop = coarse_mesh->mloop;
+ if (coarse_poly->totloop == 4) {
+ vertex_interpolation->vertex_data = &coarse_mesh->vdata;
+ vertex_interpolation->vertex_indices[0] =
+ coarse_mloop[coarse_poly->loopstart + 0].v;
+ vertex_interpolation->vertex_indices[1] =
+ coarse_mloop[coarse_poly->loopstart + 1].v;
+ vertex_interpolation->vertex_indices[2] =
+ coarse_mloop[coarse_poly->loopstart + 2].v;
+ vertex_interpolation->vertex_indices[3] =
+ coarse_mloop[coarse_poly->loopstart + 3].v;
+ vertex_interpolation->vertex_data_storage_allocated = false;
+ }
+ else {
+ vertex_interpolation->vertex_data =
+ &vertex_interpolation->vertex_data_storage;
+ /* Allocate storage for loops corresponding to ptex corners. */
+ CustomData_copy(&ctx->coarse_mesh->vdata,
+ &vertex_interpolation->vertex_data_storage,
+ CD_MASK_EVERYTHING,
+ CD_CALLOC,
+ 4);
+ /* Initialize indices. */
+ vertex_interpolation->vertex_indices[0] = 0;
+ vertex_interpolation->vertex_indices[1] = 1;
+ vertex_interpolation->vertex_indices[2] = 2;
+ vertex_interpolation->vertex_indices[3] = 3;
+ vertex_interpolation->vertex_data_storage_allocated = true;
+ /* Interpolate center of poly right away, it stays unchanged for all
+ * ptex faces.
+ */
+ const float weight = 1.0f / (float)coarse_poly->totloop;
+ float *weights = BLI_array_alloca(weights, coarse_poly->totloop);
+ int *indices = BLI_array_alloca(indices, coarse_poly->totloop);
+ for (int i = 0; i < coarse_poly->totloop; ++i) {
+ weights[i] = weight;
+ indices[i] = coarse_poly->loopstart + i;
+ }
+ CustomData_interp(&coarse_mesh->vdata,
+ &vertex_interpolation->vertex_data_storage,
+ indices,
+ weights, NULL,
+ coarse_poly->totloop,
+ 2);
+ }
+}
+
+static void vertex_interpolation_from_ptex(
+ const SubdivMeshContext *ctx,
+ VerticesForInterpolation *vertex_interpolation,
+ const MPoly *coarse_poly,
+ const int ptex_face_index)
+{
+ if (coarse_poly->totloop == 4) {
+ /* Nothing to do, all indices and data is already assigned. */
+ }
+ else {
+ const CustomData *vertex_data = &ctx->coarse_mesh->vdata;
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MLoop *coarse_mloop = coarse_mesh->mloop;
+ LoopsOfPtex loops_of_ptex;
+ loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, ptex_face_index);
+ /* Ptex face corner corresponds to a poly loop with same index. */
+ CustomData_copy_data(
+ vertex_data,
+ &vertex_interpolation->vertex_data_storage,
+ coarse_mloop[coarse_poly->loopstart + ptex_face_index].v,
+ 0,
+ 1);
+ /* Interpolate remaining ptex face corners, which hits loops
+ * middle points.
+ *
+ * TODO(sergey): Re-use one of interpolation results from previous
+ * iteration.
+ */
+ const float weights[2] = {0.5f, 0.5f};
+ const int first_indices[2] = {
+ coarse_mloop[loops_of_ptex.first_loop - coarse_mloop].v,
+ coarse_mloop[(loops_of_ptex.first_loop + 1 - coarse_mloop) %
+ coarse_poly->totloop].v};
+ const int last_indices[2] = {
+ coarse_mloop[loops_of_ptex.last_loop - coarse_mloop].v,
+ coarse_mloop[loops_of_ptex.first_loop - coarse_mloop].v};
+ CustomData_interp(vertex_data,
+ &vertex_interpolation->vertex_data_storage,
+ first_indices,
+ weights, NULL,
+ 2,
+ 1);
+ CustomData_interp(vertex_data,
+ &vertex_interpolation->vertex_data_storage,
+ last_indices,
+ weights, NULL,
+ 2,
+ 3);
+ }
+}
+
+static void vertex_interpolation_end(
+ VerticesForInterpolation *vertex_interpolation)
+{
+ if (vertex_interpolation->vertex_data_storage_allocated) {
+ CustomData_free(&vertex_interpolation->vertex_data_storage, 4);
+ }
+}
+
+typedef struct LoopsForInterpolation {
+ /* This field points to a loop data which is to be used for interpolation.
+ * The idea is to avoid unnecessary allocations for regular faces, where
+ * we can simply
+ */
+ const CustomData *loop_data;
+ /* Loops data calculated for ptex corners. There are always 4 elements
+ * in this custom data, aligned the following way:
+ *
+ * index 0 -> uv (0, 0)
+ * index 1 -> uv (0, 1)
+ * index 2 -> uv (1, 1)
+ * index 3 -> uv (1, 0)
+ *
+ * Is allocated for non-regular faces (triangles and n-gons).
+ */
+ CustomData loop_data_storage;
+ bool loop_data_storage_allocated;
+ /* Infices within loop_data to interpolate for. The indices are aligned with
+ * uv coordinates in a similar way as indices in loop_data_storage.
+ */
+ int loop_indices[4];
+} LoopsForInterpolation;
+
+static void loop_interpolation_init(
+ const SubdivMeshContext *ctx,
+ LoopsForInterpolation *loop_interpolation,
+ const MPoly *coarse_poly)
+{
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ if (coarse_poly->totloop == 4) {
+ loop_interpolation->loop_data = &coarse_mesh->ldata;
+ loop_interpolation->loop_indices[0] = coarse_poly->loopstart + 0;
+ loop_interpolation->loop_indices[1] = coarse_poly->loopstart + 1;
+ loop_interpolation->loop_indices[2] = coarse_poly->loopstart + 2;
+ loop_interpolation->loop_indices[3] = coarse_poly->loopstart + 3;
+ loop_interpolation->loop_data_storage_allocated = false;
+ }
+ else {
+ loop_interpolation->loop_data = &loop_interpolation->loop_data_storage;
+ /* Allocate storage for loops corresponding to ptex corners. */
+ CustomData_copy(&ctx->coarse_mesh->ldata,
+ &loop_interpolation->loop_data_storage,
+ CD_MASK_EVERYTHING,
+ CD_CALLOC,
+ 4);
+ /* Initialize indices. */
+ loop_interpolation->loop_indices[0] = 0;
+ loop_interpolation->loop_indices[1] = 1;
+ loop_interpolation->loop_indices[2] = 2;
+ loop_interpolation->loop_indices[3] = 3;
+ loop_interpolation->loop_data_storage_allocated = true;
+ /* Interpolate center of poly right away, it stays unchanged for all
+ * ptex faces.
+ */
+ const float weight = 1.0f / (float)coarse_poly->totloop;
+ float *weights = BLI_array_alloca(weights, coarse_poly->totloop);
+ int *indices = BLI_array_alloca(indices, coarse_poly->totloop);
+ for (int i = 0; i < coarse_poly->totloop; ++i) {
+ weights[i] = weight;
+ indices[i] = coarse_poly->loopstart + i;
+ }
+ CustomData_interp(&coarse_mesh->ldata,
+ &loop_interpolation->loop_data_storage,
+ indices,
+ weights, NULL,
+ coarse_poly->totloop,
+ 2);
+ }
+}
+
+static void loop_interpolation_from_ptex(
+ const SubdivMeshContext *ctx,
+ LoopsForInterpolation *loop_interpolation,
+ const MPoly *coarse_poly,
+ const int ptex_face_index)
+{
+ if (coarse_poly->totloop == 4) {
+ /* Nothing to do, all indices and data is already assigned. */
+ }
+ else {
+ const CustomData *loop_data = &ctx->coarse_mesh->ldata;
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MLoop *coarse_mloop = coarse_mesh->mloop;
+ LoopsOfPtex loops_of_ptex;
+ loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, ptex_face_index);
+ /* Ptex face corner corresponds to a poly loop with same index. */
+ CustomData_copy_data(loop_data,
+ &loop_interpolation->loop_data_storage,
+ coarse_poly->loopstart + ptex_face_index,
+ 0,
+ 1);
+ /* Interpolate remaining ptex face corners, which hits loops
+ * middle points.
+ *
+ * TODO(sergey): Re-use one of interpolation results from previous
+ * iteration.
+ */
+ const float weights[2] = {0.5f, 0.5f};
+ const int first_indices[2] = {
+ loops_of_ptex.first_loop - coarse_mloop,
+ (loops_of_ptex.first_loop + 1 - coarse_mloop) %
+ coarse_poly->totloop};
+ const int last_indices[2] = {
+ loops_of_ptex.last_loop - coarse_mloop,
+ loops_of_ptex.first_loop - coarse_mloop};
+ CustomData_interp(loop_data,
+ &loop_interpolation->loop_data_storage,
+ first_indices,
+ weights, NULL,
+ 2,
+ 1);
+ CustomData_interp(loop_data,
+ &loop_interpolation->loop_data_storage,
+ last_indices,
+ weights, NULL,
+ 2,
+ 3);
+ }
+}
+
+static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation)
+{
+ if (loop_interpolation->loop_data_storage_allocated) {
+ CustomData_free(&loop_interpolation->loop_data_storage, 4);
+ }
+}
+
+static void subdiv_copy_vertex_data(
+ const SubdivMeshContext *ctx,
+ MVert *subdiv_vertex,
+ const Mesh *coarse_mesh,
+ const MPoly *coarse_poly,
+ const VerticesForInterpolation *vertex_interpolation,
+ const int ptex_of_poly_index,
+ const float u, const float v)
+{
+ const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert;
+ const float weights[4] = {(1.0f - u) * (1.0f - v),
+ u * (1.0f - v),
+ u * v,
+ (1.0f - u) * v};
+ CustomData_interp(vertex_interpolation->vertex_data,
+ &ctx->subdiv_mesh->vdata,
+ vertex_interpolation->vertex_indices,
+ weights, NULL,
+ 4,
+ subdiv_vertex_index);
+ if (ctx->vert_origindex != NULL) {
+ ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
+ if (coarse_poly->totloop == 4) {
+ if (u == 0.0f && v == 0.0f) {
+ ctx->vert_origindex[subdiv_vertex_index] =
+ vertex_interpolation->vertex_indices[0];
+ }
+ else if (u == 1.0f && v == 0.0f) {
+ ctx->vert_origindex[subdiv_vertex_index] =
+ vertex_interpolation->vertex_indices[1];
+ }
+ else if (u == 1.0f && v == 1.0f) {
+ ctx->vert_origindex[subdiv_vertex_index] =
+ vertex_interpolation->vertex_indices[2];
+ }
+ else if (u == 0.0f && v == 1.0f) {
+ ctx->vert_origindex[subdiv_vertex_index] =
+ vertex_interpolation->vertex_indices[3];
+ }
+ } else {
+ if (u == 0.0f && v == 0.0f) {
+ const MLoop *coarse_mloop = coarse_mesh->mloop;
+ ctx->vert_origindex[subdiv_vertex_index] =
+ coarse_mloop[coarse_poly->loopstart +
+ ptex_of_poly_index].v;
+ }
+ }
+ }
+}
+
+static void subdiv_evaluate_vertices(SubdivMeshContext *ctx,
+ const int poly_index)
+{
+ Subdiv *subdiv = ctx->subdiv;
+ const int resolution = ctx->settings->resolution;
+ const int resolution2 = resolution * resolution;
+ const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
+ /* Base/coarse mesh information. */
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_polyoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_polyoly[poly_index];
+ const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly);
+ /* Hi-poly subdivided mesh. */
+ Mesh *subdiv_mesh = ctx->subdiv_mesh;
+ MVert *subdiv_vertex = subdiv_mesh->mvert;
+ const int ptex_face_index = subdiv->face_ptex_offset[poly_index];
+ /* Actual evaluation. */
+ VerticesForInterpolation vertex_interpolation;
+ vertex_interpolation_init(ctx, &vertex_interpolation, coarse_poly);
+ MVert *subdiv_vert = &subdiv_vertex[ptex_face_index * resolution2];
+ for (int ptex_of_poly_index = 0;
+ ptex_of_poly_index < num_poly_ptex_faces;
+ ptex_of_poly_index++)
+ {
+ vertex_interpolation_from_ptex(ctx,
+ &vertex_interpolation,
+ coarse_poly,
+ ptex_of_poly_index);
+ const int current_ptex_face_index =
+ ptex_face_index + ptex_of_poly_index;
+ BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal(
+ subdiv,
+ current_ptex_face_index,
+ resolution,
+ subdiv_vert, offsetof(MVert, co), sizeof(MVert),
+ subdiv_vert, offsetof(MVert, no), sizeof(MVert));
+ for (int y = 0; y < resolution; y++) {
+ const float v = y * inv_resolution_1;
+ for (int x = 0; x < resolution; x++, subdiv_vert++) {
+ const float u = x * inv_resolution_1;
+ subdiv_copy_vertex_data(ctx,
+ subdiv_vert,
+ coarse_mesh,
+ coarse_poly,
+ &vertex_interpolation,
+ ptex_of_poly_index,
+ u, v);
+ }
+ }
+ }
+ vertex_interpolation_end(&vertex_interpolation);
+}
+
+static void subdiv_copy_edge_data(
+ SubdivMeshContext *ctx,
+ MEdge *subdiv_edge,
+ const MEdge *coarse_edge)
+{
+ const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge;
+ if (coarse_edge == NULL) {
+ subdiv_edge->crease = 0;
+ subdiv_edge->bweight = 0;
+ subdiv_edge->flag = 0;
+ if (ctx->edge_origindex != NULL) {
+ ctx->edge_origindex[subdiv_edge_index] = ORIGINDEX_NONE;
+ }
+ return;
+ }
+ const int coarse_edge_index = coarse_edge - ctx->coarse_mesh->medge;
+ CustomData_copy_data(&ctx->coarse_mesh->edata,
+ &ctx->subdiv_mesh->edata,
+ coarse_edge_index,
+ subdiv_edge_index,
+ 1);
+ if (ctx->edge_origindex != NULL) {
+ ctx->edge_origindex[subdiv_edge_index] = coarse_edge_index;
+ }
+}
+
+static MEdge *subdiv_create_edges_row(SubdivMeshContext *ctx,
+ MEdge *subdiv_edge,
+ const MEdge *coarse_edge,
+ const int start_vertex_index,
+ const int resolution)
+{
+ int vertex_index = start_vertex_index;
+ for (int edge_index = 0;
+ edge_index < resolution - 1;
+ edge_index++, subdiv_edge++)
+ {
+ subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge);
+ subdiv_edge->v1 = vertex_index;
+ subdiv_edge->v2 = vertex_index + 1;
+ vertex_index += 1;
+ }
+ return subdiv_edge;
+}
+
+static MEdge *subdiv_create_edges_column(SubdivMeshContext *ctx,
+ MEdge *subdiv_edge,
+ const MEdge *coarse_start_edge,
+ const MEdge *coarse_end_edge,
+ const int start_vertex_index,
+ const int resolution)
+{
+ int vertex_index = start_vertex_index;
+ for (int edge_index = 0;
+ edge_index < resolution;
+ edge_index++, subdiv_edge++)
+ {
+ const MEdge *coarse_edge = NULL;
+ if (edge_index == 0) {
+ coarse_edge = coarse_start_edge;
+ }
+ else if (edge_index == resolution - 1) {
+ coarse_edge = coarse_end_edge;
+ }
+ subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge);
+ subdiv_edge->v1 = vertex_index;
+ subdiv_edge->v2 = vertex_index + resolution;
+ vertex_index += 1;
+ }
+ return subdiv_edge;
+}
+
+static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index)
+{
+ Subdiv *subdiv = ctx->subdiv;
+ const int resolution = ctx->settings->resolution;
+ const int resolution2 = resolution * resolution;
+ const int ptex_face_index = subdiv->face_ptex_offset[poly_index];
+ const int num_edges_per_ptex = num_edges_per_ptex_get(resolution);
+ const int start_edge_index = ptex_face_index * num_edges_per_ptex;
+ /* Base/coarse mesh information. */
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_polyoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_polyoly[poly_index];
+ const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly);
+ /* Hi-poly subdivided mesh. */
+ Mesh *subdiv_mesh = ctx->subdiv_mesh;
+ MEdge *subdiv_medge = subdiv_mesh->medge;
+ MEdge *subdiv_edge = &subdiv_medge[start_edge_index];
+ const int start_poly_vertex_index = ptex_face_index * resolution2;
+ /* Consider a subdivision of base face at level 1:
+ *
+ * y
+ * ^
+ * | (6) ---- (7) ---- (8)
+ * | | | |
+ * | (3) ---- (4) ---- (5)
+ * | | | |
+ * | (0) ---- (1) ---- (2)
+ * o---------------------------> x
+ *
+ * This is illustrate which parts of geometry is created by code below.
+ */
+ for (int i = 0; i < num_poly_ptex_faces; i++) {
+ const int start_ptex_face_vertex_index =
+ start_poly_vertex_index + i * resolution2;
+ EdgesOfPtex edges_of_ptex;
+ edges_of_ptex_get(ctx, &edges_of_ptex, coarse_poly, i);
+ /* Create bottom row of edges (0-1, 1-2). */
+ subdiv_edge = subdiv_create_edges_row(
+ ctx,
+ subdiv_edge,
+ edges_of_ptex.first_edge,
+ start_ptex_face_vertex_index,
+ resolution);
+ /* Create remaining edges. */
+ for (int row = 0; row < resolution - 1; row++) {
+ const int start_row_vertex_index =
+ start_ptex_face_vertex_index + row * resolution;
+ /* Create vertical columns.
+ *
+ * At first iteration it will be edges (0-3. 1-4, 2-5), then it
+ * will be (3-6, 4-7, 5-8) and so on.
+ */
+ subdiv_edge = subdiv_create_edges_column(
+ ctx,
+ subdiv_edge,
+ edges_of_ptex.last_edge,
+ edges_of_ptex.second_edge,
+ start_row_vertex_index,
+ resolution);
+ /* Create horizontal edge row.
+ *
+ * At first iteration it will be edges (3-4, 4-5), then it will be
+ * (6-7, 7-8) and so on.
+ */
+ subdiv_edge = subdiv_create_edges_row(
+ ctx,
+ subdiv_edge,
+ (row == resolution - 2) ? edges_of_ptex.third_edge
+ : NULL,
+ start_row_vertex_index + resolution,
+ resolution);
+ }
+ }
+}
+
+static void subdiv_copy_loop_data(
+ const SubdivMeshContext *ctx,
+ MLoop *subdiv_loop,
+ const LoopsForInterpolation *loop_interpolation,
+ const float u, const float v)
+{
+ const int subdiv_loop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
+ const float weights[4] = {(1.0f - u) * (1.0f - v),
+ u * (1.0f - v),
+ u * v,
+ (1.0f - u) * v};
+ CustomData_interp(loop_interpolation->loop_data,
+ &ctx->subdiv_mesh->ldata,
+ loop_interpolation->loop_indices,
+ weights, NULL,
+ 4,
+ subdiv_loop_index);
+ /* TODO(sergey): Set ORIGINDEX. */
+}
+
+static void subdiv_eval_uv_layer(SubdivMeshContext *ctx,
+ MLoop *subdiv_loop,
+ const int ptex_face_index,
+ const float u, const float v,
+ const float inv_resolution_1)
+{
+ if (ctx->num_uv_layers == 0) {
+ return;
+ }
+ Subdiv *subdiv = ctx->subdiv;
+ const int mloop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
+ const float du = inv_resolution_1;
+ const float dv = inv_resolution_1;
+ for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
+ MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index];
+ BKE_subdiv_eval_face_varying(subdiv,
+ ptex_face_index,
+ u, v,
+ subdiv_loopuv[0].uv);
+ BKE_subdiv_eval_face_varying(subdiv,
+ ptex_face_index,
+ u + du, v,
+ subdiv_loopuv[1].uv);
+ BKE_subdiv_eval_face_varying(subdiv,
+ ptex_face_index,
+ u + du, v + dv,
+ subdiv_loopuv[2].uv);
+ BKE_subdiv_eval_face_varying(subdiv,
+ ptex_face_index,
+ u, v + dv,
+ subdiv_loopuv[3].uv);
+ /* TODO(sergey): Currently evaluator only has single UV layer, so can
+ * not evaluate more than that. Need to be solved.
+ */
+ break;
+ }
+}
+
+static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index)
+{
+ Subdiv *subdiv = ctx->subdiv;
+ const int resolution = ctx->settings->resolution;
+ const int resolution2 = resolution * resolution;
+ const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
+ const int ptex_face_index = subdiv->face_ptex_offset[poly_index];
+ const int num_edges_per_ptex = num_edges_per_ptex_get(resolution);
+ const int start_edge_index = ptex_face_index * num_edges_per_ptex;
+ const int num_polys_per_ptex = num_polys_per_ptex_get(resolution);
+ const int start_poly_index = ptex_face_index * num_polys_per_ptex;
+ const int start_loop_index = 4 * start_poly_index;
+ const int start_vert_index = ptex_face_index * resolution2;
+ const float du = inv_resolution_1;
+ const float dv = inv_resolution_1;
+ /* Base/coarse mesh information. */
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_polyoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_polyoly[poly_index];
+ const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly);
+ /* Hi-poly subdivided mesh. */
+ Mesh *subdiv_mesh = ctx->subdiv_mesh;
+ MLoop *subdiv_loopoop = subdiv_mesh->mloop;
+ MLoop *subdiv_loop = &subdiv_loopoop[start_loop_index];
+ LoopsForInterpolation loop_interpolation;
+ loop_interpolation_init(ctx, &loop_interpolation, coarse_poly);
+ for (int ptex_of_poly_index = 0;
+ ptex_of_poly_index < num_poly_ptex_faces;
+ ptex_of_poly_index++)
+ {
+ loop_interpolation_from_ptex(ctx,
+ &loop_interpolation,
+ coarse_poly,
+ ptex_of_poly_index);
+ const int current_ptex_face_index =
+ ptex_face_index + ptex_of_poly_index;
+ for (int y = 0; y < resolution - 1; y++) {
+ const float v = y * inv_resolution_1;
+ for (int x = 0; x < resolution - 1; x++, subdiv_loop += 4) {
+ const float u = x * inv_resolution_1;
+ /* Vertex indicies ordered counter-clockwise. */
+ const int v0 = start_vert_index +
+ (ptex_of_poly_index * resolution2) +
+ (y * resolution + x);
+ const int v1 = v0 + 1;
+ const int v2 = v0 + resolution + 1;
+ const int v3 = v0 + resolution;
+ /* Edge indicies ordered counter-clockwise. */
+ const int e0 = start_edge_index +
+ (ptex_of_poly_index * num_edges_per_ptex) +
+ (y * (2 * resolution - 1) + x);
+ const int e1 = e0 + resolution;
+ const int e2 = e0 + (2 * resolution - 1);
+ const int e3 = e0 + resolution - 1;
+ /* Initialize 4 loops of corresponding hi-poly poly. */
+ /* TODO(sergey): For ptex boundaries we should use loops from
+ * coarse mesh.
+ */
+ subdiv_copy_loop_data(ctx,
+ &subdiv_loop[0],
+ &loop_interpolation,
+ u, v);
+ subdiv_loop[0].v = v0;
+ subdiv_loop[0].e = e0;
+ subdiv_copy_loop_data(ctx,
+ &subdiv_loop[1],
+ &loop_interpolation,
+ u + du, v);
+ subdiv_loop[1].v = v1;
+ subdiv_loop[1].e = e1;
+ subdiv_copy_loop_data(ctx,
+ &subdiv_loop[2],
+ &loop_interpolation,
+ u + du, v + dv);
+ subdiv_loop[2].v = v2;
+ subdiv_loop[2].e = e2;
+ subdiv_copy_loop_data(ctx,
+ &subdiv_loop[3],
+ &loop_interpolation,
+ u, v + dv);
+ subdiv_loop[3].v = v3;
+ subdiv_loop[3].e = e3;
+ /* Interpolate UV layers using OpenSubdiv. */
+ subdiv_eval_uv_layer(ctx,
+ subdiv_loop,
+ current_ptex_face_index,
+ u, v,
+ inv_resolution_1);
+ }
+ }
+ }
+ loop_interpolation_end(&loop_interpolation);
+}
+
+static void subdiv_copy_poly_data(const SubdivMeshContext *ctx,
+ MPoly *subdiv_poly,
+ const MPoly *coarse_poly)
+{
+ const int coarse_poly_index = coarse_poly - ctx->coarse_mesh->mpoly;
+ const int subdiv_poly_index = subdiv_poly - ctx->subdiv_mesh->mpoly;
+ CustomData_copy_data(&ctx->coarse_mesh->pdata,
+ &ctx->subdiv_mesh->pdata,
+ coarse_poly_index,
+ subdiv_poly_index,
+ 1);
+ if (ctx->poly_origindex != NULL) {
+ ctx->poly_origindex[subdiv_poly_index] = coarse_poly_index;
+ }
+}
+
+static void subdiv_create_polys(SubdivMeshContext *ctx, int poly_index)
+{
+ Subdiv *subdiv = ctx->subdiv;
+ const int resolution = ctx->settings->resolution;
+ const int ptex_face_index = subdiv->face_ptex_offset[poly_index];
+ const int num_polys_per_ptex = num_polys_per_ptex_get(resolution);
+ const int num_loops_per_ptex = 4 * num_polys_per_ptex;
+ const int start_poly_index = ptex_face_index * num_polys_per_ptex;
+ const int start_loop_index = 4 * start_poly_index;
+ /* Base/coarse mesh information. */
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_polyoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_polyoly[poly_index];
+ const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly);
+ /* Hi-poly subdivided mesh. */
+ Mesh *subdiv_mesh = ctx->subdiv_mesh;
+ MPoly *subdiv_mpoly = subdiv_mesh->mpoly;
+ MPoly *subdiv_mp = &subdiv_mpoly[start_poly_index];
+ for (int ptex_of_poly_index = 0;
+ ptex_of_poly_index < num_poly_ptex_faces;
+ ptex_of_poly_index++)
+ {
+ for (int subdiv_poly_index = 0;
+ subdiv_poly_index < num_polys_per_ptex;
+ subdiv_poly_index++, subdiv_mp++)
+ {
+ subdiv_copy_poly_data(ctx, subdiv_mp, coarse_poly);
+ subdiv_mp->loopstart = start_loop_index +
+ (ptex_of_poly_index * num_loops_per_ptex) +
+ (subdiv_poly_index * 4);
+ subdiv_mp->totloop = 4;
+ }
+ }
+}
+
+static void subdiv_eval_task(
+ void *__restrict userdata,
+ const int poly_index,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
+{
+ SubdivMeshContext *data = userdata;
+ /* Evaluate hi-poly vertex coordinates and normals. */
+ subdiv_evaluate_vertices(data, poly_index);
+ /* Create mesh geometry for the given base poly index. */
+ subdiv_create_edges(data, poly_index);
+ subdiv_create_loops(data, poly_index);
+ subdiv_create_polys(data, poly_index);
+}
+
+static void cache_uv_layers(SubdivMeshContext *ctx)
+{
+ Mesh *subdiv_mesh = ctx->subdiv_mesh;
+ ctx->num_uv_layers =
+ CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV);
+ for (int layer_index = 0; layer_index < ctx->num_uv_layers; ++layer_index) {
+ ctx->uv_layers[layer_index] = CustomData_get_layer_n(
+ &subdiv_mesh->ldata, CD_MLOOPUV, layer_index);
+ }
+}
+
+static void cache_custom_data_layers(SubdivMeshContext *ctx)
+{
+ Mesh *subdiv_mesh = ctx->subdiv_mesh;
+ /* Pointers to original indices layers. */
+ ctx->vert_origindex = CustomData_get_layer(
+ &subdiv_mesh->vdata, CD_ORIGINDEX);
+ ctx->edge_origindex = CustomData_get_layer(
+ &subdiv_mesh->edata, CD_ORIGINDEX);
+ ctx->loop_origindex = CustomData_get_layer(
+ &subdiv_mesh->ldata, CD_ORIGINDEX);
+ ctx->poly_origindex = CustomData_get_layer(
+ &subdiv_mesh->pdata, CD_ORIGINDEX);
+ /* UV layers interpolation. */
+ cache_uv_layers(ctx);
+}
+
+Mesh *BKE_subdiv_to_mesh(
+ Subdiv *subdiv,
+ const SubdivToMeshSettings *settings,
+ const Mesh *coarse_mesh)
+{
+ BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
+ /* Make sure evaluator is up to date with possible new topology, and that
+ * is is refined for the new positions of coarse vertices.
+ */
+ BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh);
+ const int resolution = settings->resolution;
+ const int resolution2 = resolution * resolution;
+ const int num_result_verts = subdiv->num_ptex_faces * resolution2;
+ const int num_result_edges =
+ subdiv->num_ptex_faces * num_edges_per_ptex_get(resolution);
+ const int num_result_polys =
+ subdiv->num_ptex_faces * num_polys_per_ptex_get(resolution);
+ const int num_result_loops = 4 * num_result_polys;
+ /* Create mesh and its arrays. */
+ Mesh *result = BKE_mesh_new_nomain_from_template(
+ coarse_mesh,
+ num_result_verts,
+ num_result_edges,
+ 0,
+ num_result_loops,
+ num_result_polys);
+ /* Evaluate subdivisions of base faces in threads. */
+ SubdivMeshContext ctx;
+ ctx.coarse_mesh = coarse_mesh;
+ ctx.subdiv = subdiv;
+ ctx.subdiv_mesh = result;
+ ctx.settings = settings;
+ cache_custom_data_layers(&ctx);
+ /* Multi-threaded evaluation. */
+ ParallelRangeSettings parallel_range_settings;
+ BLI_parallel_range_settings_defaults(&parallel_range_settings);
+ BLI_task_parallel_range(0, coarse_mesh->totpoly,
+ &ctx,
+ subdiv_eval_task,
+ &parallel_range_settings);
+ BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
+ return result;
+}
diff --git a/source/blender/blenkernel/intern/subdiv_stats.c b/source/blender/blenkernel/intern/subdiv_stats.c
new file mode 100644
index 00000000000..5da63fdbacb
--- /dev/null
+++ b/source/blender/blenkernel/intern/subdiv_stats.c
@@ -0,0 +1,80 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/subdiv_stats.c
+ * \ingroup bke
+ */
+
+#include "BKE_subdiv.h"
+
+#include <stdio.h>
+
+#include "PIL_time.h"
+
+void BKE_subdiv_stats_init(SubdivStats *stats)
+{
+ stats->topology_refiner_creation_time = 0.0;
+ stats->subdiv_to_mesh_time = 0.0;
+ stats->evaluator_creation_time = 0.0;
+ stats->evaluator_refine_time = 0.0;
+}
+
+void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value)
+{
+ stats->begin_timestamp_[value] = PIL_check_seconds_timer();
+}
+
+void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value)
+{
+ stats->values_[value] =
+ PIL_check_seconds_timer() - stats->begin_timestamp_[value];
+}
+
+void BKE_subdiv_stats_print(const SubdivStats *stats)
+{
+#define STATS_PRINT_TIME(stats, value, description) \
+ do { \
+ if ((stats)->value > 0.0) { \
+ printf(" %s: %f (sec)\n", description, (stats)->value); \
+ } \
+ } while (false)
+
+ printf("Subdivision surface statistics:\n");
+
+ STATS_PRINT_TIME(stats,
+ topology_refiner_creation_time,
+ "Topology refiner creation time");
+ STATS_PRINT_TIME(stats,
+ subdiv_to_mesh_time,
+ "Subdivision to mesh time");
+ STATS_PRINT_TIME(stats,
+ evaluator_creation_time,
+ "Evaluator creation time");
+ STATS_PRINT_TIME(stats,
+ evaluator_refine_time,
+ "Evaluator refine time");
+
+#undef STATS_PRINT_TIME
+}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 9ea6ef62e4e..cead75ae659 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -280,11 +280,11 @@ static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mpoly, struct ML
for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v = v->next) {
if (v->separate)
nv = v;
- if (v->f == fi)
+ if (v->poly_index == fi)
break;
}
- fverts[j] = SET_UINT_IN_POINTER(mpoly[nv->f].loopstart + nv->tfindex);
+ fverts[j] = SET_UINT_IN_POINTER(mpoly[nv->poly_index].loopstart + nv->loop_of_poly_index);
}
}
@@ -292,7 +292,6 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
{
MPoly *mpoly = dm->getPolyArray(dm);
MLoop *mloop = dm->getLoopArray(dm);
- MVert *mvert = dm->getVertArray(dm);
int totvert = dm->getNumVerts(dm);
int totface = dm->getNumPolys(dm);
int i, seam;
@@ -304,13 +303,12 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
BLI_array_declare(fverts);
#endif
EdgeSet *eset;
- float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */
limit[0] = limit[1] = STD_UV_CONNECT_LIMIT;
/* previous behavior here is without accounting for winding, however this causes stretching in
* UV map in really simple cases with mirror + subsurf, see second part of T44530. Also, initially
- * intention is to treat merged vertices from mirror modifier as seams, see code below with ME_VERT_MERGED
+ * intention is to treat merged vertices from mirror modifier as seams.
* This fixes a very old regression (2.49 was correct here) */
vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true);
if (!vmap)
@@ -327,12 +325,12 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
if (v->separate)
break;
- seam = (v != NULL) || ((mvert + i)->flag & ME_VERT_MERGED);
+ seam = (v != NULL);
for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) {
if (v->separate) {
CCGVert *ssv;
- int loopid = mpoly[v->f].loopstart + v->tfindex;
+ int loopid = mpoly[v->poly_index].loopstart + v->loop_of_poly_index;
CCGVertHDL vhdl = SET_INT_IN_POINTER(loopid);
copy_v2_v2(uv, mloopuv[loopid].uv);
@@ -365,18 +363,11 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) {
unsigned int v0 = GET_UINT_FROM_POINTER(fverts[j_next]);
unsigned int v1 = GET_UINT_FROM_POINTER(fverts[j]);
- MVert *mv0 = mvert + (ml[j_next].v);
- MVert *mv1 = mvert + (ml[j].v);
if (BLI_edgeset_add(eset, v0, v1)) {
CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next);
CCGEdgeHDL ehdl = SET_INT_IN_POINTER(mp->loopstart + j_next);
- float crease;
-
- if ((mv0->flag & mv1->flag) & ME_VERT_MERGED)
- crease = creaseFactor;
- else
- crease = ccgSubSurf_getEdgeCrease(orige);
+ float crease = ccgSubSurf_getEdgeCrease(orige);
ccgSubSurf_syncEdge(ss, ehdl, fverts[j_next], fverts[j], crease, &e);
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index ad60e81fe19..c5a208e3aca 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -233,7 +233,6 @@ void BKE_texture_default(Tex *tex)
tex->texfilter = TXF_EWA;
tex->afmax = 8;
tex->xrepeat = tex->yrepeat = 1;
- tex->fie_ima = 2;
tex->sfra = 1;
tex->frames = 0;
tex->offset = 0;
@@ -267,7 +266,6 @@ void BKE_texture_default(Tex *tex)
tex->vn_distm = 0;
tex->vn_coltype = 0;
- tex->iuser.fie_ima = 2;
tex->iuser.ok = 1;
tex->iuser.frames = 100;
tex->iuser.sfra = 1;
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index f0f57e8e56c..a5e93c8d765 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -157,7 +157,6 @@ WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
void BKE_workspace_free(WorkSpace *workspace)
{
BKE_workspace_relations_free(&workspace->hook_layout_relations);
- BLI_freelistN(&workspace->scene_layer_relations);
BLI_freelistN(&workspace->owner_ids);
BLI_freelistN(&workspace->layouts);
@@ -166,10 +165,10 @@ void BKE_workspace_free(WorkSpace *workspace)
tref_next = tref->next;
if (tref->runtime) {
MEM_freeN(tref->runtime);
- if (tref->properties) {
- IDP_FreeProperty(tref->properties);
- MEM_freeN(tref->properties);
- }
+ }
+ if (tref->properties) {
+ IDP_FreeProperty(tref->properties);
+ MEM_freeN(tref->properties);
}
}
BLI_freelistN(&workspace->tools);
@@ -267,48 +266,9 @@ void BKE_workspace_relations_free(
}
}
-void BKE_workspace_scene_relations_free_invalid(
- WorkSpace *workspace)
-{
- for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first, *relation_next; relation; relation = relation_next) {
- relation_next = relation->next;
-
- if (relation->scene == NULL) {
- BLI_freelinkN(&workspace->scene_layer_relations, relation);
- }
- else if (!BLI_findstring(&relation->scene->view_layers, relation->view_layer, offsetof(ViewLayer, name))) {
- BLI_freelinkN(&workspace->scene_layer_relations, relation);
- }
- }
-}
-
/* -------------------------------------------------------------------- */
/* General Utils */
-void BKE_workspace_view_layer_rename(
- const Main *bmain,
- const Scene *scene,
- const char *old_name,
- const char *new_name)
-{
- for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
- for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first; relation; relation = relation->next) {
- if (relation->scene == scene && STREQ(relation->view_layer, old_name)) {
- STRNCPY(relation->view_layer, new_name);
- }
- }
- }
-}
-
-void BKE_workspace_view_layer_remove(
- const Main *bmain,
- const ViewLayer *UNUSED(view_layer))
-{
- for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
- BKE_workspace_scene_relations_free_invalid(workspace);
- }
-}
-
WorkSpaceLayout *BKE_workspace_layout_find(
const WorkSpace *workspace, const bScreen *screen)
{
@@ -429,46 +389,6 @@ void BKE_workspace_active_screen_set(WorkSpaceInstanceHook *hook, WorkSpace *wor
BKE_workspace_hook_layout_for_workspace_set(hook, workspace, layout);
}
-Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *scene)
-{
- ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
- return view_layer->basact;
-}
-
-ViewLayer *BKE_workspace_view_layer_exists(const WorkSpace *workspace, const Scene *scene)
-{
- WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_layer_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
- return (relation) ? BLI_findstring(&scene->view_layers, relation->view_layer, offsetof(ViewLayer, name)) : NULL;
-}
-
-ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene)
-{
- ViewLayer *layer = BKE_workspace_view_layer_exists(workspace, scene);
-
- if (layer == NULL) {
- BKE_workspace_view_layer_set((WorkSpace *)workspace, scene->view_layers.first, (Scene *)scene);
- layer = scene->view_layers.first;
- }
-
- return layer;
-}
-
-void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene)
-{
- WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_layer_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
- if (relation == NULL) {
- relation = MEM_callocN(sizeof(*relation), __func__);
- }
- else {
- BLI_remlink(&workspace->scene_layer_relations, relation);
- }
-
- /* (Re)insert at the head of the list, for faster lookups. */
- relation->scene = scene;
- STRNCPY(relation->view_layer, layer->name);
- BLI_addhead(&workspace->scene_layer_relations, relation);
-}
-
ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
{
return &workspace->layouts;
@@ -504,27 +424,6 @@ void BKE_workspace_hook_layout_for_workspace_set(
workspace_relation_ensure_updated(&workspace->hook_layout_relations, hook, layout);
}
-/* Update / evaluate */
-
-void BKE_workspace_update_tagged(Main *bmain,
- WorkSpace *workspace,
- Scene *scene)
-{
- ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
- struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene,
- view_layer,
- true);
- /* TODO(sergey): For now all dependency graphs which are evaluated from
- * workspace are considered active. This will work all fine with "locked"
- * view layer and time across windows. This is to be granted separately,
- * and for until then we have to accept ambiguities when object is shared
- * across visible view layers and has overrides on it.
- */
- DEG_make_active(depsgraph);
- BKE_scene_graph_update_tagged(depsgraph, bmain);
-}
-
-
bool BKE_workspace_owner_id_check(
const WorkSpace *workspace, const char *owner_id)
{
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 69096ad7a08..3e1a9a4f57b 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -53,6 +53,8 @@
#include "BKE_node.h"
#include "BKE_world.h"
+#include "DRW_engine.h"
+
#include "DEG_depsgraph.h"
#include "GPU_material.h"
@@ -62,6 +64,8 @@ void BKE_world_free(World *wrld)
{
BKE_animdata_free((ID *)wrld, false);
+ DRW_drawdata_free((ID *)wrld);
+
/* is no lib link block, but world extension */
if (wrld->nodetree) {
ntreeFreeTree(wrld->nodetree);
@@ -119,6 +123,7 @@ void BKE_world_copy_data(Main *bmain, World *wrld_dst, const World *wrld_src, co
}
BLI_listbase_clear(&wrld_dst->gpumaterial);
+ BLI_listbase_clear((ListBase *)&wrld_dst->drawdata);
if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
BKE_previewimg_id_copy(&wrld_dst->id, &wrld_src->id);
@@ -154,6 +159,7 @@ World *BKE_world_localize(World *wrld)
wrldn->preview = NULL;
BLI_listbase_clear(&wrldn->gpumaterial);
+ BLI_listbase_clear((ListBase *)&wrldn->drawdata);
return wrldn;
}
@@ -163,10 +169,3 @@ void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local)
BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local);
}
-void BKE_world_eval(struct Depsgraph *depsgraph, World *world)
-{
- DEG_debug_print_eval(depsgraph, __func__, world->id.name, world);
- if (!BLI_listbase_is_empty(&world->gpumaterial)) {
- world->update_flag = 1;
- }
-}
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index 994592ec307..1db239b3c6f 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -197,8 +197,6 @@ static int start_avi(void *context_v, Scene *UNUSED(scene), RenderData *rd, int
avi->interlace = 0;
avi->odd_fields = 0;
-/* avi->interlace = rd->mode & R_FIELDS; */
-/* avi->odd_fields = (rd->mode & R_ODDFIELD) ? 1 : 0; */
printf("Created avi: %s\n", name);
return 1;