diff options
author | Rohan Rathi <rohanrathi08@gmail.com> | 2018-07-21 16:59:15 +0300 |
---|---|---|
committer | Rohan Rathi <rohanrathi08@gmail.com> | 2018-07-21 16:59:15 +0300 |
commit | 4e6bcd10e559ab541df53a3d7b645faac1a7fe27 (patch) | |
tree | ba214c23868fe76ec5d2199b83846814bf79be25 /source/blender/blenkernel | |
parent | b6b185691f018f6b175ffb58c65418991cda75f2 (diff) | |
parent | e361e9e99c5b6140b6284e81fa315bdcc48cee58 (diff) |
Merge branch 'blender2.8' into soc-2018-bevel
Diffstat (limited to 'source/blender/blenkernel')
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(¶llel_range_settings); + BLI_task_parallel_range(0, coarse_mesh->totpoly, + &ctx, + subdiv_eval_task, + ¶llel_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; |